检查多边形点是否在传单中的另一个内
Check if a polygon point is inside another in leaflet
我从传单 geoJSON 地图中选择了两组多边形坐标。
parent和child坐标是坐标是:
var parentCoordinates=[
[
32.05898221582174,
-28.31004731142091
],
[
32.05898221582174,
-28.308044824292978
],
[
32.06134255975485,
-28.308044824292978
],
[
32.06134255975485,
-28.31004731142091
],
[
32.05898221582174,
-28.31004731142091
]
]
var childCoordinates=[
[
32.059904895722866,
-28.30970726909422
],
[
32.059904895722866,
-28.308743809931784
],
[
32.06089194864035,
-28.308743809931784
],
[
32.06089194864035,
-28.30970726909422
],
[
32.059904895722866,
-28.30970726909422
]
]
child绘制在parent区域内,如图:
使用 Ray Casting algorithm 确定该点是否位于多边形内我无法确定,因为我得到的结果是错误的。
请让我知道我哪里做错了或任何其他方式来确定 solution.Thanks
我试过你的算法,在这里找到了另一个 https://rosettacode.org/wiki/Ray-casting_algorithm 并且 return 都是正确的值。
也许这个 fiddle 可以帮助您实施:
https://jsfiddle.net/4psL2hoo/1/
你的算法
// Data
var parentCoordinates=[
[
32.05898221582174,
-28.31004731142091
],
[
32.05898221582174,
-28.308044824292978
],
[
32.06134255975485,
-28.308044824292978
],
[
32.06134255975485,
-28.31004731142091
],
[
32.05898221582174,
-28.31004731142091
]
]
var childCoordinates=[
[
32.059904895722866,
-28.30970726909422
],
[
32.059904895722866,
-28.308743809931784
],
[
32.06089194864035,
-28.308743809931784
],
[
32.06089194864035,
-28.30970726909422
],
[
32.059904895722866,
-28.30970726909422
]
]
// Other algo
function test(point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
for (var i = 0; i < childCoordinates.length; i++) {
var testPoint = childCoordinates[i];
console.log(JSON.stringify(testPoint) + '\tin parentCoordinate\t' + test(testPoint, parentCoordinates));
}
罗塞塔代码算法
//https://rosettacode.org/wiki/Ray-casting_algorithm
function contains(bounds, lat, lng) {
//https://rosettacode.org/wiki/Ray-casting_algorithm
var count = 0;
for (var b = 0; b < bounds.length; b++) {
var vertex1 = bounds[b];
var vertex2 = bounds[(b + 1) % bounds.length];
if (west(vertex1, vertex2, lng, lat))
++count;
}
return count % 2;
/**
* @return {boolean} true if (x,y) is west of the line segment connecting A and B
*/
function west(A, B, x, y) {
if (A.y <= B.y) {
if (y <= A.y || y > B.y ||
x >= A.x && x >= B.x) {
return false;
} else if (x < A.x && x < B.x) {
return true;
} else {
return (y - A.y) / (x - A.x) > (B.y - A.y) / (B.x - A.x);
}
} else {
return west(B, A, x, y);
}
}
}
var square = {name: 'square', bounds: [{x: 32.05898221582174, y: -28.31004731142091}, {x: 32.05898221582174, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.31004731142091}]};
var shapes = [square];
var testPoints = [{lng: 32.059904895722866, lat: -28.30970726909422}, {lng: 32.059904895722866, lat: -28.308743809931784}, {lng: 32.06089194864035, lat: -28.308743809931784},
{lng: 32.06089194864035, lat: -28.30970726909422}];
for (var s = 0; s < shapes.length; s++) {
var shape = shapes[s];
for (var tp = 0; tp < testPoints.length; tp++) {
var testPoint = testPoints[tp];
console.log(JSON.stringify(testPoint) + '\tin ' + shape.name + '\t' + contains(shape.bounds, testPoint.lat, testPoint.lng));
}
}
我对 Turf 有很好的体验。它运作良好,有据可查,并且示例已在传单中显示。
对于您的问题,您可以使用 turf.within,parentCoordinates
作为 turf.polygon
,childCoordinates
作为 turf.point
的数组:
var parentPolygon = turf.polygon([parentCoordinates]);
var inside = true;
childCoordinates.forEach(function(coordinates) {
point = turf.point(coordinates);
if (!turf.inside(point, parentPolygon)){
alert("Oh no! "+ coordinates + " isn't in polygon");
inside = false;
}
});
alert("Child polygon inside parent polygon ? " + inside);
Here 是一个 Fiddle 示例。
你可以试试 Leaflet 的 api - contains
。您使用 LatLngBounds 创建父多边形,然后创建子多边形。
parentPolygon.contains(childPolygon)
我从传单 geoJSON 地图中选择了两组多边形坐标。 parent和child坐标是坐标是:
var parentCoordinates=[
[
32.05898221582174,
-28.31004731142091
],
[
32.05898221582174,
-28.308044824292978
],
[
32.06134255975485,
-28.308044824292978
],
[
32.06134255975485,
-28.31004731142091
],
[
32.05898221582174,
-28.31004731142091
]
]
var childCoordinates=[
[
32.059904895722866,
-28.30970726909422
],
[
32.059904895722866,
-28.308743809931784
],
[
32.06089194864035,
-28.308743809931784
],
[
32.06089194864035,
-28.30970726909422
],
[
32.059904895722866,
-28.30970726909422
]
]
child绘制在parent区域内,如图:
使用 Ray Casting algorithm 确定该点是否位于多边形内我无法确定,因为我得到的结果是错误的。 请让我知道我哪里做错了或任何其他方式来确定 solution.Thanks
我试过你的算法,在这里找到了另一个 https://rosettacode.org/wiki/Ray-casting_algorithm 并且 return 都是正确的值。
也许这个 fiddle 可以帮助您实施:
https://jsfiddle.net/4psL2hoo/1/
你的算法
// Data
var parentCoordinates=[
[
32.05898221582174,
-28.31004731142091
],
[
32.05898221582174,
-28.308044824292978
],
[
32.06134255975485,
-28.308044824292978
],
[
32.06134255975485,
-28.31004731142091
],
[
32.05898221582174,
-28.31004731142091
]
]
var childCoordinates=[
[
32.059904895722866,
-28.30970726909422
],
[
32.059904895722866,
-28.308743809931784
],
[
32.06089194864035,
-28.308743809931784
],
[
32.06089194864035,
-28.30970726909422
],
[
32.059904895722866,
-28.30970726909422
]
]
// Other algo
function test(point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
for (var i = 0; i < childCoordinates.length; i++) {
var testPoint = childCoordinates[i];
console.log(JSON.stringify(testPoint) + '\tin parentCoordinate\t' + test(testPoint, parentCoordinates));
}
罗塞塔代码算法
//https://rosettacode.org/wiki/Ray-casting_algorithm
function contains(bounds, lat, lng) {
//https://rosettacode.org/wiki/Ray-casting_algorithm
var count = 0;
for (var b = 0; b < bounds.length; b++) {
var vertex1 = bounds[b];
var vertex2 = bounds[(b + 1) % bounds.length];
if (west(vertex1, vertex2, lng, lat))
++count;
}
return count % 2;
/**
* @return {boolean} true if (x,y) is west of the line segment connecting A and B
*/
function west(A, B, x, y) {
if (A.y <= B.y) {
if (y <= A.y || y > B.y ||
x >= A.x && x >= B.x) {
return false;
} else if (x < A.x && x < B.x) {
return true;
} else {
return (y - A.y) / (x - A.x) > (B.y - A.y) / (B.x - A.x);
}
} else {
return west(B, A, x, y);
}
}
}
var square = {name: 'square', bounds: [{x: 32.05898221582174, y: -28.31004731142091}, {x: 32.05898221582174, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.31004731142091}]};
var shapes = [square];
var testPoints = [{lng: 32.059904895722866, lat: -28.30970726909422}, {lng: 32.059904895722866, lat: -28.308743809931784}, {lng: 32.06089194864035, lat: -28.308743809931784},
{lng: 32.06089194864035, lat: -28.30970726909422}];
for (var s = 0; s < shapes.length; s++) {
var shape = shapes[s];
for (var tp = 0; tp < testPoints.length; tp++) {
var testPoint = testPoints[tp];
console.log(JSON.stringify(testPoint) + '\tin ' + shape.name + '\t' + contains(shape.bounds, testPoint.lat, testPoint.lng));
}
}
我对 Turf 有很好的体验。它运作良好,有据可查,并且示例已在传单中显示。
对于您的问题,您可以使用 turf.within,parentCoordinates
作为 turf.polygon
,childCoordinates
作为 turf.point
的数组:
var parentPolygon = turf.polygon([parentCoordinates]);
var inside = true;
childCoordinates.forEach(function(coordinates) {
point = turf.point(coordinates);
if (!turf.inside(point, parentPolygon)){
alert("Oh no! "+ coordinates + " isn't in polygon");
inside = false;
}
});
alert("Child polygon inside parent polygon ? " + inside);
Here 是一个 Fiddle 示例。
你可以试试 Leaflet 的 api - contains
。您使用 LatLngBounds 创建父多边形,然后创建子多边形。
parentPolygon.contains(childPolygon)