+-

继续完善 上面 一篇 博客
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>
图:
