@osimatic/helpers-js 1.4.7 → 1.4.8

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.
package/location.js CHANGED
@@ -466,12 +466,85 @@ class Polygon {
466
466
  if (r.length >= 3) {
467
467
  const [lon0,lat0] = r[0];
468
468
  const [lonL,latL] = r[r.length-1];
469
- if (lon0 !== lonL || lat0 !== latL) r.push([lon0,lat0]);
469
+ if (lon0 !== lonL || lat0 !== latL) {
470
+ r.push([lon0,lat0]);
471
+ }
470
472
  }
471
473
  return r;
472
474
  });
473
475
  return { type: 'Polygon', coordinates: rings };
474
476
  }
477
+
478
+
479
+ // Test "sur le segment" en degrés (plan local) — suffisant pour le bord du polygone
480
+ static isPointOnSegmentDeg(lat, lon, A, B, EPS = 1e-12) {
481
+ const [x, y ] = [lon, lat];
482
+ const [x1, y1] = A; // A = [lon,lat]
483
+ const [x2, y2] = B; // B = [lon,lat]
484
+ const cross = (x - x1)*(y2 - y1) - (y - y1)*(x2 - x1);
485
+ if (Math.abs(cross) > EPS) {
486
+ return false;
487
+ }
488
+
489
+ const dot = (x - x1)*(x2 - x1) + (y - y1)*(y2 - y1);
490
+ if (dot < -EPS) {
491
+ return false;
492
+ }
493
+
494
+ const len2 = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1);
495
+ return dot - len2 <= EPS;
496
+ }
497
+
498
+ // Ray-casting + bords inclus pour un anneau (tableau de [lon,lat])
499
+ static isPointInRing(lat, lon, ring) {
500
+ const n0 = ring.length;
501
+ if (n0 < 3) {
502
+ return false;
503
+ }
504
+
505
+ // fermer si nécessaire
506
+ const closed = ring[n0-1][0] === ring[0][0] && ring[n0-1][1] === ring[0][1];
507
+ const pts = closed ? ring : [...ring, ring[0]];
508
+ const n = pts.length;
509
+
510
+ // bord inclus
511
+ for (let i = 0; i < n - 1; i++) {
512
+ if (Polygon.isPointOnSegmentDeg(lat, lon, pts[i], pts[i+1])) {
513
+ return true;
514
+ }
515
+ }
516
+
517
+ // ray casting (x=lon, y=lat)
518
+ let inside = false;
519
+ for (let i = 0, j = n - 1; i < n; j = i++) {
520
+ const [xi, yi] = pts[i];
521
+ const [xj, yj] = pts[j];
522
+ const intersect = ((yi > lat) !== (yj > lat)) &&
523
+ (lon < ( (xj - xi) * (lat - yi) / ((yj - yi) || 1e-20) + xi ));
524
+ if (intersect) inside = !inside;
525
+ }
526
+ return inside;
527
+ }
528
+
529
+ // Polygone avec trous: inside = dans outer ET pas dans un trou
530
+ static isPointInPolygon(lat, lon, geoJsonPolygon) {
531
+ const rings = geoJsonPolygon.coordinates;
532
+ if (!Array.isArray(rings) || rings.length === 0) {
533
+ return false;
534
+ }
535
+
536
+ if (!Polygon.isPointInRing(lat, lon, rings[0])) {
537
+ return false; // outer
538
+ }
539
+
540
+ for (let k = 1; k < rings.length; k++) {
541
+ if (Polygon.isPointInRing(lat, lon, rings[k])) {
542
+ return false; // dans un trou
543
+ }
544
+ }
545
+
546
+ return true;
547
+ }
475
548
  }
476
549
 
477
550
  class GeographicCoordinates {
@@ -553,6 +626,32 @@ class GeographicCoordinates {
553
626
  return arr;
554
627
  }
555
628
 
629
+ static isPointCorrespondingToLocationsList(lat, lon, locationsList, tolMeters = 1.0) {
630
+ for (const it of locationsList) {
631
+ if (!it) {
632
+ continue;
633
+ }
634
+
635
+ if (typeof it === 'string') {
636
+ const p = GeographicCoordinates.parse(it);
637
+ if (p && GeographicCoordinates.haversine(lat,lon,p[0],p[1]) <= tolMeters) {
638
+ return true;
639
+ }
640
+ }
641
+ else if (it.type === 'Point') {
642
+ const p = GeographicCoordinates.parse(it.coordinates);
643
+ if (p && GeographicCoordinates.haversine(lat,lon,p[0],p[1]) <= tolMeters) {
644
+ return true;
645
+ }
646
+ }
647
+ else if (it.type === 'Polygon' && Array.isArray(it.coordinates)) {
648
+ if (Polygon.isPointInPolygon(lat, lon, it)) {
649
+ return true;
650
+ }
651
+ }
652
+ }
653
+ return false;
654
+ }
556
655
 
557
656
  static haversine(lat1, long1, lat2, long2) {
558
657
  const R = 6371000;
@@ -125,7 +125,7 @@ class OpenStreetMap {
125
125
  OpenStreetMap.centerMapToLocations(this.map, this.locations, padding);
126
126
  }
127
127
 
128
- static centerMapToLocations(map, locationsList, padding=[20,20]) {
128
+ static centerMapToLocations(map, locationsList, padding=[20,20], maxZoom=18) {
129
129
  if (!map || locationsList.length === 0) {
130
130
  return;
131
131
  }
@@ -134,8 +134,8 @@ class OpenStreetMap {
134
134
 
135
135
  const bounds = L.latLngBounds(locationsList);
136
136
  map.fitBounds(bounds, { padding: padding });
137
- if (map.getZoom() > 18) {
138
- map.setZoom(18);
137
+ if (map.getZoom() > maxZoom) {
138
+ map.setZoom(maxZoom);
139
139
  }
140
140
  }
141
141
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osimatic/helpers-js",
3
- "version": "1.4.7",
3
+ "version": "1.4.8",
4
4
  "main": "main.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"