如何使用某些经纬度在Google地图上放置标记,但不能用于绘制多边形?

12
大约一周前,我遇到了一个问题:在自定义的谷歌地图上,我的多边形不会显示出来,而相同坐标的标记完全正常。尽管我尝试使用谷歌地图API,但似乎我找不到原因。 这是地图截图的链接。 紫色箭头和数字是我添加的,它们显示:
  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);

如果你对数组的数组感到困惑,它与谷歌地图Javascript API相当。

如果你想查看地图和相关脚本,可以在此处找到它。代码片段位于Scripts/tectonicus.js,从第659行开始。

[编辑] 一些调试信息:

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

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}

如果我没错的话,这意味着它们具有相同的坐标,这与代码相符。

[编辑2] 新进展!

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

在最后的评论之后,我在上面链接的实时代码中添加了两个新的调试数组debugRegionLatLngsdebugRegionPoints,上面的代码已经更新,这样您就可以看到它们包含的内容。

[编辑3] 投影和坐标

结合BicycleDude的研究和我的研究,现在几乎可以确定是自定义投影破坏了多边形。实际上,Google Maps API中可能存在相关错误

使用此投影是因为Minecraft地图可以是虚拟无限的,并且必须使用gmap,在360°经度之后进行包装。另一个相关因素是游戏内坐标以等角方式呈现,而gmaps则期望更像是Mercator投影。

我试图微调投影,但目前没有出现有趣的结果。


1
我相信您在多边形属性中使用了 path,实际上应该是 paths。否则,如果能够看到实时代码,将会更有帮助。祝好,Andres - andresf
我找到了一些空间来上传地图和相关代码的副本。链接在问题中。如果您想让我运行任何测试,请告诉我。 :) - Silver Quettier
我使用FireBug的控制台查看了对象。将我的结果添加到OP中。对我来说毫无意义,一切都应该正常工作。 - Silver Quettier
3
我再仔细看了一下,我认为你使用的自定义投影(无论你用的是哪种“Minecraft”投影)导致了奇怪的行为。你的多边形坐标似乎非常奇怪。经度之间的差异是各种度数,但纬度之间的差异是小数。我建议使用以下代码,查看坐标如何不真正遵循地图上标准的南/北东/西逻辑。--- google.maps.event.addListener(map,'click',function(e) {alert(e.latLng.lat() +''+ e.latLng.lng());}); - andresf
我已经检查了坐标,它们是赤道附近的一个平面多边形。我目前正在调查这是否与tecMap引起的等距投影有关。最好为点和thisLatLng添加日志记录。 - Stephen Quan
显示剩余3条评论
2个回答

4

嗯,我进一步查看了一下,确实看到了那个银片多边形。如果你注意到你的纬度,它们非常接近0度,这意味着在赤道附近几乎是一条直线。我通过将您的坐标粘贴到全新的Google Maps示例中进行了验证,它们似乎没有与您的标记空间位置相关联,因此,您需要检查坐标信息的处理位置,很抱歉,我不知道如何解决您的问题。

我修改了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;

这样做仍然允许在相同位置放置标记,但是多边形填充会出现问题。我认为这就是你的情况所发生的事情。
我建议你检查应用程序中的坐标系统。如果你可以选择新的坐标,你就可以避免出现这种边缘情况。

我认为谷歌的函数会自动关闭多边形,如果没有指定最后一个坐标。感谢分享你的想法和代码。我会继续研究。+1因为你花了一些时间在这上面。 :) - Silver Quettier
谢谢@SilverFXQuettier。我已经为您添加了额外的研究内容供您查看。 - Stephen Quan
我不理解的是,为什么这些“thisLatLng”坐标可以用于在预期位置放置标记,尽管具有奇怪的“x”属性。 :/ - Silver Quettier
感谢@SilverFxQuettier。我完全重新审查了我的分析,并大幅更新了我的答案。在此版本中,我现在完全同意您的算法。我将重点转移到了Minecraft投影和潜在坐标系统问题上。 - Stephen Quan
至少,我们正在朝着正确的方向前进。我不是写原始投影的人(所有这些都是Tectonicus的扩展),并将此信息转发给了作者。我尝试过对投影进行一些调整,但到目前为止没有得到任何有趣的结果-请参阅OP获取详细信息。 - Silver Quettier
是的,我制造了一些疯狂的坐标,但红线仍然没有动。然后我设置了一些疯狂的strokeWeight,我想我用了20,然后线条确实改变了,但它看起来仍然很奇怪。我无法解释,几乎感觉在经度上发生了戏剧性的裁剪。 - Stephen Quan

0

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

并且,你是否需要调用 setMap() 方法,还是仅传递 map 属性就足以使它渲染出来了呢?


以下是Google的Polygon()代码示例... (从这里)
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);
}

1
你好Simon - 不幸的是,无论我使用path(单个数组)还是paths属性(数组的数组),以及地图是通过构造函数设置还是通过setMap()函数设置,问题都会发生。感谢您的关注 :) - Silver Quettier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接