@kalisio/common-geospatial 0.5.0 → 0.7.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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +407 -340
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -5
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("@kalisio/common-core"),j=require("@logtape/logtape"),me=require("heap-js"),de=require("@turf/truncate"),pe=require("@turf/boolean-clockwise"),ve=require("@turf/kinks"),f={LATITUDE:"LAT",LONGITUDE:"LON",ALTITUDE:"ALT"};function X(e){return n.assert.that(e,n.is.string,"axis must be a string"),Object.values(f).includes(e)}function I(e){return n.assert.that(e,n.is.string,"axis must be a string"),e===f.LATITUDE}function F(e){return n.assert.that(e,n.is.string,"axis must be a string"),e===f.LONGITUDE}function Ee(e){return n.assert.that(e,n.is.string,"axis must be a string"),e===f.ALTITUDE}const be={NORTH:{label:"Nord",symbol:"N"},SOUTH:{label:"Sud",symbol:"S"},EAST:{label:"Est",symbol:"E"},WEST:{label:"Ouest",symbol:"O"}},ye={DIRECTIONS:be},he={NORTH:{label:"North",symbol:"N"},SOUTH:{label:"South",symbol:"S"},EAST:{label:"East",symbol:"E"},WEST:{label:"West",symbol:"W"}},Oe={DIRECTIONS:he},Te={DIRECTIONS:{NORTH:{label:n.is.string,symbol:n.is.string},SOUTH:{label:n.is.string,symbol:n.is.string},EAST:{label:n.is.string,symbol:n.is.string},WEST:{label:n.is.string,symbol:n.is.string}}},h={en:Oe,fr:ye};let _="en";function Le(){return Object.keys(h)}function Ie(e,t){n.assert.all([{value:e,validator:n.is.string,message:"code must be a string"},{value:e,validator:s=>!n.has.key(h,s),message:"locale already registered"},{value:t,validator:n.is.plainObject,message:"content must be an object"},{value:t,validator:s=>n.conform.schema(s,Te),message:"content does not conform to schema"}]),h[e]=t}function Se(e){n.assert.all([{value:e,validator:n.is.string,message:"code must be a string"},{value:e,validator:t=>n.has.key(h,t),message:"code is unknown"}]),_=e}function q(){return{code:_,content:h[_]}}function E(){return q().content.DIRECTIONS}function D(e,t){const s=E(),r=s[e].label.toUpperCase(),i=s[e].symbol.toUpperCase();return t.toUpperCase()===r||t.toUpperCase()===i}function De(e=null){const t=E();return n.is.defined(e)?(n.assert.that(e,X,"axis must be a valid axis"),I(e)?[t.SOUTH,t.NORTH]:F(e)?[t.EAST,t.WEST]:[]):[t.SOUTH,t.NORTH,t.EAST,t.WEST]}function Re(){return E().NORTH}function Ae(){return E().SOUTH}function Ce(){return E().EAST}function Ne(){return E().WEST}function v(e){return n.assert.that(e,n.is.string,"dir must be a string"),z(e)||U(e)||k(e)||R(e)}function z(e){return n.assert.that(e,n.is.string,"dir must be a string"),D("NORTH",e)}function U(e){return n.assert.that(e,n.is.string,"dir must be a string"),D("SOUTH",e)}function k(e){return n.assert.that(e,n.is.string,"dir must be a string"),D("EAST",e)}function R(e){return n.assert.that(e,n.is.string,"dir must be a string"),D("WEST",e)}function J(e){return n.assert.that(e,v,"dir must be a direction"),R(e)||k(e)?f.LONGITUDE:f.LATITUDE}const we={degrees:n.is.number,direction:n.optional(v)},Me=/^(-?\d{1,3}(?:\.\d+)?)°?$/,_e=/^(\d{1,3}(?:\.\d+)?)°?([NSEW])$/;function L(e){let t=null,s=null;if(n.is.plainObject(e)&&n.conform.schema(e,we))n.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.direction):t=e.degrees;else if(n.is.string(e)){const r=e.replace(/\s+/g,""),i=r.match(Me)??r.match(_e);i&&(t=parseFloat(i[1]),s=i[2]??null)}return{get degrees(){return t},get direction(){return s},get format(){return"DD"},isValid(){return n.is.number(t)},toString(r){if(n.assert.that(r,n.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let i=`${t.toFixed(r)}°`;return s&&(i+=` ${s}`),i},toDecimal(){return this.isValid()?L({degrees:t,direction:s}):null}}}const Ge={degrees:n.is.integer,minutes:e=>n.is.inRangeExclusiveMax(e,0,60),direction:n.optional(v)},xe=/^(-?\d{1,3})°(\d{1,2}(?:\.\d+)?)'?$/,$e=/^(\d{1,3})°(\d{1,2}(?:\.\d+)?)'?([NSEW])$/;function K(e){let t=null,s=null,r=null;if(n.is.plainObject(e)&&n.conform.schema(e,Ge))n.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.minutes,r=e.direction):(t=e.degrees,s=e.minutes);else if(n.is.string(e)){const i=e.replace(/\s+/g,""),o=i.match(xe)??i.match($e);o&&(t=parseFloat(o[1]),s=parseFloat(o[2]),r=o[3]??null)}return{get degrees(){return t},get minutes(){return s},get direction(){return r},get format(){return"DDM"},isValid(){return n.is.integer(t)&&n.is.inRangeExclusiveMax(s,0,60)},toString(i){if(n.assert.that(i,n.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let o=`${t}° ${s.toFixed(i)}'`;return r&&(o+=` ${r}`),o},toDecimal(){return this.isValid()?L({degrees:t+s/60,direction:r}):null}}}const Fe={degrees:n.is.nonNegativeInteger,minutes:e=>n.is.inRangeExclusiveMax(e,0,60),direction:v},Ue=/^(\d{2})(\d{3})([NS])$/,ke=/^(\d{3})(\d{3})([EW])$/;function Q(e){let t=null,s=null,r=null;if(n.is.plainObject(e)&&n.conform.schema(e,Fe))t=e.degrees,s=e.minutes,r=e.direction;else if(n.is.string(e)){const i=e.trim(),o=i.match(Ue)??i.match(ke);o&&(t=parseFloat(o[1]),s=parseFloat(o[2])/10,r=o[3])}return{get degrees(){return t},get minutes(){return s},get direction(){return r},get format(){return"DDM_AERO"},isValid(){return n.is.nonNegativeInteger(t)&&n.is.inRangeExclusiveMax(s,0,60)&&v(r)},toString(){if(!this.isValid())return"";const i=r==="E"||r==="W",o=String(t).padStart(i?3:2,"0"),l=Math.floor(s*10).toString().padStart(3,"0");return`${o}${l}${r}`},toDecimal(){return this.isValid()?L({degrees:t+s/60,direction:r}):null}}}const Pe={degrees:n.is.integer,minutes:e=>n.is.integer(e)&&n.is.inRange(e,0,59),seconds:e=>n.is.inRangeExclusiveMax(e,0,60),direction:n.optional(v)},He=/^(-?\d{1,3})°(\d{1,2})'(\d{1,2}(?:\.\d+)?)"?$/,Ve=/^(\d{1,3})°(\d{1,2})'(\d{1,2}(?:\.\d+)?)"?([NSEW])$/;function Z(e){let t=null,s=null,r=null,i=null;if(n.is.plainObject(e)&&n.conform.schema(e,Pe))n.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.minutes,r=e.seconds,i=e.direction):(t=e.degrees,s=e.minutes,r=e.seconds);else if(n.is.string(e)){const o=e.replace(/\s+/g,""),l=o.match(He)??o.match(Ve);l&&(t=parseFloat(l[1]),s=parseFloat(l[2]),r=parseFloat(l[3]),i=l[4]??null)}return{get degrees(){return t},get minutes(){return s},get seconds(){return r},get direction(){return i},get format(){return"DMS"},isValid(){return n.is.integer(t)&&n.is.integer(s)&&n.is.inRange(s,0,59)&&n.is.inRangeExclusiveMax(r,0,60)},toString(o){if(n.assert.that(o,n.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let l=`${t}° ${s}' ${r.toFixed(o)}"`;return i&&(l+=` ${i}`),l},toDecimal(){return this.isValid()?L({degrees:t+s/60+r/3600,direction:i}):null}}}function Y(e){const t=Math.floor(e.degrees),s=(e.degrees-t)*60;return{degrees:t,minutes:s,direction:e.direction}}function We(e){const t=Math.floor(e.degrees),s=(e.degrees-t)*60,r=Math.floor(s),i=(s-r)*60;return{degrees:t,minutes:r,seconds:i,direction:e.direction}}const B={DD:e=>(n.assert.that(e,t=>t.isValid(),"dd must be a valid coordinate"),e),DDM:e=>{n.assert.that(e,i=>i.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,direction:r}=Y(e);return K(r?{degrees:t,minutes:s,direction:r}:{degrees:t,minutes:s})},DMS:e=>{n.assert.that(e,o=>o.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,seconds:r,direction:i}=We(e);return Z(i?{degrees:t,minutes:s,seconds:r,direction:i}:{degrees:t,minutes:s,seconds:r})},DDM_AERO:e=>{n.assert.that(e,i=>i.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,direction:r}=Y(e);return Q({degrees:t,minutes:s,direction:r})}},S={DD:"DD",DDM:"DDM",DDM_AERO:"DDM_AERO",DMS:"DMS"},ee={DD:L,DDM:K,DDM_AERO:Q,DMS:Z},A=Array.from({length:9},(e,t)=>10**t);function G(e,t){if(n.assert.that(e,n.is.number,"coord must be a number"),n.is.defined(t))return n.assert.that(t,v,"dir must be a direction"),J(t);if(Math.abs(e)>90)return f.LONGITUDE}function x(e){n.assert.that(e,n.is.number,"coord must be a number");const t=e.toExponential(),[s,r]=t.split("e").map(Number),i=(s.toString().split(".")[1]||"").length;return Math.max(0,i-r)}function Ye(e,t=7){n.assert.all([{value:e,validator:n.is.number,message:"coord must be a number"},{value:t,validator:r=>n.is.inRange(r,0,8),message:"precision must be in range [0, 8]"}]);const s=A[t];return Math.round(e*s)/s}function Be(e,t){if(n.assert.all([{value:e,validator:n.is.number,message:"coord must be a number"},{value:t,validator:r=>F(r)||I(r),message:"axis must be either a longitude or latitude"}]),I(t))return Math.max(-90,Math.min(90,e));let s=((e+180)%360+360)%360-180;return s===-180&&(s=180),Object.is(s,-0)&&(s=0),s}function je(e,t){n.assert.all([{value:e,validator:r=>n.is.defined(r)&&r.isValid(),message:"from must be a valid coordinate"},{value:t,validator:r=>n.has.key(B,r),message:`unknown format: ${t}`}]);const s=e.format===S.DD?e:e.toDecimal();return s.isValid()?t===S.DD?s:B[t](s):null}function te(e){n.assert.that(e,n.is.nonEmptyString,"pattern must be a non empty string");for(const t of Object.keys(S)){const s=ee[t](e);if(s.isValid())return s}return null}function Xe(e){n.assert.that(e,a=>n.is.nonEmptyString(a),"pattern must be a non-empty string");const t=e.split(/[,;|]/);if(t.length!==2)return null;const[s,r]=t.map(te);if(!s||!r)return null;const i=s.toDecimal(),o=r.toDecimal(),l=G(i.degrees,i.direction),c=G(o.degrees,o.direction),u=a=>{const{degrees:d,direction:m}=a;return m&&(R(m)||U(m))?-d:d};if(l===f.LONGITUDE&&c===f.LATITUDE)return[u(i),u(o)];if(c===f.LONGITUDE&&l===f.LATITUDE)return[u(o),u(i)];if(l===f.LONGITUDE&&!c)return[u(i),o];if(l===f.LATITUDE&&!c)return[u(o),u(i)];if(c===f.LONGITUDE&&!l)return[u(o),u(i)];if(c===f.LATITUDE&&!l)return[u(i),u(o)];if(!l&&!c)return[[u(i),u(o)],[u(o),u(i)]]}function ne(e){return!n.is.arrayOfLength(e,4)&&!n.is.arrayOfLength(e,6)?!1:e.every(n.is.number)}const O={NAME:"name",LINK:"link"};function qe(e){return n.is.plainObject(e)?e.type===O.NAME?n.is.nonEmptyString(e.properties?.name):e.type===O.LINK?n.is.nonEmptyString(e.properties?.href):!1:!1}const g={POINT:"Point",MULTI_POINT:"MultiPoint",LINESTRING:"LineString",MULTI_LINESTRING:"MultiLineString",POLYGON:"Polygon",MULTI_POLYGON:"MultiPolygon",GEOMETRY_COLLECTION:"GeometryCollection"};function C(e){return!n.is.plainObject(e)||!n.is.oneOf(e.type,Object.values(g))?!1:e.type===g.GEOMETRY_COLLECTION?n.is.array(e.geometries):n.is.array(e.coordinates)}const p={FEATURE:"Feature",FEATURE_COLLECTION:"FeatureCollection"};function re(e){return n.is.plainObject(e)?p.FEATURE===e.type:!1}function se(e){return!n.is.plainObject(e)||e.type!==p.FEATURE_COLLECTION?!1:n.is.array(e.features)}function P(e){return n.is.plainObject(e)?C(e)||re(e)?!0:se(e):!1}function ie(e){return n.is.arrayOfLengthBetween(e,2,3)?e.every(n.is.number):!1}function ze(e,t,s){return Math.abs((e[0]*(t[1]-s[1])+t[0]*(s[1]-e[1])+s[0]*(e[1]-t[1]))/2)}function M(e,{tolerance:t=0,getWeight:s=()=>1}={}){if(e.length<=2)return e;const r=e.map((a,d)=>({coord:a,i:d,area:1/0,removed:!1,prev:null,next:null}));for(let a=0;a<r.length;a++)a>0&&(r[a].prev=r[a-1]),a<r.length-1&&(r[a].next=r[a+1]);const i=a=>!a.prev||!a.next?1/0:ze(a.prev.coord,a.coord,a.next.coord)*s(a.coord,a.i),o=new me.Heap((a,d)=>a.area-d.area);for(let a=1;a<r.length-1;a++)r[a].area=i(r[a]),r[a]._currentArea=r[a].area,o.push(r[a]);let l=0;for(;o.size()>0;){const a=o.pop();if(!a.removed&&a.area===a._currentArea){if(a.area<l?a.area=l:l=a.area,a.area>=t)break;a.removed=!0,a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),a.prev?.prev&&(a.prev.area=i(a.prev),a.prev._currentArea=a.prev.area,o.push(a.prev)),a.next?.next&&(a.next.area=i(a.next),a.next._currentArea=a.next.area,o.push(a.next))}}const c=[];let u=r[0];for(;u;)u.removed||c.push(u.coord),u=u.next;return c}function N(e,t){switch(n.assert.all([{value:e,validator:C,message:"geometry must be a GeoJson geometry"}]),e.type){case g.LINESTRING:e.coordinates=M(e.coordinates,t);break;case g.POLYGON:case g.MULTI_LINESTRING:e.coordinates=e.coordinates.map(s=>M(s,t));break;case g.MULTI_POLYGON:e.coordinates=e.coordinates.map(s=>s.map(r=>M(r,t)));break;case g.GEOMETRY_COLLECTION:e.geometries.forEach(s=>N(s,t));break}return e}const Je=j.getLogger(["common-ekosystem","simplify","geojson"]);function ae(e,t){if(e.type===p.FEATURE)e.geometry&&N(e.geometry,t);else if(e.type===p.FEATURE_COLLECTION)for(const s of e.features)ae(s,t);else Je.warn('Unknown feature type "{type}", skipping.',{type:e.type});return e}function Ke(e,t){return n.assert.all([{value:e,validator:P,message:"geoJson must be a GeoJson object"}]),n.is.oneOf(e.type,Object.values(g))?N(e,t):ae(e,t)}function H(e,t=7){n.assert.all([{value:e,validator:ne,message:"bbox must be bounding box"},{value:t,validator:r=>n.is.inRange(r,0,8),message:"precision must be in range [0, 8]"}]);const s=A[t];for(let r=0;r<e.length;r++)e[r]=Math.round(e[r]*s)/s;return e}function V(e,t=7){n.assert.all([{value:e,validator:C,message:"geometry must be a GeoJson geometry"},{value:t,validator:r=>n.is.inRange(r,0,8),message:"precision must be in range [0, 8]"}]);const s=de(e,{precision:t,mutate:!0});return s.bbox&&H(s.bbox,t),s}const Qe=j.getLogger(["common-ekosystem","truncate","geojson"]);function oe(e,t){if(e.type===p.FEATURE)e.geometry&&V(e.geometry,t);else if(e.type===p.FEATURE_COLLECTION)for(const s of e.features)oe(s,t);else Qe.warn('Unknown feature type "{type}", skipping.',{type:e.type});return e.bbox&&H(e.bbox,t),e}function Ze(e,t=7){return n.assert.all([{value:e,validator:P,message:"geoJson must be a valid GeoJson"},{value:t,validator:s=>n.is.inRange(s,0,8),message:"precision must be in range [0, 8]"}]),n.is.oneOf(e.type,Object.values(g))?V(e,t):oe(e,t)}function et(e,t=7){n.assert.all([{value:e,validator:ie,message:"position must be a position"},{value:t,validator:r=>n.is.inRange(r,0,8),message:"precision must be in range [0, 8]"}]);const s=A[t];for(let r=0;r<e.length;r++)e[r]=Math.round(e[r]*s)/s;return e}function T(e){if(!n.is.arrayOfLengthBetween(e,2,3))return{valid:!1,errors:[{message:"Invalid coordinates: must be an array of 2 or 3 coordinates"}],warnings:[]};if(!n.is.inRange(e[0],-180,180))return{valid:!1,errors:[{message:"Invalid coordinates: longitude must be in the range -180 to 180"}],warnings:[]};if(!n.is.inRange(e[1],-90,90))return{valid:!1,errors:[{message:"Invalid coordinates: latitude must be in the range -90 to 90"}],warnings:[]};if(e.length===3&&!n.is.number(e[2]))return{valid:!1,errors:[{message:"Invalid coordinates: altitude must be a number"}],warnings:[]};const t={valid:!0,errors:[],warnings:[]},s=x(e[0]);s>6&&t.warnings.push({message:`longitude precision is high (${s} decimals, max recommended: 6)`});const r=x(e[1]);return r>6&&t.warnings.push({message:`latitude precision is high (${r} decimals, max recommended: 6)`}),t}function le(e){if(!n.is.arrayOfLength(e,4)&&!n.is.arrayOfLength(e,6))return{valid:!1,errors:[{message:"Invalid bbox: must be an array of 4 (2D) or 6 (3D) numbers"}],warnings:[]};const t=e.length===4,s=t?[e[0],e[1]]:[e[0],e[1],e[2]],r=t?[e[2],e[3]]:[e[3],e[4],e[5]],i=T(s);if(!i.valid)return{valid:!1,errors:i.errors.map(m=>({...m,message:`Invalid bbox south-west: ${m.message}`})),warnings:[]};const o=T(r);if(!o.valid)return{valid:!1,errors:o.errors.map(m=>({...m,message:`Invalid bbox north-east: ${m.message}`})),warnings:[]};const[l,c]=s,[u,a]=r;if(c>a)return{valid:!1,errors:[{message:`Invalid bbox: south (${c}) must be <= north (${a})`}],warnings:[]};const d={valid:!0,errors:[],warnings:[]};return l>u&&d.warnings.push({message:`bbox crosses the antimeridian (west: ${l} > east: ${u})`}),d.warnings.push(...i.warnings.map(m=>({...m,message:`south-west: ${m.message}`}))),d.warnings.push(...o.warnings.map(m=>({...m,message:`north-east: ${m.message}`}))),d}function ue(e){if(!n.is.plainObject(e))return{valid:!1,errors:[{message:"Invalid crs: must be an object"}],warnings:[]};switch(e.type){case O.NAME:return n.is.nonEmptyString(e.properties?.name)?{valid:!0,errors:[],warnings:[]}:{valid:!1,errors:[{message:"Invalid crs: linked crs must have a non-empty properties.name string"}],warnings:[]};case O.LINK:return n.is.nonEmptyString(e.properties?.href)?{valid:!0,errors:[],warnings:[]}:{valid:!1,errors:[{message:"Invalid crs: linked crs must have a non-empty properties.href string"}],warnings:[]};default:return{valid:!1,errors:[{message:`Invalid crs: unknown type: ${e.type}`}],warnings:[]}}}function y(){return{Feature:0,FeatureCollection:0,geometries:{}}}function tt(...e){const t=y();for(const s of e){const r=s.statistics;if(r){t.Feature+=r.Feature??0,t.FeatureCollection+=r.FeatureCollection??0;for(const[i,o]of Object.entries(r.geometries??{}))t.geometries[i]=(t.geometries[i]??0)+o}}return t}function b(e,t,s=""){const r={valid:!0,errors:[],warnings:[]};for(let i=0;i<e.length;i++){const o=`${s}/${i}`,l=t(e[i],o,i);if(!l.valid){r.valid=!1,r.errors=r.errors.concat(l.errors.map(c=>({...c,path:c.path||o,index:i})));continue}n.is.empty(l.warnings)||(r.warnings=r.warnings.concat(l.warnings.map(c=>({...c,path:c.path||o,index:i})))),l.statistics&&(r.statistics=tt(r,l))}return r}function nt(e,t){if(!n.is.defined(e.crs))return t;const s=ue(e.crs);return s.valid||(t.valid=!1,t.errors.push(...s.errors.map(r=>({...r,path:"/crs"})))),t.warnings.push(...s.warnings.map(r=>({...r,path:"/crs"}))),t}function $(e,t,s=""){if(!n.is.defined(e.bbox))return t;const r=le(e.bbox);return r.valid||(t.valid=!1,t.errors.push(...r.errors.map(i=>({...i,path:`${s}/bbox`})))),t.warnings.push(...r.warnings.map(i=>({...i,path:`${s}/bbox`}))),t}function W(e,t=0,s=""){return n.is.arrayOfLengthAtLeast(e,t)?b(e,T,s):{valid:!1,errors:[{message:`Invalid coordinates: must have at least ${t} positions`,path:s}],warnings:[]}}function ce(e,t=""){const s=W(e,2,t);if(!s.valid)return s;for(let r=0;r<e.length-1;r++){const i=e[r][0],o=e[r+1][0];Math.abs(o-i)>180&&s.warnings.push({message:`LineString crosses the antimeridian between positions ${r} and ${r+1}, consider using MultiLineString`,path:`${t}/${r}`})}return s}function rt(e,t=""){return n.is.nonEmptyArray(e)?b(e,ce,t):{valid:!1,errors:[{message:"Invalid MultiLineString: coordinates must be a non empty array",path:t}],warnings:[]}}function st(e,t,s=""){const r=W(e,4,s);if(!r.valid)return r;const i=e[0],o=e[e.length-1];if(i[0]!==o[0]||i[1]!==o[1])return r.valid=!1,r.errors.push({message:"Invalid LinearRing: first and last position must be identical",path:s}),r;const c=pe(e)?"clockwise":"counter-clockwise";c!==t&&r.warnings.push({message:`Ring must be ${t} but is ${c}`,path:s});const u=ve({type:"Polygon",coordinates:[e]});return u.features.length>0&&(r.valid=!1,r.errors.push({message:`Invalid LinearRing: ${u.features.length} self-intersection(s) detected`,path:s})),r}function ge(e,t=""){return n.is.nonEmptyArray(e)?b(e,(s,r,i)=>st(s,i===0?"counter-clockwise":"clockwise",r),t):{valid:!1,errors:[{message:"Invalid Polygon: coordinates must be a non empty array",path:t}],warnings:[]}}function it(e,t=""){return n.is.nonEmptyArray(e)?b(e,(s,r)=>ge(s,r),t):{valid:!1,errors:[{message:"Invalid MultiPolygon: coordinates must be a non empty array",path:t}],warnings:[]}}function at(e,t=""){return n.is.nonEmptyArray(e)?b(e,(s,r)=>w(s,r),t):{valid:!1,errors:[{message:"Invalid geometries: geometries must be a non empty array",path:t}],warnings:[]}}function w(e,t=""){if(!n.is.nonEmptyObject(e))return{valid:!1,errors:[{message:"Invalid geometry: geometry must be a non empty object",path:t}],warnings:[]};const s=`${t}/coordinates`;let r;switch(e.type){case g.POINT:{const i=T(e.coordinates);r={valid:i.valid,errors:i.errors.map(o=>({...o,path:s})),warnings:i.warnings.map(o=>({...o,path:s}))};break}case g.MULTI_POINT:{r=W(e.coordinates,0,s);break}case g.LINESTRING:{r=ce(e.coordinates,s);break}case g.MULTI_LINESTRING:{r=rt(e.coordinates,s);break}case g.POLYGON:{r=ge(e.coordinates,s);break}case g.MULTI_POLYGON:{r=it(e.coordinates,s);break}case g.GEOMETRY_COLLECTION:{r=at(e.geometries,`${t}/geometries`);break}default:return{valid:!1,errors:[{message:`Invalid geometry type: ${e.type}`,path:t}],warnings:[]}}return $(e,r,t)}function fe(e,t=""){if(!n.is.nonEmptyObject(e))return{valid:!1,errors:[{message:"Invalid feature: must be a non empty object",path:t}],warnings:[],statistics:y()};if(e.type===p.FEATURE){if(n.is.nonEmptyObject(e.geometry)){const s=w(e.geometry,`${t}/geometry`);return{...$(e,s,t),statistics:{Feature:1,FeatureCollection:0,geometries:{[e.geometry.type]:1}}}}return{valid:!0,errors:[],warnings:[{message:"Feature has no geometry",path:t}],statistics:{Feature:1,FeatureCollection:0,geometries:{}}}}if(e.type===p.FEATURE_COLLECTION){if(n.is.nonEmptyArray(e.features)){const s=b(e.features,fe,`${t}/features`);return{...$(e,s,t),statistics:{...s.statistics,FeatureCollection:s.statistics.FeatureCollection+1}}}return{valid:!1,errors:[{message:"Invalid FeatureCollection: features must be a non empty array",path:t}],warnings:[],statistics:y()}}return{valid:!1,errors:[{message:`Invalid feature: unknown type: ${e.type}`,path:t}],warnings:[],statistics:y()}}function ot(e){if(n.assert.that(e,n.is.nonEmptyObject,"geojson must be a non empty object"),n.is.oneOf(e.type,Object.values(g)))return{...w(e,""),statistics:{Feature:0,FeatureCollection:0,geometries:{[e.type]:1}}};if(e.type===p.FEATURE||e.type===p.FEATURE_COLLECTION){const t=fe(e,"");return nt(e,t)}return{valid:!1,errors:[{message:"Invalid GeoJson: type must be either a Geometry, a Feature or a FeatureCollection"}],warnings:[],statistics:y()}}exports.AXES=f;exports.COORDINATE_FORMATS=S;exports.COORDINATE_MODELS=ee;exports.COORDINATE_TRUNCATION_FACTORS=A;exports.CRS_TYPES=O;exports.FEATURE_TYPES=p;exports.GEOMETRY_TYPES=g;exports.convertCoordinate=je;exports.getCoordinatePrecision=x;exports.getDirectionAxis=J;exports.getDirections=De;exports.getEast=Ce;exports.getLocale=q;exports.getNorth=Re;exports.getSouth=Ae;exports.getWest=Ne;exports.guessCoordinateAxis=G;exports.isAltitude=Ee;exports.isAxis=X;exports.isDirection=v;exports.isEast=k;exports.isLatitude=I;exports.isLikeBBox=ne;exports.isLikeCRS=qe;exports.isLikeFeature=re;exports.isLikeFeatureCollection=se;exports.isLikeGeoJson=P;exports.isLikeGeometry=C;exports.isLikePosition=ie;exports.isLongitude=F;exports.isNorth=z;exports.isSouth=U;exports.isWest=R;exports.listLocales=Le;exports.normalizeCoordinate=Be;exports.parseCoordinate=te;exports.parsePosition=Xe;exports.registerLocale=Ie;exports.setLocale=Se;exports.simplifyGeoJson=Ke;exports.simplifyGeometry=N;exports.truncateBBox=H;exports.truncateCoordinate=Ye;exports.truncateGeoJson=Ze;exports.truncateGeometry=V;exports.truncatePosition=et;exports.validateBBox=le;exports.validateCRS=ue;exports.validateGeoJson=ot;exports.validateGeometry=w;exports.validatePosition=T;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@kalisio/common-core"),Z=require("@logtape/logtape"),Te=require("heap-js"),Le=require("@turf/truncate"),Se=require("@turf/boolean-clockwise"),Ie=require("@turf/kinks"),m={LATITUDE:"LAT",LONGITUDE:"LON",ALTITUDE:"ALT"};function ee(e){return r.assert.that(e,r.is.string,"axis must be a string"),Object.values(m).includes(e)}function R(e){return r.assert.that(e,r.is.string,"axis must be a string"),e===m.LATITUDE}function P(e){return r.assert.that(e,r.is.string,"axis must be a string"),e===m.LONGITUDE}function Re(e){return r.assert.that(e,r.is.string,"axis must be a string"),e===m.ALTITUDE}const De={NORTH:{label:"Nord",symbol:"N"},SOUTH:{label:"Sud",symbol:"S"},EAST:{label:"Est",symbol:"E"},WEST:{label:"Ouest",symbol:"O"}},Ae={DIRECTIONS:De},Ce={NORTH:{label:"North",symbol:"N"},SOUTH:{label:"South",symbol:"S"},EAST:{label:"East",symbol:"E"},WEST:{label:"West",symbol:"W"}},Ne={DIRECTIONS:Ce},we={DIRECTIONS:{NORTH:{label:r.is.string,symbol:r.is.char},SOUTH:{label:r.is.string,symbol:r.is.char},EAST:{label:r.is.string,symbol:r.is.char},WEST:{label:r.is.string,symbol:r.is.char}}},b={en:Ne,fr:Ae};let h="en";const K="en";function Me(){return Object.keys(b)}function xe(e,t){r.assert.all([{value:e,validator:r.is.string,message:"code must be a string"},{value:e,validator:s=>!r.has.key(b,s),message:"locale already registered"},{value:t,validator:r.is.plainObject,message:"content must be an object"},{value:t,validator:s=>r.conform.schema(s,we),message:"content does not conform to schema"}]),b[e]=t}function $e(e){r.assert.all([{value:e,validator:r.is.string,message:"code must be a string"},{value:e,validator:t=>r.has.key(b,t),message:"code is unknown"}]),h=e}function te(){return h}function C(e){return r.assert.all([{value:e,validator:r.is.string,message:"code must be a string"},{value:e,validator:t=>r.has.key(b,t),message:"code is unknown"}]),b[e]}function H(){return h===K?[h]:[h,K]}function B(e){const t=new Set;for(const s of H()){const{DIRECTIONS:n}=C(s);for(const i of e)t.add(n[i].symbol)}return[...t]}function ne(){return B(["NORTH","SOUTH"])}function re(){return B(["EAST","WEST"])}function N(){return B(["NORTH","SOUTH","EAST","WEST"])}function L(){return C(te()).DIRECTIONS}function w(e,t){const s=t.toUpperCase();return H().some(n=>{const{label:i,symbol:o}=C(n).DIRECTIONS[e];return s===i.toUpperCase()||s===o.toUpperCase()})}function _e(e=null){const t=L();return r.is.defined(e)?(r.assert.that(e,ee,"axis must be a valid axis"),R(e)?[t.SOUTH,t.NORTH]:P(e)?[t.EAST,t.WEST]:[]):[t.SOUTH,t.NORTH,t.EAST,t.WEST]}function Fe(){return L().NORTH}function Ge(){return L().SOUTH}function ke(){return L().EAST}function Ue(){return L().WEST}function v(e){return r.assert.that(e,r.is.string,"dir must be a string"),se(e)||j(e)||M(e)||S(e)}function se(e){return r.assert.that(e,r.is.string,"dir must be a string"),w("NORTH",e)}function j(e){return r.assert.that(e,r.is.string,"dir must be a string"),w("SOUTH",e)}function M(e){return r.assert.that(e,r.is.string,"dir must be a string"),w("EAST",e)}function S(e){return r.assert.that(e,r.is.string,"dir must be a string"),w("WEST",e)}function ie(e){return r.assert.that(e,v,"dir must be a direction"),S(e)||M(e)?m.LONGITUDE:m.LATITUDE}const Pe={degrees:r.is.number,direction:r.optional(v)},He=/^(-?\d{1,3}(?:\.\d+)?)°?$/;function Be(){return new RegExp(`^(\\d{1,3}(?:\\.\\d+)?)°?([${N()}])$`,"i")}function I(e){let t=null,s=null;if(r.is.plainObject(e)&&r.conform.schema(e,Pe))r.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.direction):t=e.degrees;else if(r.is.string(e)){const n=e.replace(/\s+/g,""),i=n.match(He)??n.match(Be());i&&(t=parseFloat(i[1]),s=i[2]??null)}return{get degrees(){return t},get direction(){return s},get format(){return"DD"},isValid(){return r.is.number(t)},toString(n){if(r.assert.that(n,r.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let i=`${t.toFixed(n)}°`;return s&&(i+=` ${s}`),i},toDecimal(){return this.isValid()?I({degrees:t,direction:s}):null}}}const je={degrees:r.is.integer,minutes:e=>r.is.inRangeExclusiveMax(e,0,60),direction:r.optional(v)},Ve=/^(-?\d{1,3})°(\d{1,2}(?:\.\d+)?)'?$/;function Ye(){return new RegExp(`^(\\d{1,3})°(\\d{1,2}(?:\\.\\d+)?)'?([${N().join("")}])$`,"i")}function ae(e){let t=null,s=null,n=null;if(r.is.plainObject(e)&&r.conform.schema(e,je))r.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.minutes,n=e.direction):(t=e.degrees,s=e.minutes);else if(r.is.string(e)){const i=e.replace(/\s+/g,""),o=i.match(Ve)??i.match(Ye());o&&(t=parseFloat(o[1]),s=parseFloat(o[2]),n=o[3]??null)}return{get degrees(){return t},get minutes(){return s},get direction(){return n},get format(){return"DDM"},isValid(){return r.is.integer(t)&&r.is.inRangeExclusiveMax(s,0,60)},toString(i){if(r.assert.that(i,r.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let o=`${t}° ${s.toFixed(i)}'`;return n&&(o+=` ${n}`),o},toDecimal(){return this.isValid()?I({degrees:t+s/60,direction:n}):null}}}const We={degrees:r.is.nonNegativeInteger,minutes:e=>r.is.inRangeExclusiveMax(e,0,60),direction:v};function qe(){return new RegExp(`^(\\d{2})(\\d{3})([${ne().join("")}])$`,"i")}function Xe(){return new RegExp(`^(\\d{3})(\\d{3})([${re().join("")}])$`,"i")}function oe(e){let t=null,s=null,n=null;if(r.is.plainObject(e)&&r.conform.schema(e,We))t=e.degrees,s=e.minutes,n=e.direction;else if(r.is.string(e)){const i=e.trim(),o=i.match(qe())??i.match(Xe());o&&(t=parseFloat(o[1]),s=parseFloat(o[2])/10,n=o[3])}return{get degrees(){return t},get minutes(){return s},get direction(){return n},get format(){return"DDM_AERO"},isValid(){return r.is.nonNegativeInteger(t)&&r.is.inRangeExclusiveMax(s,0,60)&&v(n)},toString(){if(!this.isValid())return"";const i=M(n)||S(n),o=String(t).padStart(i?3:2,"0"),l=Math.floor(s*10).toString().padStart(3,"0");return`${o}${l}${n}`},toDecimal(){return this.isValid()?I({degrees:t+s/60,direction:n}):null}}}const Ke={degrees:r.is.integer,minutes:e=>r.is.integer(e)&&r.is.inRange(e,0,59),seconds:e=>r.is.inRangeExclusiveMax(e,0,60),direction:r.optional(v)},ze=/^(-?\d{1,3})°(\d{1,2})'(\d{1,2}(?:\.\d+)?)"?$/;function Je(){return new RegExp(`^(\\d{1,3})°(\\d{1,2})'(\\d{1,2}(?:\\.\\d+)?)"?([${N().join("")}])$`,"i")}function le(e){let t=null,s=null,n=null,i=null;if(r.is.plainObject(e)&&r.conform.schema(e,Ke))r.is.defined(e.direction)?e.degrees>=0&&(t=e.degrees,s=e.minutes,n=e.seconds,i=e.direction):(t=e.degrees,s=e.minutes,n=e.seconds);else if(r.is.string(e)){const o=e.replace(/\s+/g,""),l=o.match(ze)??o.match(Je());l&&(t=parseFloat(l[1]),s=parseFloat(l[2]),n=parseFloat(l[3]),i=l[4]??null)}return{get degrees(){return t},get minutes(){return s},get seconds(){return n},get direction(){return i},get format(){return"DMS"},isValid(){return r.is.integer(t)&&r.is.integer(s)&&r.is.inRange(s,0,59)&&r.is.inRangeExclusiveMax(n,0,60)},toString(o){if(r.assert.that(o,r.is.positiveInteger,"decimalPlaces must be a positive integer"),!this.isValid())return"";let l=`${t}° ${s}' ${n.toFixed(o)}"`;return i&&(l+=` ${i}`),l},toDecimal(){return this.isValid()?I({degrees:t+s/60+n/3600,direction:i}):null}}}function z(e){const t=Math.floor(e.degrees),s=(e.degrees-t)*60;return{degrees:t,minutes:s,direction:e.direction}}function Qe(e){const t=Math.floor(e.degrees),s=(e.degrees-t)*60,n=Math.floor(s),i=(s-n)*60;return{degrees:t,minutes:n,seconds:i,direction:e.direction}}const J={DD:e=>(r.assert.that(e,t=>t.isValid(),"dd must be a valid coordinate"),e),DDM:e=>{r.assert.that(e,i=>i.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,direction:n}=z(e);return ae(n?{degrees:t,minutes:s,direction:n}:{degrees:t,minutes:s})},DMS:e=>{r.assert.that(e,o=>o.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,seconds:n,direction:i}=Qe(e);return le(i?{degrees:t,minutes:s,seconds:n,direction:i}:{degrees:t,minutes:s,seconds:n})},DDM_AERO:e=>{r.assert.that(e,i=>i.isValid(),"dd must be a valid coordinate");const{degrees:t,minutes:s,direction:n}=z(e);return oe({degrees:t,minutes:s,direction:n})}},D={DD:"DD",DDM:"DDM",DDM_AERO:"DDM_AERO",DMS:"DMS"},ue={DD:I,DDM:ae,DDM_AERO:oe,DMS:le},x=Array.from({length:9},(e,t)=>10**t);function k(e,t){if(r.assert.that(e,r.is.number,"coord must be a number"),r.is.defined(t))return r.assert.that(t,v,"dir must be a direction"),ie(t);if(Math.abs(e)>90)return m.LONGITUDE}function U(e){r.assert.that(e,r.is.number,"coord must be a number");const t=e.toExponential(),[s,n]=t.split("e").map(Number),i=(s.toString().split(".")[1]||"").length;return Math.max(0,i-n)}function Ze(e,t=7){r.assert.all([{value:e,validator:r.is.number,message:"coord must be a number"},{value:t,validator:n=>r.is.inRange(n,0,8),message:"precision must be in range [0, 8]"}]);const s=x[t];return Math.round(e*s)/s}function et(e,t){if(r.assert.all([{value:e,validator:r.is.number,message:"coord must be a number"},{value:t,validator:n=>P(n)||R(n),message:"axis must be either a longitude or latitude"}]),R(t))return Math.max(-90,Math.min(90,e));let s=((e+180)%360+360)%360-180;return s===-180&&(s=180),Object.is(s,-0)&&(s=0),s}function tt(e,t){r.assert.all([{value:e,validator:n=>r.is.defined(n)&&n.isValid(),message:"from must be a valid coordinate"},{value:t,validator:n=>r.has.key(J,n),message:`unknown format: ${t}`}]);const s=e.format===D.DD?e:e.toDecimal();return s.isValid()?t===D.DD?s:J[t](s):null}function ce(e){r.assert.that(e,r.is.nonEmptyString,"pattern must be a non empty string");for(const t of Object.keys(D)){const s=ue[t](e);if(s.isValid())return s}return null}function nt(e){r.assert.that(e,a=>r.is.nonEmptyString(a),"pattern must be a non-empty string");const t=e.split(/[,;|]/);if(t.length!==2)return null;const[s,n]=t.map(ce);if(!s||!n)return null;const i=s.toDecimal(),o=n.toDecimal(),l=k(i.degrees,i.direction),c=k(o.degrees,o.direction),u=a=>{const{degrees:d,direction:g}=a;return g&&(S(g)||j(g))?-d:d};if(l===m.LONGITUDE&&c===m.LATITUDE)return[u(i),u(o)];if(c===m.LONGITUDE&&l===m.LATITUDE)return[u(o),u(i)];if(l===m.LONGITUDE&&!c)return[u(i),o];if(l===m.LATITUDE&&!c)return[u(o),u(i)];if(c===m.LONGITUDE&&!l)return[u(o),u(i)];if(c===m.LATITUDE&&!l)return[u(i),u(o)];if(!l&&!c)return[[u(i),u(o)],[u(o),u(i)]]}function ge(e){return!r.is.arrayOfLength(e,4)&&!r.is.arrayOfLength(e,6)?!1:e.every(r.is.number)}const O={NAME:"name",LINK:"link"};function rt(e){return r.is.plainObject(e)?e.type===O.NAME?r.is.nonEmptyString(e.properties?.name):e.type===O.LINK?r.is.nonEmptyString(e.properties?.href):!1:!1}const f={POINT:"Point",MULTI_POINT:"MultiPoint",LINESTRING:"LineString",MULTI_LINESTRING:"MultiLineString",POLYGON:"Polygon",MULTI_POLYGON:"MultiPolygon",GEOMETRY_COLLECTION:"GeometryCollection"};function $(e){return!r.is.plainObject(e)||!r.is.oneOf(e.type,Object.values(f))?!1:e.type===f.GEOMETRY_COLLECTION?r.is.array(e.geometries):r.is.array(e.coordinates)}const p={FEATURE:"Feature",FEATURE_COLLECTION:"FeatureCollection"};function fe(e){return r.is.plainObject(e)?p.FEATURE===e.type:!1}function me(e){return!r.is.plainObject(e)||e.type!==p.FEATURE_COLLECTION?!1:r.is.array(e.features)}function V(e){return r.is.plainObject(e)?$(e)||fe(e)?!0:me(e):!1}function de(e){return r.is.arrayOfLengthBetween(e,2,3)?e.every(r.is.number):!1}function st(e,t,s){return Math.abs((e[0]*(t[1]-s[1])+t[0]*(s[1]-e[1])+s[0]*(e[1]-t[1]))/2)}function G(e,{tolerance:t=0,getWeight:s=()=>1}={}){if(e.length<=2)return e;const n=e.map((a,d)=>({coord:a,i:d,area:1/0,removed:!1,prev:null,next:null}));for(let a=0;a<n.length;a++)a>0&&(n[a].prev=n[a-1]),a<n.length-1&&(n[a].next=n[a+1]);const i=a=>!a.prev||!a.next?1/0:st(a.prev.coord,a.coord,a.next.coord)*s(a.coord,a.i),o=new Te.Heap((a,d)=>a.area-d.area);for(let a=1;a<n.length-1;a++)n[a].area=i(n[a]),n[a]._currentArea=n[a].area,o.push(n[a]);let l=0;for(;o.size()>0;){const a=o.pop();if(!a.removed&&a.area===a._currentArea){if(a.area<l?a.area=l:l=a.area,a.area>=t)break;a.removed=!0,a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),a.prev?.prev&&(a.prev.area=i(a.prev),a.prev._currentArea=a.prev.area,o.push(a.prev)),a.next?.next&&(a.next.area=i(a.next),a.next._currentArea=a.next.area,o.push(a.next))}}const c=[];let u=n[0];for(;u;)u.removed||c.push(u.coord),u=u.next;return c}function _(e,t){switch(r.assert.all([{value:e,validator:$,message:"geometry must be a GeoJson geometry"}]),e.type){case f.LINESTRING:e.coordinates=G(e.coordinates,t);break;case f.POLYGON:case f.MULTI_LINESTRING:e.coordinates=e.coordinates.map(s=>G(s,t));break;case f.MULTI_POLYGON:e.coordinates=e.coordinates.map(s=>s.map(n=>G(n,t)));break;case f.GEOMETRY_COLLECTION:e.geometries.forEach(s=>_(s,t));break}return e}const it=Z.getLogger(["common-ekosystem","simplify","geojson"]);function pe(e,t){if(e.type===p.FEATURE)e.geometry&&_(e.geometry,t);else if(e.type===p.FEATURE_COLLECTION)for(const s of e.features)pe(s,t);else it.warn('Unknown feature type "{type}", skipping.',{type:e.type});return e}function at(e,t){return r.assert.all([{value:e,validator:V,message:"geoJson must be a GeoJson object"}]),r.is.oneOf(e.type,Object.values(f))?_(e,t):pe(e,t)}function Y(e,t=7){r.assert.all([{value:e,validator:ge,message:"bbox must be bounding box"},{value:t,validator:n=>r.is.inRange(n,0,8),message:"precision must be in range [0, 8]"}]);const s=x[t];for(let n=0;n<e.length;n++)e[n]=Math.round(e[n]*s)/s;return e}function W(e,t=7){r.assert.all([{value:e,validator:$,message:"geometry must be a GeoJson geometry"},{value:t,validator:n=>r.is.inRange(n,0,8),message:"precision must be in range [0, 8]"}]);const s=Le(e,{precision:t,mutate:!0});return s.bbox&&Y(s.bbox,t),s}const ot=Z.getLogger(["common-ekosystem","truncate","geojson"]);function ve(e,t){if(e.type===p.FEATURE)e.geometry&&W(e.geometry,t);else if(e.type===p.FEATURE_COLLECTION)for(const s of e.features)ve(s,t);else ot.warn('Unknown feature type "{type}", skipping.',{type:e.type});return e.bbox&&Y(e.bbox,t),e}function lt(e,t=7){return r.assert.all([{value:e,validator:V,message:"geoJson must be a valid GeoJson"},{value:t,validator:s=>r.is.inRange(s,0,8),message:"precision must be in range [0, 8]"}]),r.is.oneOf(e.type,Object.values(f))?W(e,t):ve(e,t)}function ut(e,t=7){r.assert.all([{value:e,validator:de,message:"position must be a position"},{value:t,validator:n=>r.is.inRange(n,0,8),message:"precision must be in range [0, 8]"}]);const s=x[t];for(let n=0;n<e.length;n++)e[n]=Math.round(e[n]*s)/s;return e}function T(e){if(!r.is.arrayOfLengthBetween(e,2,3))return{valid:!1,errors:[{message:"Invalid coordinates: must be an array of 2 or 3 coordinates"}],warnings:[]};if(!r.is.number(e[0])||!r.is.number(e[1]))return{valid:!1,errors:[{message:"Invalid coordinates: longitude and latitude must be numbers"}],warnings:[]};if(!r.is.inRange(e[0],-180,180))return{valid:!1,errors:[{message:"Invalid coordinates: longitude must be in the range -180 to 180"}],warnings:[]};if(!r.is.inRange(e[1],-90,90))return{valid:!1,errors:[{message:"Invalid coordinates: latitude must be in the range -90 to 90"}],warnings:[]};if(e.length===3&&!r.is.number(e[2]))return{valid:!1,errors:[{message:"Invalid coordinates: altitude must be a number"}],warnings:[]};const t={valid:!0,errors:[],warnings:[]},s=U(e[0]);s>6&&t.warnings.push({message:`longitude precision is high (${s} decimals, max recommended: 6)`});const n=U(e[1]);return n>6&&t.warnings.push({message:`latitude precision is high (${n} decimals, max recommended: 6)`}),t}function Ee(e){if(!r.is.arrayOfLength(e,4)&&!r.is.arrayOfLength(e,6))return{valid:!1,errors:[{message:"Invalid bbox: must be an array of 4 (2D) or 6 (3D) numbers"}],warnings:[]};const t=e.length===4,s=t?[e[0],e[1]]:[e[0],e[1],e[2]],n=t?[e[2],e[3]]:[e[3],e[4],e[5]],i=T(s);if(!i.valid)return{valid:!1,errors:i.errors.map(g=>({...g,message:`Invalid bbox south-west: ${g.message}`})),warnings:[]};const o=T(n);if(!o.valid)return{valid:!1,errors:o.errors.map(g=>({...g,message:`Invalid bbox north-east: ${g.message}`})),warnings:[]};const[l,c]=s,[u,a]=n;if(c>a)return{valid:!1,errors:[{message:`Invalid bbox: south (${c}) must be <= north (${a})`}],warnings:[]};if(!t){const g=e[2],X=e[5];if(g>X)return{valid:!1,errors:[{message:`Invalid bbox: min altitude (${g}) must be <= max altitude (${X})`}],warnings:[]}}const d={valid:!0,errors:[],warnings:[]};return l>u&&d.warnings.push({message:`bbox crosses the antimeridian (west: ${l} > east: ${u})`}),d.warnings.push(...i.warnings.map(g=>({...g,message:`south-west: ${g.message}`}))),d.warnings.push(...o.warnings.map(g=>({...g,message:`north-east: ${g.message}`}))),d}function be(e){if(!r.is.plainObject(e))return{valid:!1,errors:[{message:"Invalid crs: must be an object"}],warnings:[]};switch(e.type){case O.NAME:return r.is.nonEmptyString(e.properties?.name)?{valid:!0,errors:[],warnings:[]}:{valid:!1,errors:[{message:"Invalid crs: linked crs must have a non-empty properties.name string"}],warnings:[]};case O.LINK:return r.is.nonEmptyString(e.properties?.href)?{valid:!0,errors:[],warnings:[]}:{valid:!1,errors:[{message:"Invalid crs: linked crs must have a non-empty properties.href string"}],warnings:[]};default:return{valid:!1,errors:[{message:`Invalid crs: unknown type: ${e.type}`}],warnings:[]}}}function E(){return{Feature:0,FeatureCollection:0,geometries:{}}}function ct(...e){const t=E();for(const s of e){const n=s.statistics;if(n){t.Feature+=n.Feature??0,t.FeatureCollection+=n.FeatureCollection??0;for(const[i,o]of Object.entries(n.geometries??{}))t.geometries[i]=(t.geometries[i]??0)+o}}return t}function y(e,t,s=""){const n={valid:!0,errors:[],warnings:[],statistics:E()};for(let i=0;i<e.length;i++){const o=`${s}/${i}`,l=t(e[i],o,i);if(l.statistics&&(n.statistics=ct(n,l)),!l.valid){n.valid=!1,n.errors=n.errors.concat(l.errors.map(c=>({...c,path:c.path||o,index:i})));continue}r.is.empty(l.warnings)||(n.warnings=n.warnings.concat(l.warnings.map(c=>({...c,path:c.path||o,index:i}))))}return n}function Q(e,t){if(!r.is.defined(e.crs))return t;const s=be(e.crs);return s.valid||(t.valid=!1,t.errors.push(...s.errors.map(n=>({...n,path:"/crs"})))),t.warnings.push(...s.warnings.map(n=>({...n,path:"/crs"}))),t}function A(e,t,s=""){if(!r.is.defined(e.bbox))return t;const n=Ee(e.bbox);return n.valid||(t.valid=!1,t.errors.push(...n.errors.map(i=>({...i,path:`${s}/bbox`})))),t.warnings.push(...n.warnings.map(i=>({...i,path:`${s}/bbox`}))),t}function q(e,t=0,s=""){return r.is.arrayOfLengthAtLeast(e,t)?y(e,T,s):{valid:!1,errors:[{message:`Invalid coordinates: must have at least ${t} positions`,path:s}],warnings:[]}}function ye(e,t=""){const s=q(e,2,t);if(!s.valid)return s;for(let n=0;n<e.length-1;n++){const i=e[n][0],o=e[n+1][0];Math.abs(o-i)>180&&s.warnings.push({message:`LineString crosses the antimeridian between positions ${n} and ${n+1}, consider using MultiLineString`,path:`${t}/${n}`})}return s}function gt(e,t=""){return r.is.nonEmptyArray(e)?y(e,ye,t):{valid:!1,errors:[{message:"Invalid MultiLineString: coordinates must be a non empty array",path:t}],warnings:[]}}function ft(e,t,s=""){const n=q(e,4,s);if(!n.valid)return n;const i=e[0],o=e[e.length-1];if(i[0]!==o[0]||i[1]!==o[1])return n.valid=!1,n.errors.push({message:"Invalid LinearRing: first and last position must be identical",path:s}),n;const c=Se(e)?"clockwise":"counter-clockwise";c!==t&&n.warnings.push({message:`Ring must be ${t} but is ${c}`,path:s});const u=Ie({type:"Polygon",coordinates:[e]});return u.features.length>0&&(n.valid=!1,n.errors.push({message:`Invalid LinearRing: ${u.features.length} self-intersection(s) detected`,path:s})),n}function he(e,t=""){return r.is.nonEmptyArray(e)?y(e,(s,n,i)=>ft(s,i===0?"counter-clockwise":"clockwise",n),t):{valid:!1,errors:[{message:"Invalid Polygon: coordinates must be a non empty array",path:t}],warnings:[]}}function mt(e,t=""){return r.is.nonEmptyArray(e)?y(e,(s,n)=>he(s,n),t):{valid:!1,errors:[{message:"Invalid MultiPolygon: coordinates must be a non empty array",path:t}],warnings:[]}}function dt(e,t=""){return r.is.nonEmptyArray(e)?y(e,(s,n)=>F(s,n),t):{valid:!1,errors:[{message:"Invalid geometries: geometries must be a non empty array",path:t}],warnings:[]}}function F(e,t=""){if(!r.is.nonEmptyObject(e))return{valid:!1,errors:[{message:"Invalid geometry: geometry must be a non empty object",path:t}],warnings:[]};const s=`${t}/coordinates`;let n;switch(e.type){case f.POINT:{const i=T(e.coordinates);n={valid:i.valid,errors:i.errors.map(o=>({...o,path:s})),warnings:i.warnings.map(o=>({...o,path:s}))};break}case f.MULTI_POINT:{n=q(e.coordinates,0,s);break}case f.LINESTRING:{n=ye(e.coordinates,s);break}case f.MULTI_LINESTRING:{n=gt(e.coordinates,s);break}case f.POLYGON:{n=he(e.coordinates,s);break}case f.MULTI_POLYGON:{n=mt(e.coordinates,s);break}case f.GEOMETRY_COLLECTION:{n=dt(e.geometries,`${t}/geometries`);break}default:return{valid:!1,errors:[{message:`Invalid geometry type: ${e.type}`,path:t}],warnings:[]}}return n=A(e,n,t),n.statistics={geometries:{[e.type]:1}},n}function Oe(e,t=""){if(!r.is.nonEmptyObject(e))return{valid:!1,errors:[{message:"Invalid feature: must be a non empty object",path:t}],warnings:[],statistics:E()};if(e.type===p.FEATURE){if(r.is.nonEmptyObject(e.geometry)){const s=F(e.geometry,`${t}/geometry`);return{...A(e,s,t),statistics:{Feature:1,FeatureCollection:0,geometries:{...s.statistics.geometries}}}}return{valid:!0,errors:[],warnings:[{message:"Feature has no geometry",path:t}],statistics:{Feature:1,FeatureCollection:0,geometries:{}}}}if(e.type===p.FEATURE_COLLECTION){if(r.is.nonEmptyArray(e.features)){const s=y(e.features,Oe,`${t}/features`);return{...A(e,s,t),statistics:{...s.statistics,FeatureCollection:s.statistics.FeatureCollection+1}}}return{valid:!1,errors:[{message:"Invalid FeatureCollection: features must be a non empty array",path:t}],warnings:[],statistics:E()}}return{valid:!1,errors:[{message:`Invalid feature: unknown type: ${e.type}`,path:t}],warnings:[],statistics:E()}}function pt(e){if(r.assert.that(e,r.is.nonEmptyObject,"geojson must be a non empty object"),r.is.oneOf(e.type,Object.values(f))){const t=F(e,""),s=A(e,t,"");return{...Q(e,s),statistics:{Feature:0,FeatureCollection:0,geometries:{...t.statistics.geometries}}}}if(e.type===p.FEATURE||e.type===p.FEATURE_COLLECTION){const t=Oe(e,"");return Q(e,t)}return{valid:!1,errors:[{message:"Invalid GeoJson: type must be either a Geometry, a Feature or a FeatureCollection",path:""}],warnings:[],statistics:E()}}exports.AXES=m;exports.COORDINATE_FORMATS=D;exports.COORDINATE_MODELS=ue;exports.COORDINATE_TRUNCATION_FACTORS=x;exports.CRS_TYPES=O;exports.FEATURE_TYPES=p;exports.GEOMETRY_TYPES=f;exports.convertCoordinate=tt;exports.getActiveLocales=H;exports.getAllDirectionSymbols=N;exports.getCoordinatePrecision=U;exports.getDirectionAxis=ie;exports.getDirections=_e;exports.getEast=ke;exports.getLatitudeSymbols=ne;exports.getLocale=te;exports.getLocaleByCode=C;exports.getLongitudeSymbols=re;exports.getNorth=Fe;exports.getSouth=Ge;exports.getWest=Ue;exports.guessCoordinateAxis=k;exports.isAltitude=Re;exports.isAxis=ee;exports.isDirection=v;exports.isEast=M;exports.isLatitude=R;exports.isLikeBBox=ge;exports.isLikeCRS=rt;exports.isLikeFeature=fe;exports.isLikeFeatureCollection=me;exports.isLikeGeoJson=V;exports.isLikeGeometry=$;exports.isLikePosition=de;exports.isLongitude=P;exports.isNorth=se;exports.isSouth=j;exports.isWest=S;exports.listLocales=Me;exports.normalizeCoordinate=et;exports.parseCoordinate=ce;exports.parsePosition=nt;exports.registerLocale=xe;exports.setLocale=$e;exports.simplifyGeoJson=at;exports.simplifyGeometry=_;exports.truncateBBox=Y;exports.truncateCoordinate=Ze;exports.truncateGeoJson=lt;exports.truncateGeometry=W;exports.truncatePosition=ut;exports.validateBBox=Ee;exports.validateCRS=be;exports.validateGeoJson=pt;exports.validateGeometry=F;exports.validatePosition=T;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/foundation/axes.js","../src/foundation/locale.js","../src/foundation/directions.js","../src/foundation/coordinate-formats/dd.js","../src/foundation/coordinate-formats/ddm.js","../src/foundation/coordinate-formats/ddm-aero.js","../src/foundation/coordinate-formats/dms.js","../src/foundation/coordinate-formats/converter.js","../src/foundation/coordinate-formats/index.js","../src/foundation/coordinate.js","../src/foundation/position.js","../src/operators/is-like/bbox.js","../src/operators/is-like/crs.js","../src/operators/is-like/geometry.js","../src/operators/is-like/geojson.js","../src/operators/is-like/position.js","../src/operators/simplify/visvalingam-whyatt.js","../src/operators/simplify/geometry.js","../src/operators/simplify/geojson.js","../src/operators/truncate/bbox.js","../src/operators/truncate/geometry.js","../src/operators/truncate/geojson.js","../src/operators/truncate/position.js","../src/operators/validate/position.js","../src/operators/validate/bbox.js","../src/operators/validate/crs.js","../src/operators/validate/utils.js","../src/operators/validate/geometry.js","../src/operators/validate/geojson.js"],"sourcesContent":["import { assert, is } from '@kalisio/common-core'\n\nexport const AXES = {\n LATITUDE: 'LAT',\n LONGITUDE: 'LON',\n ALTITUDE: 'ALT'\n}\n\nexport function isAxis (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return Object.values(AXES).includes(axis)\n}\n\nexport function isLatitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.LATITUDE\n}\n\nexport function isLongitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.LONGITUDE\n}\n\nexport function isAltitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.ALTITUDE\n}\n","import { assert, is, has, conform } from '@kalisio/common-core'\nimport fr from './locales/fr.json'\nimport en from './locales/en.json'\n\nconst LOCALE_SCHEMA = {\n DIRECTIONS: {\n NORTH: { label: is.string, symbol: is.string },\n SOUTH: { label: is.string, symbol: is.string },\n EAST: { label: is.string, symbol: is.string },\n WEST: { label: is.string, symbol: is.string }\n }\n}\n\nconst LOCALES = {\n en,\n fr\n}\n\nlet CURRENT_LOCALE = 'en'\n\nexport function listLocales () {\n return Object.keys(LOCALES)\n}\n\nexport function registerLocale (code, content) {\n assert.all([\n { value: code, validator: is.string, message: 'code must be a string' },\n { value: code, validator: (v) => !has.key(LOCALES, v), message: 'locale already registered' },\n { value: content, validator: is.plainObject, message: 'content must be an object' },\n { value: content, validator: (v) => conform.schema(v, LOCALE_SCHEMA), message: 'content does not conform to schema' }\n ])\n LOCALES[code] = content\n}\n\nexport function setLocale (code) {\n assert.all([\n { value: code, validator: is.string, message: 'code must be a string' },\n { value: code, validator: (v) => has.key(LOCALES, v), message: 'code is unknown' }\n ])\n CURRENT_LOCALE = code\n}\n\nexport function getLocale () {\n return {\n code: CURRENT_LOCALE,\n content: LOCALES[CURRENT_LOCALE]\n }\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { getLocale } from './locale.js'\nimport { AXES, isLatitude, isLongitude, isAxis } from './axes.js'\n\nfunction getAll () {\n return getLocale().content.DIRECTIONS\n}\n\nfunction isDirectionOf (type, dir) {\n const all = getAll()\n const label = all[type].label.toUpperCase()\n const symbol = all[type].symbol.toUpperCase()\n return dir.toUpperCase() === label || dir.toUpperCase() === symbol\n}\n\nexport function getDirections (axis = null) {\n const directions = getAll()\n if (is.defined(axis)) {\n assert.that(axis, isAxis, 'axis must be a valid axis')\n if (isLatitude(axis)) return [directions.SOUTH, directions.NORTH]\n if (isLongitude(axis)) return [directions.EAST, directions.WEST]\n return []\n }\n return [directions.SOUTH, directions.NORTH, directions.EAST, directions.WEST]\n}\n\nexport function getNorth () { return getAll().NORTH }\nexport function getSouth () { return getAll().SOUTH }\nexport function getEast () { return getAll().EAST }\nexport function getWest () { return getAll().WEST }\n\nexport function isDirection (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isNorth(dir) || isSouth(dir) || isEast(dir) || isWest(dir)\n}\n\nexport function isNorth (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('NORTH', dir)\n}\n\nexport function isSouth (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('SOUTH', dir)\n}\n\nexport function isEast (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('EAST', dir)\n}\n\nexport function isWest (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('WEST', dir)\n}\n\nexport function getDirectionAxis (dir) {\n assert.that(dir, isDirection, 'dir must be a direction')\n if (isWest(dir) || isEast(dir)) return AXES.LONGITUDE\n return AXES.LATITUDE\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { isDirection } from '../directions.js'\n\nconst SCHEMA = {\n degrees: is.number,\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3}(?:\\.\\d+)?)°?$/\nconst REGEX_DIR = /^(\\d{1,3}(?:\\.\\d+)?)°?([NSEW])$/\n\nexport function DD (dd) {\n let _degrees = null\n let _direction = null\n\n if (is.plainObject(dd) && conform.schema(dd, SCHEMA)) {\n if (is.defined(dd.direction)) {\n if (dd.degrees >= 0) {\n _degrees = dd.degrees\n _direction = dd.direction\n }\n } else {\n _degrees = dd.degrees\n }\n } else if (is.string(dd)) {\n const pattern = dd.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(REGEX_DIR)\n if (match) {\n _degrees = parseFloat(match[1])\n _direction = match[2] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get direction () { return _direction },\n get format () { return 'DD' },\n\n isValid () {\n return is.number(_degrees)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees.toFixed(decimalPlaces)}°`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees, direction: _direction })\n }\n }\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { isDirection } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.integer,\n minutes: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3})°(\\d{1,2}(?:\\.\\d+)?)'?$/\nconst REGEX_DIR = /^(\\d{1,3})°(\\d{1,2}(?:\\.\\d+)?)'?([NSEW])$/\n\nexport function DDM (ddm) {\n let _degrees = null\n let _minutes = null\n let _direction = null\n\n if (is.plainObject(ddm) && conform.schema(ddm, SCHEMA)) {\n if (is.defined(ddm.direction)) {\n if (ddm.degrees >= 0) {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n _direction = ddm.direction\n }\n } else {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n }\n } else if (is.string(ddm)) {\n const pattern = ddm.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(REGEX_DIR)\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2])\n _direction = match[3] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get direction () { return _direction },\n get format () { return 'DDM' },\n\n isValid () {\n return is.integer(_degrees) && is.inRangeExclusiveMax(_minutes, 0, 60)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees}° ${_minutes.toFixed(decimalPlaces)}'`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60, direction: _direction })\n }\n }\n}\n","import { is, conform } from '@kalisio/common-core'\nimport { isDirection } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.nonNegativeInteger,\n minutes: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: isDirection\n}\n\nconst REGEX_LAT = /^(\\d{2})(\\d{3})([NS])$/\nconst REGEX_LON = /^(\\d{3})(\\d{3})([EW])$/\n\nexport function DDMAero (ddm) {\n let _degrees = null\n let _minutes = null\n let _direction = null\n\n if (is.plainObject(ddm) && conform.schema(ddm, SCHEMA)) {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n _direction = ddm.direction\n } else if (is.string(ddm)) {\n const pattern = ddm.trim()\n const match = pattern.match(REGEX_LAT) ?? pattern.match(REGEX_LON)\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2]) / 10\n _direction = match[3]\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get direction () { return _direction },\n get format () { return 'DDM_AERO' },\n\n isValid () {\n return is.nonNegativeInteger(_degrees) &&\n is.inRangeExclusiveMax(_minutes, 0, 60) &&\n isDirection(_direction)\n },\n\n toString () {\n if (!this.isValid()) return ''\n const isLon = _direction === 'E' || _direction === 'W'\n const deg = String(_degrees).padStart(isLon ? 3 : 2, '0')\n const min = Math.floor(_minutes * 10).toString().padStart(3, '0')\n return `${deg}${min}${_direction}`\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60, direction: _direction })\n }\n }\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { isDirection } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.integer,\n minutes: (v) => is.integer(v) && is.inRange(v, 0, 59),\n seconds: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3})°(\\d{1,2})'(\\d{1,2}(?:\\.\\d+)?)\"?$/\nconst REGEX_DIR = /^(\\d{1,3})°(\\d{1,2})'(\\d{1,2}(?:\\.\\d+)?)\"?([NSEW])$/\n\nexport function DMS (dms) {\n let _degrees = null\n let _minutes = null\n let _seconds = null\n let _direction = null\n\n if (is.plainObject(dms) && conform.schema(dms, SCHEMA)) {\n if (is.defined(dms.direction)) {\n if (dms.degrees >= 0) {\n _degrees = dms.degrees\n _minutes = dms.minutes\n _seconds = dms.seconds\n _direction = dms.direction\n }\n } else {\n _degrees = dms.degrees\n _minutes = dms.minutes\n _seconds = dms.seconds\n }\n } else if (is.string(dms)) {\n const pattern = dms.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(REGEX_DIR)\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2])\n _seconds = parseFloat(match[3])\n _direction = match[4] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get seconds () { return _seconds },\n get direction () { return _direction },\n get format () { return 'DMS' },\n\n isValid () {\n return is.integer(_degrees) &&\n is.integer(_minutes) && is.inRange(_minutes, 0, 59) &&\n is.inRangeExclusiveMax(_seconds, 0, 60)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees}° ${_minutes}' ${_seconds.toFixed(decimalPlaces)}\"`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60 + _seconds / 3600, direction: _direction })\n }\n }\n}\n","import { assert } from '@kalisio/common-core'\nimport { DDM } from './ddm.js'\nimport { DDMAero } from './ddm-aero.js'\nimport { DMS } from './dms.js'\n\nfunction decimalToDDM (dd) {\n const degrees = Math.floor(dd.degrees)\n const minutes = (dd.degrees - degrees) * 60\n return { degrees, minutes, direction: dd.direction }\n}\n\nfunction decimalToDMS (dd) {\n const degrees = Math.floor(dd.degrees)\n const minutesDecimal = (dd.degrees - degrees) * 60\n const minutes = Math.floor(minutesDecimal)\n const seconds = (minutesDecimal - minutes) * 60\n return { degrees, minutes, seconds, direction: dd.direction }\n}\n\nexport const converter = {\n DD: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n return dd\n },\n\n DDM: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, direction } = decimalToDDM(dd)\n return DDM(direction ? { degrees, minutes, direction } : { degrees, minutes })\n },\n\n DMS: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, seconds, direction } = decimalToDMS(dd)\n return DMS(direction ? { degrees, minutes, seconds, direction } : { degrees, minutes, seconds })\n },\n\n DDM_AERO: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, direction } = decimalToDDM(dd)\n return DDMAero({ degrees, minutes, direction })\n }\n}\n","import { DD } from './dd.js'\nimport { DDM } from './ddm.js'\nimport { DDMAero } from './ddm-aero.js'\nimport { DMS } from './dms.js'\nexport * from './converter.js'\n\nexport const COORDINATE_FORMATS = {\n DD: 'DD',\n DDM: 'DDM',\n DDM_AERO: 'DDM_AERO',\n DMS: 'DMS'\n}\n\nexport const COORDINATE_MODELS = {\n DD,\n DDM,\n DDM_AERO: DDMAero,\n DMS\n}\n","import { assert, is, has } from '@kalisio/common-core'\nimport { AXES, isLatitude, isLongitude } from './axes.js'\nimport { isDirection, getDirectionAxis } from './directions.js'\nimport { COORDINATE_FORMATS, COORDINATE_MODELS, converter } from './coordinate-formats'\nexport { COORDINATE_FORMATS, COORDINATE_MODELS } from './coordinate-formats'\n\nexport const COORDINATE_TRUNCATION_FACTORS = Array.from({ length: 9 }, (_, i) => 10 ** i)\n\nexport function guessCoordinateAxis (coord, dir) {\n assert.that(coord, is.number, 'coord must be a number')\n if (is.defined(dir)) {\n assert.that(dir, isDirection, 'dir must be a direction')\n return getDirectionAxis(dir)\n }\n if (Math.abs(coord) > 90) return AXES.LONGITUDE\n return undefined\n}\n\nexport function getCoordinatePrecision (coord) {\n assert.that(coord, is.number, 'coord must be a number')\n const str = coord.toExponential()\n const [base, exp] = str.split('e').map(Number)\n const decimalsInBase = (base.toString().split('.')[1] || '').length\n return Math.max(0, decimalsInBase - exp)\n}\n\nexport function truncateCoordinate (coord, precision = 7) {\n assert.all([\n { value: coord, validator: is.number, message: 'coord must be a number' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n return Math.round(coord * factor) / factor\n}\n\nexport function normalizeCoordinate (coord, axis) {\n assert.all([\n { value: coord, validator: is.number, message: 'coord must be a number' },\n { value: axis, validator: (v) => isLongitude(v) || isLatitude(v), message: 'axis must be either a longitude or latitude' }\n ])\n if (isLatitude(axis)) {\n return Math.max(-90, Math.min(90, coord))\n }\n let lon = ((coord + 180) % 360 + 360) % 360 - 180\n if (lon === -180) lon = 180\n if (Object.is(lon, -0)) lon = 0\n return lon\n}\n\nexport function convertCoordinate (from, to) {\n assert.all([\n { value: from, validator: (v) => is.defined(v) && v.isValid(), message: 'from must be a valid coordinate' },\n { value: to, validator: (v) => has.key(converter, v), message: `unknown format: ${to}` }\n ])\n const dd = from.format === COORDINATE_FORMATS.DD ? from : from.toDecimal()\n if (!dd.isValid()) return null\n if (to === COORDINATE_FORMATS.DD) {\n return dd\n }\n return converter[to](dd)\n}\n\nexport function parseCoordinate (pattern) {\n assert.that(pattern, is.nonEmptyString, 'pattern must be a non empty string')\n for (const format of Object.keys(COORDINATE_FORMATS)) {\n const coord = COORDINATE_MODELS[format](pattern)\n if (coord.isValid()) return coord\n }\n return null\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { AXES } from './axes.js'\nimport { isWest, isSouth } from './directions.js'\nimport { guessCoordinateAxis, parseCoordinate } from './coordinate.js'\n\nexport function parsePosition (pattern) {\n assert.that(pattern, (v) => is.nonEmptyString(v), 'pattern must be a non-empty string')\n const parts = pattern.split(/[,;|]/)\n if (parts.length !== 2) return null\n const [first, second] = parts.map(parseCoordinate)\n if (!first || !second) return null\n const firstDD = first.toDecimal()\n const secondDD = second.toDecimal()\n const firstAxis = guessCoordinateAxis(firstDD.degrees, firstDD.direction)\n const secondAxis = guessCoordinateAxis(secondDD.degrees, secondDD.direction)\n // Apply signedDegrees based on direction\n const signedDegrees = (dd) => {\n const { degrees, direction } = dd\n if (!direction) return degrees\n return (isWest(direction) || isSouth(direction)) ? -degrees : degrees\n }\n if (firstAxis === AXES.LONGITUDE && secondAxis === AXES.LATITUDE) return [signedDegrees(firstDD), signedDegrees(secondDD)]\n if (secondAxis === AXES.LONGITUDE && firstAxis === AXES.LATITUDE) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (firstAxis === AXES.LONGITUDE && !secondAxis) return [signedDegrees(firstDD), secondDD]\n if (firstAxis === AXES.LATITUDE && !secondAxis) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (secondAxis === AXES.LONGITUDE && !firstAxis) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (secondAxis === AXES.LATITUDE && !firstAxis) return [signedDegrees(firstDD), signedDegrees(secondDD)]\n if (!firstAxis && !secondAxis) {\n return [\n [signedDegrees(firstDD), signedDegrees(secondDD)],\n [signedDegrees(secondDD), signedDegrees(firstDD)]\n ]\n }\n}\n","import { is } from '@kalisio/common-core'\n\nexport function isLikeBBox (object) {\n if (!is.arrayOfLength(object, 4) && !is.arrayOfLength(object, 6)) return false\n return object.every(is.number)\n}\n","import { is } from '@kalisio/common-core'\n\nexport const CRS_TYPES = {\n NAME: 'name',\n LINK: 'link'\n}\n\nexport function isLikeCRS (object) {\n if (!is.plainObject(object)) return false\n if (object.type === CRS_TYPES.NAME) {\n return is.nonEmptyString(object.properties?.name)\n }\n if (object.type === CRS_TYPES.LINK) {\n return is.nonEmptyString(object.properties?.href)\n }\n return false\n}\n","import { is } from '@kalisio/common-core'\n\nexport const GEOMETRY_TYPES = {\n POINT: 'Point',\n MULTI_POINT: 'MultiPoint',\n LINESTRING: 'LineString',\n MULTI_LINESTRING: 'MultiLineString',\n POLYGON: 'Polygon',\n MULTI_POLYGON: 'MultiPolygon',\n GEOMETRY_COLLECTION: 'GeometryCollection'\n}\n\nexport function isLikeGeometry (object) {\n if (!is.plainObject(object)) return false\n if (!is.oneOf(object.type, Object.values(GEOMETRY_TYPES))) return false\n if (object.type === GEOMETRY_TYPES.GEOMETRY_COLLECTION) {\n return is.array(object.geometries)\n }\n return is.array(object.coordinates)\n}\n","import { is } from '@kalisio/common-core'\nimport { isLikeGeometry } from './geometry.js'\n\nexport const FEATURE_TYPES = {\n FEATURE: 'Feature',\n FEATURE_COLLECTION: 'FeatureCollection'\n}\n\nexport function isLikeFeature (object) {\n if (!is.plainObject(object)) return false\n return FEATURE_TYPES.FEATURE === object.type\n}\n\nexport function isLikeFeatureCollection (object) {\n if (!is.plainObject(object)) return false\n if (object.type !== FEATURE_TYPES.FEATURE_COLLECTION) return false\n return is.array(object.features)\n}\n\nexport function isLikeGeoJson (object) {\n if (!is.plainObject(object)) return false\n if (isLikeGeometry(object)) return true\n if (isLikeFeature(object)) return true\n return isLikeFeatureCollection(object)\n}\n","import { is } from '@kalisio/common-core'\n\nexport function isLikePosition (object) {\n if (!is.arrayOfLengthBetween(object, 2, 3)) return false\n return object.every(is.number)\n}\n","import { Heap } from 'heap-js'\n\nfunction triangleArea (a, b, c) {\n return Math.abs(\n (a[0] * (b[1] - c[1]) +\n b[0] * (c[1] - a[1]) +\n c[0] * (a[1] - b[1])) / 2\n )\n}\n\nexport function simplify (coords, { tolerance = 0, getWeight = () => 1 } = {}) {\n if (coords.length <= 2) return coords\n\n const pts = coords.map((coord, i) => ({ coord, i, area: Infinity, removed: false, prev: null, next: null }))\n for (let i = 0; i < pts.length; i++) {\n if (i > 0) pts[i].prev = pts[i - 1]\n if (i < pts.length - 1) pts[i].next = pts[i + 1]\n }\n\n const computeArea = (node) => {\n if (!node.prev || !node.next) return Infinity\n const area = triangleArea(node.prev.coord, node.coord, node.next.coord)\n return area * getWeight(node.coord, node.i)\n }\n\n const heap = new Heap((a, b) => a.area - b.area)\n for (let i = 1; i < pts.length - 1; i++) {\n pts[i].area = computeArea(pts[i])\n pts[i]._currentArea = pts[i].area\n heap.push(pts[i])\n }\n\n let maxArea = 0\n\n while (heap.size() > 0) {\n const node = heap.pop()\n if (node.removed) continue\n if (node.area !== node._currentArea) continue\n if (node.area < maxArea) node.area = maxArea\n else maxArea = node.area\n\n if (node.area >= tolerance) break\n\n node.removed = true\n if (node.prev) node.prev.next = node.next\n if (node.next) node.next.prev = node.prev\n\n if (node.prev?.prev) {\n node.prev.area = computeArea(node.prev)\n node.prev._currentArea = node.prev.area\n heap.push(node.prev)\n }\n if (node.next?.next) {\n node.next.area = computeArea(node.next)\n node.next._currentArea = node.next.area\n heap.push(node.next)\n }\n }\n\n const result = []\n let cur = pts[0]\n while (cur) {\n if (!cur.removed) result.push(cur.coord)\n cur = cur.next\n }\n return result\n}\n","import { assert } from '@kalisio/common-core'\nimport { GEOMETRY_TYPES, isLikeGeometry } from '../is-like'\nimport { simplify } from './visvalingam-whyatt.js'\n\nexport function simplifyGeometry (geometry, options) {\n assert.all([\n { value: geometry, validator: isLikeGeometry, message: 'geometry must be a GeoJson geometry' }\n ])\n switch (geometry.type) {\n case GEOMETRY_TYPES.LINESTRING:\n geometry.coordinates = simplify(geometry.coordinates, options)\n break\n case GEOMETRY_TYPES.POLYGON:\n case GEOMETRY_TYPES.MULTI_LINESTRING:\n geometry.coordinates = geometry.coordinates.map(ring => simplify(ring, options))\n break\n case GEOMETRY_TYPES.MULTI_POLYGON:\n geometry.coordinates = geometry.coordinates.map(poly => poly.map(ring => simplify(ring, options)))\n break\n case GEOMETRY_TYPES.GEOMETRY_COLLECTION:\n geometry.geometries.forEach(g => simplifyGeometry(g, options))\n break\n }\n return geometry\n}\n","import { getLogger } from '@logtape/logtape'\nimport { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES, isLikeGeoJson } from '../is-like'\nimport { simplifyGeometry } from './geometry.js'\n\nconst logger = getLogger(['common-ekosystem', 'simplify', 'geojson'])\n\nfunction simplifyFeature (feature, options) {\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (feature.geometry) simplifyGeometry(feature.geometry, options)\n } else if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n for (const feat of feature.features) simplifyFeature(feat, options)\n } else {\n logger.warn('Unknown feature type \"{type}\", skipping.', { type: feature.type })\n }\n return feature\n}\n\nexport function simplifyGeoJson (geoJson, options) {\n assert.all([\n { value: geoJson, validator: isLikeGeoJson, message: 'geoJson must be a GeoJson object' }\n ])\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) return simplifyGeometry(geoJson, options)\n return simplifyFeature(geoJson, options)\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { COORDINATE_TRUNCATION_FACTORS } from '../../foundation'\nimport { isLikeBBox } from '../is-like'\n\nexport function truncateBBox (bbox, precision = 7) {\n assert.all([\n { value: bbox, validator: isLikeBBox, message: 'bbox must be bounding box' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n for (let i = 0; i < bbox.length; i++) {\n bbox[i] = Math.round(bbox[i] * factor) / factor\n }\n return bbox\n}\n","import truncate from '@turf/truncate'\nimport { assert, is } from '@kalisio/common-core'\nimport { isLikeGeometry } from '../is-like'\nimport { truncateBBox } from './bbox.js'\n\nexport function truncateGeometry (geometry, precision = 7) {\n assert.all([\n { value: geometry, validator: isLikeGeometry, message: 'geometry must be a GeoJson geometry' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const result = truncate(geometry, { precision, mutate: true })\n if (result.bbox) truncateBBox(result.bbox, precision)\n return result\n}\n","import { getLogger } from '@logtape/logtape'\nimport { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES, isLikeGeoJson } from '../is-like'\nimport { truncateBBox } from './bbox.js'\nimport { truncateGeometry } from './geometry.js'\n\nconst logger = getLogger(['common-ekosystem', 'truncate', 'geojson'])\n\nfunction truncateFeature (feature, precision) {\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (feature.geometry) truncateGeometry(feature.geometry, precision)\n } else if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n for (const feat of feature.features) truncateFeature(feat, precision)\n } else {\n logger.warn('Unknown feature type \"{type}\", skipping.', { type: feature.type })\n }\n if (feature.bbox) truncateBBox(feature.bbox, precision)\n return feature\n}\n\nexport function truncateGeoJson (geoJson, precision = 7) {\n assert.all([\n { value: geoJson, validator: isLikeGeoJson, message: 'geoJson must be a valid GeoJson' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) return truncateGeometry(geoJson, precision)\n return truncateFeature(geoJson, precision)\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { COORDINATE_TRUNCATION_FACTORS } from '../../foundation'\nimport { isLikePosition } from '../is-like'\n\nexport function truncatePosition (position, precision = 7) {\n assert.all([\n { value: position, validator: isLikePosition, message: 'position must be a position' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n for (let i = 0; i < position.length; i++) {\n position[i] = Math.round(position[i] * factor) / factor\n }\n return position\n}\n","import { is } from '@kalisio/common-core'\nimport { getCoordinatePrecision } from '../../foundation'\n\nexport function validatePosition (coordinates) {\n if (!is.arrayOfLengthBetween(coordinates, 2, 3)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: must be an array of 2 or 3 coordinates' }],\n warnings: []\n }\n }\n if (!is.inRange(coordinates[0], -180, 180)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: longitude must be in the range -180 to 180' }],\n warnings: []\n }\n }\n if (!is.inRange(coordinates[1], -90, 90)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: latitude must be in the range -90 to 90' }],\n warnings: []\n }\n }\n if (coordinates.length === 3 && !is.number(coordinates[2])) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: altitude must be a number' }],\n warnings: []\n }\n }\n const response = { valid: true, errors: [], warnings: [] }\n const lonPrecision = getCoordinatePrecision(coordinates[0])\n if (lonPrecision > 6) {\n response.warnings.push({ message: `longitude precision is high (${lonPrecision} decimals, max recommended: 6)` })\n }\n const latPrecision = getCoordinatePrecision(coordinates[1])\n if (latPrecision > 6) {\n response.warnings.push({ message: `latitude precision is high (${latPrecision} decimals, max recommended: 6)` })\n }\n return response\n}\n","import { is } from '@kalisio/common-core'\nimport { validatePosition } from './position.js'\n\nexport function validateBBox (bbox) {\n // Must be array of 4 (2D) or 6 (3D) numbers\n if (!is.arrayOfLength(bbox, 4) && !is.arrayOfLength(bbox, 6)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid bbox: must be an array of 4 (2D) or 6 (3D) numbers' }],\n warnings: []\n }\n }\n const is2D = bbox.length === 4\n const min = is2D ? [bbox[0], bbox[1]] : [bbox[0], bbox[1], bbox[2]]\n const max = is2D ? [bbox[2], bbox[3]] : [bbox[3], bbox[4], bbox[5]]\n const minResult = validatePosition(min)\n if (!minResult.valid) {\n return {\n valid: false,\n errors: minResult.errors.map(e => ({ ...e, message: `Invalid bbox south-west: ${e.message}` })),\n warnings: []\n }\n }\n const maxResult = validatePosition(max)\n if (!maxResult.valid) {\n return {\n valid: false,\n errors: maxResult.errors.map(e => ({ ...e, message: `Invalid bbox north-east: ${e.message}` })),\n warnings: []\n }\n }\n const [west, south] = min\n const [east, north] = max\n if (south > north) {\n return {\n valid: false,\n errors: [{ message: `Invalid bbox: south (${south}) must be <= north (${north})` }],\n warnings: []\n }\n }\n const response = { valid: true, errors: [], warnings: [] }\n if (west > east) {\n response.warnings.push({ message: `bbox crosses the antimeridian (west: ${west} > east: ${east})` })\n }\n // Retrieve warnings from both points\n response.warnings.push(...minResult.warnings.map(w => ({ ...w, message: `south-west: ${w.message}` })))\n response.warnings.push(...maxResult.warnings.map(w => ({ ...w, message: `north-east: ${w.message}` })))\n return response\n}\n","import { is } from '@kalisio/common-core'\nimport { CRS_TYPES } from '../is-like'\n\nexport function validateCRS (crs) {\n if (!is.plainObject(crs)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: must be an object' }],\n warnings: []\n }\n }\n switch (crs.type) {\n case CRS_TYPES.NAME: {\n if (!is.nonEmptyString(crs.properties?.name)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: linked crs must have a non-empty properties.name string' }],\n warnings: []\n }\n }\n return { valid: true, errors: [], warnings: [] }\n }\n case CRS_TYPES.LINK: {\n if (!is.nonEmptyString(crs.properties?.href)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: linked crs must have a non-empty properties.href string' }],\n warnings: []\n }\n }\n return { valid: true, errors: [], warnings: [] }\n }\n default:\n return {\n valid: false,\n errors: [{ message: `Invalid crs: unknown type: ${crs.type}` }],\n warnings: []\n }\n }\n}\n","import { is } from '@kalisio/common-core'\nimport { validateBBox } from './bbox.js'\nimport { validateCRS } from './crs.js'\n\nexport function emptyStatistics () {\n return { Feature: 0, FeatureCollection: 0, geometries: {} }\n}\n\nfunction mergeStatistics (...results) {\n const statistics = emptyStatistics()\n for (const result of results) {\n const s = result.statistics\n if (!s) continue\n statistics.Feature += s.Feature ?? 0\n statistics.FeatureCollection += s.FeatureCollection ?? 0\n for (const [type, count] of Object.entries(s.geometries ?? {})) {\n statistics.geometries[type] = (statistics.geometries[type] ?? 0) + count\n }\n }\n return statistics\n}\n\nexport function validateArray (items, validator, path = '') {\n const response = {\n valid: true,\n errors: [],\n warnings: []\n }\n for (let i = 0; i < items.length; i++) {\n const itemPath = `${path}/${i}`\n const result = validator(items[i], itemPath, i)\n if (!result.valid) {\n response.valid = false\n response.errors = response.errors.concat(result.errors.map(e => ({ ...e, path: e.path || itemPath, index: i })))\n continue\n }\n if (!is.empty(result.warnings)) {\n response.warnings = response.warnings.concat(result.warnings.map(w => ({ ...w, path: w.path || itemPath, index: i })))\n }\n if (result.statistics) {\n response.statistics = mergeStatistics(response, result)\n }\n }\n return response\n}\n\nexport function validateOptionalCRS (obj, result) {\n if (!is.defined(obj.crs)) return result\n const crsResult = validateCRS(obj.crs)\n if (!crsResult.valid) {\n result.valid = false\n result.errors.push(...crsResult.errors.map(e => ({ ...e, path: '/crs' })))\n }\n result.warnings.push(...crsResult.warnings.map(w => ({ ...w, path: '/crs' })))\n return result\n}\n\nexport function validateOptionalBBox (obj, result, path = '') {\n if (!is.defined(obj.bbox)) return result\n const bboxResult = validateBBox(obj.bbox)\n if (!bboxResult.valid) {\n result.valid = false\n result.errors.push(...bboxResult.errors.map(e => ({ ...e, path: `${path}/bbox` })))\n }\n result.warnings.push(...bboxResult.warnings.map(w => ({ ...w, path: `${path}/bbox` })))\n return result\n}\n","import booleanClockwise from '@turf/boolean-clockwise'\nimport kinks from '@turf/kinks'\nimport { is } from '@kalisio/common-core'\nimport { GEOMETRY_TYPES } from '../is-like/index.js'\nimport { validatePosition } from './position.js'\nimport { validateOptionalBBox, validateArray } from './utils.js'\n\nfunction validateCoordinatesArray (coordinates, minimumLength = 0, path = '') {\n if (!is.arrayOfLengthAtLeast(coordinates, minimumLength)) {\n return {\n valid: false,\n errors: [{ message: `Invalid coordinates: must have at least ${minimumLength} positions`, path }],\n warnings: []\n }\n }\n return validateArray(coordinates, validatePosition, path)\n}\n\nfunction validateLineStringCoordinates (coordinates, path = '') {\n const result = validateCoordinatesArray(coordinates, 2, path)\n if (!result.valid) return result\n // Check for antimeridian crossings\n for (let i = 0; i < coordinates.length - 1; i++) {\n const lon1 = coordinates[i][0]\n const lon2 = coordinates[i + 1][0]\n if (Math.abs(lon2 - lon1) > 180) {\n result.warnings.push({\n message: `LineString crosses the antimeridian between positions ${i} and ${i + 1}, consider using MultiLineString`,\n path: `${path}/${i}`\n })\n }\n }\n return result\n}\n\nfunction validateMultiLineStringCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid MultiLineString: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, validateLineStringCoordinates, path)\n}\n\nfunction validateLinearRing (coordinates, expectedWindingOrder, path = '') {\n const result = validateCoordinatesArray(coordinates, 4, path)\n if (!result.valid) return result\n // check ring is closed\n const first = coordinates[0]\n const last = coordinates[coordinates.length - 1]\n if (first[0] !== last[0] || first[1] !== last[1]) {\n result.valid = false\n result.errors.push({ message: 'Invalid LinearRing: first and last position must be identical', path })\n return result\n }\n // check winding order\n const isClockwise = booleanClockwise(coordinates)\n const actualWindingOrder = isClockwise ? 'clockwise' : 'counter-clockwise'\n if (actualWindingOrder !== expectedWindingOrder) {\n result.warnings.push({ message: `Ring must be ${expectedWindingOrder} but is ${actualWindingOrder}`, path })\n }\n // check self-intersection\n const intersections = kinks({ type: 'Polygon', coordinates: [coordinates] })\n if (intersections.features.length > 0) {\n result.valid = false\n result.errors.push({ message: `Invalid LinearRing: ${intersections.features.length} self-intersection(s) detected`, path })\n }\n return result\n}\n\nfunction validatePolygonCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid Polygon: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, (ring, p, i) => validateLinearRing(ring, i === 0 ? 'counter-clockwise' : 'clockwise', p), path)\n}\n\nfunction validateMultiPolygonCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid MultiPolygon: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, (c, p) => validatePolygonCoordinates(c, p), path)\n}\n\nfunction validateGeometryCollectionGeometries (geometries, path = '') {\n if (!is.nonEmptyArray(geometries)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid geometries: geometries must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(geometries, (g, p) => validateGeometry(g, p), path)\n}\n\nexport function validateGeometry (geometry, path = '') {\n if (!is.nonEmptyObject(geometry)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid geometry: geometry must be a non empty object', path }],\n warnings: []\n }\n }\n const coordsPath = `${path}/coordinates`\n let result\n switch (geometry.type) {\n case GEOMETRY_TYPES.POINT: {\n const positionResult = validatePosition(geometry.coordinates, coordsPath)\n result = {\n valid: positionResult.valid,\n errors: positionResult.errors.map(e => ({ ...e, path: coordsPath })),\n warnings: positionResult.warnings.map(w => ({ ...w, path: coordsPath }))\n }\n break\n }\n case GEOMETRY_TYPES.MULTI_POINT: {\n result = validateCoordinatesArray(geometry.coordinates, 0, coordsPath)\n break\n }\n case GEOMETRY_TYPES.LINESTRING: {\n result = validateLineStringCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.MULTI_LINESTRING: {\n result = validateMultiLineStringCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.POLYGON: {\n result = validatePolygonCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.MULTI_POLYGON: {\n result = validateMultiPolygonCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.GEOMETRY_COLLECTION: {\n result = validateGeometryCollectionGeometries(geometry.geometries, `${path}/geometries`)\n break\n }\n default:\n return {\n valid: false,\n errors: [{ message: `Invalid geometry type: ${geometry.type}`, path }],\n warnings: []\n }\n }\n return validateOptionalBBox(geometry, result, path)\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES } from '../is-like/index.js'\nimport { emptyStatistics, validateArray, validateOptionalBBox, validateOptionalCRS } from './utils.js'\nimport { validateGeometry } from './geometry.js'\n\nfunction validateFeature (feature, path = '') {\n if (!is.nonEmptyObject(feature)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid feature: must be a non empty object', path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n }\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (is.nonEmptyObject(feature.geometry)) {\n const result = validateGeometry(feature.geometry, `${path}/geometry`)\n const bboxResult = validateOptionalBBox(feature, result, path)\n return {\n ...bboxResult,\n statistics: {\n Feature: 1,\n FeatureCollection: 0,\n geometries: { [feature.geometry.type]: 1 }\n }\n }\n }\n return {\n valid: true,\n errors: [],\n warnings: [{ message: 'Feature has no geometry', path }],\n statistics: { Feature: 1, FeatureCollection: 0, geometries: {} }\n }\n }\n if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n if (is.nonEmptyArray(feature.features)) {\n const result = validateArray(feature.features, validateFeature, `${path}/features`)\n const bboxResult = validateOptionalBBox(feature, result, path)\n return {\n ...bboxResult,\n statistics: { ...result.statistics, FeatureCollection: result.statistics.FeatureCollection + 1 }\n }\n }\n return {\n valid: false,\n errors: [{ message: 'Invalid FeatureCollection: features must be a non empty array', path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n }\n return {\n valid: false,\n errors: [{ message: `Invalid feature: unknown type: ${feature.type}`, path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n}\n\nexport function validateGeoJson (geoJson) {\n assert.that(geoJson, is.nonEmptyObject, 'geojson must be a non empty object')\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) {\n const result = validateGeometry(geoJson, '')\n return {\n ...result,\n statistics: { Feature: 0, FeatureCollection: 0, geometries: { [geoJson.type]: 1 } }\n }\n }\n if (geoJson.type === FEATURE_TYPES.FEATURE || geoJson.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n const result = validateFeature(geoJson, '')\n return validateOptionalCRS(geoJson, result)\n }\n return {\n valid: false,\n errors: [{ message: 'Invalid GeoJson: type must be either a Geometry, a Feature or a FeatureCollection' }],\n warnings: [],\n statistics: emptyStatistics()\n }\n}\n"],"names":["AXES","isAxis","axis","assert","is","isLatitude","isLongitude","isAltitude","LOCALE_SCHEMA","LOCALES","en","fr","CURRENT_LOCALE","listLocales","registerLocale","code","content","v","has","conform","setLocale","getLocale","getAll","isDirectionOf","type","dir","all","label","symbol","getDirections","directions","getNorth","getSouth","getEast","getWest","isDirection","isNorth","isSouth","isEast","isWest","getDirectionAxis","SCHEMA","optional","REGEX_SIGNED","REGEX_DIR","DD","dd","_degrees","_direction","pattern","match","decimalPlaces","str","DDM","ddm","_minutes","REGEX_LAT","REGEX_LON","DDMAero","isLon","deg","min","DMS","dms","_seconds","decimalToDDM","degrees","minutes","decimalToDMS","minutesDecimal","seconds","converter","direction","COORDINATE_FORMATS","COORDINATE_MODELS","COORDINATE_TRUNCATION_FACTORS","_","i","guessCoordinateAxis","coord","getCoordinatePrecision","base","exp","decimalsInBase","truncateCoordinate","precision","factor","normalizeCoordinate","lon","convertCoordinate","from","to","parseCoordinate","format","parsePosition","parts","first","second","firstDD","secondDD","firstAxis","secondAxis","signedDegrees","isLikeBBox","object","CRS_TYPES","isLikeCRS","GEOMETRY_TYPES","isLikeGeometry","FEATURE_TYPES","isLikeFeature","isLikeFeatureCollection","isLikeGeoJson","isLikePosition","triangleArea","a","b","c","simplify","coords","tolerance","getWeight","pts","computeArea","node","heap","Heap","maxArea","result","cur","simplifyGeometry","geometry","options","ring","poly","g","logger","getLogger","simplifyFeature","feature","feat","simplifyGeoJson","geoJson","truncateBBox","bbox","truncateGeometry","truncate","truncateFeature","truncateGeoJson","truncatePosition","position","validatePosition","coordinates","response","lonPrecision","latPrecision","validateBBox","is2D","max","minResult","e","maxResult","west","south","east","north","w","validateCRS","crs","emptyStatistics","mergeStatistics","results","statistics","s","count","validateArray","items","validator","path","itemPath","validateOptionalCRS","obj","crsResult","validateOptionalBBox","bboxResult","validateCoordinatesArray","minimumLength","validateLineStringCoordinates","lon1","lon2","validateMultiLineStringCoordinates","validateLinearRing","expectedWindingOrder","last","actualWindingOrder","booleanClockwise","intersections","kinks","validatePolygonCoordinates","p","validateMultiPolygonCoordinates","validateGeometryCollectionGeometries","geometries","validateGeometry","coordsPath","positionResult","validateFeature","validateGeoJson"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/foundation/axes.js","../src/foundation/localization.js","../src/foundation/directions.js","../src/foundation/coordinate-formats/dd.js","../src/foundation/coordinate-formats/ddm.js","../src/foundation/coordinate-formats/ddm-aero.js","../src/foundation/coordinate-formats/dms.js","../src/foundation/coordinate-formats/converter.js","../src/foundation/coordinate-formats/index.js","../src/foundation/coordinate.js","../src/foundation/position.js","../src/operators/is-like/bbox.js","../src/operators/is-like/crs.js","../src/operators/is-like/geometry.js","../src/operators/is-like/geojson.js","../src/operators/is-like/position.js","../src/operators/simplify/visvalingam-whyatt.js","../src/operators/simplify/geometry.js","../src/operators/simplify/geojson.js","../src/operators/truncate/bbox.js","../src/operators/truncate/geometry.js","../src/operators/truncate/geojson.js","../src/operators/truncate/position.js","../src/operators/validate/position.js","../src/operators/validate/bbox.js","../src/operators/validate/crs.js","../src/operators/validate/utils.js","../src/operators/validate/geometry.js","../src/operators/validate/geojson.js"],"sourcesContent":["import { assert, is } from '@kalisio/common-core'\n\nexport const AXES = {\n LATITUDE: 'LAT',\n LONGITUDE: 'LON',\n ALTITUDE: 'ALT'\n}\n\nexport function isAxis (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return Object.values(AXES).includes(axis)\n}\n\nexport function isLatitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.LATITUDE\n}\n\nexport function isLongitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.LONGITUDE\n}\n\nexport function isAltitude (axis) {\n assert.that(axis, is.string, 'axis must be a string')\n return axis === AXES.ALTITUDE\n}\n","import { assert, is, has, conform } from '@kalisio/common-core'\nimport fr from './i18n/fr.json'\nimport en from './i18n/en.json'\n\nconst LOCALE_SCHEMA = {\n DIRECTIONS: {\n NORTH: { label: is.string, symbol: is.char },\n SOUTH: { label: is.string, symbol: is.char },\n EAST: { label: is.string, symbol: is.char },\n WEST: { label: is.string, symbol: is.char }\n }\n}\n\nconst LOCALES = {\n en,\n fr\n}\n\nlet CURRENT_LOCALE = 'en'\nconst FALLBACK_LOCALE = 'en'\n\nexport function listLocales () {\n return Object.keys(LOCALES)\n}\n\nexport function registerLocale (code, content) {\n assert.all([\n { value: code, validator: is.string, message: 'code must be a string' },\n { value: code, validator: (v) => !has.key(LOCALES, v), message: 'locale already registered' },\n { value: content, validator: is.plainObject, message: 'content must be an object' },\n { value: content, validator: (v) => conform.schema(v, LOCALE_SCHEMA), message: 'content does not conform to schema' }\n ])\n LOCALES[code] = content\n}\n\nexport function setLocale (code) {\n assert.all([\n { value: code, validator: is.string, message: 'code must be a string' },\n { value: code, validator: (v) => has.key(LOCALES, v), message: 'code is unknown' }\n ])\n CURRENT_LOCALE = code\n}\n\nexport function getLocale () {\n return CURRENT_LOCALE\n}\n\nexport function getLocaleByCode (code) {\n assert.all([\n { value: code, validator: is.string, message: 'code must be a string' },\n { value: code, validator: (v) => has.key(LOCALES, v), message: 'code is unknown' }\n ])\n return LOCALES[code]\n}\n\nexport function getActiveLocales () {\n return CURRENT_LOCALE === FALLBACK_LOCALE\n ? [CURRENT_LOCALE]\n : [CURRENT_LOCALE, FALLBACK_LOCALE]\n}\n\nfunction collectSymbols (keys) {\n const symbols = new Set()\n for (const code of getActiveLocales()) {\n const { DIRECTIONS } = getLocaleByCode(code)\n for (const key of keys) symbols.add(DIRECTIONS[key].symbol)\n }\n return [...symbols]\n}\n\n// Latitude symbols (NORTH/SOUTH), current locale + fallback.\nexport function getLatitudeSymbols () {\n return collectSymbols(['NORTH', 'SOUTH'])\n}\n\n// Longitude symbols (EAST/WEST), current locale + fallback.\nexport function getLongitudeSymbols () {\n return collectSymbols(['EAST', 'WEST'])\n}\n\n// All direction symbols (both axes), current locale + fallback.\nexport function getAllDirectionSymbols () {\n return collectSymbols(['NORTH', 'SOUTH', 'EAST', 'WEST'])\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { getLocale, getLocaleByCode, getActiveLocales } from './localization.js'\nimport { AXES, isLatitude, isLongitude, isAxis } from './axes.js'\n\nfunction getAll () {\n return getLocaleByCode(getLocale()).DIRECTIONS\n}\n\n// A direction matches a type if it equals its label or its symbol, in any of\n// the active locales (current + fallback), case-insensitively.\nfunction isDirectionOf (type, dir) {\n const value = dir.toUpperCase()\n return getActiveLocales().some((code) => {\n const { label, symbol } = getLocaleByCode(code).DIRECTIONS[type]\n return value === label.toUpperCase() || value === symbol.toUpperCase()\n })\n}\n\nexport function getDirections (axis = null) {\n const directions = getAll()\n if (is.defined(axis)) {\n assert.that(axis, isAxis, 'axis must be a valid axis')\n if (isLatitude(axis)) return [directions.SOUTH, directions.NORTH]\n if (isLongitude(axis)) return [directions.EAST, directions.WEST]\n return []\n }\n return [directions.SOUTH, directions.NORTH, directions.EAST, directions.WEST]\n}\n\nexport function getNorth () { return getAll().NORTH }\nexport function getSouth () { return getAll().SOUTH }\nexport function getEast () { return getAll().EAST }\nexport function getWest () { return getAll().WEST }\n\nexport function isDirection (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isNorth(dir) || isSouth(dir) || isEast(dir) || isWest(dir)\n}\n\nexport function isNorth (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('NORTH', dir)\n}\n\nexport function isSouth (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('SOUTH', dir)\n}\n\nexport function isEast (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('EAST', dir)\n}\n\nexport function isWest (dir) {\n assert.that(dir, is.string, 'dir must be a string')\n return isDirectionOf('WEST', dir)\n}\n\nexport function getDirectionAxis (dir) {\n assert.that(dir, isDirection, 'dir must be a direction')\n if (isWest(dir) || isEast(dir)) return AXES.LONGITUDE\n return AXES.LATITUDE\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { getAllDirectionSymbols } from '../localization.js'\nimport { isDirection } from '../directions.js'\n\nconst SCHEMA = {\n degrees: is.number,\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3}(?:\\.\\d+)?)°?$/\n\nfunction dirRegex () {\n return new RegExp(`^(\\\\d{1,3}(?:\\\\.\\\\d+)?)°?([${getAllDirectionSymbols()}])$`, 'i')\n}\n\nexport function DD (dd) {\n let _degrees = null\n let _direction = null\n\n if (is.plainObject(dd) && conform.schema(dd, SCHEMA)) {\n if (is.defined(dd.direction)) {\n if (dd.degrees >= 0) {\n _degrees = dd.degrees\n _direction = dd.direction\n }\n } else {\n _degrees = dd.degrees\n }\n } else if (is.string(dd)) {\n const pattern = dd.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(dirRegex())\n if (match) {\n _degrees = parseFloat(match[1])\n _direction = match[2] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get direction () { return _direction },\n get format () { return 'DD' },\n\n isValid () {\n return is.number(_degrees)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees.toFixed(decimalPlaces)}°`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees, direction: _direction })\n }\n }\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { getAllDirectionSymbols } from '../localization.js'\nimport { isDirection } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.integer,\n minutes: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3})°(\\d{1,2}(?:\\.\\d+)?)'?$/\n\nfunction dirRegex () {\n return new RegExp(`^(\\\\d{1,3})°(\\\\d{1,2}(?:\\\\.\\\\d+)?)'?([${getAllDirectionSymbols().join('')}])$`, 'i')\n}\n\nexport function DDM (ddm) {\n let _degrees = null\n let _minutes = null\n let _direction = null\n\n if (is.plainObject(ddm) && conform.schema(ddm, SCHEMA)) {\n if (is.defined(ddm.direction)) {\n if (ddm.degrees >= 0) {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n _direction = ddm.direction\n }\n } else {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n }\n } else if (is.string(ddm)) {\n const pattern = ddm.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(dirRegex())\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2])\n _direction = match[3] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get direction () { return _direction },\n get format () { return 'DDM' },\n\n isValid () {\n return is.integer(_degrees) && is.inRangeExclusiveMax(_minutes, 0, 60)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees}° ${_minutes.toFixed(decimalPlaces)}'`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60, direction: _direction })\n }\n }\n}\n","import { is, conform } from '@kalisio/common-core'\nimport { getLatitudeSymbols, getLongitudeSymbols } from '../localization.js'\nimport { isDirection, isEast, isWest } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.nonNegativeInteger,\n minutes: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: isDirection\n}\n\nfunction latRegex () {\n return new RegExp(`^(\\\\d{2})(\\\\d{3})([${getLatitudeSymbols().join('')}])$`, 'i')\n}\n\nfunction lonRegex () {\n return new RegExp(`^(\\\\d{3})(\\\\d{3})([${getLongitudeSymbols().join('')}])$`, 'i')\n}\n\nexport function DDMAero (ddm) {\n let _degrees = null\n let _minutes = null\n let _direction = null\n\n if (is.plainObject(ddm) && conform.schema(ddm, SCHEMA)) {\n _degrees = ddm.degrees\n _minutes = ddm.minutes\n _direction = ddm.direction\n } else if (is.string(ddm)) {\n const pattern = ddm.trim()\n const match = pattern.match(latRegex()) ?? pattern.match(lonRegex())\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2]) / 10\n _direction = match[3]\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get direction () { return _direction },\n get format () { return 'DDM_AERO' },\n\n isValid () {\n return is.nonNegativeInteger(_degrees) &&\n is.inRangeExclusiveMax(_minutes, 0, 60) &&\n isDirection(_direction)\n },\n\n toString () {\n if (!this.isValid()) return ''\n const isLon = isEast(_direction) || isWest(_direction)\n const deg = String(_degrees).padStart(isLon ? 3 : 2, '0')\n const min = Math.floor(_minutes * 10).toString().padStart(3, '0')\n return `${deg}${min}${_direction}`\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60, direction: _direction })\n }\n }\n}\n","import { assert, is, conform, optional } from '@kalisio/common-core'\nimport { getAllDirectionSymbols } from '../localization.js'\nimport { isDirection } from '../directions.js'\nimport { DD } from './dd.js'\n\nconst SCHEMA = {\n degrees: is.integer,\n minutes: (v) => is.integer(v) && is.inRange(v, 0, 59),\n seconds: (v) => is.inRangeExclusiveMax(v, 0, 60),\n direction: optional(isDirection)\n}\n\nconst REGEX_SIGNED = /^(-?\\d{1,3})°(\\d{1,2})'(\\d{1,2}(?:\\.\\d+)?)\"?$/\n\nfunction dirRegex () {\n return new RegExp(`^(\\\\d{1,3})°(\\\\d{1,2})'(\\\\d{1,2}(?:\\\\.\\\\d+)?)\"?([${getAllDirectionSymbols().join('')}])$`, 'i')\n}\n\nexport function DMS (dms) {\n let _degrees = null\n let _minutes = null\n let _seconds = null\n let _direction = null\n\n if (is.plainObject(dms) && conform.schema(dms, SCHEMA)) {\n if (is.defined(dms.direction)) {\n if (dms.degrees >= 0) {\n _degrees = dms.degrees\n _minutes = dms.minutes\n _seconds = dms.seconds\n _direction = dms.direction\n }\n } else {\n _degrees = dms.degrees\n _minutes = dms.minutes\n _seconds = dms.seconds\n }\n } else if (is.string(dms)) {\n const pattern = dms.replace(/\\s+/g, '')\n const match = pattern.match(REGEX_SIGNED) ?? pattern.match(dirRegex())\n if (match) {\n _degrees = parseFloat(match[1])\n _minutes = parseFloat(match[2])\n _seconds = parseFloat(match[3])\n _direction = match[4] ?? null\n }\n }\n\n return {\n get degrees () { return _degrees },\n get minutes () { return _minutes },\n get seconds () { return _seconds },\n get direction () { return _direction },\n get format () { return 'DMS' },\n\n isValid () {\n return is.integer(_degrees) &&\n is.integer(_minutes) && is.inRange(_minutes, 0, 59) &&\n is.inRangeExclusiveMax(_seconds, 0, 60)\n },\n\n toString (decimalPlaces) {\n assert.that(decimalPlaces, is.positiveInteger, 'decimalPlaces must be a positive integer')\n if (!this.isValid()) return ''\n let str = `${_degrees}° ${_minutes}' ${_seconds.toFixed(decimalPlaces)}\"`\n if (_direction) str += ` ${_direction}`\n return str\n },\n\n toDecimal () {\n if (!this.isValid()) return null\n return DD({ degrees: _degrees + _minutes / 60 + _seconds / 3600, direction: _direction })\n }\n }\n}\n","import { assert } from '@kalisio/common-core'\nimport { DDM } from './ddm.js'\nimport { DDMAero } from './ddm-aero.js'\nimport { DMS } from './dms.js'\n\nfunction decimalToDDM (dd) {\n const degrees = Math.floor(dd.degrees)\n const minutes = (dd.degrees - degrees) * 60\n return { degrees, minutes, direction: dd.direction }\n}\n\nfunction decimalToDMS (dd) {\n const degrees = Math.floor(dd.degrees)\n const minutesDecimal = (dd.degrees - degrees) * 60\n const minutes = Math.floor(minutesDecimal)\n const seconds = (minutesDecimal - minutes) * 60\n return { degrees, minutes, seconds, direction: dd.direction }\n}\n\nexport const converter = {\n DD: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n return dd\n },\n\n DDM: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, direction } = decimalToDDM(dd)\n return DDM(direction ? { degrees, minutes, direction } : { degrees, minutes })\n },\n\n DMS: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, seconds, direction } = decimalToDMS(dd)\n return DMS(direction ? { degrees, minutes, seconds, direction } : { degrees, minutes, seconds })\n },\n\n DDM_AERO: (dd) => {\n assert.that(dd, (v) => v.isValid(), 'dd must be a valid coordinate')\n const { degrees, minutes, direction } = decimalToDDM(dd)\n return DDMAero({ degrees, minutes, direction })\n }\n}\n","import { DD } from './dd.js'\nimport { DDM } from './ddm.js'\nimport { DDMAero } from './ddm-aero.js'\nimport { DMS } from './dms.js'\nexport * from './converter.js'\n\nexport const COORDINATE_FORMATS = {\n DD: 'DD',\n DDM: 'DDM',\n DDM_AERO: 'DDM_AERO',\n DMS: 'DMS'\n}\n\nexport const COORDINATE_MODELS = {\n DD,\n DDM,\n DDM_AERO: DDMAero,\n DMS\n}\n","import { assert, is, has } from '@kalisio/common-core'\nimport { AXES, isLatitude, isLongitude } from './axes.js'\nimport { isDirection, getDirectionAxis } from './directions.js'\nimport { COORDINATE_FORMATS, COORDINATE_MODELS, converter } from './coordinate-formats/index.js'\nexport { COORDINATE_FORMATS, COORDINATE_MODELS } from './coordinate-formats/index.js'\n\nexport const COORDINATE_TRUNCATION_FACTORS = Array.from({ length: 9 }, (_, i) => 10 ** i)\n\nexport function guessCoordinateAxis (coord, dir) {\n assert.that(coord, is.number, 'coord must be a number')\n if (is.defined(dir)) {\n assert.that(dir, isDirection, 'dir must be a direction')\n return getDirectionAxis(dir)\n }\n if (Math.abs(coord) > 90) return AXES.LONGITUDE\n return undefined\n}\n\nexport function getCoordinatePrecision (coord) {\n assert.that(coord, is.number, 'coord must be a number')\n const str = coord.toExponential()\n const [base, exp] = str.split('e').map(Number)\n const decimalsInBase = (base.toString().split('.')[1] || '').length\n return Math.max(0, decimalsInBase - exp)\n}\n\nexport function truncateCoordinate (coord, precision = 7) {\n assert.all([\n { value: coord, validator: is.number, message: 'coord must be a number' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n return Math.round(coord * factor) / factor\n}\n\nexport function normalizeCoordinate (coord, axis) {\n assert.all([\n { value: coord, validator: is.number, message: 'coord must be a number' },\n { value: axis, validator: (v) => isLongitude(v) || isLatitude(v), message: 'axis must be either a longitude or latitude' }\n ])\n if (isLatitude(axis)) {\n return Math.max(-90, Math.min(90, coord))\n }\n let lon = ((coord + 180) % 360 + 360) % 360 - 180\n if (lon === -180) lon = 180\n if (Object.is(lon, -0)) lon = 0\n return lon\n}\n\nexport function convertCoordinate (from, to) {\n assert.all([\n { value: from, validator: (v) => is.defined(v) && v.isValid(), message: 'from must be a valid coordinate' },\n { value: to, validator: (v) => has.key(converter, v), message: `unknown format: ${to}` }\n ])\n const dd = from.format === COORDINATE_FORMATS.DD ? from : from.toDecimal()\n if (!dd.isValid()) return null\n if (to === COORDINATE_FORMATS.DD) {\n return dd\n }\n return converter[to](dd)\n}\n\nexport function parseCoordinate (pattern) {\n assert.that(pattern, is.nonEmptyString, 'pattern must be a non empty string')\n for (const format of Object.keys(COORDINATE_FORMATS)) {\n const coord = COORDINATE_MODELS[format](pattern)\n if (coord.isValid()) return coord\n }\n return null\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { AXES } from './axes.js'\nimport { isWest, isSouth } from './directions.js'\nimport { guessCoordinateAxis, parseCoordinate } from './coordinate.js'\n\nexport function parsePosition (pattern) {\n assert.that(pattern, (v) => is.nonEmptyString(v), 'pattern must be a non-empty string')\n const parts = pattern.split(/[,;|]/)\n if (parts.length !== 2) return null\n const [first, second] = parts.map(parseCoordinate)\n if (!first || !second) return null\n const firstDD = first.toDecimal()\n const secondDD = second.toDecimal()\n const firstAxis = guessCoordinateAxis(firstDD.degrees, firstDD.direction)\n const secondAxis = guessCoordinateAxis(secondDD.degrees, secondDD.direction)\n // Apply signedDegrees based on direction\n const signedDegrees = (dd) => {\n const { degrees, direction } = dd\n if (!direction) return degrees\n return (isWest(direction) || isSouth(direction)) ? -degrees : degrees\n }\n if (firstAxis === AXES.LONGITUDE && secondAxis === AXES.LATITUDE) return [signedDegrees(firstDD), signedDegrees(secondDD)]\n if (secondAxis === AXES.LONGITUDE && firstAxis === AXES.LATITUDE) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (firstAxis === AXES.LONGITUDE && !secondAxis) return [signedDegrees(firstDD), secondDD]\n if (firstAxis === AXES.LATITUDE && !secondAxis) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (secondAxis === AXES.LONGITUDE && !firstAxis) return [signedDegrees(secondDD), signedDegrees(firstDD)]\n if (secondAxis === AXES.LATITUDE && !firstAxis) return [signedDegrees(firstDD), signedDegrees(secondDD)]\n if (!firstAxis && !secondAxis) {\n return [\n [signedDegrees(firstDD), signedDegrees(secondDD)],\n [signedDegrees(secondDD), signedDegrees(firstDD)]\n ]\n }\n}\n","import { is } from '@kalisio/common-core'\n\nexport function isLikeBBox (object) {\n if (!is.arrayOfLength(object, 4) && !is.arrayOfLength(object, 6)) return false\n return object.every(is.number)\n}\n","import { is } from '@kalisio/common-core'\n\nexport const CRS_TYPES = {\n NAME: 'name',\n LINK: 'link'\n}\n\nexport function isLikeCRS (object) {\n if (!is.plainObject(object)) return false\n if (object.type === CRS_TYPES.NAME) {\n return is.nonEmptyString(object.properties?.name)\n }\n if (object.type === CRS_TYPES.LINK) {\n return is.nonEmptyString(object.properties?.href)\n }\n return false\n}\n","import { is } from '@kalisio/common-core'\n\nexport const GEOMETRY_TYPES = {\n POINT: 'Point',\n MULTI_POINT: 'MultiPoint',\n LINESTRING: 'LineString',\n MULTI_LINESTRING: 'MultiLineString',\n POLYGON: 'Polygon',\n MULTI_POLYGON: 'MultiPolygon',\n GEOMETRY_COLLECTION: 'GeometryCollection'\n}\n\nexport function isLikeGeometry (object) {\n if (!is.plainObject(object)) return false\n if (!is.oneOf(object.type, Object.values(GEOMETRY_TYPES))) return false\n if (object.type === GEOMETRY_TYPES.GEOMETRY_COLLECTION) {\n return is.array(object.geometries)\n }\n return is.array(object.coordinates)\n}\n","import { is } from '@kalisio/common-core'\nimport { isLikeGeometry } from './geometry.js'\n\nexport const FEATURE_TYPES = {\n FEATURE: 'Feature',\n FEATURE_COLLECTION: 'FeatureCollection'\n}\n\nexport function isLikeFeature (object) {\n if (!is.plainObject(object)) return false\n return FEATURE_TYPES.FEATURE === object.type\n}\n\nexport function isLikeFeatureCollection (object) {\n if (!is.plainObject(object)) return false\n if (object.type !== FEATURE_TYPES.FEATURE_COLLECTION) return false\n return is.array(object.features)\n}\n\nexport function isLikeGeoJson (object) {\n if (!is.plainObject(object)) return false\n if (isLikeGeometry(object)) return true\n if (isLikeFeature(object)) return true\n return isLikeFeatureCollection(object)\n}\n","import { is } from '@kalisio/common-core'\n\nexport function isLikePosition (object) {\n if (!is.arrayOfLengthBetween(object, 2, 3)) return false\n return object.every(is.number)\n}\n","import { Heap } from 'heap-js'\n\nfunction triangleArea (a, b, c) {\n return Math.abs(\n (a[0] * (b[1] - c[1]) +\n b[0] * (c[1] - a[1]) +\n c[0] * (a[1] - b[1])) / 2\n )\n}\n\nexport function simplify (coords, { tolerance = 0, getWeight = () => 1 } = {}) {\n if (coords.length <= 2) return coords\n\n const pts = coords.map((coord, i) => ({ coord, i, area: Infinity, removed: false, prev: null, next: null }))\n for (let i = 0; i < pts.length; i++) {\n if (i > 0) pts[i].prev = pts[i - 1]\n if (i < pts.length - 1) pts[i].next = pts[i + 1]\n }\n\n const computeArea = (node) => {\n if (!node.prev || !node.next) return Infinity\n const area = triangleArea(node.prev.coord, node.coord, node.next.coord)\n return area * getWeight(node.coord, node.i)\n }\n\n const heap = new Heap((a, b) => a.area - b.area)\n for (let i = 1; i < pts.length - 1; i++) {\n pts[i].area = computeArea(pts[i])\n pts[i]._currentArea = pts[i].area\n heap.push(pts[i])\n }\n\n let maxArea = 0\n\n while (heap.size() > 0) {\n const node = heap.pop()\n if (node.removed) continue\n if (node.area !== node._currentArea) continue\n if (node.area < maxArea) node.area = maxArea\n else maxArea = node.area\n\n if (node.area >= tolerance) break\n\n node.removed = true\n if (node.prev) node.prev.next = node.next\n if (node.next) node.next.prev = node.prev\n\n if (node.prev?.prev) {\n node.prev.area = computeArea(node.prev)\n node.prev._currentArea = node.prev.area\n heap.push(node.prev)\n }\n if (node.next?.next) {\n node.next.area = computeArea(node.next)\n node.next._currentArea = node.next.area\n heap.push(node.next)\n }\n }\n\n const result = []\n let cur = pts[0]\n while (cur) {\n if (!cur.removed) result.push(cur.coord)\n cur = cur.next\n }\n return result\n}\n","import { assert } from '@kalisio/common-core'\nimport { GEOMETRY_TYPES, isLikeGeometry } from '../is-like'\nimport { simplify } from './visvalingam-whyatt.js'\n\nexport function simplifyGeometry (geometry, options) {\n assert.all([\n { value: geometry, validator: isLikeGeometry, message: 'geometry must be a GeoJson geometry' }\n ])\n switch (geometry.type) {\n case GEOMETRY_TYPES.LINESTRING:\n geometry.coordinates = simplify(geometry.coordinates, options)\n break\n case GEOMETRY_TYPES.POLYGON:\n case GEOMETRY_TYPES.MULTI_LINESTRING:\n geometry.coordinates = geometry.coordinates.map(ring => simplify(ring, options))\n break\n case GEOMETRY_TYPES.MULTI_POLYGON:\n geometry.coordinates = geometry.coordinates.map(poly => poly.map(ring => simplify(ring, options)))\n break\n case GEOMETRY_TYPES.GEOMETRY_COLLECTION:\n geometry.geometries.forEach(g => simplifyGeometry(g, options))\n break\n }\n return geometry\n}\n","import { getLogger } from '@logtape/logtape'\nimport { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES, isLikeGeoJson } from '../is-like'\nimport { simplifyGeometry } from './geometry.js'\n\nconst logger = getLogger(['common-ekosystem', 'simplify', 'geojson'])\n\nfunction simplifyFeature (feature, options) {\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (feature.geometry) simplifyGeometry(feature.geometry, options)\n } else if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n for (const feat of feature.features) simplifyFeature(feat, options)\n } else {\n logger.warn('Unknown feature type \"{type}\", skipping.', { type: feature.type })\n }\n return feature\n}\n\nexport function simplifyGeoJson (geoJson, options) {\n assert.all([\n { value: geoJson, validator: isLikeGeoJson, message: 'geoJson must be a GeoJson object' }\n ])\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) return simplifyGeometry(geoJson, options)\n return simplifyFeature(geoJson, options)\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { COORDINATE_TRUNCATION_FACTORS } from '../../foundation'\nimport { isLikeBBox } from '../is-like'\n\nexport function truncateBBox (bbox, precision = 7) {\n assert.all([\n { value: bbox, validator: isLikeBBox, message: 'bbox must be bounding box' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n for (let i = 0; i < bbox.length; i++) {\n bbox[i] = Math.round(bbox[i] * factor) / factor\n }\n return bbox\n}\n","import truncate from '@turf/truncate'\nimport { assert, is } from '@kalisio/common-core'\nimport { isLikeGeometry } from '../is-like'\nimport { truncateBBox } from './bbox.js'\n\nexport function truncateGeometry (geometry, precision = 7) {\n assert.all([\n { value: geometry, validator: isLikeGeometry, message: 'geometry must be a GeoJson geometry' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const result = truncate(geometry, { precision, mutate: true })\n if (result.bbox) truncateBBox(result.bbox, precision)\n return result\n}\n","import { getLogger } from '@logtape/logtape'\nimport { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES, isLikeGeoJson } from '../is-like'\nimport { truncateBBox } from './bbox.js'\nimport { truncateGeometry } from './geometry.js'\n\nconst logger = getLogger(['common-ekosystem', 'truncate', 'geojson'])\n\nfunction truncateFeature (feature, precision) {\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (feature.geometry) truncateGeometry(feature.geometry, precision)\n } else if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n for (const feat of feature.features) truncateFeature(feat, precision)\n } else {\n logger.warn('Unknown feature type \"{type}\", skipping.', { type: feature.type })\n }\n if (feature.bbox) truncateBBox(feature.bbox, precision)\n return feature\n}\n\nexport function truncateGeoJson (geoJson, precision = 7) {\n assert.all([\n { value: geoJson, validator: isLikeGeoJson, message: 'geoJson must be a valid GeoJson' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) return truncateGeometry(geoJson, precision)\n return truncateFeature(geoJson, precision)\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { COORDINATE_TRUNCATION_FACTORS } from '../../foundation'\nimport { isLikePosition } from '../is-like'\n\nexport function truncatePosition (position, precision = 7) {\n assert.all([\n { value: position, validator: isLikePosition, message: 'position must be a position' },\n { value: precision, validator: (v) => is.inRange(v, 0, 8), message: 'precision must be in range [0, 8]' }\n ])\n const factor = COORDINATE_TRUNCATION_FACTORS[precision]\n for (let i = 0; i < position.length; i++) {\n position[i] = Math.round(position[i] * factor) / factor\n }\n return position\n}\n","import { is } from '@kalisio/common-core'\nimport { getCoordinatePrecision } from '../../foundation'\n\nexport function validatePosition (coordinates) {\n if (!is.arrayOfLengthBetween(coordinates, 2, 3)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: must be an array of 2 or 3 coordinates' }],\n warnings: []\n }\n }\n if (!is.number(coordinates[0]) || !is.number(coordinates[1])) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: longitude and latitude must be numbers' }],\n warnings: []\n }\n }\n if (!is.inRange(coordinates[0], -180, 180)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: longitude must be in the range -180 to 180' }],\n warnings: []\n }\n }\n if (!is.inRange(coordinates[1], -90, 90)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: latitude must be in the range -90 to 90' }],\n warnings: []\n }\n }\n if (coordinates.length === 3 && !is.number(coordinates[2])) {\n return {\n valid: false,\n errors: [{ message: 'Invalid coordinates: altitude must be a number' }],\n warnings: []\n }\n }\n const response = { valid: true, errors: [], warnings: [] }\n const lonPrecision = getCoordinatePrecision(coordinates[0])\n if (lonPrecision > 6) {\n response.warnings.push({ message: `longitude precision is high (${lonPrecision} decimals, max recommended: 6)` })\n }\n const latPrecision = getCoordinatePrecision(coordinates[1])\n if (latPrecision > 6) {\n response.warnings.push({ message: `latitude precision is high (${latPrecision} decimals, max recommended: 6)` })\n }\n return response\n}\n","import { is } from '@kalisio/common-core'\nimport { validatePosition } from './position.js'\n\nexport function validateBBox (bbox) {\n // Must be array of 4 (2D) or 6 (3D) numbers\n if (!is.arrayOfLength(bbox, 4) && !is.arrayOfLength(bbox, 6)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid bbox: must be an array of 4 (2D) or 6 (3D) numbers' }],\n warnings: []\n }\n }\n const is2D = bbox.length === 4\n const min = is2D ? [bbox[0], bbox[1]] : [bbox[0], bbox[1], bbox[2]]\n const max = is2D ? [bbox[2], bbox[3]] : [bbox[3], bbox[4], bbox[5]]\n const minResult = validatePosition(min)\n if (!minResult.valid) {\n return {\n valid: false,\n errors: minResult.errors.map(e => ({ ...e, message: `Invalid bbox south-west: ${e.message}` })),\n warnings: []\n }\n }\n const maxResult = validatePosition(max)\n if (!maxResult.valid) {\n return {\n valid: false,\n errors: maxResult.errors.map(e => ({ ...e, message: `Invalid bbox north-east: ${e.message}` })),\n warnings: []\n }\n }\n const [west, south] = min\n const [east, north] = max\n if (south > north) {\n return {\n valid: false,\n errors: [{ message: `Invalid bbox: south (${south}) must be <= north (${north})` }],\n warnings: []\n }\n }\n if (!is2D) {\n const minAlt = bbox[2]\n const maxAlt = bbox[5]\n if (minAlt > maxAlt) {\n return {\n valid: false,\n errors: [{ message: `Invalid bbox: min altitude (${minAlt}) must be <= max altitude (${maxAlt})` }],\n warnings: []\n }\n }\n }\n const response = { valid: true, errors: [], warnings: [] }\n if (west > east) {\n response.warnings.push({ message: `bbox crosses the antimeridian (west: ${west} > east: ${east})` })\n }\n // Retrieve warnings from both points\n response.warnings.push(...minResult.warnings.map(w => ({ ...w, message: `south-west: ${w.message}` })))\n response.warnings.push(...maxResult.warnings.map(w => ({ ...w, message: `north-east: ${w.message}` })))\n return response\n}\n","import { is } from '@kalisio/common-core'\nimport { CRS_TYPES } from '../is-like'\n\nexport function validateCRS (crs) {\n if (!is.plainObject(crs)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: must be an object' }],\n warnings: []\n }\n }\n switch (crs.type) {\n case CRS_TYPES.NAME: {\n if (!is.nonEmptyString(crs.properties?.name)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: linked crs must have a non-empty properties.name string' }],\n warnings: []\n }\n }\n return { valid: true, errors: [], warnings: [] }\n }\n case CRS_TYPES.LINK: {\n if (!is.nonEmptyString(crs.properties?.href)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid crs: linked crs must have a non-empty properties.href string' }],\n warnings: []\n }\n }\n return { valid: true, errors: [], warnings: [] }\n }\n default:\n return {\n valid: false,\n errors: [{ message: `Invalid crs: unknown type: ${crs.type}` }],\n warnings: []\n }\n }\n}\n","import { is } from '@kalisio/common-core'\nimport { validateBBox } from './bbox.js'\nimport { validateCRS } from './crs.js'\n\nexport function emptyStatistics () {\n return { Feature: 0, FeatureCollection: 0, geometries: {} }\n}\n\nfunction mergeStatistics (...results) {\n const statistics = emptyStatistics()\n for (const result of results) {\n const s = result.statistics\n if (!s) continue\n statistics.Feature += s.Feature ?? 0\n statistics.FeatureCollection += s.FeatureCollection ?? 0\n for (const [type, count] of Object.entries(s.geometries ?? {})) {\n statistics.geometries[type] = (statistics.geometries[type] ?? 0) + count\n }\n }\n return statistics\n}\n\nexport function validateArray (items, validator, path = '') {\n const response = {\n valid: true,\n errors: [],\n warnings: [],\n statistics: emptyStatistics()\n }\n for (let i = 0; i < items.length; i++) {\n const itemPath = `${path}/${i}`\n const result = validator(items[i], itemPath, i)\n\n // Merge statistics before the valid/invalid branch, so invalid items are\n // still counted and the continue below cannot skip the merge.\n if (result.statistics) {\n response.statistics = mergeStatistics(response, result)\n }\n\n if (!result.valid) {\n response.valid = false\n response.errors = response.errors.concat(result.errors.map(e => ({ ...e, path: e.path || itemPath, index: i })))\n continue\n }\n if (!is.empty(result.warnings)) {\n response.warnings = response.warnings.concat(result.warnings.map(w => ({ ...w, path: w.path || itemPath, index: i })))\n }\n }\n return response\n}\n\nexport function validateOptionalCRS (obj, result) {\n if (!is.defined(obj.crs)) return result\n const crsResult = validateCRS(obj.crs)\n if (!crsResult.valid) {\n result.valid = false\n result.errors.push(...crsResult.errors.map(e => ({ ...e, path: '/crs' })))\n }\n result.warnings.push(...crsResult.warnings.map(w => ({ ...w, path: '/crs' })))\n return result\n}\n\nexport function validateOptionalBBox (obj, result, path = '') {\n if (!is.defined(obj.bbox)) return result\n const bboxResult = validateBBox(obj.bbox)\n if (!bboxResult.valid) {\n result.valid = false\n result.errors.push(...bboxResult.errors.map(e => ({ ...e, path: `${path}/bbox` })))\n }\n result.warnings.push(...bboxResult.warnings.map(w => ({ ...w, path: `${path}/bbox` })))\n return result\n}\n","import booleanClockwise from '@turf/boolean-clockwise'\nimport kinks from '@turf/kinks'\nimport { is } from '@kalisio/common-core'\nimport { GEOMETRY_TYPES } from '../is-like/index.js'\nimport { validatePosition } from './position.js'\nimport { validateOptionalBBox, validateArray } from './utils.js'\n\nfunction validateCoordinatesArray (coordinates, minimumLength = 0, path = '') {\n if (!is.arrayOfLengthAtLeast(coordinates, minimumLength)) {\n return {\n valid: false,\n errors: [{ message: `Invalid coordinates: must have at least ${minimumLength} positions`, path }],\n warnings: []\n }\n }\n return validateArray(coordinates, validatePosition, path)\n}\n\nfunction validateLineStringCoordinates (coordinates, path = '') {\n const result = validateCoordinatesArray(coordinates, 2, path)\n if (!result.valid) return result\n // Check for antimeridian crossings\n for (let i = 0; i < coordinates.length - 1; i++) {\n const lon1 = coordinates[i][0]\n const lon2 = coordinates[i + 1][0]\n if (Math.abs(lon2 - lon1) > 180) {\n result.warnings.push({\n message: `LineString crosses the antimeridian between positions ${i} and ${i + 1}, consider using MultiLineString`,\n path: `${path}/${i}`\n })\n }\n }\n return result\n}\n\nfunction validateMultiLineStringCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid MultiLineString: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, validateLineStringCoordinates, path)\n}\n\nfunction validateLinearRing (coordinates, expectedWindingOrder, path = '') {\n const result = validateCoordinatesArray(coordinates, 4, path)\n if (!result.valid) return result\n // check ring is closed\n const first = coordinates[0]\n const last = coordinates[coordinates.length - 1]\n if (first[0] !== last[0] || first[1] !== last[1]) {\n result.valid = false\n result.errors.push({ message: 'Invalid LinearRing: first and last position must be identical', path })\n return result\n }\n // check winding order\n const isClockwise = booleanClockwise(coordinates)\n const actualWindingOrder = isClockwise ? 'clockwise' : 'counter-clockwise'\n if (actualWindingOrder !== expectedWindingOrder) {\n result.warnings.push({ message: `Ring must be ${expectedWindingOrder} but is ${actualWindingOrder}`, path })\n }\n // check self-intersection\n const intersections = kinks({ type: 'Polygon', coordinates: [coordinates] })\n if (intersections.features.length > 0) {\n result.valid = false\n result.errors.push({ message: `Invalid LinearRing: ${intersections.features.length} self-intersection(s) detected`, path })\n }\n return result\n}\n\nfunction validatePolygonCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid Polygon: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, (ring, p, i) => validateLinearRing(ring, i === 0 ? 'counter-clockwise' : 'clockwise', p), path)\n}\n\nfunction validateMultiPolygonCoordinates (coordinates, path = '') {\n if (!is.nonEmptyArray(coordinates)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid MultiPolygon: coordinates must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(coordinates, (c, p) => validatePolygonCoordinates(c, p), path)\n}\n\nfunction validateGeometryCollectionGeometries (geometries, path = '') {\n if (!is.nonEmptyArray(geometries)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid geometries: geometries must be a non empty array', path }],\n warnings: []\n }\n }\n return validateArray(geometries, (g, p) => validateGeometry(g, p), path)\n}\n\nexport function validateGeometry (geometry, path = '') {\n if (!is.nonEmptyObject(geometry)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid geometry: geometry must be a non empty object', path }],\n warnings: []\n }\n }\n const coordsPath = `${path}/coordinates`\n let result\n switch (geometry.type) {\n case GEOMETRY_TYPES.POINT: {\n const positionResult = validatePosition(geometry.coordinates, coordsPath)\n result = {\n valid: positionResult.valid,\n errors: positionResult.errors.map(e => ({ ...e, path: coordsPath })),\n warnings: positionResult.warnings.map(w => ({ ...w, path: coordsPath }))\n }\n break\n }\n case GEOMETRY_TYPES.MULTI_POINT: {\n result = validateCoordinatesArray(geometry.coordinates, 0, coordsPath)\n break\n }\n case GEOMETRY_TYPES.LINESTRING: {\n result = validateLineStringCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.MULTI_LINESTRING: {\n result = validateMultiLineStringCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.POLYGON: {\n result = validatePolygonCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.MULTI_POLYGON: {\n result = validateMultiPolygonCoordinates(geometry.coordinates, coordsPath)\n break\n }\n case GEOMETRY_TYPES.GEOMETRY_COLLECTION: {\n result = validateGeometryCollectionGeometries(geometry.geometries, `${path}/geometries`)\n break\n }\n default:\n return {\n valid: false,\n errors: [{ message: `Invalid geometry type: ${geometry.type}`, path }],\n warnings: []\n }\n }\n result = validateOptionalBBox(geometry, result, path)\n // Count this geometry by its own type. A GeometryCollection counts as one\n // and its members are NOT decomposed, so we overwrite any statistics that\n // bubbled up from the members.\n result.statistics = { geometries: { [geometry.type]: 1 } }\n return result\n}\n","import { assert, is } from '@kalisio/common-core'\nimport { FEATURE_TYPES, GEOMETRY_TYPES } from '../is-like/index.js'\nimport { emptyStatistics, validateArray, validateOptionalBBox, validateOptionalCRS } from './utils.js'\nimport { validateGeometry } from './geometry.js'\n\nfunction validateFeature (feature, path = '') {\n if (!is.nonEmptyObject(feature)) {\n return {\n valid: false,\n errors: [{ message: 'Invalid feature: must be a non empty object', path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n }\n if (feature.type === FEATURE_TYPES.FEATURE) {\n if (is.nonEmptyObject(feature.geometry)) {\n const result = validateGeometry(feature.geometry, `${path}/geometry`)\n const bboxResult = validateOptionalBBox(feature, result, path)\n return {\n ...bboxResult,\n statistics: {\n Feature: 1,\n FeatureCollection: 0,\n // Geometry counting is owned by validateGeometry.\n geometries: { ...result.statistics.geometries }\n }\n }\n }\n return {\n valid: true,\n errors: [],\n warnings: [{ message: 'Feature has no geometry', path }],\n statistics: { Feature: 1, FeatureCollection: 0, geometries: {} }\n }\n }\n if (feature.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n if (is.nonEmptyArray(feature.features)) {\n const result = validateArray(feature.features, validateFeature, `${path}/features`)\n const bboxResult = validateOptionalBBox(feature, result, path)\n return {\n ...bboxResult,\n statistics: { ...result.statistics, FeatureCollection: result.statistics.FeatureCollection + 1 }\n }\n }\n return {\n valid: false,\n errors: [{ message: 'Invalid FeatureCollection: features must be a non empty array', path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n }\n return {\n valid: false,\n errors: [{ message: `Invalid feature: unknown type: ${feature.type}`, path }],\n warnings: [],\n statistics: emptyStatistics()\n }\n}\n\nexport function validateGeoJson (geoJson) {\n assert.that(geoJson, is.nonEmptyObject, 'geojson must be a non empty object')\n if (is.oneOf(geoJson.type, Object.values(GEOMETRY_TYPES))) {\n const result = validateGeometry(geoJson, '')\n const withBBox = validateOptionalBBox(geoJson, result, '')\n const withCRS = validateOptionalCRS(geoJson, withBBox)\n return {\n ...withCRS,\n // Geometry counting is owned by validateGeometry.\n statistics: { Feature: 0, FeatureCollection: 0, geometries: { ...result.statistics.geometries } }\n }\n }\n if (geoJson.type === FEATURE_TYPES.FEATURE || geoJson.type === FEATURE_TYPES.FEATURE_COLLECTION) {\n const result = validateFeature(geoJson, '')\n return validateOptionalCRS(geoJson, result)\n }\n return {\n valid: false,\n errors: [{ message: 'Invalid GeoJson: type must be either a Geometry, a Feature or a FeatureCollection', path: '' }],\n warnings: [],\n statistics: emptyStatistics()\n }\n}\n"],"names":["AXES","isAxis","axis","assert","is","isLatitude","isLongitude","isAltitude","LOCALE_SCHEMA","LOCALES","en","fr","CURRENT_LOCALE","FALLBACK_LOCALE","listLocales","registerLocale","code","content","v","has","conform","setLocale","getLocale","getLocaleByCode","getActiveLocales","collectSymbols","keys","symbols","DIRECTIONS","key","getLatitudeSymbols","getLongitudeSymbols","getAllDirectionSymbols","getAll","isDirectionOf","type","dir","value","label","symbol","getDirections","directions","getNorth","getSouth","getEast","getWest","isDirection","isNorth","isSouth","isEast","isWest","getDirectionAxis","SCHEMA","optional","REGEX_SIGNED","dirRegex","DD","dd","_degrees","_direction","pattern","match","decimalPlaces","str","DDM","ddm","_minutes","latRegex","lonRegex","DDMAero","isLon","deg","min","DMS","dms","_seconds","decimalToDDM","degrees","minutes","decimalToDMS","minutesDecimal","seconds","converter","direction","COORDINATE_FORMATS","COORDINATE_MODELS","COORDINATE_TRUNCATION_FACTORS","_","i","guessCoordinateAxis","coord","getCoordinatePrecision","base","exp","decimalsInBase","truncateCoordinate","precision","factor","normalizeCoordinate","lon","convertCoordinate","from","to","parseCoordinate","format","parsePosition","parts","first","second","firstDD","secondDD","firstAxis","secondAxis","signedDegrees","isLikeBBox","object","CRS_TYPES","isLikeCRS","GEOMETRY_TYPES","isLikeGeometry","FEATURE_TYPES","isLikeFeature","isLikeFeatureCollection","isLikeGeoJson","isLikePosition","triangleArea","a","b","c","simplify","coords","tolerance","getWeight","pts","computeArea","node","heap","Heap","maxArea","result","cur","simplifyGeometry","geometry","options","ring","poly","g","logger","getLogger","simplifyFeature","feature","feat","simplifyGeoJson","geoJson","truncateBBox","bbox","truncateGeometry","truncate","truncateFeature","truncateGeoJson","truncatePosition","position","validatePosition","coordinates","response","lonPrecision","latPrecision","validateBBox","is2D","max","minResult","e","maxResult","west","south","east","north","minAlt","maxAlt","w","validateCRS","crs","emptyStatistics","mergeStatistics","results","statistics","s","count","validateArray","items","validator","path","itemPath","validateOptionalCRS","obj","crsResult","validateOptionalBBox","bboxResult","validateCoordinatesArray","minimumLength","validateLineStringCoordinates","lon1","lon2","validateMultiLineStringCoordinates","validateLinearRing","expectedWindingOrder","last","actualWindingOrder","booleanClockwise","intersections","kinks","validatePolygonCoordinates","p","validateMultiPolygonCoordinates","validateGeometryCollectionGeometries","geometries","validateGeometry","coordsPath","positionResult","validateFeature","validateGeoJson","withBBox"],"mappings":"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"}
|