Leaflet 笔记二:简单插件编写leaflet-pip-v2

简单插件编写leaflet-pip-v2

github源码在此,记得点星:
https://github.com/brandonxiang/leaflet-pip-v2


在学习了leaflet之后,你可能会注意到它的插件,生态丰富,实用有效。当然,你也可以写一些满足自己需求的插件。相对而言,这有点难度。

而leaflet的插件而言,我将其分为两大类:

这篇笔记主要写的是前者。受leaflet-pip插件启发,点与线之间的数据选择进行扩展。你可以先参考mapbox/leaflet-pip,再看我的这段代码brandonxiang/leaflet-pip-v2,再做调整。如果还是很难理解,那就看demo。

Demo

他们的 demo

685800-ec192b01a2780b8a.png
他们的 demo

我的demo

685800-3c0f0112c7ddda5d.png
我的demo

不难看出,leaflet-pip的本意是通过点选择面,与点产生包含关系的多边形被选择,我将其设置为红色。

而leaflet-pip-v2的想法是通过面去选择点,与面积相交的点被选择,我将其设置成半透明。

原理

本插件的目标是去完成一个找出点与面包含关系的查询,即Point in Polygon(pip)。当然,方法很多,你可以使用空间查询,那可以是后端技术利用空间数据库。方法可以参考substack/point-in-polygon以及maxogden/geojson-js-utils,而mapbox/leaflet-pip则是利用过这两个库。

原理都是[PNPOLY](https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html#The Method)。原理大概是将多边形分成多个三角形,判断点是否在三角形内。而凸三角形或凹三角形可能影响判断点是否在多边形。C语言代码如下,可以被改写为其它语言。

参数 意义
nvert 多边形顶点数
vertx,verty 顶点的x和y数组
testx,testy 测试点的x和y
685800-029066edf89db1c8.png
原理
int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
  int i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
     (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
       c = !c;
  }
  return c;
}

利用leaflet选点在某个多边形内

leaflet-pip通过点要素的相交关系从多面状GeoJSON中选择一个面状,但是我的想法是通过面要素的相交关系从点的GeoJSON中选择多个点。这两个处理过程都基于同样的原理–空间查询。

使用方法

var selectedpoints = leafletPip.pointsInPolygon(
L.geoJson(point.geojson),L.geoJson(singlepolygon.geojson)
);

我的demo

源码剖析

引用了geojson-utils内的其中一个方法,用于判断点是否在面之类,所以原理十分简单。即是将点图层循环,查找它是否在多边形内部。如果是,将其返回即可。在这里极度推荐各位GISER看看maxogden/geojson-js-utils的源码。

pointsInPolygon: function(points, layer) {

'use strict';

var results = [];

points.eachLayer(function(p) {

if (gju.pointInPolygon(p.toGeoJSON().geometry, layer.toGeoJSON().geometry)) {

results.push(p);

}

});

return results;

}

转载,请表明出处。总目录Awesome GIS

转载自:https://blog.csdn.net/weixin_34396902/article/details/86970195

You may also like...