google maps API v3 - 如何绘制动态多边形/折线?

Posted

技术标签:

【中文标题】google maps API v3 - 如何绘制动态多边形/折线?【英文标题】:google maps API v3 - how to draw dynamic polygons/polylines? 【发布时间】:2011-03-24 14:58:29 【问题描述】:

我有 4 天的 Google Maps javascript API 使用经验,我发现他们的文档和信息共享充其量是令人困惑的。

有没有人有关于如何在谷歌地图(使用 Javascript API V3)上绘制多边形/折线的经验或知识,类似于this 示例? (我在 2008 年的 this blogPost 上发现)

据我的研究可以告诉我,该示例​​直接使用 Javascript API V2 或使用 V2 中的 GeometryControl 实用程序库(可以找到 here 以供参考)。我似乎找不到 Javascript API V3 是否有任何方式允许这样的接口。

我将继续我的研究,但如果有任何有用的评论、链接或建议,我将不胜感激。即使您为我指明了进一步研究的正确方向。 :)

【问题讨论】:

【参考方案1】:

经过大量研究,我遇到了this 示例。在发现它并用谷歌搜索它之后,它似乎是对像我这样的问题的一般答案。这是非常基本的,但根据 V3 API 是正确的。

使用本示例中的代码,我成功地构建了我需要的原型。代码是基本的,但我发现可以对其进行扩展以更好地适应我的规范,这很好。

我在评论中提供的对 plexer 答案的链接将是最好的解决方案,但开发它的人表示它仍在开发中,因此不够稳定,无法在发布应用程序中使用。

【讨论】:

你的例子不工作,你能提供另一个工作网址 这个答案和相关链接是 6 年前给出的。据我了解,谷歌从那时起在地图“API”中的绘图工具功能上做了一些体面的工作。我建议访问developers.google.com 看看发生了什么。【参考方案2】:

对于谷歌地图 v3.7,您可以使用Drawing Library

另一个不错的库:polygonEdit/polylineEdit by ryshkin@gmail.com

【讨论】:

@Phaed:您推荐的 polygonEdit 链接被 Comodo 标记为网络钓鱼站点:该站点可能存在欺诈行为,试图通过伪装成合法站点来收集您的个人信息。该网站已被多位用户报告为不安全,我们不建议您继续浏览。【参考方案3】:

看看我的曲线脚本: http://curved_lines.overfx.net/

以下是我使用的函数:

function curved_line_generate(LatStart, LngStart, LatEnd, LngEnd, Color, Horizontal, Multiplier) 

  var LastLat = LatStart;
  var LastLng = LngStart;

  var PartLat;
  var PartLng;

  var Points = new Array(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9);
  var PointsOffset = new Array(0.2, 0.35, 0.5, 0.55, 0.60, 0.55, 0.5, 0.35, 0.2);

  var OffsetMultiplier = 0;

  if (Horizontal == 1) 
    var OffsetLenght = (LngEnd - LngStart) * 0.1;
   else 
    var OffsetLenght = (LatEnd - LatStart) * 0.1;
  

  for (var i = 0; i < Points.length; i++) 
    if (i == 4) 
      OffsetMultiplier = 1.5 * Multiplier;
    

    if (i >= 5) 
      OffsetMultiplier = (OffsetLenght * PointsOffset[i]) * Multiplier;
     else 
      OffsetMultiplier = (OffsetLenght * PointsOffset[i]) * Multiplier;
    

    if (Horizontal == 1) 
      PartLat = (LatStart + ((LatEnd - LatStart) * Points[i])) + OffsetMultiplier;
      PartLng = (LngStart + ((LngEnd - LngStart) * Points[i]));
     else 
      PartLat = (LatStart + ((LatEnd - LatStart) * Points[i]));
      PartLng = (LngStart + ((LngEnd - LngStart) * Points[i])) + OffsetMultiplier;
    

    curved_line_create_segment(LastLat, LastLng, PartLat, PartLng, Color);

    LastLat = PartLat;
    LastLng = PartLng;
  

  curved_line_create_segment(LastLat, LastLng, LatEnd, LngEnd, Color);



function curved_line_create_segment(LatStart, LngStart, LatEnd, LngEnd, Color) 
  var LineCordinates = new Array();

  LineCordinates[0] = new google.maps.LatLng(LatStart, LngStart);
  LineCordinates[1] = new google.maps.LatLng(LatEnd, LngEnd);

  var Line = new google.maps.Polyline(
    path: LineCordinates,
    geodesic: false,
    strokeColor: Color,
    strokeOpacity: 1,
    strokeWeight: 3
  ); 

  Line.setMap(map);

这是您的 html 内容 + 初始化脚本:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">

  var map;
  google.maps.event.addDomListener(window, 'load', initialize);

  function initialize() 

    /* Create Google Map */ 

    var myOptions = 
      zoom: 6,
      center: new google.maps.LatLng(41, 19.6),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    ;

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

    /* Add Sample Lines */

    /* Sofia - Burgas */
    curved_line_generate(42.68243562027229, 23.280029421875042, 42.488302202180364, 27.432861453125042,"#F00", true, 1);

    /* Sofia - Varna */
    curved_line_generate(42.68243562027229, 23.280029421875042, 43.19716750254011, 27.894287234375042,"#1a8809", true, 1);

    /* Ancona - Sofia */
    curved_line_generate(43.61221698671215, 13.458252078125042,42.68243562027229, 23.280029421875042, "#00F", true, 1);

    /* Sofia - Florence */
    curved_line_generate(42.68243562027229, 23.280029421875042, 43.73935229722859, 11.217041140625042,"#666", true, 1);

    /* Sofia - Athens */
    curved_line_generate(42.68243562027229, 23.280029421875042, 37.97884527841534, 23.719482546875042,"#ffa200", false, 2);
  

</script>

【讨论】:

【参考方案4】:

查看此示例,来自 Maps API v3 示例页面:

http://code.google.com/apis/maps/documentation/javascript/examples/polyline-complex.html

代码监听地图上的点击,并在每次点击时将额外的纬度/经度对添加到折线数组中。这会产生一条连接每个点击点的折线。

将此扩展到多边形应该相对简单。在某些时候,您需要关闭多边形。您可以通过单击多边形或标记(指示交叉点)或通过用户可以单击的按钮并将多边形设置为自动关闭来做到这一点。

【讨论】:

感谢信息 plexer。我发现了两件有趣的事情,一件我将标记为问题的“答案”。但仅供参考,看看shanetomlinson.com/2010/enabledrawing-enableediting-for-gmap-v3 和他的例子。它仍然有点不稳定,所以不是最好的解决方案,但他似乎正朝着正确的方向前进。 只是一个更新 - 上面的评论链接不再有效。所以HERE 似乎是更新版本。 :)【参考方案5】:

我发现这个很简单。你可以画多边形,可以找到它们的长度,而且很简单。http://geojason.info/demos/line-length-polygon-area-google-maps-v3/

这里有一些代码,以防链接断开。

var map;

// Create a meausure object to store our markers, MVCArrays, lines and polygons
var measure = 
  mvcLine: new google.maps.MVCArray(),
  mvcPolygon: new google.maps.MVCArray(),
  mvcMarkers: new google.maps.MVCArray(),
  line: null,
  polygon: null
;

// When the document is ready, create the map and handle clicks on it
jQuery(document).ready(function() 

  map = new google.maps.Map(document.getElementById("map"), 
    zoom: 15,
    center: new google.maps.LatLng(39.57592, -105.01476),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    draggableCursor: "crosshair" // Make the map cursor a crosshair so the user thinks they should click something
  );

  google.maps.event.addListener(map, "click", function(evt) 
    // When the map is clicked, pass the LatLng obect to the measureAdd function
    measureAdd(evt.latLng);
  );

);

function measureAdd(latLng) 

  // Add a draggable marker to the map where the user clicked
  var marker = new google.maps.Marker(
      map: map,
      position: latLng,
      draggable: true,
      raiseOnDrag: false,
      title: "Drag me to change shape",
      icon: new google.maps.MarkerImage(
        "/images/demos/markers/measure-vertex.png", 
        new google.maps.Size(9, 9),
        new google.maps.Point(0, 0),
        new google.maps.Point(5, 5)
      )
  );

  // Add this LatLng to our line and polygon MVCArrays
  // Objects added to these MVCArrays automatically update the line and polygon shapes on the map
  measure.mvcLine.push(latLng);
  measure.mvcPolygon.push(latLng);

  // Push this marker to an MVCArray
  // This way later we can loop through the array and remove them when measuring is done
  measure.mvcMarkers.push(marker);

  // Get the index position of the LatLng we just pushed into the MVCArray
  // We'll need this later to update the MVCArray if the user moves the measure vertexes
  var latLngIndex = measure.mvcLine.getLength() - 1;

  // When the user mouses over the measure vertex markers, change shape and color to make it obvious they can be moved
  google.maps.event.addListener(marker, "mouseover", function() 
    marker.setIcon(
      new google.maps.MarkerImage("/images/demos/markers/measure-vertex-hover.png",
        new google.maps.Size(15, 15), 
        new google.maps.Point(0, 0), 
        new google.maps.Point(8, 8)
      )
    );
  );

  // Change back to the default marker when the user mouses out
  google.maps.event.addListener(marker, "mouseout", function() 
    marker.setIcon(
      new google.maps.MarkerImage(
        "/images/demos/markers/measure-vertex.png",
        new google.maps.Size(9, 9),
        new google.maps.Point(0, 0),
        new google.maps.Point(5, 5)
      )
    );
  );

  // When the measure vertex markers are dragged, update the geometry of the line and polygon by resetting the
  //     LatLng at this position
  google.maps.event.addListener(marker, "drag", function(evt) 
    measure.mvcLine.setAt(latLngIndex, evt.latLng);
    measure.mvcPolygon.setAt(latLngIndex, evt.latLng);
  );

  // When dragging has ended and there is more than one vertex, measure length, area.
  google.maps.event.addListener(marker, "dragend", function() 
    if (measure.mvcLine.getLength() > 1) 
      measureCalc();
    
  );

  // If there is more than one vertex on the line
  if (measure.mvcLine.getLength() > 1) 

    // If the line hasn't been created yet
    if (!measure.line) 

      // Create the line (google.maps.Polyline)
      measure.line = new google.maps.Polyline(
        map: map,
        clickable: false,
        strokeColor: "#FF0000",
        strokeOpacity: 1,
        strokeWeight: 3,
        path:measure. mvcLine
      );

    

    // If there is more than two vertexes for a polygon
    if (measure.mvcPolygon.getLength() > 2) 

      // If the polygon hasn't been created yet
      if (!measure.polygon) 

        // Create the polygon (google.maps.Polygon)
        measure.polygon = new google.maps.Polygon(
          clickable: false,
          map: map,
          fillOpacity: 0.25,
          strokeOpacity: 0,
          paths: measure.mvcPolygon
        );

      

    

  

  // If there's more than one vertex, measure length, area.
  if (measure.mvcLine.getLength() > 1) 
      measureCalc();
  

【讨论】:

感谢 TheRaaaZ 提供代码。我很快就会接触到地理定位项目,这肯定有助于重新开始工作。似乎确实有一些事情发生了变化,我认为其中大部分是由于他们最近对 Google 地图进行了重大升级?【参考方案6】:

这看起来是我发现的最接近多边形编辑器的实现:http://snipplr.com/view/38270/google-maps-api-v3--enableediting-polylines/

【讨论】:

以上是关于google maps API v3 - 如何绘制动态多边形/折线?的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps API v3 - 如何清除叠加层?

使用带有google maps api v3的addresspiquer在地图中绘制圆圈

从 MySQL 数据库在 Google Maps API v3 上绘制多个多边形

Google Map API Javascript v3-如何在多边形/矩形区域内突出显示特定街道/街道段?

google maps api v3 导出当前地图的 kml 文件

Google MAPS API V3 --> 如何显示存储在我的 MYSQL 表中的所有多边形?