我正在绘制相邻且边界共享的多边形。看下面的示例图片,如果我要为蒙大拿州绘制一个多边形,我希望能够点击Idaho多边形的节点以获得相同的边界部分,以确保边界不重叠或有洞。但是,节点不允许直接点击它们,如果我使节点不可见,那么精度会变差,我可能最终会在两个多边形之间出现漏洞或重叠。
有没有办法将绘图捕捉到现有多边形的节点?如果没有,是否至少有一种方法可以使我可以直接点击节点所在的位置?我已将多边形的属性设置为editable:false和clickable:false,但多边形(和节点)的边界仍然不允许点击。
我没有在API中看到任何用于捕捉的文档。
答案 0 :(得分:8)
我创建了此this github repo和complementary jsfiddle。
一个简短的例子可能如下:
var PS = PolySnapper({
map: map,
threshold: 20,
key: 'shift',
keyRequired: true,
polygons: polygons,
polystyle: polystyle,
hidePOI: true,
onEnabled: function(){
console.log("enabled")
},
onDisabled: function(){
console.log("disabled")
},
onChange: function(){
console.log("a point was added, removed, or moved")
}
});
//first enable the manager (enter drawing mode)
PS.enable();
//user draws the polygon, point by point, snapping when necessary.
//now, retrieve the polygon from the manager.
the_poly = PS.polygon();
//and disable the manager (exit drawing mode and clean up poly).
//you should now use the_poly as a polygon reference
PS.disable();
注意:根据设计,jsfiddle上的西方形状未设置为snapable
(请参阅上面的polygons
属性),因此只有东方形状会突然显示:)
//the only global variable
//SM will become the SnapManager instance.
var SM = null;
google.maps.event.addDomListener(window, "load", function () {
//we will center the map here
var vancouver = {
lat: 49.269858,
lng: -123.137283
}
//granville island coordinates.
//you should be fetching your coordinates from your server
var granville_coords = [
{lat: 49.27158485202591, lng: -123.13729763031006},
{lat: 49.27277488695786, lng: -123.13691139221191},
{lat: 49.27316689217891, lng: -123.13613891601562},
{lat: 49.27319489243262, lng: -123.13474416732788},
{lat: 49.27248088099777, lng: -123.13384294509888},
{lat: 49.2696667352996, lng: -123.13049554824829},
{lat: 49.268546632648494,lng: -123.13055992126465},
{lat: 49.268350612069995,lng: -123.13066720962524},
{lat: 49.2684906268484, lng: -123.13146114349365},
{lat: 49.268546632648494,lng: -123.13249111175537},
{lat: 49.26888266611402, lng: -123.13347816467285},
{lat: 49.26889666745873, lng: -123.13401460647583},
{lat: 49.2706328034105, lng: -123.1368041038513 }
];
//coordinates of blocks just east of burrard.
var burrard_coords = [
{lat: 49.267972570183545, lng: -123.145751953125},
{lat: 49.2679445669656, lng: -123.14085960388184},
{lat: 49.27032478374826, lng: -123.14077377319336},
{lat: 49.27138884351881, lng: -123.14176082611084},
{lat: 49.27309689147504, lng: -123.14356327056885},
{lat: 49.27267688516586, lng: -123.14467906951904},
{lat: 49.27152884967477, lng: -123.14553737640381},
{lat: 49.269834748503946, lng: -123.1459450721740}
];
//make the satellite view google map, center it in Vancouver.
map = new google.maps.Map(document.getElementById("map_div"), {
center: new google.maps.LatLng(vancouver.lat, vancouver.lng),
zoom: 16,
mapTypeId: google.maps.MapTypeId.HYBRID
});
//this style is easier on the eyes than the default black.
//BADASS and COFFEE hex to the rescue.
var polystyle = {
strokeColor: '#BADA55',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#C0FFEE',
fillOpacity: 0.35
}
//options for granville polygon.
//SNAPABLE = TRUE
var poly1_opts = $.extend({
paths: granville_coords,
map: map,
snapable: true
}, polystyle);
//options for burrard polygon
//SNAPABLE not present (false)
var poly2_opts = $.extend({
paths: burrard_coords,
map: map
}, polystyle);
//let's make the polygons
var granville = new google.maps.Polygon(poly1_opts);
var burrard = new google.maps.Polygon(poly2_opts);
/*
For demo purposes, lets just put two gmaps Polys into the polygon array.
For your application purposes, you would populate this array with
all of the polygons you want to snap to - likely driven from the DB.
*/
polygons = [granville, burrard];
/*
Now, we make the SnapManager.
See http://stackoverflow.com/a/33338065/568884 for API
Will be transferred to Github soon.
*/
SM = PolySnapper({
map: map,
marker: new google.maps.Marker(),
threshold: 20,
keyRequired: false,
polygons: polygons,
polystyle: polystyle,
hidePOI: true,
onEnabled: function(){
console.log("enabled")
},
onDisabled: function(){
console.log("disabled")
}
});
//add the buttons initial state on top of the map.
renderCpanel(false);
});
//when user clicks log poly button, pull the poly out of the manager and console.log it.
$(document).on("click", "#query", function(){
console.log( SM.poly().getPath().getArray() );
});
//just a small render function to re-draw the buttons whenever the enabled state is flipped on and off.
function renderCpanel(drawing){
var t = $("#control-panel").html();
var html = _.template(t, {drawing: drawing});
$("#cp-wrap").html(html);
}
//attach the click handlers to the button. #cp-wrap is never added or removed
//from the DOM, so its safe to bind the listeners to it.
$("#cp-wrap").on("click", "button", function(){
var action = $(this).data("action");
if (action == 'new') SM.enable();
else if(action == 'query') console.log( SM.polygon() )
else SM.disable();
renderCpanel( (action == 'new') );
});

body {
margin: 0;
padding: 0;
font: 12px sans-serif;
}
#cp-wrap{
position: absolute;
top: 10px;
left:120px;
background-color:white;
}
#cp-wrap button{
font-size: 22px;
}

<script src="https://rawgit.com/jordanarseno/polysnapper/master/polysnapper.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.google.com/maps/api/js?.js"></script>
<div style='position:relative;'>
<div id="map_div" style="height: 600px; width:100%;"></div>
<div id='cp-wrap'></div>
</div>
<script id='control-panel' type='text/template'>
<% if(drawing) { %>
<button data-action='cancel' >cancel</button>
<button data-action='query' >log poly</button>
<% } else { %>
<button data-action='new' >new poly</button>
<% } %>
</script>
&#13;