谷歌地图API V3 - 防止ImageMapType包装

9
请注意:
这个问题与我在stackoverflow上找到的这个问题非常相似。 Google Maps v3 ImageMapType Prevent Wrapping 然而,上述问题和答案对于我的示例/问题没有起作用,因为我需要能够在任何缩放级别下查看我的所有图像,更重要的是,我需要绘图工具正常工作。

我的情况:

我有一个使用ImageMapType的自定义谷歌地图,它还具有DrawingManager库和工具。

我的问题:

乍一看所有的东西都很好,但是如果您要绘制任何标记或多边形,然后平移地图,标记/多边形会重复或移动到地图视图区域内。

在地图上绘制大型多边形时也会出现同样的问题,当您绘制多边形时,您会注意到您正在绘制的线突然会跳到多边形的错误侧面。

我的问题是:

如何防止包装问题,以使所有标记不移动或重复,并使绘图工具在不捕捉多边形的另一侧的情况下工作?


在线示例:

http://jsbin.com/ecujug/5/edit#javascript,live

问题的视频:

https://dl.dropbox.com/u/14037764/Development/stackoverflow/map-drawing/issue.html

期望效果:

http://www.maplib.net/map.php?id=1236

2个回答

13

你应该在更高的缩放级别工作,并选择除了 (0,0) 瓦片以外的其他起点来处理图像,而不是使用 1-3 缩放级别。你所需要的只是简单的 数学。默认情况下,您的地图将以 LatLng(0,0) 点为中心(正如您在 MapOptions 中提到的),计算将围绕该点进行。

理论

在任何缩放级别下,总共有 2^zoom x 2^zoom 个瓦片:

                           zoom
  _______________________ 2
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_|          
  |_|_|_|_|_|_|_|_|_|_|_|          
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_|          
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_|
  |_|_|_|_|_|_|_|_|_|_|_| 
  zoom
 2

由于LatLng(0,0)是中心GPS点,包含该点的瓦片应该是瓦片表(tile-sheet)的中央瓦片:

                           zoom
  _______________________ 2
  |                     |
  |                     |
  |                     |           zoom
  |                     |          2         zoom-1
  |          o----------|-------*  ------ = 2
  |          |_|        |            2
  |          |          |
  |          |          |
  |          |          |
  |__________|__________| 
  zoom       |
 2           |  zoom-1
             * 2

在任何zoom级别下,中心瓦片具有(2^(zoom-1), 2^(zoom-1))个坐标。该瓦片将成为映射的origin。通过从当前瓦片的坐标中减去原点坐标,我们将获得这样一个coordinate-space,就好像我们在1-3缩放级别工作时,原点是(0,0)瓦片一样。

实现

首先,选择更高的缩放级别,例如:

var MIN_ZOOM = 11,
    MAX_ZOOM = 13;

映射将通过getNormalizedCoord函数完成:

function getNormalizedCoord(coord, zoom) {
    //Amount of total tiles:
    // MIN_ZOOM    ->     1 tile
    // MIN_ZOOM+1  ->     2 tiles
    // MIN_ZOOM+2  ->     4 tiles
    var totalTiles = 1 << (zoom - MIN_ZOOM),
        y = coord.y,
        x = coord.x;
    var originx = 1 << (zoom-1),
        originy = 1 << (zoom-1);

    if(y < originx || y >= originx + totalTiles ||
        x < originx || x >= originx + totalTiles){
        return null;
    }

    x -= originx;
    y -= originy;

    return { x:x, y:y };
 }

最后,ImageMapOptions 应该是:

var siteMapOptions = {
    getTileUrl: function (coord, zoom) {
         var normalizedCoord = getNormalizedCoord(coord, zoom);
         if (normalizedCoord) {
             return 'https://edocstorage.blob.core.windows.net/siteimages/2fa9fc72-23a7-41ed-86a1-b83a3ba04790/_siteTiles/tile_' + 
                    (zoom-MIN_ZOOM) + '_' + 
                    normalizedCoord.x + '-' + 
                    normalizedCoord.y + '.png';
         } else {
             return 'content/tilecutter/empty.jpg';
         }
    },
    tileSize: new google.maps.Size(256, 256),
    maxZoom: MAX_ZOOM,
    minZoom: MIN_ZOOM,
    radius: 1738000,
    name: "Site Plan"
}; 

演示现场


非常感谢你的出色回答!我相信这对许多人都会有用。 - Blowsie

3

看起来很明显 - 谷歌地图认为这是整个地球,因此它是圆形的。为什么要在最小(全球范围内)缩放级别上进行工作?让谷歌地图认为这只是一小块土地,不超过1°,问题就解决了。


谢谢您的答案,不过... 整个想法是用户可以上传图像,然后完整地查看它,如果需要,可以放大。 - Blowsie
这种方法对我的情况确实行不通,而且总体上会导致糟糕的用户体验,谢谢你的想法,但我不赞同。 - Blowsie
@Blowsie,我不明白我的解决方案是如何禁用它的。唯一改变的是您将图像映射到不同的地理坐标,这样谷歌就认为它只是一个小城市,而不是整个地球。从用户的角度来看,它看起来完全相同!窗口中的完全相同的图片。 - Tomas
也许我误解了你的回答,请提供一个示例。 - Blowsie
我在ImapeMapType的文档中没有看到如何指定放置图像的位置。https://developers.google.com/maps/documentation/javascript/reference#ImageMapType - Blowsie
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接