【问题标题】:How can some LatLng be used to place markers on a Google map, but not to draw a Polygon?如何使用一些 LatLng 在谷歌地图上放置标记,而不是绘制多边形?
【发布时间】:2012-02-06 08:11:59
【问题描述】:

大约一周前,我遇到了一个问题:在自定义的 google 地图上,我的多边形不会显示,而相同坐标的标记完全可以。尽管我努力使用 Google Maps API,但似乎我找不到原因。

Here is a link to a screenshot of the map.紫色箭头和数字是我添加的,它们显示:

  1. google.maps.Marker 我可以放置在“区域”的边缘。
  2. google.maps.Polygon 代码生成的工件。正如预期的那样,它是红色的,但完全不合适,而且平坦得奇怪。

这是生成标记和多边形的代码部分:

var regionData = tecMap.regions[r];
var regionMapMarkers = new google.maps.MVCArray();

for (c in regionData.coords) {
    var point = projection.worldToMap(regionData.coords[c]);
    debugRegionPoints.push(point);
    var thisLatLng = projection.fromPointToLatLng(point);
    debugRegionLatLngs.push(thisLatLng);
    regionMapMarkers.push(thisLatLng);
}

regionMapMarkers.forEach(function(latLng, m){
    var marker = new google.maps.Marker({       
        position: latLng,
        map: map, 
        title: '',
        optimized: false
    });
    regionCorners.push(marker);
});

var paths = new google.maps.MVCArray();
paths.push(regionMapMarkers);

var region = new google.maps.Polygon({
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map: map,
    paths: paths,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2     
});
regionPolys.push(region);

如果您对数组数组感到好奇,这与Google Maps Javascript API 完全一样。

如果想看地图和相关脚本,可以find it here。 代码 sn-p 在Scripts/tectonicus.js 中,从第 659 行开始。

[编辑]一些调试信息:

这似乎是一个渲染问题,而不是“计算”问题。 从萤火虫控制台,在我链接的地图中,两个

regionPolys[0].getPath().getArray();

for (i in regionCorners) {console.log(regionCorners[i].getPosition())};

会回来

P { Na=0.20123958504464223, Oa=-22.5249097921875}
P { Na=-0.21702715474330336, Oa=-32.7277467}
P { Na=0.19466306397879407, Oa=-37.51230686484375}
P { Na=0.12889785332031245, Oa=-49.04594858671875}

如果我是对的,这意味着它们具有相同的坐标,这与代码相同。

[Edit2] 新进展!

在处理自定义投影时,矢量似乎存在渲染问题,例如用于显示此等距 Minecraft 地图的投影。 (使用 Tectonicus 生成)

在最后一个 cmets 之后,我将添加到两个新调试数组上方链接的实时代码中, debugRegionLatLngsdebugRegionPoints。上面的代码已更新,因此您可以看到它们包含的内容。

[Edit3]投影和坐标

Cross BicycleDude 的研究与我的研究相比,现在几乎可以肯定是自定义投影破坏了多边形。其实还有a possibly related bug in Google Maps' API

之所以使用此投影,是因为 Minecraft 地图几乎是无限的,但必须使用 gmap,它在 360° 经度后环绕。同样相关的是,游戏内坐标以等距方式呈现,而 gmaps 期望更像墨卡托投影。

我尝试稍微调整一下投影,但到目前为止没有任何有趣的结果。

【问题讨论】:

  • 我相信您在多边形属性中使用了path,而实际上它应该是paths,否则,在某处查看实时代码会有所帮助。干杯,安德烈斯
  • 我找到了一些空间来上传地图和相关代码的副本。链接在问题中。如果您希望我进行任何测试,请询问。 :)
  • 您能否发布一个稍微小一点的示例来重现这一点,或者至少将我们指向您示例中的 Google 地图代码?我迷失在所有的 JavaScript 文件中......
  • @bamnet 抱歉,我在上次编辑中没有包含此内容。您要查找的代码部分位于 Scripts/tectonicus.js 中,从第 659 行开始。使用此代码编辑主帖。
  • 再看一遍后,我认为您的自定义投影(无论您用于“我的世界”投影的是什么)是什么给了您奇怪的行为。你的多边形的坐标看起来很奇怪。经度之间的增量是不同的度数,但纬度的增量是小数。我建议使用以下代码来查看坐标是否真正遵循地图上的标准北/南东/西逻辑。 --- google.maps.event.addListener(map, 'click', function(e) { alert(e.latLng.lat()+', '+e.latLng.lng()); });跨度>

标签: javascript google-maps google-maps-api-3 polygon projection


【解决方案1】:

嗯,我进一步查看了这个,我确实看到了那个长条多边形。如果你注意你的纬度,它们非常接近 0 度,这意味着赤道附近几乎是一条平线。我通过将您的坐标粘贴到一个全新的 Google 地图样本中自己验证了这一点,并且它们似乎没有与您的标记在空间上定位,因此,您需要查看坐标信息被操纵的位置,抱歉,我知道我没有找到你的问题。

我修改了 Google 地图的百慕大三角形示例以使用您的编码风格。即我采用了您的变量并遵循了您的代码的精神。此示例显示 3 个标记并为百慕大三角形绘制一个多边形。

<!DOCTYPE html>
<html>
  <head>
    <title>Bermuda Hack Triangle</title>
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta charset="UTF-8">
    <style type="text/css">
      #map_canvas {
        width: 500px;
        height: 500px;
      }
    </style>
    <script type="text/javascript" scr="https://github.com/douglascrockford/JSON-js/blob/master/json2.js"></script>
    <script type="text/javascript"
        src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script type="text/javascript">
      var map;
      function initialize() {
        var myoptions = {
            zoom: 4,
            center: new google.maps.LatLng(25, -70),
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        map = new google.maps.Map(
          document.getElementById('map_canvas'),
          myoptions
        );

        // Create pseudo coordinates
        var regionMapMarkers = new google.maps.MVCArray();
        var p1 = new google.maps.LatLng(25, -80);
        var p2 = new google.maps.LatLng(18, -66);
        var p3 = new google.maps.LatLng(32, -64);
        //p2.Qa += 360;
        //p3.Qa -= 360;
        regionMapMarkers.push(p1);
        regionMapMarkers.push(p2);
        regionMapMarkers.push(p3);
        console.log(JSON.stringify(regionMapMarkers));

        // Draw Markers
        regionMapMarkers.forEach(function(latLng, m){
            var marker = new google.maps.Marker(
            {        
            position: latLng,
            map: map, 
            title: '',
            optimized: false
            });
        });

        // Draw Polygon
        var region = new google.maps.Polygon({
          map: map,
          paths: regionMapMarkers,
          strokeColor: "#FF0000",
          strokeOpacity: 0.8,
          strokeWeight: 2,
          fillColor: "#FF0000",
          fillOpacity: 0.35
        });
      }

      google.maps.event.addDomListener(window, 'load', initialize);
    </script>
  </head>
  <body>
    <div id="map_canvas"></div>
  </body>
</html>

示例有效。如果你要运行它,你会得到被标记包围的百慕大三角形。那么问题就在于,在实践中,什么会影响你的算法?到目前为止,我们推测 Minecraft 投影会有所作为。我仍然认为是这样的。

为了验证这个理论,我试图破坏百慕大三角样本。我尝试通过取消注释以下行来添加和减去 360 度经度到两个点:

        p2.Qa += 360;
        p3.Qa -= 360;

它的作用是它仍然允许将标记放置在同一位置,但多边形填充绝对是 spacko。我相信这就是您的场景中正在发生的事情。

然后我建议您在应用程序中查看坐标系。如果你可以选择新的坐标,你就可以避免这种边缘情况的发生。

【讨论】:

  • 我认为如果未指定最后一个坐标,Google 的函数会自动关闭多边形。感谢您分享您的想法和代码。我会继续做一些研究。 +1,因为您为此花了一些时间。 :)
  • 感谢@SilverFXQuettier。我添加了额外的研究供您查看。
  • 我不明白为什么这些“thisLatLng”坐标可用于在预期位置放置标记,尽管有奇怪的“x”属性。 ://
  • 感谢@SilverFxQuettier。我完全重新审查了我的分析并大幅更新了我的答案。在这个版本中,我现在完全同意你的算法。我将重点转移到 Minecraft 投影和潜在的坐标系问题上。
  • 至少,我们正朝着正确的方向前进。我不是编写原始投影的人(所有这些都是Tectonicus 的扩展)并将此信息转发给作者。我试着摆弄一下投影,但到目前为止没有任何有趣的东西 - 请参阅 OP 了解详细信息。
【解决方案2】:

我注意到您将 paths 作为包含另一个 MVCArray 的 MVCArray 传递。您是否尝试过像 Google 文档中的示例那样只传递一个简单的单维数组?

您是否需要调用setMap() 或传入map 属性以使其呈现?


以下是 Google 的 Polygon() 代码示例... (from here)

function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var myOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737),
    new google.maps.LatLng(25.774252, -80.190262)
  ];

  // Construct the polygon
  // Note that we don't specify an array or arrays, but instead just
  // a simple array of LatLngs in the paths property
  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);
}

【讨论】:

  • 您好 Simon - 很遗憾,是的,无论我使用 path(单个数组)还是 paths 属性(数组数组),以及是否在构造函数或通过setMap() 函数。感谢您查看:)
猜你喜欢
  • 1970-01-01
  • 2011-01-20
  • 2017-12-29
  • 2020-07-27
  • 1970-01-01
  • 2012-05-31
  • 2012-11-16
  • 2017-12-16
  • 2020-06-28
相关资源
最近更新 更多