Google Maps API v.3将折线转换为具有给定宽度的多边形

时间:2016-04-22 16:47:50

标签: google-maps google-maps-api-3

我正在寻找将折线(从2坐标创建)转换为包含至少4个坐标的多边形的方法。简单的使用案例是航空地图上的气道,它从A点开始,B点结束, x 海里宽度。虚拟代码是:

var someLine = new google.maps.Polyline({
    path: [
        {lat: 51.15, lng: 15},
        {lat: 51.15, lng: 18}
    ],
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 5
});
someLine.setMap(map);

// how to convert above someLine into?:
var airway = new google.maps.Polygon({
    paths: [
        {lat: 51, lng: 15},
        {lat: 51, lng: 18},
        {lat: 51.3, lng: 18},
        {lat: 51.3, lng: 15}
    ],
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    geodesic: true
});
airway.setMap(map);

看起来像:

dummy sample

其中黑线是常见折线,红色多边形是期望的效果。

是否有任何API /插件可用于此类任务,或者我需要手动计算多边形的角落?

1 个答案:

答案 0 :(得分:2)

一种选择是使用Google Maps Javascript API v3 geometry library根据气道宽度和中心线计算多边形。如果您使用米(而不是海里,这只是一个转换)指定空中通道的宽度:

var lineWidth = 10000; // (meters)
var lineHeading = google.maps.geometry.spherical.computeHeading(someLine.getPath().getAt(0), someLine.getPath().getAt(1));
var p0a = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(0), lineWidth, lineHeading+90);
var p0b = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(0), lineWidth, lineHeading-90);
var p1a = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(1), lineWidth, lineHeading+90);
var p1b = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(1), lineWidth, lineHeading-90);

var airway = new google.maps.Polygon({
  paths: [p0a, p0b, p1b, p1a],
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 3,
  fillColor: '#FF0000',
  fillOpacity: 0.35,
  geodesic: true
});

代码段



var geocoder;
var map;

function initialize() {
  var map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(37.4419, -122.1419),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  var someLine = new google.maps.Polyline({
    path: [{
      lat: 51.15,
      lng: 15
    }, {
      lat: 49.15,
      lng: 18
    }],
    geodesic: true,
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 5
  });
  someLine.setMap(map);
  var lineWidth = 10000; // (meters)
  var lineHeading = google.maps.geometry.spherical.computeHeading(someLine.getPath().getAt(0), someLine.getPath().getAt(1));
  var p0a = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(0), lineWidth, lineHeading + 90);
  var p0b = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(0), lineWidth, lineHeading - 90);
  var p1a = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(1), lineWidth, lineHeading + 90);
  var p1b = google.maps.geometry.spherical.computeOffset(someLine.getPath().getAt(1), lineWidth, lineHeading - 90);


  // how to convert above someLine into?:
  var airway = new google.maps.Polygon({
    paths: [p0a, p0b, p1b, p1a],
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    geodesic: true
  });
  airway.setMap(map);
  var bounds = new google.maps.LatLngBounds();
  for (var i = 0; i < airway.getPath().getLength(); i++) {
    bounds.extend(airway.getPath().getAt(i));
  }
  map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, "load", initialize);
&#13;
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
&#13;
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map_canvas"></div>
&#13;
&#13;
&#13;