实现 cesium 包络
可实现两个区域相交的方式有很多种:
-
three.js
-
@turf/turf
-
Proj4js
-
clipper.js
这里采用 clipper 插件进行合成
import ClipperLib from 'js-clipper'
export const ClipperEnvelopJS = (subj_paths, clip_paths, scale = Math.pow(10, 6), type = 'union') => {
if (subj_paths.length) subj_paths = subj_paths.map(item => fn(item))
if (clip_paths.length) clip_paths = clip_paths.map(item => fn(item))
ClipperLib.JS.ScaleUpPaths(subj_paths, scale)
ClipperLib.JS.ScaleUpPaths(clip_paths, scale)
var cpr = new ClipperLib.Clipper()
spr.AddPaths(subj_paths, ClipperLib.PolyType.ptSubject, true)
spr.AddPaths(clip_paths, ClipperLib.PolyType.ptClip, true)
var subject_fillType = ClipperLib.PolyFillType.pftNonZero
var clip_fillType = ClipperLib.PolyFillType.pftNonZero
const { ctUnion, ctDifference, ctXor, ctIntersection } = ClipperLib.ClipType
let solution_paths = new ClippperLib.Paths()
if (type === 'union') {
cpr.Execute(ctUnion, solution_paths, subject_fillType, clip_fillType)
}
let _arr = []
for (let i2 = 0; i2 < solution_paths.length; i2++) {
let _arr_ = []
for (let j = 0; j < solution_paths[i2].length; j++) {
let _x = solution_paths[i2][j].X / scale
let _y = solution_paths[i2][j].Y / scale
_arr_.push(_x, _y)
}
if (_arr_.length) _arr_.push(_arr_[0], _arr_[1])
_arr.push(_arr_)
}
cpr.Clear()
ClipperLib.Clear(solution_paths)
cpr = null
solution_path = null
return _arr
}
function fn (arr) {
let a = []
for (let i = 0; i < arr.length; i++) a.push({ X: arr[i], Y: arr[i + 1] })
return a
}
这种方式,普通的圆可以有效的合成包络,但是如果采用非普通的圆,例如过两个极点坐标,或者包含两个极点坐标,那么这么一合成,出问题了,各种乱七八糟的方式
验证方式:
-
当只有一个圆时,不折叠,
-
北极点为中心,大圆包含之,无法融合,或者融合出现一个奇怪的线条
-
和 0 。180 度 经度无关
-
只和北极点,男极点有关
-
和相交点无关
-
通过极点或者说区域包含极点处理手段
处理方式:
-
CGAL(Computational Geometry Algorithms Library)或 JTS(Java Topology Suite)包含了 处理极点手段,但是 web 端 并没有这方面的复杂的处理手段,且无法满足判断相对于区域位置
-
采用 二维方式的 clipper.js 在二维平面上查看,极点内的区域是否在当前的区域内,数点法,矢量法,是否可以满足需求
得到结论,无法满足,那么采用补点手段来完善clipper.js 针对 区域的合并