自定义投影坐标(GProjection)来实现Google Map中国地图和卫星图的偏差纠正

84 views
Skip to first unread message

nukq

unread,
Mar 6, 2008, 2:03:59 PM3/6/08
to Google 地图 API 讨论组
原理:

通过自定义GMapType(ditu)和自定义投影坐标GProjection(dituProjection) 来实现偏差纠正。

原理是修改ditu层的投影换算函数,
在.fromLatLngToPixel()里面 +Offset
在.fromPixelToLatLng()里面 -Offset

这样子就无需修改上层Overlay的坐标参数,直接使用正确的Lat,Lng即可
代码:(以上海为例)

function load_gmap()
{

//shanghai
var xOffset= -0.001889737;
var yOffset= 0.004844069;

var map = null;


if(GBrowserIsCompatible()) {


var Cditu = new GCopyright(1,
new GLatLngBounds(
new GLatLng(-90,-180),
new GLatLng(90,180) ),
0,
"Mapabc.com");

var copyright = new GCopyrightCollection("");

copyright.addCopyright(Cditu);
var dituTileLayer = new GTileLayer(copyright, 1, 17);

dituTileLayer.getTileUrl = function(tile, zoomlevel,x) {
var url = G_NORMAL_MAP.getTileLayers()
[0].getTileUrl(tile,zoomlevel,x);
var bits = url.split("&");
bits[1] = "http://mapgoogle.mapabc.com/googlechina/maptile?" +
bits[1];
bits.shift();
url = bits.join("&");
return url;
};


function dituProjection(xOffset,yOffset){
this.xOffset = xOffset;
this.yOffset = yOffset;
}

dituProjection.prototype = new GProjection();

dituProjection.prototype.fromLatLngToPixel = function(latlng, zoom){
return (G_NORMAL_MAP.getProjection()).fromLatLngToPixel(new
GLatLng(latlng.lat()+this.xOffset,latlng.lng()+this.yOffset),zoom);
};

dituProjection.prototype.fromPixelToLatLng =
function(pixel,zoom,unbounded)
{
var latlng =
(G_NORMAL_MAP.getProjection()).fromPixelToLatLng(pixel,zoom,unbounded);
return new GLatLng(latlng.lat()-this.xOffset,latlng.lng()-
this.yOffset);
}

dituProjection.prototype.tileCheckRange = function(tile, zoom,
tilesize)
{
return
(G_NORMAL_MAP.getProjection()).tileCheckRange(tile,zoom,tilesize);
}
dituProjection.prototype.getWrapWidth = function(zoom)
{
return (G_NORMAL_MAP.getProjection()).getWrapWidth(zoom);
}


var ditu = new GMapType([dituTileLayer],
new dituProjection(xOffset,yOffset),
"Ditu",
{ shortName: "ditu", alt: "layer from ditu.google.com" }
);


map = new GMap2(document.getElementById('gmap'),{mapTypes:[ditu,/
*G_NORMAL_MAP,*/G_SATELLITE_MAP]});
map.addControl(new GLargeMapControl());
/**map.addControl(new GMapTypeControl());**/
map.addControl(new GOverviewMapControl());
map.addControl(new GScaleControl());

map.enableDoubleClickZoom();
/**map.enableScrollWheelZoom();**/

map.setCenter(new GLatLng(31.231628368031693, 121.47645235061645 ),
16);

ditu.getName = function(){ return '中国地图';};
ditu._getName = function(){ return 'ditu';};
/*
G_NORMAL_MAP.getName = function(){ return '世界地图';};
G_NORMAL_MAP._getName = function(){ return 'Map';};
*/
G_SATELLITE_MAP.getName = function(){ return '卫星图';};
G_SATELLITE_MAP._getName = function(){ return 'Satellite';};

/** the map type **/
var _mt = ditu;

map.setMapType(_mt);

map.addControl(new GMapTypeControl());

var point = new GLatLng(31.231628368031693, 121.47645235061645);

map.addOverlay(new GMarker(point));

}



}

演示地址:
http://www.mipang.com/tmp/gmap_offset_test.ue

交流:
http://www.mipang.com/groups/31@/t.26540.f4a.htm

John Wang

unread,
Mar 9, 2008, 11:44:15 PM3/9/08
to Google 地图 API 讨论组
一个很不错的方法。
但是这里还存在一个问题就是,lat, lng offset这个值的问题
1. 每个城市不一样
2. mapabc是否会周期性对这个进行修改?

nukq

unread,
Mar 10, 2008, 3:34:23 AM3/10/08
to Google 地图 API 讨论组
1. 这个需要采集资料维护偏差数值
2. 如果mapabc真的动态更改偏差,那么可以考虑自己实现Tile的数据源(.getTileUrl()方法),可以使用其他地图商
(51ditu之类)的数据

John Wang

unread,
Mar 26, 2008, 5:15:21 AM3/26/08
to Google 地图 API 讨论组
不知道你有没有添加infowin试过?我试了一下,显示没问题,但是添加infowin之后,点击marker之后,infowin的窗口偏移很不正
常。

nukq

unread,
Mar 27, 2008, 7:20:25 AM3/27/08
to Google 地图 API 讨论组
还没试过,有空我尝试一下

马子逊

unread,
Mar 27, 2008, 3:46:16 AM3/27/08
to Google-Map...@googlegroups.com
我做的marker没有偏移啊。
我用的方法如下:
function createMarker(lat,lng,index,region) {
var point = new GLatLng(lat,lng)
var marker = new GMarker(point,icon);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(region);
});

markers[index] = marker;
return marker;

nukq

unread,
Apr 3, 2008, 4:40:12 AM4/3/08
to Google 地图 API 讨论组
我试了一下,很正常,没有你说的infowin窗口偏移问题。

http://www.mipang.com/tmp/gmap_offset_test.ue

On 3月26日, 下午5时15分, John Wang <yongtao.w...@gmail.com> wrote:

nukq

unread,
Apr 3, 2008, 4:42:29 AM4/3/08
to Google 地图 API 讨论组
另外提醒一下,Google引用Mapabc的tile地址变了
要改成
bits[1] = "http://servicetile.mapabc.com/googlechina/maptile?" +
bits[1];
Reply all
Reply to author
Forward
0 new messages