Update src/client/types/geom.ts
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
sora-ext 2025-02-27 17:31:09 +01:00
parent fe4190313b
commit 1814a8a87d

View File

@ -1,5 +1,3 @@
// import L from "leaflet"
const ellipsoid = { const ellipsoid = {
a: 6378137, a: 6378137,
b: 6356752.3142, b: 6356752.3142,
@ -19,7 +17,7 @@ function wrap(degrees: number, max = 360) {
} }
} }
function dist(src, dst, itr = 100, mit = true): number { function dist(src: LatLng, dst: LatLng, itr = 100, mit = true): number {
const p1 = src, const p1 = src,
p2 = dst; p2 = dst;
const φ1 = toRadians(p1.lat), const φ1 = toRadians(p1.lat),
@ -84,7 +82,7 @@ function dist(src, dst, itr = 100, mit = true): number {
if (mit) { if (mit) {
return dist( return dist(
src, src,
new L.LatLng(dst.lat, dst.lng - 0.01), { lat: dst.lat, lng: dst.lng - 0.01 },
itr, itr,
mit mit
); );
@ -109,10 +107,10 @@ function dist(src, dst, itr = 100, mit = true): number {
} }
function pointDistance(src: L.LatLng, dst: L.LatLng): number { function pointDistance(src: LatLng, dst: LatLng): number {
return dist( return dist(
new L.LatLng(src.lat, wrap(src.lng, 180)), { lat: src.lat, lng: wrap(src.lng, 180) },
new L.LatLng(dst.lat, wrap(dst.lng, 180)) { lat: dst.lat, lng: wrap(dst.lng, 180) }
); );
} }
@ -124,7 +122,7 @@ function toDegrees(radians: number): number {
return (radians * 180) / Math.PI; return (radians * 180) / Math.PI;
} }
function midpoint(src: L.LatLng, dst: L.LatLng): L.LatLng { function midpoint(src: LatLng, dst: LatLng): LatLng {
// φm = atan2( sinφ1 + sinφ2, √( (cosφ1 + cosφ2⋅cosΔλ)² + cos²φ2⋅sin²Δλ ) ) // φm = atan2( sinφ1 + sinφ2, √( (cosφ1 + cosφ2⋅cosΔλ)² + cos²φ2⋅sin²Δλ ) )
// λm = λ1 + atan2(cosφ2⋅sinΔλ, cosφ1 + cosφ2⋅cosΔλ) // λm = λ1 + atan2(cosφ2⋅sinΔλ, cosφ1 + cosφ2⋅cosΔλ)
// midpoint is sum of vectors to two points: mathforum.org/library/drmath/view/51822.html // midpoint is sum of vectors to two points: mathforum.org/library/drmath/view/51822.html
@ -144,31 +142,24 @@ function midpoint(src: L.LatLng, dst: L.LatLng): L.LatLng {
const φm = Math.atan2(C.z, Math.sqrt(C.x * C.x + C.y * C.y)); const φm = Math.atan2(C.z, Math.sqrt(C.x * C.x + C.y * C.y));
const λm = λ1 + Math.atan2(C.y, C.x); const λm = λ1 + Math.atan2(C.y, C.x);
return new L.LatLng(toDegrees(φm), toDegrees(λm)); return { lat: toDegrees(φm), lng: toDegrees(λm) };
} }
function recursiveMidPoint(src: L.LatLng, dst: L.LatLng, opt: { step?: number, dist?: number }): L.LatLng[] { function recursiveMidPoint(src: LatLng, dst: LatLng, opt: { step?: number, dist?: number } = {}, curr = 0): LatLng[] {
const geom: L.LatLng[] = [src, dst]; const geom: LatLng[] = [src, dst];
const mp = midpoint(src, dst); const mp = midpoint(src, dst);
const split_step = (opt.step != undefined && (opt.step > 0 || curr == 0))
if (opt.step != undefined) { const split_dist = (opt.dist != undefined && (pointDistance(src, dst) > opt.dist || curr == 0))
if (opt.step > 0) { const next_opt = split_step ? { step: (opt.step || 0) - 1 } : { dist: opt.dist };
geom.splice(0, 1, ...recursiveMidPoint(src, mp, { step: opt.step - 1 })); if (split_step || split_dist) {
geom.splice(geom.length - 2, 2, ...recursiveMidPoint(mp, dst, { step: opt.step - 1 })); geom.splice(0, 1, ...recursiveMidPoint(src, mp, next_opt, curr + 1));
} else { geom.splice(geom.length - 2, 2, ...recursiveMidPoint(mp, dst, next_opt, curr + 1));
geom.splice(1, 0, mp); } else {
} geom.splice(1, 0, mp);
} else if (opt.dist != undefined) {
if (pointDistance(src, dst) > opt.dist) {
geom.splice(0, 1, ...recursiveMidPoint(src, mp, { dist: opt.dist }));
geom.splice(geom.length - 2, 2, ...recursiveMidPoint(mp, dst, { dist: opt.dist }));
} else {
geom.splice(1, 0, mp);
}
} }
return geom; return geom;
} }
export function getGeoLine(src: L.LatLng, dst: L.LatLng, opt: { step: number, dist: number }) { export function getGeoLine(src: LatLng, dst: LatLng, opt: { step?: number, dist?: number }) {
return recursiveMidPoint(src, dst, opt) return recursiveMidPoint(src, dst, opt, 0)
} }