【问题标题】:How do I prevent horizontal wrapping of overlays on a google map when panned?平移时如何防止谷歌地图上的叠加层水平环绕?
【发布时间】:2013-07-18 18:26:20
【问题描述】:

我创建了一个页面,允许用户在谷歌地图上突出显示国家/地区。我的代码非常简单——我使用的是 D3.js 和谷歌的 OverlayView——我获取了国家/地区的地理 json from here

一切都很好——但是当一个国家跨越地图的最远边缘时,我的国家轮廓有时会错误地环绕在地图的中心。例如,如果平移地图以使中国的西半部在最右边,而东半部在最左边。这就是发生的事情。

注意:这似乎是地图平移问题,与缩放级别无关 - 这是地图的最小缩放设置为 2 时的相同问题

关于如何在平移地图时避免这种影响的任何想法?提前致谢!

更新 #1 (2013.07.18)

非常感谢您的回答和评论。我创建了一个very simple example of my issue。此测试页面在谷歌地图上概述了中国,并以美国为中心(因此您可以在加载时看到问题)。请注意,向任一方向平移可以解决问题,放大美国似乎无济于事。再次感谢!

【问题讨论】:

  • 你能告诉我们你的代码吗?

标签: google-maps d3.js geojson overlays


【解决方案1】:

这个问题演示了如何控制覆盖缩放范围和平移范围,以防止通过简单地不允许用户一次看到整个世界来换行。

Prevent horizontal world-wrapping of overlays in GMap v3

所以问题的关键在于 OverlayView 获取像素坐标的位置。如果我们能弄清楚如何改进该部分以使形状保持在一起,它可能会解决我们的问题。这可能有助于测试换行,但它可能不起作用,因为即使我们放大,您的问题似乎也会发生。

var proj = overlay.getProjection();
var wwidth = 0;
if (proj) wwidth = proj.getWorldWidth();
var mapsWrapsAround=false;
if (__wwidth > 0 && __wwidth < domContainer.width()) mapsWrapsAround = true;

我意识到测试经度是否与起始经度有很大不同可能不起作用,因为经度可能是正确的,但会映射到屏幕上的多个 div 位置。所以这是我们要测试的div像素坐标。但是也许您可以通过测试与地理坐标的差异相比是否在相反的方向来测试 x 的翻转。

// UNTESTED

// dimensioned somewhere outside
var start;
var startgeo;

// inside the overlay.onAdd content I think.
// Turn the overlay projection into a d3 projection
var googleMapProjection = function (coordinates) {
    var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]);
    var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates);
    var proj = overlay.getProjection();
    var worldwidth = proj.getWorldWidth();
    var finalX = pixelCoordinates.x;

    if(typeof(start) === "undefined"){
        start = pixelCoordinates;
        startgeo = googleCoordinates;
    }
    else {
        if(pixelCoordinates.x > start.x && googleCoordinates.lng() < startgeo.lng()){
              finalX -= worldwidth;
        }
        else if(pixelCoordinates.x < start.x && googleCoordinates.lng() > startgeo.lng()){
             finalX += worldwidth;                     
        } 
    }
    return [finalX, pixelCoordinates.y];
}

所以这是假设谷歌地图已经为每个坐标选择了最接近北美的屏幕位置。如果形状正确地结合在一起,那么如果结束经度大于开始经度,那么结束像素.X 也应该大于开始像素.X。但是,如果投影返回了世界另一侧的点,则相对于起始像素的新像素应该是错误的方向。也就是说,end.x 现在小于 start.x。所以要修复它,我们只需在可以修复问题的方向上按世界宽度调整像素。希望。

【讨论】:

  • 我刚刚上传了一个实现此修复的示例,但不幸的是我仍然遇到同样的问题。请参阅上面我的问题中的更新#1
  • 我一直在修改一个未经验证的想法。也许您可以在 googleMapProjection 函数中寻找翻转并尝试在返回 div 坐标的位置进行更正,如答案帖子中所示。
  • 再次感谢您的帮助。我刚刚更新了您的答案,其中包含一些示例和关于每个示例的注释。
  • 我认为您尝试发布的编辑被拒绝或其他原因。我试图添加变量更改。这是否有效还是仍然绘制不正确?
  • 谢谢 ted - 我刚刚发布了我们提出的解决方案,该解决方案很大程度上受到了您的意见的启发。再次感谢
【解决方案2】:

非常感谢 Ted 为我指明了正确的方向 - 我试图将您的答案标记为正确,但不幸的是,我在编辑您的答案时仍然遇到问题。

无论如何,实现解决方案的here is a simple sample。我们提出的策略是跟踪我们处理的最后一个点的经度。在处理新点时,如果我们看到一个点进行了真正的错误跳转(在 x 方向上) - 我们假设它已被包裹,并且我们添加或减去世界的宽度以将该点移回该国家的其他点。

这是 overlay.draw 函数中修复的重点

var markerOverlay = this;
var overlayProjection = markerOverlay.getProjection();
var worldwidth = overlayProjection.getWorldWidth();
var prevX = null;

// Turn the overlay projection into a d3 projection
var googleMapProjection = function (coordinates) {
    var googleCoordinates = new google.maps.LatLng(coordinates[1], coordinates[0]);
    var pixelCoordinates = overlayProjection.fromLatLngToDivPixel(googleCoordinates);
    if (prevX != null) {
        // Check for a gigantic jump to prevent wrapping around the world
        var dist = pixelCoordinates.x - prevX;
        if (Math.abs(dist) > (worldwidth * 0.9)) {
            if (dist > 0) { pixelCoordinates.x -= worldwidth } else { pixelCoordinates.x += worldwidth }
        }
    }
    prevX = pixelCoordinates.x;
    return [pixelCoordinates.x + 10000, pixelCoordinates.y + 10000];
}

【讨论】:

    猜你喜欢
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-15
    • 2012-04-10
    • 2023-03-22
    • 2011-06-05
    • 2011-01-30
    • 1970-01-01
    相关资源
    最近更新 更多