前言

使用turf.js裁剪,不是用turf.js中的bboxClip方法,此方法只能输入矩形边界,对于不规则边界去裁剪多边形,使用intersect()可以完成,下面所说的裁剪和求交集默认一个意思。之前遇到过这种问题:解决Turf.js中计算交集intersect方法产生的bug。随着遇到的图形越复杂问题可能就越多,当要素为multiPolygon类型的带孔洞多边形时,会出现另一种问题。

问题

如下图所示,蓝色边框为裁剪面,黄色为被裁剪面,被裁剪面是multiPolygon类型带孔的多边形,可以看出这个multiPolygon形状还是比较复杂的。(leaflet加载显示)

当使用intersect方法裁剪时(输入蓝色裁剪面和这个multiPolygon多边形),出来的结果如下图,很明显结果与预期不符合,右侧原本是孔洞的地方在经过裁剪后居然会被填充。

当把multiPolygon分解成单个Polygon分别再进行裁剪,最后把结果合并,这个最终结果也是有问题的,和上面结果基本无差别,如下图所示,

地图加载这个multiPolygon多边形是使用leaflet,当把这个multiPolygon使用mapshaper加载时,出来的形状如下图,也就是leaflet加载这个图形和其他工具加载显示的不一样,按照裁剪的结果来看,turf.js把这个multiPolygon当成了下面这种图形来处理,把右侧空洞没有当做空洞处理,而是当成了图形,裁剪的结果自然不对,这里可以看出turf.js还是有点问题的在处理复杂多边形时。

解决

既然出现了问题,但还是要摸索着解决一下,这里有个前提,对于这个multiPolygon类型的数据,leaflet加载时没问题的,出问题的是turf.js。这里想到了一种思路:取出multiPolygon中的每个单多边形的坐标集合包括空洞坐标集,利用这些坐标集分别构建成单polygon要素再与边界进行裁剪,同时记录该polygon坐标集合在multiPolygon要素坐标集中的位置信息,把裁剪得到的要素的坐标集合去替换这个polygon在multiPolygon中的位置的坐标集合。也就是用multiPolygon要素中单个坐标集合分别构建polygon去裁剪,把得到的结果重新替换multiPolygon对应位置的坐标集。这里如果裁剪得到的多边形是multiPolygon类型,需要把这个类型分解成单个polygon坐标集,在放入原先对应位置,此时在相应层级位置处不需要再分层级,并列放入。利用这种方法可以裁剪成功。
如果不去替换,拿到裁剪后得到的坐标集合重新组合成一个新的要素时,要和原先要素集合坐标排列的位置顺序一样,替换的目的就是保障坐标集合位置和以前一样,位置要不一样的话,会出现问题。

裁剪得到的结果如下图,这个multipolygon总共分解8个geometry坐标集合,采集结果也得到8个坐标集,其中一个是multipolygon类型的多边形,其余都是Polygon类型,最后一个集合为空,说明这个分解multipolygon得到的坐标集不在裁剪边界里,也就不需要这部分坐标集了。利用这个些新坐标集去替换原先multipolygon。

代码

具体实现代码:

const clipArray: any[] = []
getIntersectFeature(layer1, layer2, clipArray)
replaceCoord(layer1, clipArray)//求相交和位置信息
const getIntersectFeature = (inLayer: any, clipLayer: any, clipArray: any[]) => {const coordinates_0 = inLayer.geometry.coordinatesfor (let i = 0; i < coordinates_0.length; i++) {const coordinates_1 = inLayer.geometry.coordinates[i]for (let j = 0; j < coordinates_1.length; j++) {const geometry = {type: 'Polygon',coordinates: [[...coordinates_1[j]]]}const feature: any = turf.feature(geometry)feature.properties = inLayer.propertiesconst f = intersect(feature, clipLayer)clipArray.push({start: i,end: j,coords: f ? f.geometry.coordinates : null,type: f ? f.geometry.type : null})}}
}//替换multiPolygon坐标集
const replaceCoord = (layer1: any, clipArray: any[]) => {for (let i = 0; i < layer1.geometry.coordinates.length; i++) {const tempArray = clipArray.filter((e: any) => {return e.start == i})layer1.geometry.coordinates[i] = []for (let j = 0; j < tempArray.length; j++) {if (tempArray[j].type) {if (tempArray[j].type == 'Polygon') {layer1.geometry.coordinates[i].push(tempArray[j].coords[0])} else {tempArray[j].coords.forEach((e: any) => {layer1.geometry.coordinates[i].push(e[0])})}}}}
}const intersect = (layer1: any, layer2: any): any => {let intersection = nullintersection = turf.intersect(layer1, layer2)if (intersection != null) {intersection.properties = layer1.propertiesintersection.id = Math.random() * 100000return intersection} else {return null}
}

结果

采用上面的方法处理这个multiPolygon多边形,裁剪出来的结果符合预期效果。

数据:
链接:https://pan.baidu.com/s/1Tfa8f8YUBRV4NpQHNOAqiw
提取码:1234

解决turf.js裁剪multiPolygon类型的复杂带孔洞多边形时出现的问题相关推荐

  1. 后端 Long类型,超过 js 的number类型最大值的解决办法

    先看问题: 数据库 id 为 Bigint 类型: 通过后端逻辑取值返回给前端: JS 的number类型有个最大值(安全值).即2的53次方,为9007199254740992(16位).如果超过这 ...

  2. java 地理围栏实现_基于Turf.js教你快速实现地理围栏的合并拆分

    以下内容转载自totoro的文章<几何计算-基于Turf.js实现多边形的拆分及合并> 作者:totoro 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. JavaS ...

  3. 【前端2】js:原始类型,运算符,调试,页面加载,轮播图,Bom(对象,时钟),Dom(全选全不选,省市级联,隔行/触摸换色,表单校验)

    文章目录 1.js两种引入:js最终要引入到html在浏览器中运行 2.js五大原始类型:undefined 3.js的运算符和流程控制:js不支持单&和单|性能低 4.案例_99乘法表:So ...

  4. js中Numer类型最大值9007199254740991,精度丢失问题解决

    Numer类型最大值/最小值 js中数值类型的个最大值(安全值)为9,007,199,254,740,991,是2的53次方-1.在10进制表示下有16位. Number.MAX_SAFE_INTEG ...

  5. cropper.js 裁剪图片并上传(文档翻译+demo)(转)

    官网http://fengyuanchen.github.io/cropper/ 文档https://github.com/fengyuanchen/cropper/blob/master/READM ...

  6. js大数字类型(超过16位)失真问题

    bug经过:点击修改无法展示信息(修改时调用queryOne,以id(long)为值,页面传过去的id=1480042498255640-00 ,在数据库中该id=148004249825564012 ...

  7. uniapp 框架下如何引入turf.js

    turf.js是一个非常优秀的前端空间计算框架.最近遇到一个问题,在使用uniapp进行开发微信小程序时,无法通过npm正常引入turf.js,这个问题也解决了很久.最后解决的方式也稍微复杂. 在空项 ...

  8. OpenLayers6(8):引入Turf.js做缓冲区分析

    1 版本 OpenLayers:6.14.1 2 相关配置 //前端的地理空间分析库,处理各种地图算法npm i @turf/turf 3 Openlayers图形与图形Turf之间的互相转换 使用策 ...

  9. OL4结合turf.js实现等值线

    概述 本文分享一个结合turf.js实现前端等值线的生成,并对结果做了圆滑处理,并在OL4中进行展示. 效果 实现 实现比较简单,源代码如下: <!DOCTYPE html> <ht ...

最新文章

  1. Swift解读专题四——字符串与字符
  2. linux操作系统-设置静态ip
  3. 构建动态域名解析系统DDNS
  4. JAVA元注解@interface详解(@Target,@Documented,@Retention,@Inherited)。
  5. 【H2 Database】shell
  6. rxjs里switchMap operators的用法
  7. SAP ABAP, Fiori, Android和Hybris里的异步操作
  8. C语言指南-数组之谜
  9. hbuilder热更新
  10. android启动其他app的服务器,Android中通过外部程序启动App的三种方法
  11. 用户控件与自定义控件
  12. 贪吃蛇大战 java小游戏百度云源码
  13. header元素 footer元素 hgroup元素
  14. SHP(shapefile)文件
  15. 《网络攻防》实验九:web安全基础实践
  16. 你可能不知道的印度手机市场
  17. 计算机教程求和,电脑excel求和怎么操作步骤 | excel竖列自动求和sum
  18. 常用web前端UI组件库
  19. 利用libpcap捕获DPDK网络包
  20. 项目Beta冲刺(2/7)(追光的人)(2019.5.24)

热门文章

  1. 移动支付的浪潮下,支付接入会遇到哪些难题?
  2. 霜蝉DTU对接组态王组态软件的使用方法
  3. [深入研究4G/5G/6G专题-4]: DTU系统架构与软件架构
  4. STM32如何在LCD上显示单词、文字、图片等
  5. k8s使用nfs持久化存储
  6. 编程很难?很枯燥?那我们就玩起来燥起来。
  7. springboot启动提示文件不能找到问题解决
  8. Linux系统简单介绍
  9. vue2.x 标签动态设置背景问题,有透明度
  10. Idea中设置护眼绿