使用Google地图在多边形内绘制较小的多边形

Dar*_*ech 2 javascript google-maps google-maps-api-3

我正在尝试在Google Maps(使用API​​的V3)上渲染形状,这些形状包含相同的形状,但内部较小。基本上是一个盒子内的一个盒子或一个多边形内的一个多边形。

对于矩形,我有以下代码可以正常工作:

var drawEdgesRectangle = function (shape) {
  // shape is the original, parent rectangle

  var NE, SW, childNE, childSW, padding, diagonal, inner;

  // set padding constant to 1 (i.e. 1m distance all around) 
  padding = 1;

  // get diagonal distance from corner
  diagonal = Math.sqrt(2) * padding;

  // get NE of parent
  NE = shape.bounds.getNorthEast();

  // get SW of parent
  SW = shape.bounds.getSouthWest();

  // get child NE, SW
  childNE = google.maps.geometry.spherical.computeOffset(NE, diagonal, 225);
  childSW = google.maps.geometry.spherical.computeOffset(SW, diagonal, 45);

  // render inner shape
  inner = new google.maps.Rectangle({
    strokeColor: 'white',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: 'black',
    fillOpacity: 0.35,
    map: map,
    bounds: new google.maps.LatLngBounds(
      childSW,
      childNE
    )
  });
}
Run Code Online (Sandbox Code Playgroud)

当然,对多边形执行此操作是另一回事。我知道我可以getPaths()用来获取每条线的属性,但是要弄清楚如何放置内线,实际上,要弄清楚“内部”的位置在概念上对我来说是相当困难的。

我想知道如果使用Google API,我想实现的目标是否可行。

geo*_*zip 5

如果多边形是“简单的”(中心在多边形的“内部”并且没有凹面),则一种选择是做与矩形(类似于满足这些条件的四边形多边形)相似的操作):

使用几何库

要包括它:

<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script>
Run Code Online (Sandbox Code Playgroud)

代码(假设全局“多边形”等):

var drawEdgesPoly = function() {
  // shape is the original, parent polygon

  var shape = poly;
  // set padding constant to 1 (i.e. 1m distance all around) 
  padding = 50;

  var vertices = shape.getPath();
  var polybounds = new google.maps.LatLngBounds();
  for (var i = 0; i < vertices.getLength(); i++) {
    polybounds.extend(vertices.getAt(i));
  }
  var center = polybounds.getCenter();
  if (centerMarker && centerMarker.setMap) {
    centerMarker.setMap(null);
  }
  centerMarker = new google.maps.Marker({
    position: center,
    map: map,
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(4, 4)
    }
  });
  if (polylines && (polylines.length > 0)) {
    for (var i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }
  }
  polylines = [];
  var newPath = [];
  for (var i = 0; i < vertices.getLength(); i++) {
    polylines.push(new google.maps.Polyline({
      path: [center, vertices.getAt(i)],
      map: map,
      strokeWidth: 2,
      strokeColor: 'red'
    }));
    newPath[i] = google.maps.geometry.spherical.computeOffset(vertices.getAt(i),
      padding,
      google.maps.geometry.spherical.computeHeading(vertices.getAt(i), center));
  }
  if (inner && inner.setMap)
    inner.setMap(null);
  // render inner shape
  inner = new google.maps.Polygon({
    strokeColor: 'white',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: 'black',
    fillOpacity: 0.35,
    map: map,
    editable: false,
    path: newPath
  });
};
Run Code Online (Sandbox Code Playgroud)

概念证明小提琴 在代码片段或jsfiddle中玩多边形以查看约束。 小提琴的屏幕截图

<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script>
Run Code Online (Sandbox Code Playgroud)
var drawEdgesPoly = function() {
  // shape is the original, parent polygon

  var shape = poly;
  // set padding constant to 1 (i.e. 1m distance all around) 
  padding = 50;

  var vertices = shape.getPath();
  var polybounds = new google.maps.LatLngBounds();
  for (var i = 0; i < vertices.getLength(); i++) {
    polybounds.extend(vertices.getAt(i));
  }
  var center = polybounds.getCenter();
  if (centerMarker && centerMarker.setMap) {
    centerMarker.setMap(null);
  }
  centerMarker = new google.maps.Marker({
    position: center,
    map: map,
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(4, 4)
    }
  });
  if (polylines && (polylines.length > 0)) {
    for (var i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }
  }
  polylines = [];
  var newPath = [];
  for (var i = 0; i < vertices.getLength(); i++) {
    polylines.push(new google.maps.Polyline({
      path: [center, vertices.getAt(i)],
      map: map,
      strokeWidth: 2,
      strokeColor: 'red'
    }));
    newPath[i] = google.maps.geometry.spherical.computeOffset(vertices.getAt(i),
      padding,
      google.maps.geometry.spherical.computeHeading(vertices.getAt(i), center));
  }
  if (inner && inner.setMap)
    inner.setMap(null);
  // render inner shape
  inner = new google.maps.Polygon({
    strokeColor: 'white',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: 'black',
    fillOpacity: 0.35,
    map: map,
    editable: false,
    path: newPath
  });
};
Run Code Online (Sandbox Code Playgroud)
var map;
var infoWindow;
var poly;
var inner;
var polylines = [];
var centerMarker;

var paths = [
  [
    new google.maps.LatLng(38.872886, -77.054720),
    new google.maps.LatLng(38.872602, -77.058046),
    new google.maps.LatLng(38.870080, -77.058604),
    new google.maps.LatLng(38.868894, -77.055664),
    new google.maps.LatLng(38.870598, -77.053346)
  ]
];

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(38.8714, -77.0556),
    zoom: 15
  };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

  poly = new google.maps.Polygon({
    paths: paths,
    strokeWeight: 3,
    fillColor: '#55FF55',
    fillOpacity: 0.5,
    editable: true
  });

  poly.setMap(map);
  drawEdgesPoly();

  google.maps.event.addListener(poly.getPath(), 'insert_at', drawEdgesPoly);
  google.maps.event.addListener(poly.getPath(), 'remove_at', drawEdgesPoly);
  google.maps.event.addListener(poly.getPath(), 'set_at', drawEdgesPoly);

  // Define an info window on the map.
  infoWindow = new google.maps.InfoWindow();
}

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

var drawEdgesPoly = function() {
  // shape is the original, parent polygon

  var shape = poly;
  // set padding constant to 1 (i.e. 1m distance all around) 
  padding = 50;

  var vertices = shape.getPath();
  var polybounds = new google.maps.LatLngBounds();
  for (var i = 0; i < vertices.getLength(); i++) {
    polybounds.extend(vertices.getAt(i));
  }
  var center = polybounds.getCenter();
  if (centerMarker && centerMarker.setMap) {
    centerMarker.setMap(null);
  }
  centerMarker = new google.maps.Marker({
    position: center,
    map: map,
    icon: {
      url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
      size: new google.maps.Size(7, 7),
      anchor: new google.maps.Point(4, 4)
    }
  });
  if (polylines && (polylines.length > 0)) {
    for (var i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }
  }
  polylines = [];
  var newPath = [];
  for (var i = 0; i < vertices.getLength(); i++) {
    polylines.push(new google.maps.Polyline({
      path: [center, vertices.getAt(i)],
      map: map,
      strokeWidth: 2,
      strokeColor: 'red'
    }));
    newPath[i] = google.maps.geometry.spherical.computeOffset(vertices.getAt(i),
      padding,
      google.maps.geometry.spherical.computeHeading(vertices.getAt(i), center));
  }
  if (inner && inner.setMap)
    inner.setMap(null);
  // render inner shape
  inner = new google.maps.Polygon({
    strokeColor: 'white',
    strokeOpacity: 0.8,
    strokeWeight: 1,
    fillColor: 'black',
    fillOpacity: 0.35,
    map: map,
    editable: false,
    path: newPath
  });
};
Run Code Online (Sandbox Code Playgroud)