2013-07-18 82 views
0

我創建了一個頁面,允許用戶在谷歌地圖上突出顯示國家。我的代碼非常簡單 - 我使用D3.js和Google的OverlayView - 我爲from here的國家獲取了geo json。如何在平移時防止Google地圖上的疊加層水平纏繞?

一切都很好 - 但是當一個國家跨越地圖的最遠邊緣時,我的國家輪廓有時會錯誤地跨越地圖中心。例如,如果地圖是平移的,那麼中國西部的一半位於最右側,而東部的一半位於最左側。這是發生了什麼。

enter image description here

注:這似乎是一個地圖平移問題,並沒有與縮放級別做的 - 這裏是同樣的問題,與地圖的最小縮放設置爲2

enter image description here

有關如何在地圖平移時避免此效應的任何想法?提前致謝!

更新#1(2013年7月18日)

感謝這麼多的答案和註釋。我創建了一個very simple example of my issue。這個測試頁面在谷歌地圖上列出了中國概況,並以美國爲中心(因此您可以在負載情況下看到問題)。通知在任何一個方向平移都可以解決問題,放大美國似乎沒有幫助。再次感謝!

+0

肉你能告訴我們你的代碼? –

回答

0

非常感謝特德爲我指出了正確的方向 - 我試圖標記你的答案是正確的,但不幸的是我仍然有問題編輯你的答案。

無論如何,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]; 
} 
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。因此,爲了解決這個問題,我們只是按照解決問題的方向按照世界寬度調整像素。希望。

+0

我剛剛上傳了一個實現此修復程序的示例,但不幸的是我仍然遇到同樣的問題。請參閱我的問題上面的更新#1 – jskunkle

+0

我一直在修補一個未經測試的想法。也許你可以在googleMapProjection函數中尋找翻轉的東西,然後嘗試在返回div座標的位置進行修正,如答案文章中所示。 – Ted

+0

再次感謝您的幫助。我剛剛更新了一些關於每一個的樣本和備註。 – jskunkle