2017-08-11 64 views
2

我試圖通過android繪製谷歌地圖上的方形網格。儘管投影谷歌地圖繪製廣場

如果我在geopy中使用VincentyDistance在我的python服務器上測量出250米乘250米的距離,那麼地圖上生成的網格顯着爲矩形而非方形。

由於谷歌地圖所使用的投影導致了不成比例的拉伸,因此如果我改用谷歌的SphericalUtil.computeOffset,我可以在地圖上生成接近完美的正方形。

這是否表明距離computeOffset的距離是錯誤的?或者地理錯誤?有人可以幫我理解這種行爲嗎?

理想情況下,像計算是服務器端,理想情況下,我可以在世界上的任何地方生成方形網格,即使它實際上意味着方形不是方形,只要它在地圖投影上呈現方形。

回答

1

編輯:

「?這是否表明,從computeOffset的距離是錯誤的......」

不,這是沒有錯的,這是一個投影。投影伸展,壁球,歪斜,...所有東西

這個詞被投影爲一個矩形,高度的兩倍大。 360°寬,180°高。 北極和南極(都只是一個popint)被拉長,就像赤道一樣長。

除了...谷歌地圖然後壓縮該地圖,幾乎一個正方形(取決於變焦)。所以,你必須檢查的界限,使谷歌地圖爲您提供了


您可以閱讀度密度水平,然後垂直,從地圖邊界。當瓷磚加載時,你可以閱讀這個。如果你想你可以發送這個數據到服務器,與AJAX(不包括在此代碼中)

有一件事我不禁要是你的屏幕上的像素不是正方形。那麼,也許你可以搜索的物理像素密度和因素,以及。也許這有助於:Mobile web: how to get physical pixel size?

作爲一個例子:400x400像素的地圖。中間的紅色正方形,地圖寬度和高度的一半。 對不起,這是一個JavaScript /網站的例子,而不是Python/Android。但我想你可以使用相同的原則。

<!DOCTYPE html> 
<html> 
<head> 
<title>Square on Map</title> 
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"> 
<meta charset="utf-8"> 
<style> 
    html, 
    body { 
     height: 400px; 
     width: 400px; 
     padding: 0; 
    } 
    #map { 
     height: 80%; 
    } 
</style> 
<script> 
    var map; 
    // return a polyline. If you give 2 points, it will simply be a line 
    function makePolyline(points, color, close) { 
     if (close) { 
      points.push(points[0]); // closed polyline, so duplicate the start point as the endpoint 
     } 
     return new google.maps.Polyline({ 
      path: points, 
      //geodesic: false, 
      strokeColor: color, // example: '#FF0000', 
      strokeOpacity: 1.0, 
      strokeWeight: 2, 
      map: map 
     }); 
    } 

    function initMap() { 
     var myLocation = { 
      lat: 43, 
      lng: -108 
     }; 
     map = new google.maps.Map(document.getElementById('map'), { 
      center: myLocation, 
      zoom: 5 
     }); 

     // wait until the map is loaded before calculating bounds 
     google.maps.event.addListenerOnce(map, 'tilesloaded', function() { 
      var mapWidth = document.getElementById('map').offsetWidth; 
      var mapHeight = document.getElementById('map').offsetWidth; 
      var bounds = map.getBounds(); 
      var NE = bounds.getNorthEast(); 
      var SW = bounds.getSouthWest(); 

      // draw a square half the size of the map (200 X 200 px), in the midle => start at 1/4, stop at 3/4 
      points = [{ 
      lat: SW.lat() + ((NE.lat() - SW.lat()) * 1/4), 
      lng: SW.lng() + ((NE.lng() - SW.lng()) * 1/4) 
      }, 
      { 
      lat: SW.lat() + ((NE.lat() - SW.lat()) * 1/4), 
      lng: SW.lng() + ((NE.lng() - SW.lng()) * 3/4) 
      }, 
      { 
      lat: SW.lat() + ((NE.lat() - SW.lat()) * 3/4), 
      lng: SW.lng() + ((NE.lng() - SW.lng()) * 3/4) 
      }, 
      { 
      lat: SW.lat() + ((NE.lat() - SW.lat()) * 3/4), 
      lng: SW.lng() + ((NE.lng() - SW.lng()) * 1/4) 
      }]; 
      makePolyline(points, '#ff0000', true); 

      // display the numbers in a div. Feel free to not do this 
      document.getElementById('log').innerHTML = 'map width: ' + mapWidth + 'px - map height: ' + mapHeight + 'px<br/>'; 
      document.getElementById('log').innerHTML += 'horizontal: ' + ((NE.lng() - SW.lng())/mapWidth).toFixed(4) + ' degrees/px<br/>'; 
      document.getElementById('log').innerHTML += 'vertical: ' + ((NE.lat() - SW.lat())/mapHeight).toFixed(4) + ' degrees/px<br/>'; 
     }); 
    } 
</script> 
</head> 
<body> 
    <div id="map"></div> 
    <div id="log"></div> 
    <script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script> 
</body> 
</html> 
+0

感謝這個有趣的方法。問題是,需要一個從用戶到用戶一致的網格,這就是爲什麼我在服務器端做這件事。 – RedEyes