+-
继续完善 上面 一篇 博客
4、射线法 点与面的关系【2010-08-11】(google.map.plugin.js下面有下载)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>点与面的关系</title> </head> <body onload="initialize()"> <h1>点与面的关系</h1> <div id="map_canvas" style="width : 800px; height : 600px;"></div> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript" src="<span style="white-space: normal; line-height: 18px;"><strong style="font-weight: bold;"><span style="color: #0000ff;">google.map.plugin.js</span> </strong> </span> "></script> <input type='button' onclick='isPointInPolygon();' value='判断点与面的关系'></input> <input type='button' onclick='viewVertex();' value='查看面顶点的坐标'></input> <div style="padding:5px;">点与面的关系:<span id="relation"></span></div> <div id="console" style="padding:5px;">面积:<span id="total_km"></span></div> <input type='button' id='clearOverlays' onclick='clearOverlays();' value='清空地图'></input> <div style="padding:5px;">面顶点信息:</div> <div style="padding:5px;" id="vertexInfo"></div> <script type="text/javascript"> var map; var marker; var geocoder; var markersArray = []; var polygon; var polygonArray =[]; var infowindowLevel = 0; var markerPoint ; function initialize() { geocoder = new google.maps.Geocoder(); var myLatlng = new google.maps.LatLng(39.042102026773605,117.65275967700195); var myOptions = { zoom: 13, center: myLatlng, navigationControl: true, scaleControl: true, streetViewControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); google.maps.event.addListener(map, 'click', function(event) { addMarker(event.latLng); }); var latLngPoint = new google.maps.LatLng(39.042102026773605,117.65275967700195); markerPoint = new google.maps.Marker({ position: latLngPoint, draggable: true, map: map }); google.maps.event.addListener(markerPoint, 'drag', function() { isPointInPolygon(); //$("#relation").html(markerPoint.getPosition()); }); } //画多边形,计算多边形面积 function drawOverlay() { var flightPlanCoordinates = []; if (markersArray) { for (i in markersArray) { flightPlanCoordinates.push(markersArray[i].getPosition()); } } polygon = new google.maps.Polygon({ path: flightPlanCoordinates, strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35 }); if (polygonArray) { for (i in polygonArray) { polygonArray[i].setMap(null); } polygonArray = []; } polygon.setMap(map); $("#total_km").empty().html((polygon.getArea()).toFixed(3) + "km²"); polygonArray.push(polygon); } //增加点 function addMarker(location) { marker = new google.maps.Marker({ position: location, map: map, icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png', draggable: true }); markersArray.push(marker); drawOverlay(); google.maps.event.addListener(marker, 'drag', function() { drawOverlay(); }); } //顶点信息 function viewVertex() { if (markersArray) { $("#vertexInfo").empty(); for (i in markersArray) { var point = markersArray[i].getPosition(); $("#vertexInfo").append("var p" + i + " = new google.maps.LatLng" + point + ";<br />"); } for (i in markersArray) { $("#vertexInfo").append("points.push(p" + i + ");<br />"); } } } //清空地图 function clearOverlays(infowindow) { if (markersArray) { for (i in markersArray) { markersArray[i].setMap(null); } markersArray.length = 0; } if (polygonArray) { for (i in polygonArray) { polygonArray[i].setMap(null); } polygonArray = []; } $("#total_km").empty(); } function FC(x1, x2) { if (x1 - x2 < 0.000002 && x1 - x2 > -0.000002) { return 1; } else { return 0; } } /* * 参数 * p1、p2:线段的两个端点 * p: 被判断点 * 返回值: false:点在不在线段上;true:点在线段上 */ function isPointOnLine(p1, p2, p) { var x1, y1, x2, y2; x1 = p.lat() - p1.lat(); x2 = p2.lat() - p1.lat(); y1 = p.lng() - p1.lng(); y2 = p2.lng() - p1.lng(); if (FC(x1 * y2 - x2 * y1, 0) == 0) { return false; } if ((Math.min(p1.lat(), p2.lat()) <= p.lat() && p.lat() <= Math.max(p1.lat(), p2.lat())) && (Math.min(p1.lng(), p2.lng()) <= p.lng() && p.lng() <= Math.max(p1.lng(), p2.lng()))) { return true; } else { return false; } } // 射向法判断点是否在多边形内部 function isPointInPolygon() { /*latLngPoints 多边形顶点 */ /*latLngPoint 单个顶点*/ var latLngPoints = []; var latLngPoint; if (markersArray) { for (i in markersArray) { var point = markersArray[i].getPosition(); latLngPoints.push(point); } } if (null != markerPoint) { var point = markerPoint.getPosition(); latLngPoint = point; } if (null == latLngPoints || latLngPoints.length == 0 || null == latLngPoint) { return -1; } var counter = 0; var i; var xinters; var p1 = null; var p2 = null; var isPointOnLineFlag = false; p1 = latLngPoints[0]; for (i = 1; i <= latLngPoints.length; i++) { //p2 = latLngPoints + (i % nCount); p2 = latLngPoints[i % latLngPoints.length]; if (isPointOnLine(p1, p2, latLngPoint)) { isPointOnLineFlag = true; } if (latLngPoint.lng() > Math.min(p1.lng(), p2.lng())) { if (latLngPoint.lng() <= Math.max(p1.lng(), p2.lng())) { if (latLngPoint.lat() <= Math.max(p1.lat(), p2.lat())) { if (p1.lng() != p2.lng()) { xinters = (latLngPoint.lng() - p1.lng()) * (p2.lat() - p1.lat()) / (p2.lng() - p1.lng()) + p1.lat(); if ((p1.lat() == p2.lat()) || (latLngPoint.lat() < xinters) || (latLngPoint.lat() == xinters)) { counter++; } } } } } p1 = p2; } if (isPointOnLineFlag) { $("#relation").html("<b style='color:blue'>点在边上</b>"); return true; } if (counter % 2 == 0) { $("#relation").html("<b style='color:red'>点在多边形外</b>"); return false; } else { $("#relation").html("<b style='color:green'>点在多边形内</b>") return true; } } </script> </body> </html>
图: