2014-09-23 102 views
0

所以我试图渲染谷歌地图上的形状(使用V3的API),其中包含相同的形状,只是更小的内部。基本上是一个盒子或一个多边形内的多边形。谷歌地图在一个多边形内绘制一个更小的多边形

对于矩形我有以下的代码,它的工作原理:

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 
    ) 
    }); 
} 

当然,这样做了多边形是鱼的不同水壶。我知道我可以使用getPaths()来获得每一行的属性,但是要弄清楚如何放置内部行,并且确实找出'内部'在哪里对我来说在概念上是相当困难的。

我想知道我想要达到的目标是否可能给予谷歌API,并希望如何解决它的任何指针。

+0

有多复杂,你需要做的多边形?他们是武断的吗? – geocodezip 2014-09-24 00:15:31

+0

理想情况下,我想接受任何类型的多边形。在现实中,问题不大可能包含10行以上。 – 2014-09-24 00:18:42

+0

线/顶点的数量不是复杂度的真正度量。有没有凹面?多边形内多边形的中心?如果是这样(并且没有凹边),你应该可以做类似于你为矩形做的事情。 – geocodezip 2014-09-24 00:40:56

回答

2

如果多边形是“简单的”(中心是“内部”多边形且没有凹面),那么可以采取类似于矩形的操作(这是一个四边形多边形而符合这些标准):

使用geometry library

包括它:

<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script> 

代码(假定全球 “聚” 等):

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 
    }); 
}; 

proof of concept fiddle 用代码片段或jsfiddle中的多边形播放来查看约束。 screen shot of fiddle

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 
 
    }); 
 
};
html, 
 
body, 
 
#map-canvas { 
 
    height: 100%; 
 
    width: 100%; 
 
}
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=geometry"></script> 
 
<div id="map-canvas" style="height:100%; width:100%;"></div>

+0

哇。非常感谢。这正是我需要的。奖金标记用于突出显示小提琴中的多边形'set_at','insert_at'和'remove_at'事件。做得好。 – 2014-09-24 18:26:35