Google Maps API V3:捕捉到另一个多边形的节点 [英] Google Maps API V3: Snapping to nodes of another polygon

查看:155
本文介绍了Google Maps API V3:捕捉到另一个多边形的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在绘制相邻且边界共享的多边形。查看下面的示例图像,如果我要为蒙大拿州绘制多边形,我希望能够点击爱达荷州多边形的节点来确定边界的相同部分,以确保边界不会重叠或有洞。但是,节点不允许直接点击它们,如果我使节点不可见,则准确性会变差,并且最终可能会在两个多边形之间产生空洞或重叠。



有没有办法将图形对齐到现有多边形的节点?如果没有,是否至少有一种方法可以让我可以直接点击节点所在的位置?我已将多边形的属性设置为可编辑:false和clickable:false,但多边形(和节点)的边界仍不允许点击。

我没有看到API中的任何文档用于捕捉。



解决方案

PolySnapper:简单多边形顶点捕捉。





I创建了这个这个github repo 补充jsfiddle



一个简单的例子可能如下:

  var PS = PolySnapper ({
map:map,
threshold:20,
key:'shift',
keyRequired:true,
多边形:
polystyle: polystyle,
hidePOI:true,
onEnabled:function(){
console.log(enabled)
},
onDisabled:function(){
console.log(disabled)
},
onChange:function(){
console.log(添加,删除或移动了某个点)
}
});

//首先启用管理器(进入绘图模式)
PS.enable();

//用户在必要时逐点绘制多边形。
//现在,从管理器中检索多边形。
the_poly = PS.polygon();

//并禁用管理器(退出绘图模式并清理多边形)。
//你现在应该使用the_poly作为多边形引用
PS.disable();

注意:通过设计,jsfiddle上的西方形状未设置为 snapable (见上面的 polygons 属性),所以只有东部形状可以捕捉:



  //唯一的全局变量// SM将成为SnapManager instance.var SM = null; google.maps.event.addDomListener(window,load ,function(){//我们将把地图居中在这里var vancouver = {lat:49.269858,lng:-123.137283} //格朗维尔岛坐标//你应该从你的服务器获取你的坐标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}] ; //在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}]; //使卫星视图谷歌地图,中心在温哥华。 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 }); //这种风格比默认的黑色更容易。 // BADASS和COFFEE十六进制来拯救。 var polystyle = {strokeColor:'#BADA55',strokeOpacity:0.8,strokeWeight:2,fillColor:'#C0FFEE',fillOpacity:0.35} //格兰维尔多边形的选项。 // SNAPABLE = TRUE var poly1_opts = $ .extend({paths:granville_coords,map:map,snapable:true},polystyle); //可选择burrard多边形// SNAPABLE不存在(false)var poly2_opts = $ .extend({paths:burrard_coords,map:map},polystyle); //让我们制作多边形var granville = new google.maps.Polygon(poly1_opts); var burrard = new google.maps.Polygon(poly2_opts); / *为了便于演示,只需将两个gmaps Polys放入多边形数组中即可。为了您的应用目的,您可以使用您想要捕捉的所有多边形填充此阵列 - 可能是从数据库驱动的。 * / polygons = [granville,burrard]; / *现在,我们制作SnapManager。请参阅http://stackoverflow.com/a/33338065/568884 API将很快转移到Github。 * / 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)}}); //在地图顶部添加按钮初始状态。 renderCpanel(假); }(); //当用户点击log poly按钮时,将poly从manager和console.log中拉出来,$(document).on(click,#query,function(){console.log(SM ()函数renderCpanel(drawing){var t = $();}; //当然, 。( #控制面板)的HTML(); var html = _.template(t,{drawing:drawing}); $( #CP-包装)HTML(HTML); } //将点击处理程序附加到按钮。 #(cp-wrap)永远不会被添加或从DOM中删除,所以它安全地绑定了监听器。 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;填充:0; font:12px sans-serif;}#cp-wrap {position:absolute;顶部:10px;左:120像素;背景颜色:白色;}#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_divstyle =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>  

I am drawing polygons that are adjacent and whose borders are shared. Looking at the example image below, if I were to draw a polygon for Montana, I'd like to be able to click on the nodes of the Idaho polygon for the part of the border that is the same to ensure the borders don't overlap or have holes. However, the nodes don't allow clicks directly on them, and if I make the nodes invisible then the accuracy is worsened and I'll probably end up with holes or overlaps between the two polygons.

Is there a way to snap a drawing to a node of an existing polygon? If not, is there at least a way to make it so that I can click directly where the nodes are? I've set the polygon's properties to editable: false and clickable: false, but the boundary of the polygon (and the nodes) still disallows clicks.

I haven't seen any documentation in the API for snapping.

解决方案

PolySnapper: easy polygon vertice snapping.

I created this this github repo and complementary jsfiddle.

A brief example might look like:

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

Note: By design, the western shape on jsfiddle is not set to snapable (see above polygons property) so only the eastern shape will snap :)

//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>

这篇关于Google Maps API V3:捕捉到另一个多边形的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆