Programmatically drawing polygons on a map by joining the outermost markers

只谈情不闲聊 提交于 2019-12-11 11:09:34

问题


I have a sample map layer in this fiddle where the map layer is drawn using fusion table as,

var Layer = new google.maps.FusionTablesLayer({
    query: {
       select: 'lat',
       from: '1BLPDF4n0sW0i0BfD9Yo0DqbshyTH1s5Iuu_1IeU'
    },
    map: map,
    suppressInfoWindows: true
});

How can I draw a polygon programmatically by joining the outermost markers in the map so that if someone add new marker and if it is falling outside the drawn polygon then automatically the polygon should redraw to include the newly added marker too.


回答1:


You want to do a Convex Hull of your points.

Example using the Google Maps API v3 on a random set of points

jsfiddle

code snippet:

var gmarkers = [];
var points = [];
var hullPoints = [];
var map = null;
var polyline;

var infowindow = new google.maps.InfoWindow({
  size: new google.maps.Size(150, 50)
});

function initialize() {
  var myOptions = {
    zoom: 13,
    center: new google.maps.LatLng(37.4419, -122.1419),
    mapTypeControl: true,
    mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    },
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map_canvas"),
    myOptions);

  google.maps.event.addListener(map, 'click', function() {
    infowindow.close();
  });

  google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
    // Add 10 markers to the map at random locations
    var bounds = map.getBounds();
    var southWest = bounds.getSouthWest();
    var northEast = bounds.getNorthEast();
    var lngSpan = northEast.lng() - southWest.lng();
    var latSpan = northEast.lat() - southWest.lat();
    map.setCenter(map.getCenter());
    map.setZoom(map.getZoom() - 1);
    for (var i = 0; i < 10; i++) {
      var point = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(),
        southWest.lng() + lngSpan * Math.random());
      points.push(point);
      var marker = createMarker(point, i);
      gmarkers.push(marker);
    }
    for (var i = 0; i < points.length; i++) {
      document.getElementById("input_points").innerHTML += i + ": " + points[i].toUrlValue() + "<br>";
    }
    calculateConvexHull();
  });
  google.maps.event.addListener(map, "click", function(evt) {
    if (evt.latLng) {
      var latlng = evt.latLng;
      var marker = createMarker(latlng, gmarkers.length - 1);
      points.push(latlng);
      gmarkers.push(marker);
      calculateConvexHull();
    }
  });
}

function removeMarker(latlng) {
  for (var i = 0; i < gmarkers.length; i++) {
    if (google.maps.geometry.spherical.computeDistanceBetween(
        latlng, gmarkers[i].getPosition()) < 0.1) {
      gmarkers[i].setMap(null);
      gmarkers.splice(i, 1);
    }
  }
  calculateConvexHull();
}

function createMarker(latlng, marker_number) {
  var html = "marker " + marker_number;
  var marker = new google.maps.Marker({
    position: latlng,
    map: map,
    zIndex: Math.round(latlng.lat() * -100000) << 5
  });

  google.maps.event.addListener(marker, 'click', function() {
    var contentString = html + "<br>" + marker.getPosition().toUrlValue() + "<br><a href='javascript:removeMarker(new google.maps.LatLng(" + marker.getPosition().toUrlValue() + "));'>Remove Marker</a>";
    infowindow.setContent(contentString);
    infowindow.open(map, marker);
  });
  return marker;
}

function calculateConvexHull() {
  if (polyline) polyline.setMap(null);
  document.getElementById("hull_points").innerHTML = "";
  points = [];
  for (var i = 0; i < gmarkers.length; i++) {
    points.push(gmarkers[i].getPosition());
  }
  points.sort(sortPointY);
  points.sort(sortPointX);
  DrawHull();
}

function sortPointX(a, b) {
  return a.lng() - b.lng();
}

function sortPointY(a, b) {
  return a.lat() - b.lat();
}

function DrawHull() {
  hullPoints = [];
  chainHull_2D(points, points.length, hullPoints);
  polyline = new google.maps.Polygon({
    map: map,
    paths: hullPoints,
    fillColor: "#FF0000",
    strokeWidth: 2,
    fillOpacity: 0.5,
    strokeColor: "#0000FF",
    strokeOpacity: 0.5
  });
  displayHullPts();
}

function displayHullPts() {
  document.getElementById("hull_points").innerHTML = "";
  for (var i = 0; i < hullPoints.length; i++) {
    document.getElementById("hull_points").innerHTML += hullPoints[i].toUrlValue() + "<br>";
  }
}

google.maps.event.addDomListener(window, "load", initialize);
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<script src="http://www.geocodezip.com/scripts/convex_hull.js"></script>
<h2>Convex Hull of random set of points</h2>
<table border="0">
  <tr>
    <td>
      <button onclick="polyline.setMap(null);">hide polygon</button>
      <button onclick="calculateConvexHull();">calculate Convex Hull</button>
      <button onclick="displayHullPts();">display Hull Points</button>
    </td>
  </tr>

  <tr>
    <td valign="top">
      <div id="map_canvas" style="width: 500px; height: 300px"></div>
      <table border="1" width="100%">
        <tr>
          <th>random pts</th>
          <th>hull points</th>
        </tr>
        <tr>
          <td valign="top">
            <div id="input_points"></div>
          </td>
          <td valign="top">
            <div id="hull_points"></div>
          </td>
        </tr>
      </table>
    </td>
    <td>
    </td>
  </tr>
  <tr>
    <td></td>
  </tr>
</table>
<div id="info"></div>


来源:https://stackoverflow.com/questions/22678563/programmatically-drawing-polygons-on-a-map-by-joining-the-outermost-markers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!