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中文网

相关推荐
小羊Linux客栈6 小时前
Python小程序:上班该做点摸鱼的事情
开发语言·python·小程序·游戏程序
27669582928 小时前
得物 小程序 6宫格 分析
java·python·小程序·得物·得物小程序·得物六宫格·六宫格验证码
MYmayue9 小时前
微信小程序封装选择年月日时分秒组件
微信小程序·小程序
niech_cn17 小时前
仿微信上传头像,实现拍摄、相册选择、手动缩放、裁剪、蒙版、撤回、还原、上传微信本地文件功能
微信·小程序
某公司摸鱼前端21 小时前
uniapp 支付宝小程序自定义 navbar 无效解决方案
小程序·uni-app
旧人231 天前
微信小程序 首页之轮播图和搜索框 代码分享
微信小程序·小程序
人工智能的苟富贵1 天前
微信小程序直传阿里云 OSS 实践指南(V4 签名 · 秒传支持 · 高性能封装)
阿里云·微信小程序·小程序
时之彼岸Φ1 天前
Fiddler+Yakit实现手机流量抓包和小程序抓包
智能手机·小程序·fiddler
suncentwl1 天前
为什么选择有版权的答题pk小程序
小程序·答题小程序·答题pk