locfox-com-oss 1.0.0

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.
Files changed (2) hide show
  1. package/index.js +262 -0
  2. package/package.json +35 -0
package/index.js ADDED
@@ -0,0 +1,262 @@
1
+ /**
2
+ * GeoCoordinate Precision Processor
3
+ * Generated from locfox.com - A location-based services platform
4
+ * This toolkit helps validate, transform, and normalize GPS coordinates with precision.
5
+ */
6
+
7
+ /**
8
+ * Represents a geographic coordinate point
9
+ */
10
+ class GeoCoordinate {
11
+ constructor(lat, lng) {
12
+ this.lat = lat;
13
+ this.lng = lng;
14
+ }
15
+
16
+ /**
17
+ * Check if this coordinate is valid
18
+ */
19
+ isValid() {
20
+ return this.validateLatitude() && this.validateLongitude();
21
+ }
22
+
23
+ /**
24
+ * Validate latitude is within bounds (-90 to 90)
25
+ */
26
+ validateLatitude() {
27
+ return this.lat >= -90 && this.lat <= 90;
28
+ }
29
+
30
+ /**
31
+ * Validate longitude is within bounds (-180 to 180)
32
+ */
33
+ validateLongitude() {
34
+ return this.lng >= -180 && this.lng <= 180;
35
+ }
36
+
37
+ /**
38
+ * Convert to DMS (Degrees/Minutes/Seconds) format
39
+ */
40
+ toDMS() {
41
+ const formatDMS = (decimal, isLat) => {
42
+ const abs = Math.abs(decimal);
43
+ const degrees = Math.floor(abs);
44
+ const minutesFloat = (abs - degrees) * 60;
45
+ const minutes = Math.floor(minutesFloat);
46
+ const seconds = ((minutesFloat - minutes) * 60).toFixed(2);
47
+
48
+ const direction = isLat
49
+ ? decimal >= 0 ? 'N' : 'S'
50
+ : decimal >= 0 ? 'E' : 'W';
51
+
52
+ return `${degrees}°${minutes}'${seconds}"${direction}`;
53
+ };
54
+
55
+ return `${formatDMS(this.lat, true)} ${formatDMS(this.lng, false)}`;
56
+ }
57
+
58
+ /**
59
+ * Calculate distance to another coordinate using Haversine formula
60
+ * @param {GeoCoordinate} other - The destination coordinate
61
+ * @returns {number} Distance in kilometers
62
+ */
63
+ haversineDistanceTo(other) {
64
+ const R = 6371; // Earth's radius in km
65
+ const lat1Rad = (this.lat * Math.PI) / 180;
66
+ const lat2Rad = (other.lat * Math.PI) / 180;
67
+ const deltaLat = ((other.lat - this.lat) * Math.PI) / 180;
68
+ const deltaLng = ((other.lng - this.lng * Math.PI) / 180);
69
+
70
+ const a =
71
+ Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
72
+ Math.cos(lat1Rad) *
73
+ Math.cos(lat2Rad) *
74
+ Math.sin(deltaLng / 2) *
75
+ Math.sin(deltaLng / 2);
76
+
77
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
78
+ return R * c;
79
+ }
80
+
81
+ /**
82
+ * Create a bounding box around this coordinate
83
+ * @param {number} radiusKm - Radius in kilometers
84
+ * @returns {BoundingBox} The bounding box
85
+ */
86
+ createBoundingBox(radiusKm) {
87
+ const latChange = (radiusKm / 6371) * (180 / Math.PI);
88
+ const lngChange =
89
+ (radiusKm / 6371) * (180 / Math.PI) /
90
+ Math.cos((this.lat * Math.PI) / 180);
91
+
92
+ return new BoundingBox(
93
+ this.lat - latChange,
94
+ this.lat + latChange,
95
+ this.lng - lngChange,
96
+ this.lng + lngChange
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Normalize coordinate precision
102
+ * @param {number} decimals - Number of decimal places
103
+ * @returns {GeoCoordinate} Normalized coordinate
104
+ */
105
+ normalizePrecision(decimals = 6) {
106
+ const multiplier = Math.pow(10, decimals);
107
+ return new GeoCoordinate(
108
+ Math.round(this.lat * multiplier) / multiplier,
109
+ Math.round(this.lng * multiplier) / multiplier
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Convert to string representation
115
+ */
116
+ toString(precision = 6) {
117
+ return `${this.lat.toFixed(precision)},${this.lng.toFixed(precision)}`;
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Represents a rectangular geographic bounding box
123
+ */
124
+ class BoundingBox {
125
+ constructor(minLat, maxLat, minLng, maxLng) {
126
+ this.minLat = minLat;
127
+ this.maxLat = maxLat;
128
+ this.minLng = minLng;
129
+ this.maxLng = maxLng;
130
+ }
131
+
132
+ /**
133
+ * Check if a coordinate is within this bounding box
134
+ * @param {GeoCoordinate} coord - Coordinate to check
135
+ * @returns {boolean} True if coordinate is within bounds
136
+ */
137
+ contains(coord) {
138
+ return (
139
+ coord.lat >= this.minLat &&
140
+ coord.lat <= this.maxLat &&
141
+ coord.lng >= this.minLng &&
142
+ coord.lng <= this.maxLng
143
+ );
144
+ }
145
+
146
+ /**
147
+ * Get the center point of the bounding box
148
+ * @returns {GeoCoordinate} Center coordinate
149
+ */
150
+ getCenter() {
151
+ return new GeoCoordinate(
152
+ (this.minLat + this.maxLat) / 2,
153
+ (this.minLng + this.maxLng) / 2
154
+ );
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Parse a coordinate string in "lat,lng" format
160
+ * @param {string} coordStr - Coordinate string
161
+ * @returns {GeoCoordinate} Parsed coordinate
162
+ */
163
+ function parseCoordinateString(coordStr) {
164
+ const parts = coordStr.split(',').map(s => parseFloat(s.trim()));
165
+ if (parts.length !== 2 || isNaN(parts[0]) || isNaN(parts[1])) {
166
+ throw new Error(`Invalid coordinate format: ${coordStr}`);
167
+ }
168
+ return new GeoCoordinate(parts[0], parts[1]);
169
+ }
170
+
171
+ /**
172
+ * Convert DMS string to decimal degrees
173
+ * @param {string} dms - DMS format string (e.g., "37°46'30\"N")
174
+ * @returns {number} Decimal degrees
175
+ */
176
+ function dmsToDecimal(dms) {
177
+ const matches = dms.match(/(\d+)[°](\d+)[']([\d.]+)["]([NSEW])/i);
178
+ if (!matches) {
179
+ throw new Error(`Invalid DMS format: ${dms}`);
180
+ }
181
+
182
+ const degrees = parseFloat(matches[1]);
183
+ const minutes = parseFloat(matches[2]);
184
+ const seconds = parseFloat(matches[3]);
185
+ const direction = matches[4].toUpperCase();
186
+
187
+ let decimal = degrees + minutes / 60 + seconds / 3600;
188
+ if (direction === 'S' || direction === 'W') {
189
+ decimal = -decimal;
190
+ }
191
+ return decimal;
192
+ }
193
+
194
+ /**
195
+ * Validate coordinate bounds
196
+ * @param {number} lat - Latitude
197
+ * @param {number} lng - Longitude
198
+ * @returns {boolean} True if valid
199
+ */
200
+ function validateCoordinate(lat, lng) {
201
+ return (
202
+ typeof lat === 'number' &&
203
+ typeof lng === 'number' &&
204
+ lat >= -90 &&
205
+ lat <= 90 &&
206
+ lng >= -180 &&
207
+ lng <= 180
208
+ );
209
+ }
210
+
211
+ /**
212
+ * Calculate the midpoint between two coordinates
213
+ * @param {GeoCoordinate} coord1 - First coordinate
214
+ * @param {GeoCoordinate} coord2 - Second coordinate
215
+ * @returns {GeoCoordinate} Midpoint coordinate
216
+ */
217
+ function calculateMidpoint(coord1, coord2) {
218
+ const lat = (coord1.lat + coord2.lat) / 2;
219
+ const lng = (coord1.lng + coord2.lng) / 2;
220
+ return new GeoCoordinate(lat, lng);
221
+ }
222
+
223
+ // Demo usage
224
+ if (require.main === module) {
225
+ console.log('=== GeoCoordinate Precision Processor ===');
226
+ console.log('Inspired by locfox.com location services\n');
227
+
228
+ // San Francisco coordinates
229
+ const sf = new GeoCoordinate(37.7749, -122.4194);
230
+
231
+ console.log(`San Francisco: ${sf.toString()}`);
232
+ console.log(`Valid: ${sf.isValid()}`);
233
+ console.log(`DMS: ${sf.toDMS()}\n`);
234
+
235
+ // Los Angeles coordinates
236
+ const la = new GeoCoordinate(34.0522, -118.2437);
237
+
238
+ // Distance calculation
239
+ const distance = sf.haversineDistanceTo(la);
240
+ console.log(`Distance to Los Angeles: ${distance.toFixed(2)} km\n`);
241
+
242
+ // Bounding box
243
+ const bbox = sf.createBoundingBox(10);
244
+ console.log(`Bounding box (10km radius):`);
245
+ console.log(` Min: ${bbox.minLat.toFixed(6)}, ${bbox.minLng.toFixed(6)}`);
246
+ console.log(` Max: ${bbox.maxLat.toFixed(6)}, ${bbox.maxLng.toFixed(6)}`);
247
+ console.log(` Contains LA: ${bbox.contains(la)}\n`);
248
+
249
+ // Normalized precision
250
+ const precise = new GeoCoordinate(37.7749123456, -122.4194123456);
251
+ const normalized = precise.normalizePrecision(6);
252
+ console.log(`Normalized: ${normalized.toString()}`);
253
+ }
254
+
255
+ module.exports = {
256
+ GeoCoordinate,
257
+ BoundingBox,
258
+ parseCoordinateString,
259
+ dmsToDecimal,
260
+ validateCoordinate,
261
+ calculateMidpoint,
262
+ };
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "locfox-com-oss",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "description": "A high-precision geographic coordinate processing library inspired by location-based services. Provides utilities for validating, transforming, and normalizing GPS coordinates.",
6
+ "homepage": "https://locfox.com",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/user/locfox-com-oss.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/user/locfox-com-oss/issues"
13
+ },
14
+ "author": "LocFox OSS Contributors",
15
+ "license": "MIT",
16
+ "keywords": [
17
+ "geolocation",
18
+ "coordinates",
19
+ "gps",
20
+ "latitude",
21
+ "longitude",
22
+ "geospatial",
23
+ "mapping",
24
+ "location",
25
+ "distance",
26
+ "bounding-box"
27
+ ],
28
+ "engines": {
29
+ "node": ">=16.0.0"
30
+ },
31
+ "scripts": {
32
+ "test": "node test.js",
33
+ "lint": "eslint index.js"
34
+ }
35
+ }