Skip to content

Commit 9cfc412

Browse files
fix: determine correct projection from features at getProj (#1959)
* fix: determine correct projection from features at getProj * chore: add test * fix: test * fix: another [0] * fix: recursively search for number to get reference coordinate
1 parent 7ece87c commit 9cfc412

File tree

4 files changed

+85
-6
lines changed

4 files changed

+85
-6
lines changed

elements/map/src/helpers/parse-text.js

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,42 @@ import { READ_FEATURES_OPTIONS } from "../enums";
1111
* @param {string} text
1212
* @returns {string | undefined} - Returns the projection string if determined, otherwise undefined.
1313
*/
14-
function getProj(formatReader, text) {
14+
export function getProj(formatReader, text) {
1515
const features = formatReader.readFeatures(text);
1616
const feature = features[0];
1717
const geometry = feature.getGeometry();
1818
// @ts-expect-error - Property 'getCoordinates' does not exist on type 'Geometry' but it does not showing
1919
const coordinates = geometry.getCoordinates();
2020
if (coordinates && coordinates.length > 0) {
21-
const coord = coordinates[0][0][0];
22-
if (coord >= -180 && coord <= 180) {
23-
return "EPSG:4326";
24-
} else {
25-
return "EPSG:3857";
21+
const coord = findFirstCoordinateValue(coordinates);
22+
if (typeof coord === "number") {
23+
if (coord >= -180 && coord <= 180) {
24+
return "EPSG:4326"; // WGS 84 (Lon/Lat)
25+
} else {
26+
return "EPSG:3857"; // Web Mercator (X/Y)
27+
}
2628
}
2729
}
2830

2931
return undefined;
3032
}
3133

34+
/**
35+
* Recursively finds the first numerical coordinate value in a nested array.
36+
*
37+
* @param {any} coordinates - The coordinates array returned by geometry.getCoordinates().
38+
* @returns {number | undefined} - The first numerical coordinate (longitude/x), or undefined.
39+
*/
40+
function findFirstCoordinateValue(coordinates) {
41+
if (typeof coordinates === "number") {
42+
return coordinates;
43+
}
44+
if (Array.isArray(coordinates) && coordinates.length > 0) {
45+
return findFirstCoordinateValue(coordinates[0]);
46+
}
47+
return undefined;
48+
}
49+
3250
/**
3351
* This function reads text and attempts to parse it as GeoJSON, KML, or TopoJSON.
3452
* If successful, it adds the parsed features to the map.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { getProj } from "../../../src/helpers/parse-text";
2+
import GeoJSON from "ol/format/GeoJSON";
3+
4+
const checkGetProj = () => {
5+
const geojson = JSON.stringify({
6+
type: "FeatureCollection",
7+
features: [
8+
{
9+
type: "Feature",
10+
geometry: {
11+
type: "Polygon",
12+
coordinates: [
13+
[
14+
[10, 10],
15+
[20, 10],
16+
[20, 20],
17+
[10, 20],
18+
[10, 10],
19+
],
20+
],
21+
},
22+
properties: {},
23+
},
24+
],
25+
});
26+
const proj = getProj(new GeoJSON(), geojson);
27+
expect(proj).to.be.equal("EPSG:4326");
28+
29+
const geojson2 = JSON.stringify({
30+
type: "FeatureCollection",
31+
features: [
32+
{
33+
type: "Feature",
34+
geometry: {
35+
type: "Polygon",
36+
coordinates: [
37+
[
38+
[200, 10],
39+
[210, 10],
40+
[210, 20],
41+
[200, 20],
42+
[200, 10],
43+
],
44+
],
45+
},
46+
properties: {},
47+
},
48+
],
49+
});
50+
const proj2 = getProj(new GeoJSON(), geojson2);
51+
expect(proj2).to.be.equal("EPSG:3857");
52+
};
53+
54+
export default checkGetProj;

elements/map/test/cases/projection/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export { default as changeProjection } from "./change-projection";
55
export { default as specialProjection } from "./special-projection";
66
export { default as fetchProjectionFromCode } from "./fetch-projection-from-code";
77
export { default as getWgsCoordinates } from "./get-wgs-coordinates";
8+
export { default as checkGetProj } from "./check-get-proj";

elements/map/test/viewProjection.cy.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
getWgsCoordinates,
66
initProjection,
77
specialProjection,
8+
checkGetProj,
89
} from "./cases/projection";
910

1011
/**
@@ -36,4 +37,9 @@ describe("view projections", () => {
3637
*/
3738
it("lonLatExtent delivering correct WGS coordinates", () =>
3839
getWgsCoordinates());
40+
41+
/**
42+
* Test case to check getProj projection guessing logic
43+
*/
44+
it("correctly guesses projection from coordinates", () => checkGetProj());
3945
});

0 commit comments

Comments
 (0)