2017-08-11 49 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