@osimatic/helpers-js 1.4.15 → 1.4.16
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 +28 -28
- package/package.json +1 -1
package/location.js
CHANGED
|
@@ -441,7 +441,7 @@ class Polygon {
|
|
|
441
441
|
const [firstLon, firstLat] = ring0[0];
|
|
442
442
|
|
|
443
443
|
const maxShow = Math.min(5, ring0.length);
|
|
444
|
-
const concise = ring0.slice(0, maxShow).map(([
|
|
444
|
+
const concise = ring0.slice(0, maxShow).map(([long,lat]) => GeographicCoordinates.format(lat, long)).join(' · ');
|
|
445
445
|
const more = ring0.length > maxShow ? ` … (+${ring0.length - maxShow} sommets)` : '';
|
|
446
446
|
|
|
447
447
|
return {
|
|
@@ -494,7 +494,7 @@ class Polygon {
|
|
|
494
494
|
return false;
|
|
495
495
|
}
|
|
496
496
|
|
|
497
|
-
// polygonCoords: [ [ [
|
|
497
|
+
// polygonCoords: [ [ [long,lat], ... ] , ... ]
|
|
498
498
|
const rings = [];
|
|
499
499
|
for (const ring of polygonCoords) {
|
|
500
500
|
const latlngRing = [];
|
|
@@ -502,8 +502,8 @@ class Polygon {
|
|
|
502
502
|
if (!Array.isArray(coord) || coord.length < 2) {
|
|
503
503
|
continue;
|
|
504
504
|
}
|
|
505
|
-
const [
|
|
506
|
-
latlngRing.push([lat,
|
|
505
|
+
const [long, lat] = coord;
|
|
506
|
+
latlngRing.push([lat, long]);
|
|
507
507
|
}
|
|
508
508
|
if (latlngRing.length > 0) {
|
|
509
509
|
// Fermer l'anneau si nécessaire (Leaflet accepte ouvert/fermé, on nettoie par sécurité)
|
|
@@ -520,10 +520,10 @@ class Polygon {
|
|
|
520
520
|
|
|
521
521
|
|
|
522
522
|
// Test "sur le segment" en degrés (plan local) — suffisant pour le bord du polygone
|
|
523
|
-
static isPointOnSegmentDeg(lat,
|
|
524
|
-
const [x, y ] = [
|
|
525
|
-
const [x1, y1] = A; // A = [
|
|
526
|
-
const [x2, y2] = B; // B = [
|
|
523
|
+
static isPointOnSegmentDeg(lat, long, A, B, EPS = 1e-12) {
|
|
524
|
+
const [x, y ] = [long, lat];
|
|
525
|
+
const [x1, y1] = A; // A = [long,lat]
|
|
526
|
+
const [x2, y2] = B; // B = [long,lat]
|
|
527
527
|
const cross = (x - x1)*(y2 - y1) - (y - y1)*(x2 - x1);
|
|
528
528
|
if (Math.abs(cross) > EPS) {
|
|
529
529
|
return false;
|
|
@@ -538,8 +538,8 @@ class Polygon {
|
|
|
538
538
|
return dot - len2 <= EPS;
|
|
539
539
|
}
|
|
540
540
|
|
|
541
|
-
// Ray-casting + bords inclus pour un anneau (tableau de [
|
|
542
|
-
static isPointInRing(lat,
|
|
541
|
+
// Ray-casting + bords inclus pour un anneau (tableau de [long,lat])
|
|
542
|
+
static isPointInRing(lat, long, ring) {
|
|
543
543
|
const n0 = ring.length;
|
|
544
544
|
if (n0 < 3) {
|
|
545
545
|
return false;
|
|
@@ -552,36 +552,36 @@ class Polygon {
|
|
|
552
552
|
|
|
553
553
|
// bord inclus
|
|
554
554
|
for (let i = 0; i < n - 1; i++) {
|
|
555
|
-
if (Polygon.isPointOnSegmentDeg(lat,
|
|
555
|
+
if (Polygon.isPointOnSegmentDeg(lat, long, pts[i], pts[i+1])) {
|
|
556
556
|
return true;
|
|
557
557
|
}
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
-
// ray casting (x=
|
|
560
|
+
// ray casting (x=long, y=lat)
|
|
561
561
|
let inside = false;
|
|
562
562
|
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
563
563
|
const [xi, yi] = pts[i];
|
|
564
564
|
const [xj, yj] = pts[j];
|
|
565
565
|
const intersect = ((yi > lat) !== (yj > lat)) &&
|
|
566
|
-
(
|
|
566
|
+
(long < ( (xj - xi) * (lat - yi) / ((yj - yi) || 1e-20) + xi ));
|
|
567
567
|
if (intersect) inside = !inside;
|
|
568
568
|
}
|
|
569
569
|
return inside;
|
|
570
570
|
}
|
|
571
571
|
|
|
572
572
|
// Polygone avec trous: inside = dans outer ET pas dans un trou
|
|
573
|
-
static isPointInPolygon(lat,
|
|
573
|
+
static isPointInPolygon(lat, long, geoJsonPolygon) {
|
|
574
574
|
const rings = geoJsonPolygon.coordinates;
|
|
575
575
|
if (!Array.isArray(rings) || rings.length === 0) {
|
|
576
576
|
return false;
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
-
if (!Polygon.isPointInRing(lat,
|
|
579
|
+
if (!Polygon.isPointInRing(lat, long, rings[0])) {
|
|
580
580
|
return false; // outer
|
|
581
581
|
}
|
|
582
582
|
|
|
583
583
|
for (let k = 1; k < rings.length; k++) {
|
|
584
|
-
if (Polygon.isPointInRing(lat,
|
|
584
|
+
if (Polygon.isPointInRing(lat, long, rings[k])) {
|
|
585
585
|
return false; // dans un trou
|
|
586
586
|
}
|
|
587
587
|
}
|
|
@@ -608,12 +608,12 @@ class GeographicCoordinates {
|
|
|
608
608
|
}
|
|
609
609
|
|
|
610
610
|
const lat = parseFloat(parts[0]);
|
|
611
|
-
const
|
|
612
|
-
if (!isFinite(lat) || !isFinite(
|
|
611
|
+
const long = parseFloat(parts[1]);
|
|
612
|
+
if (!isFinite(lat) || !isFinite(long)) {
|
|
613
613
|
return null;
|
|
614
614
|
}
|
|
615
615
|
|
|
616
|
-
return asString ? str.join(',') : [lat,
|
|
616
|
+
return asString ? str.join(',') : [lat, long];
|
|
617
617
|
}
|
|
618
618
|
|
|
619
619
|
static toFixed(latOrLong, fractionDigit=6) {
|
|
@@ -644,7 +644,7 @@ class GeographicCoordinates {
|
|
|
644
644
|
return null;
|
|
645
645
|
}
|
|
646
646
|
|
|
647
|
-
return asString ? str.join(',') : [lat,
|
|
647
|
+
return asString ? str.join(',') : [lat, long];
|
|
648
648
|
}
|
|
649
649
|
|
|
650
650
|
static getAllLatLongsFromGeoJsonList(geoJsonList) {
|
|
@@ -657,15 +657,15 @@ class GeographicCoordinates {
|
|
|
657
657
|
}
|
|
658
658
|
|
|
659
659
|
if (geoJsonItem.type === 'Point') {
|
|
660
|
-
const [
|
|
661
|
-
arr.push([lat,
|
|
660
|
+
const [long, lat] = geoJsonItem.coordinates || [];
|
|
661
|
+
arr.push([lat, long]);
|
|
662
662
|
continue;
|
|
663
663
|
}
|
|
664
664
|
|
|
665
665
|
if (geoJsonItem.type === 'Polygon') {
|
|
666
666
|
for (const ring of geoJsonItem.coordinates || []) {
|
|
667
|
-
for (const [
|
|
668
|
-
arr.push([lat,
|
|
667
|
+
for (const [long,lat] of ring) {
|
|
668
|
+
arr.push([lat, long]);
|
|
669
669
|
}
|
|
670
670
|
}
|
|
671
671
|
continue;
|
|
@@ -675,7 +675,7 @@ class GeographicCoordinates {
|
|
|
675
675
|
return arr;
|
|
676
676
|
}
|
|
677
677
|
|
|
678
|
-
static isPointCorrespondingToLocationsList(lat,
|
|
678
|
+
static isPointCorrespondingToLocationsList(lat, long, locationsList, tolMeters = 1.0) {
|
|
679
679
|
for (const it of locationsList) {
|
|
680
680
|
if (!it) {
|
|
681
681
|
continue;
|
|
@@ -683,18 +683,18 @@ class GeographicCoordinates {
|
|
|
683
683
|
|
|
684
684
|
if (typeof it === 'string') {
|
|
685
685
|
const p = GeographicCoordinates.parse(it);
|
|
686
|
-
if (p && GeographicCoordinates.haversine(lat,
|
|
686
|
+
if (p && GeographicCoordinates.haversine(lat,long,p[0],p[1]) <= tolMeters) {
|
|
687
687
|
return true;
|
|
688
688
|
}
|
|
689
689
|
}
|
|
690
690
|
else if (it.type === 'Point') {
|
|
691
691
|
const p = it.coordinates || [];
|
|
692
|
-
if (p && GeographicCoordinates.haversine(lat,
|
|
692
|
+
if (p && GeographicCoordinates.haversine(lat,long,p[1],p[0]) <= tolMeters) {
|
|
693
693
|
return true;
|
|
694
694
|
}
|
|
695
695
|
}
|
|
696
696
|
else if (it.type === 'Polygon' && Array.isArray(it.coordinates)) {
|
|
697
|
-
if (Polygon.isPointInPolygon(lat,
|
|
697
|
+
if (Polygon.isPointInPolygon(lat, long, it)) {
|
|
698
698
|
return true;
|
|
699
699
|
}
|
|
700
700
|
}
|