@dra2020/baseclient 1.0.164 → 1.0.165

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@ export * from './blend';
10
10
  export * from './cartesian';
11
11
  export * from './minbound';
12
12
  export * from './polyround';
13
+ export * from './polyconvert';
13
14
  export * from './topo';
14
15
  export * from './selfintersect';
15
16
  export * from './shamos';
@@ -0,0 +1,10 @@
1
+ export type PointConverter = (pt: [number, number]) => [number, number];
2
+ export declare function polyConvert(o: any, cvt: PointConverter): any;
3
+ export declare function polyFrom32614(o: any): any;
4
+ export declare function colValidateCRS(o: any): any;
5
+ /**
6
+ * Convert UTM Zone 14N (EPSG:32614) coordinates to WGS84 lon/lat.
7
+ * Input: [easting, northing] in meters
8
+ * Output: [longitude, latitude] in degrees
9
+ */
10
+ export declare function utm14ToLonLat([E, N]: [number, number]): [number, number];
package/lib/poly/all.ts CHANGED
@@ -10,6 +10,7 @@ export * from './blend';
10
10
  export * from './cartesian';
11
11
  export * from './minbound';
12
12
  export * from './polyround';
13
+ export * from './polyconvert';
13
14
  export * from './topo';
14
15
  export * from './selfintersect';
15
16
  export * from './shamos';
@@ -0,0 +1,128 @@
1
+ import * as Util from '../util/all';
2
+ import * as PP from './polypack';
3
+
4
+ export type PointConverter = (pt: [number, number]) => [number, number]
5
+
6
+ // Convert geometry given point conversion function. Takes any form of feature, collection or coordinate array(s)
7
+ export function polyConvert(o: any, cvt: PointConverter): any
8
+ {
9
+ if (o)
10
+ {
11
+ if (Array.isArray(o))
12
+ {
13
+ if (o.length && typeof o[0] === 'number')
14
+ {
15
+ for (let i = 0; i < o.length; i += 2)
16
+ {
17
+ const p = cvt([o[i], o[i+1]]);
18
+ o[i] = p[0];
19
+ o[i+1] = p[1];
20
+ }
21
+ }
22
+ else
23
+ o.forEach((e: any) => { polyConvert(e, cvt) });
24
+ }
25
+ else if (o.features !== undefined && Array.isArray(o.features))
26
+ o.features.forEach((f: any) => { polyConvert(f, cvt) });
27
+ else if (o.geometry !== undefined && o.geometry.coordinates !== undefined)
28
+ polyConvert(o.geometry.coordinates, cvt);
29
+ else if (o.geometry !== undefined && o.geometry.packed !== undefined)
30
+ PP.polyPackEachPoint(o.geometry.packed, (b: Float64Array, iPoly: number, iRing: number, iOffset: number) => {
31
+ const p = cvt([b[iOffset], b[iOffset+1]]);
32
+ b[iOffset] = p[0];
33
+ b[iOffset+1] = p[1];
34
+ });
35
+ }
36
+ return o;
37
+ }
38
+
39
+ export function polyFrom32614(o: any): any
40
+ {
41
+ return polyConvert(o, utm14ToLonLat);
42
+ }
43
+
44
+ // If coordinates in 32614 format, convert to WGS84 (GeoJSON standard format)
45
+ //
46
+ export function colValidateCRS(o: any): any
47
+ {
48
+ // "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::32614" } },
49
+
50
+ if (o?.crs?.properties?.name === 'urn:ogc:def:crs:EPSG::32614')
51
+ {
52
+ delete o.crs;
53
+ return polyFrom32614(o);
54
+ }
55
+ return o
56
+ }
57
+
58
+ /**
59
+ * Convert UTM Zone 14N (EPSG:32614) coordinates to WGS84 lon/lat.
60
+ * Input: [easting, northing] in meters
61
+ * Output: [longitude, latitude] in degrees
62
+ */
63
+ export function utm14ToLonLat([E, N]: [number, number]): [number, number] {
64
+ // WGS84 parameters
65
+ const a = 6378137.0;
66
+ const f = 1 / 298.257223563;
67
+ const k0 = 0.9996;
68
+
69
+ const e = Math.sqrt(f * (2 - f)); // eccentricity
70
+ const e1sq = e * e / (1 - e * e);
71
+
72
+ // UTM zone parameters
73
+ const zone = 14;
74
+ const lonOrigin = (zone - 1) * 6 - 180 + 3; // central meridian
75
+ const falseEasting = 500000;
76
+
77
+ // Remove false northing for northern hemisphere (EPSG:326xx always north)
78
+ const x = E - falseEasting;
79
+ const y = N;
80
+
81
+ // Footpoint latitude
82
+ const M = y / k0;
83
+ const mu = M / (a * (1 - e*e/4 - 3*e**4/64 - 5*e**6/256));
84
+
85
+ const e1 = (1 - Math.sqrt(1 - e*e)) / (1 + Math.sqrt(1 - e*e));
86
+
87
+ const J1 = (3 * e1 / 2 - 27 * e1**3 / 32);
88
+ const J2 = (21 * e1**2 / 16 - 55 * e1**4 / 32);
89
+ const J3 = (151 * e1**3 / 96);
90
+ const J4 = (1097 * e1**4 / 512);
91
+
92
+ const fp = mu
93
+ + J1 * Math.sin(2 * mu)
94
+ + J2 * Math.sin(4 * mu)
95
+ + J3 * Math.sin(6 * mu)
96
+ + J4 * Math.sin(8 * mu);
97
+
98
+ // Precompute trig functions
99
+ const sinfp = Math.sin(fp);
100
+ const cosfp = Math.cos(fp);
101
+ const tanfp = Math.tan(fp);
102
+
103
+ const C1 = e1sq * cosfp**2;
104
+ const T1 = tanfp**2;
105
+ const R1 = a * (1 - e*e) / Math.pow(1 - e*e * sinfp**2, 3/2);
106
+ const N1 = a / Math.sqrt(1 - e*e * sinfp**2);
107
+ const D = x / (N1 * k0);
108
+
109
+ // Latitude (φ)
110
+ const lat =
111
+ fp
112
+ - (N1 * tanfp / R1) *
113
+ (D**2 / 2
114
+ - (5 + 3*T1 + 10*C1 - 4*C1**2 - 9*e1sq) * D**4 / 24
115
+ + (61 + 90*T1 + 298*C1 + 45*T1**2 - 252*e1sq - 3*C1**2) * D**6 / 720);
116
+
117
+ // Longitude (λ)
118
+ const lon =
119
+ (D
120
+ - (1 + 2*T1 + C1) * D**3 / 6
121
+ + (5 - 2*C1 + 28*T1 - 3*C1**2 + 8*e1sq + 24*T1**2) * D**5 / 120) / cosfp;
122
+
123
+ // Convert to degrees and apply central meridian offset
124
+ const latitude = lat * (180 / Math.PI);
125
+ const longitude = lonOrigin + lon * (180 / Math.PI);
126
+
127
+ return [longitude, latitude];
128
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dra2020/baseclient",
3
- "version": "1.0.164",
3
+ "version": "1.0.165",
4
4
  "description": "Utility functions for Javascript projects.",
5
5
  "main": "dist/baseclient.js",
6
6
  "types": "./dist/all/all.d.ts",