【问题标题】:Draw google polyline with line width set in meters以米为单位绘制线宽的谷歌折线
【发布时间】:2016-06-09 04:11:49
【问题描述】:

我注意到,当您在谷歌地图中绘制折线时,您会设置它的宽度(以像素为单位)(笔画宽度)。有没有办法可以改为以米为单位?

【问题讨论】:

    标签: google-maps google-polyline


    【解决方案1】:

    不幸的是,我不知道有什么简单的方法可以做到这一点。 API 似乎没有这方面的文档,我认为此功能不受支持。

    一个问题是像素在 API 中以不同的缩放级别表示不同的米数。因此,如果缩放级别发生变化,这将是一个动态量。

    一种选择可能是以像素为单位计算宽度,以表示给定缩放级别的给定米数。为此,您必须根据每个缩放级别的地图比例编写自己的函数。该数据似乎可在此处获得:

    http://webhelp.esri.com/arcgisserver/9.3/java/index.htm#designing_overlay_gm_mve.htm

    20 : 1128.497220
    19 : 2256.994440
    18 : 4513.988880
    17 : 9027.977761
    16 : 18055.955520
    15 : 36111.911040
    14 : 72223.822090
    13 : 144447.644200
    12 : 288895.288400
    11 : 577790.576700
    10 : 1155581.153000
    9  : 2311162.307000
    8  : 4622324.614000
    7  : 9244649.227000
    6  : 18489298.450000
    5  : 36978596.910000
    4  : 73957193.820000
    3  : 147914387.600000
    2  : 295828775.300000
    1  : 591657550.500000
    

    然后,您可以根据您尝试表示的米数和当前缩放级别动态设置像素值。

    可能仍然存在问题,因为您生成的像素大小可能与屏幕像素大小不对应,具体取决于 API 如何处理屏幕 DPI 和分辨率

    【讨论】:

    • 感谢 R Ghosh。我不知道这是否奇怪,但我只是认为有一些方法可以轻松做到这一点。它们允许指定半径以米为单位的圆......
    • @dreza 此功能在文档中不存在。部分问题是行程重量不能直接转换为以米为单位的固定长度。在地图的极端角落,地图极度拉伸(水平)。在地图上的给定点,您可以计算该值,但在任何给定的缩放级别,笔画宽度到米的整个值范围。圆可能(我的猜测)允许以米为单位定义,因为它们可以在球面几何中整齐地表示和转换。
    • 我遇到了这个麻烦,我决定做一些不同的事情,所以,没有折线,只有多边形,像这样,你可以把你的 WGS84 坐标变成 UTM 和 UTM 允许更多,即你可以添加 X 米 Right /Left 到你的位置,前后 Y 米。我只是想在纵轴中间用 GPS 跟踪拖拉机并工作!
    • 问题1)描边宽度不能超过32px。问题2)墨卡托投影上的地图分辨率在所有纬度都不相同,因此您不能使用这样的固定值。
    【解决方案2】:

    基于this answer,我可以获得可接受的结果。即使这不是最好的解决方案。

    在我的例子中,我使用 Android 和 com.google.android.gms:play-services-location:8.4.0。但是原来的答案是用 JavaScript 写的,所以我觉得不难适应。

    LatLng center = <get map center>.
    float requiredWidth = 10; // in meters
    Projection proj = googleMap.getProjection();
    Point pointCenter = proj.toScreenLocation(center); // point in pixels
    LatLng neighbor = proj.fromScreenLocation(new Point(pointCenter.x + 1000, pointCenter.y));
    float[] distance = new float[1]; 
    Location.distanceBetween(center.latitude, center.longitude, neighbor.latitude, neighbor.longitude, distance); // return distance in meters
    float pixelsWidth = requiredWidth / (distance[0] / 1000f); // 10 meters conveted to pixels
    myPolyline.setWidth(pixelsWidth);
    

    我的答案与原答案的不同之处在于我创建了距离为 1000 像素的邻居,以获得更高的采样率并提高精度。

    这种方法也会自动考虑缩放。

    【讨论】:

      【解决方案3】:

      这不是准确的解决方案

      您可以使用传单的Scale control。基本上,您会得到比例尺的值并计算一个像素可以容纳多少米。

      /**
       * Returns number of meters in one pixel.
       *
       * @return Integer number of meters in one pixel
       */
      var _metersInPixel = function () {
          var pixels = $('.leaflet-control-scale-line').width();
          var distance = $('.leaflet-control-scale-line').first().text();
      
          var testRegExpKm = /(\d+)\skm/;
          var testRegExpM = /(\d+)\sm/;
          if (testRegExpKm.test(distance)) {
              var match = testRegExpKm.exec(distance);
              var meters = parseInt(match[1]) * 1000;
          } else if (testRegExpM.test(distance)) {
              var match = testRegExpM.exec(distance);
              var meters = parseInt(match[1]);
          } else {
              throw "Unable to determine meters to pixels ratio";
          }
      
          var metersInPixels = Math.round(meters / parseInt(pixels));
          return metersInPixels;
      };
      

      【讨论】:

      • 好的,这是横向思维的一个巧妙之处。我是否假设它仅在存在 L.Control.Scale 的实例时才有效?
      猜你喜欢
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多