0

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

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

在此处输入图像描述

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

在此处输入图像描述

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

更新 #1 (2013.07.18)

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

4

2 回答 2

1

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

防止 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。所以要修复它,我们只需在可以修复问题的方向上按世界宽度调整像素。希望。

于 2013-07-18T18:41:03.357 回答
0

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

无论如何,这是一个实现该解决方案的简单示例。我们提出的策略是跟踪我们处理的最后一个点的经度。在处理新点时,如果我们看到一个点进行了真正的错误跳转(在 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];
}
于 2013-07-23T16:10:53.123 回答