wx小程序turf.js判断点是否位于该多边形内部

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"

javascript 复制代码
// index.ts
 
const  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] &&
                currentP[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、调用

javascript 复制代码
 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中文网

相关推荐
放逐者-保持本心,方可放逐5 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
计算机-秋大田5 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
钰@8 小时前
小程序开发者工具的network选项卡中有某域名的接口请求,但是在charles中抓不到该接口
运维·服务器·小程序
尚学教辅学习资料8 小时前
基于微信小程序的电商平台+LW示例参考
java·微信小程序·小程序·毕业设计·springboot·电商平台
尘浮生8 小时前
Java项目实战II基于微信小程序的移动学习平台的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·学习·微信小程序·小程序
小泽呀x11 小时前
微信小程序中使用离线版阿里云矢量图标
微信小程序·小程序
fakaifa11 小时前
CRMEB Pro版v3.1源码全开源+PC端+Uniapp前端+搭建教程
前端·小程序·uni-app·php·源码下载
托马斯-酷涛12 小时前
小程序源码-模版 100多套小程序(附源码)
小程序
小蒜学长14 小时前
springboot基于SpringBoot的企业客户管理系统的设计与实现
java·spring boot·后端·spring·小程序·旅游