1、当前打卡位置在地理围栏内判断。使用turf.js(地理空间分析库,处理各种地图算法)。
2、wx小程序在使用npm构建后,引用时一直会提示“ 'xxx.js' is not defined, require args”
3、最终使用 "npm install @turf/boolean-point-in-polygon",到新建项目中,也可以直接使用下面代码。以下代码是方法“booleanPointInPolygon”,所以关联的方法,都是从npm下载下来的js中提炼出来的,直接用即可。文件名称命名为“boolean-point-in-polygon.js”
// index.tsconst booleanPointInPolygon = function(point, polygon, options = {}) {if (!point) {throw new Error("point is required");}if (!polygon) {throw new Error("polygon is required");}const pt = getCoord(point);const geom = getGeom(polygon);const type = geom.type;const bbox = polygon.bbox;let polys = geom.coordinates;if (bbox && inBBox(pt, bbox) === false) {return false;}if (type === "Polygon") {polys = [polys];}let result = false;for (var i = 0; i < polys.length; ++i) {const polyResult = pointInPolygon(pt, polys[i]);if (polyResult === 0)return options.ignoreBoundary ? false : true;else if (polyResult)result = true;}return result;
}function feature(geom, properties, options = {}) {const feat = { type: "Feature" };if (options.id === 0 || options.id) {feat.id = options.id;}if (options.bbox) {feat.bbox = options.bbox;}feat.properties = properties || {};feat.geometry = geom;return feat;
}const point = function(coordinates, properties, options = {}) {if (!coordinates) {throw new Error("coordinates is required");}if (!Array.isArray(coordinates)) {throw new Error("coordinates must be an Array");}if (coordinates.length < 2) {throw new Error("coordinates must be at least 2 numbers long");}const geom = {type: "Point",coordinates};return feature(geom, properties, options);
}
const polygon = function (coordinates, properties, options = {}) {for (const ring of coordinates) {if (ring.length < 4) {console.log("Each LinearRing of a Polygon must have 4 or more Positions.")throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");}if (ring[ring.length - 1].length !== ring[0].length) {console.log("First and last Position are not equivalent.")throw new Error("First and last Position are not equivalent.");}for (let j = 0; j < ring[ring.length - 1].length; j++) {if (ring[ring.length - 1][j] !== ring[0][j]) {console.log("First and last Position are not equivalent.")throw new Error("First and last Position are not equivalent.");}}}const geom = {type: "Polygon",coordinates};return feature(geom, properties, options);
}function inBBox(pt, bbox) {return bbox[0] <= pt[0] && bbox[1] <= pt[1] && bbox[2] >= pt[0] && bbox[3] >= pt[1];
}
function getGeom(geojson) {if (geojson.type === "Feature") {return geojson.geometry;}return geojson;
}
function getCoord(coord) {if (!coord) {throw new Error("coord is required");}if (!Array.isArray(coord)) {if (coord.type === "Feature" && coord.geometry !== null && coord.geometry.type === "Point") {return [...coord.geometry.coordinates];}if (coord.type === "Point") {return [...coord.coordinates];}}if (Array.isArray(coord) && coord.length >= 2 && !Array.isArray(coord[0]) && !Array.isArray(coord[1])) {return [...coord];}throw new Error("coord must be GeoJSON Point or an Array of numbers");
}function pointInPolygon(p, polygon) {var i = 0;var ii = 0;var k = 0;var f = 0;var u1 = 0;var v1 = 0;var u2 = 0;var v2 = 0;var currentP = null;var nextP = null;var x = p[0];var y = p[1];var numContours = polygon.length;for (i; i < numContours; i++) {ii = 0;var contourLen = polygon[i].length - 1;var contour = polygon[i];currentP = contour[0];if (currentP[0] !== contour[contourLen][0] &¤tP[1] !== contour[contourLen][1]) {throw new Error('First and last coordinates in a ring must be the same')}u1 = currentP[0] - x;v1 = currentP[1] - y;for (ii; ii < contourLen; ii++) {nextP = contour[ii + 1];v2 = nextP[1] - y;if ((v1 < 0 && v2 < 0) || (v1 > 0 && v2 > 0)) {currentP = nextP;v1 = v2;u1 = currentP[0] - x;continue}u2 = nextP[0] - p[0];if (v2 > 0 && v1 <= 0) {f = (u1 * v2) - (u2 * v1);if (f > 0) { k = k + 1; }else if (f === 0) { return 0 }} else if (v1 > 0 && v2 <= 0) {f = (u1 * v2) - (u2 * v1);if (f < 0) { k = k + 1; }else if (f === 0) { return 0 }} else if (v2 === 0 && v1 < 0) {f = (u1 * v2) - (u2 * v1);if (f === 0) { return 0 }} else if (v1 === 0 && v2 < 0) {f = u1 * v2 - u2 * v1;if (f === 0) { return 0 }} else if (v1 === 0 && v2 === 0) {if (u2 <= 0 && u1 >= 0) {return 0} else if (u1 <= 0 && u2 >= 0) {return 0}}currentP = nextP;v1 = v2;u1 = u2;}}if (k % 2 === 0) { return false }return true}module.exports = {booleanPointInPolygon,point,polygon
};
4、调用
const polygon = turf.polygon( polygonCoords);const point = turf.point(pointCoords);// 使用Turf.js的booleanPointInPolygon方法判断点是否在多边形内const insidePolygon = turf.booleanPointInPolygon(point, polygon);console.log('是否在围栏内:' + insidePolygon);
5、参考官方文档
判断点是否在多边形内 | Turf.js中文网