瀏覽代碼

add @dc-modules/math

tags/2.0.0
Caven Chen 4 年之前
父節點
當前提交
5ac80c7b03

+ 21
- 0
modules/math/area.js 查看文件

@@ -0,0 +1,21 @@
/**
* @Author: Caven
* @Date: 2020-04-24 14:49:37
*/

import { Transform } from '@dc-modules/transform'

export default function area(positions) {
let result = 0
if (positions && Array.isArray(positions)) {
let h = 0
let pos = positions.concat(positions[0])
for (let i = 1; i < pos.length; i++) {
let oel = Transform.transformWGS84ToCartesian(pos[i - 1])
let el = Transform.transformWGS84ToCartesian(pos[i])
h += oel.x * el.y - el.x * oel.y
}
result = Math.abs(h).toFixed(2)
}
return result
}

+ 32
- 0
modules/math/bounds.js 查看文件

@@ -0,0 +1,32 @@
/**
* @Author: Caven
* @Date: 2020-04-23 09:29:56
*/

export default function bounds(positions = [], expand = 0) {
let minLng = 180
let minLat = 90
let maxLng = -180
let maxLat = -90
positions.forEach(item => {
minLng = Math.min(minLng, item.lng || item.x)
minLat = Math.min(minLat, item.lat || item.y)
maxLng = Math.max(maxLng, item.lng || item.x)
maxLat = Math.max(maxLat, item.lat || item.y)
})

if (expand > 0) {
let diffLng = Math.abs(maxLng - maxLng)
let diffLat = Math.abs(maxLat - minLat)
minLng -= diffLng * expand
minLat -= diffLat * expand
maxLng += diffLng * expand
maxLat += diffLat * expand
}
return {
west: minLng,
south: minLat,
east: maxLng,
north: maxLat
}
}

+ 20
- 0
modules/math/center.js 查看文件

@@ -0,0 +1,20 @@
/**
* @Author: Caven
* @Date: 2020-04-24 14:43:39
*/

import { Transform } from '@dc-modules/transform'
import Position from '@dc-modules/position/Position'

const { Cesium } = DC.Namespace

export default function center(positions) {
if (positions && Array.isArray(positions)) {
let boundingSphere = Cesium.BoundingSphere.fromPoints(
Transform.transformWGS84ArrayToCartesianArray(positions)
)
return Transform.transformCartesianToWGS84(boundingSphere.center)
}

return new Position()
}

+ 92
- 0
modules/math/curve.js 查看文件

@@ -0,0 +1,92 @@
/**
* @Author: Caven
* @Date: 2020-08-16 11:14:23
*/

/**
* Some of the code borrows from MAPV
* https://github.com/huiyan-fe/mapv/blob/3292c7c25dbbf29af3cf7b3acb48108d60b3eed8/src/utils/curve.js
*/
export default function curve(points, options) {
options = options || {}
let curvePoints = []
for (let i = 0; i < points.length - 1; i++) {
let p = getCurveByTwoPoints(points[i], points[i + 1], options.count)
if (p && p.length > 0) {
curvePoints = curvePoints.concat(p)
}
}
return curvePoints
}

/**
* Get a curvilinear coordinate set of points based on two points
* @param obj1
* @param obj2
* @param count
* @returns {null|[]}
*/
function getCurveByTwoPoints(obj1, obj2, count) {
if (!obj1 || !obj2) {
return null
}
let curveCoordinates = []
count = count || 40 // 曲线是由一些小的线段组成的,这个表示这个曲线所有到的折线的个数
let B1 = function(x) {
return 1 - 2 * x + x * x
}
let B2 = x => {
return 2 * x - 2 * x * x
}
let B3 = x => {
return x * x
}

let t, h, h2, lat3, lng3, t2
let inc = 0
let lat1 = parseFloat(obj1.lat)
let lat2 = parseFloat(obj2.lat)
let lng1 = parseFloat(obj1.lng)
let lng2 = parseFloat(obj2.lng)

// 计算曲线角度的方法
if (lng2 > lng1) {
if (lng2 - lng1 > 180) {
if (lng1 < 0) {
lng1 = 180 + 180 + lng1
lng2 = 180 + 180 + lng2
}
}
}
// 此时纠正了 lng1 lng2

t2 = 0
// 纬度相同
if (lat2 === lat1) {
t = 0
h = lng1 - lng2
// 经度相同
} else if (lng2 === lng1) {
t = Math.PI / 2
h = lat1 - lat2
} else {
t = Math.atan((lat2 - lat1) / (lng2 - lng1))
h = (lat2 - lat1) / Math.sin(t)
}
if (t2 === 0) {
t2 = t + Math.PI / 5
}
h2 = h / 2
lng3 = h2 * Math.cos(t2) + lng1
lat3 = h2 * Math.sin(t2) + lat1

for (let i = 0; i < count + 1; i++) {
let x = lng1 * B1(inc) + lng3 * B2(inc) + lng2 * B3(inc)
let y = lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc)
let lng1_src = obj1.lng
let lng2_src = obj2.lng
curveCoordinates.push([lng1_src < 0 && lng2_src > 0 ? x - 360 : x, y])
inc = inc + 1 / count
}
return curveCoordinates
}

+ 25
- 0
modules/math/distance.js 查看文件

@@ -0,0 +1,25 @@
/**
* @Author: Caven
* @Date: 2020-03-31 20:58:06
*/

import { Transform } from '@dc-modules/transform'

const { Cesium } = DC.Namespace

export default function distance(positions) {
let distance = 0
if (positions && Array.isArray(positions)) {
for (let i = 0; i < positions.length - 1; i++) {
let c1 = Transform.transformWGS84ToCartographic(positions[i])
let c2 = Transform.transformWGS84ToCartographic(positions[i + 1])
let geodesic = new Cesium.EllipsoidGeodesic()
geodesic.setEndPoints(c1, c2)
let s = geodesic.surfaceDistance
s = Math.sqrt(Math.pow(s, 2) + Math.pow(c2.height - c1.height, 2))
distance += s
}
}

return distance.toFixed(3)
}

+ 40
- 0
modules/math/heading.js 查看文件

@@ -0,0 +1,40 @@
/**
* @Author: Caven
* @Date: 2020-04-11 00:41:47
*/

import { Transform } from '@dc-modules/transform'
import Parse from '@dc-modules/parse/Parse'

const { Cesium } = DC.Namespace

export default function heading(start, end) {
let heading = 0
let startPosition = Parse.parsePosition(start)
let endPosition = Parse.parsePosition(end)
startPosition = Transform.transformWGS84ToCartesian(startPosition)
endPosition = Transform.transformWGS84ToCartesian(endPosition)
let v = Cesium.Cartesian3.subtract(
endPosition,
startPosition,
new Cesium.Cartesian3()
)
if (v) {
Cesium.Cartesian3.normalize(v, v)
let up = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(
startPosition,
new Cesium.Cartesian3()
)
let east = Cesium.Cartesian3.cross(
Cesium.Cartesian3.UNIT_Z,
up,
new Cesium.Cartesian3()
)
let north = Cesium.Cartesian3.cross(up, east, new Cesium.Cartesian3())
heading = Math.atan2(
Cesium.Cartesian3.dot(v, east),
Cesium.Cartesian3.dot(v, north)
)
}
return heading
}

+ 14
- 0
modules/math/index.js 查看文件

@@ -0,0 +1,14 @@
/**
* @Author: Caven
* @Date: 2020-03-31 20:57:36
*/

export { default as area } from './area'
export { default as bounds } from './bounds'
export { default as mid } from './mid'
export { default as center } from './center'
export { default as distance } from './distance'
export { default as heading } from './heading'
export { default as isBetween } from './isBetween'
export { default as parabola } from './parabola'
export { default as curve } from './curve'

+ 9
- 0
modules/math/isBetween.js 查看文件

@@ -0,0 +1,9 @@
/**
* @Author: Caven
* @Date: 2020-03-31 20:58:06
*/

export default function isBetween(value, min, max) {
value = parseFloat(value) || 0.0
return value >= parseFloat(min) && value <= parseFloat(max)
}

+ 28
- 0
modules/math/mid.js 查看文件

@@ -0,0 +1,28 @@
/**
* @Author: Caven
* @Date: 2020-08-21 18:16:52
*/

import { Transform } from '@dc-modules/transform'
import Parse from '@dc-modules/parse/Parse'
import Position from '@dc-modules/position/Position'

const { Cesium } = DC.Namespace

export default function mid(start, end) {
let startPosition = Parse.parsePosition(start)
let endPosition = Parse.parsePosition(end)
startPosition = Transform.transformWGS84ToCartographic(startPosition)
endPosition = Transform.transformWGS84ToCartographic(endPosition)

let mc = new Cesium.EllipsoidGeodesic(
startPosition,
endPosition
).interpolateUsingFraction(0.5)

return new Position(
Cesium.Math.toDegrees(mc.longitude),
Cesium.Math.toDegrees(mc.latitude),
mc.height
)
}

+ 53
- 0
modules/math/parabola.js 查看文件

@@ -0,0 +1,53 @@
/**
* @Author: Caven
* @Date: 2020-05-28 10:24:38
*/

export default function parabola(
startPosition,
endPosition,
height = 0,
count = 50
) {
//方程 y=-(4h/L^2)*x^2+h h:顶点高度 L:横纵间距较大者
let result = []
height = Math.max(+height, 100)
count = Math.max(+count, 50)
let diffLng = Math.abs(startPosition.lng - endPosition.lng)
let diffLat = Math.abs(startPosition.lat - endPosition.lat)
let L = Math.max(diffLng, diffLat)
let dlt = L / count
if (diffLng > diffLat) {
//base on lng
let delLat = (endPosition.lat - startPosition.lat) / count
if (startPosition.lng - endPosition.lng > 0) {
dlt = -dlt
}
for (let i = 0; i < count; i++) {
let h =
height -
(Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * height) /
Math.pow(L, 2)
let lng = startPosition.lng + dlt * i
let lat = startPosition.lat + delLat * i
result.push([lng, lat, h])
}
} else {
//base on lat
let delLng = (endPosition.lng - startPosition.lng) / count
if (startPosition.lat - endPosition.lat > 0) {
dlt = -dlt
}
for (let i = 0; i < count; i++) {
let h =
height -
(Math.pow(-0.5 * L + Math.abs(dlt) * i, 2) * 4 * height) /
Math.pow(L, 2)
let lng = startPosition.lng + delLng * i
let lat = startPosition.lat + dlt * i
result.push([lng, lat, h])
}
}

return result
}

Loading…
取消
儲存