diff --git a/PROJJSONBuilderBase.js b/PROJJSONBuilderBase.js index aab012e..7cfec1e 100644 --- a/PROJJSONBuilderBase.js +++ b/PROJJSONBuilderBase.js @@ -46,10 +46,11 @@ class PROJJSONBuilderBase { if (abbreviation === 'E') direction = 'east'; else if (abbreviation === 'N') direction = 'north'; else if (abbreviation === 'U') direction = 'up'; + else if (node[2]) direction = node[2]; else throw new Error(`Unknown axis abbreviation: ${abbreviation}`); } else { // Use the explicit direction provided in the AXIS node - direction = node[2] ? node[2].toLowerCase() : 'unknown'; + direction = node[2] || 'unknown'; } const orderNode = node.find((child) => Array.isArray(child) && child[0] === 'ORDER'); @@ -109,7 +110,8 @@ class PROJJSONBuilderBase { case 'BASEGEOGCRS': case 'GEOGCRS': - result.type = 'GeographicCRS'; + case 'GEODCRS': + result.type = node[0] === 'GEODCRS' ? 'GeodeticCRS' : 'GeographicCRS'; result.name = node[1]; // Handle DATUM or ENSEMBLE diff --git a/index.js b/index.js index 7bd6545..54b1ed7 100644 --- a/index.js +++ b/index.js @@ -124,7 +124,7 @@ function setPropertiesFromWkt(wkt) { } wkt.a = geogcs.DATUM.SPHEROID.a; - wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf, 10); + wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf); } if (geogcs.DATUM && geogcs.DATUM.TOWGS84) { diff --git a/test-fixtures.json b/test-fixtures.json index 8494792..dcf703b 100644 --- a/test-fixtures.json +++ b/test-fixtures.json @@ -1614,5 +1614,33 @@ "srsCode": "unknown", "name": "unknown" } +}, { + "code": {"$schema":"https://proj.org/schemas/v0.7/projjson.schema.json","type":"GeodeticCRS","name":"WGS 84","datum_ensemble":{"name":"World Geodetic System 1984 ensemble","members":[{"name":"World Geodetic System 1984 (Transit)","id":{"authority":"EPSG","code":1166}},{"name":"World Geodetic System 1984 (G730)","id":{"authority":"EPSG","code":1152}},{"name":"World Geodetic System 1984 (G873)","id":{"authority":"EPSG","code":1153}},{"name":"World Geodetic System 1984 (G1150)","id":{"authority":"EPSG","code":1154}},{"name":"World Geodetic System 1984 (G1674)","id":{"authority":"EPSG","code":1155}},{"name":"World Geodetic System 1984 (G1762)","id":{"authority":"EPSG","code":1156}},{"name":"World Geodetic System 1984 (G2139)","id":{"authority":"EPSG","code":1309}},{"name":"World Geodetic System 1984 (G2296)","id":{"authority":"EPSG","code":1383}}],"ellipsoid":{"name":"WGS 84","semi_major_axis":6378137,"inverse_flattening":298.257223563},"accuracy":"2.0","id":{"authority":"EPSG","code":6326}},"coordinate_system":{"subtype":"Cartesian","axis":[{"name":"Geocentric X","abbreviation":"X","direction":"geocentricX","unit":"metre"},{"name":"Geocentric Y","abbreviation":"Y","direction":"geocentricY","unit":"metre"},{"name":"Geocentric Z","abbreviation":"Z","direction":"geocentricZ","unit":"metre"}]},"scope":"Geodesy. Navigation and positioning using GPS satellite system.","area":"World.","bbox":{"south_latitude":-90,"west_longitude":-180,"north_latitude":90,"east_longitude":180},"id":{"authority":"EPSG","code":4978}}, + "value": { + "projName": "geocent", + "ellps": "WGS 84", + "a": 6378137, + "rf": 298.257223563, + "axis": "enu", + "units": "meter", + "to_meter": 1, + "srsCode": "WGS 84", + "name": "WGS 84", + "title": "EPSG:4978" + } +}, { + "code": "GEODCRS[\"WGS 84\",ENSEMBLE[\"World Geodetic System 1984 ensemble\",MEMBER[\"World Geodetic System 1984 (Transit)\"],MEMBER[\"World Geodetic System 1984 (G730)\"],MEMBER[\"World Geodetic System 1984 (G873)\"],MEMBER[\"World Geodetic System 1984 (G1150)\"],MEMBER[\"World Geodetic System 1984 (G1674)\"],MEMBER[\"World Geodetic System 1984 (G1762)\"],MEMBER[\"World Geodetic System 1984 (G2139)\"],MEMBER[\"World Geodetic System 1984 (G2296)\"],ELLIPSOID[\"WGS 84\",6378137,298.257223563,LENGTHUNIT[\"metre\",1]],ENSEMBLEACCURACY[2.0]],PRIMEM[\"Greenwich\",0,ANGLEUNIT[\"degree\",0.0174532925199433]],CS[Cartesian,3],AXIS[\"(X)\",geocentricX,ORDER[1],LENGTHUNIT[\"metre\",1]],AXIS[\"(Y)\",geocentricY,ORDER[2],LENGTHUNIT[\"metre\",1]],AXIS[\"(Z)\",geocentricZ,ORDER[3],LENGTHUNIT[\"metre\",1]],USAGE[SCOPE[\"Geodesy. Navigation and positioning using GPS satellite system.\"],AREA[\"World.\"],BBOX[-90,-180,90,180]],ID[\"EPSG\",4978]]", + "value": { + "projName": "geocent", + "ellps": "WGS 84", + "a": 6378137, + "rf": 298.257223563, + "axis": "enu", + "units": "meter", + "to_meter": 1, + "srsCode": "WGS 84", + "name": "WGS 84", + "title": "EPSG:4978" + } } ] diff --git a/transformPROJJSON.js b/transformPROJJSON.js index d79334d..f6a7a0d 100644 --- a/transformPROJJSON.js +++ b/transformPROJJSON.js @@ -83,6 +83,12 @@ export function transformPROJJSON(projjson, result = {}) { case 'type': if (value === 'GeographicCRS') { result.projName = 'longlat'; + } else if (value === 'GeodeticCRS') { + if (projjson.coordinate_system && projjson.coordinate_system.subtype === 'Cartesian') { + result.projName = 'geocent'; + } else { + result.projName = 'longlat'; + } } else if (value === 'ProjectedCRS' && projjson.conversion && projjson.conversion.method) { result.projName = projjson.conversion.method.name; // Retain original capitalization } @@ -111,16 +117,24 @@ export function transformPROJJSON(projjson, result = {}) { case 'coordinate_system': if (value.axis) { - result.axis = value.axis - .map((axis) => { - const direction = axis.direction; - if (direction === 'east') return 'e'; - if (direction === 'north') return 'n'; - if (direction === 'west') return 'w'; - if (direction === 'south') return 's'; - throw new Error(`Unknown axis direction: ${direction}`); - }) - .join('') + 'u'; // Combine into a single string (e.g., "enu") + const directionMap = { + 'east': 'e', + 'north': 'n', + 'west': 'w', + 'south': 's', + 'up': 'u', + 'down': 'd', + 'geocentricx': 'e', + 'geocentricy': 'n', + 'geocentricz': 'u', + }; + const mapped = value.axis.map((axis) => directionMap[axis.direction.toLowerCase()]); + if (mapped.every(Boolean)) { + result.axis = mapped.join(''); + if (result.axis.length === 2) { + result.axis += 'u'; + } + } if (value.unit) { const { units, to_meter } = processUnit(value.unit);