| @@ -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 | |||
| } | |||
| @@ -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 | |||
| } | |||
| } | |||
| @@ -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() | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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) | |||
| } | |||
| @@ -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 | |||
| } | |||
| @@ -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' | |||
| @@ -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) | |||
| } | |||
| @@ -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 | |||
| ) | |||
| } | |||
| @@ -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 | |||
| } | |||