GoogleMapsAPI V3 射线法 点与面的关系

继续完善 上面 一篇 博客

 

在线预览地址:

 

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&sup2;");
	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>



图: