Improve Map view lat/lon field autodetection

Prioritize field names that are more likely to be actual latitude/longitude
fields instead of randomly selecting the first numeric field containing
"lat" or "lon" in its name.
This commit is contained in:
David Pivoňka
2025-12-08 14:42:56 +01:00
parent df226fea22
commit 408496eb7c

View File

@@ -1,4 +1,44 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const LAT_PRIORITY_PATTERNS = [
/^lat$/i,
/^latitude$/i,
/latitude$/i,
/lat$/i,
/latitude/i,
/lat/i,
];
const LON_PRIORITY_PATTERNS = [
/^lon$/i,
/^lng$/i,
/^longitude$/i,
/longitude$/i,
/lon$/i,
/lng$/i,
/longitude/i,
/lon|lng/i,
];
function getFieldName(fieldPath) {
return fieldPath.split('.').pop() || fieldPath;
}
function getFieldPriority(fieldPath, patterns) {
const name = getFieldName(fieldPath);
for (let i = 0; i < patterns.length; i++) {
if (patterns[i].test(name)) return i;
}
return patterns.length;
}
function sortByPriorityThenLength(paths, patterns) {
return paths.sort((a, b) => {
const priorityDiff = getFieldPriority(a, patterns) - getFieldPriority(b, patterns);
if (priorityDiff !== 0) return priorityDiff;
return getFieldName(a).length - getFieldName(b).length;
});
}
function findLatLonPaths(obj, attrTest, res = [], prefix = '') { function findLatLonPaths(obj, attrTest, res = [], prefix = '') {
for (const key of Object.keys(obj)) { for (const key of Object.keys(obj)) {
if (attrTest(key, obj[key])) { if (attrTest(key, obj[key])) {
@@ -10,11 +50,15 @@
} }
return res; return res;
} }
export function findLatPaths(obj) { export function findLatPaths(obj) {
return findLatLonPaths(obj, x => x.toLowerCase()?.includes('lat')); const paths = findLatLonPaths(obj, x => x.toLowerCase()?.includes('lat'));
return sortByPriorityThenLength(paths, LAT_PRIORITY_PATTERNS);
} }
export function findLonPaths(obj) { export function findLonPaths(obj) {
return findLatLonPaths(obj, x => x.toLowerCase()?.includes('lon') || x.toLowerCase()?.includes('lng')); const paths = findLatLonPaths(obj, x => x.toLowerCase()?.includes('lon') || x.toLowerCase()?.includes('lng'));
return sortByPriorityThenLength(paths, LON_PRIORITY_PATTERNS);
} }
export function findAllObjectPaths(obj) { export function findAllObjectPaths(obj) {
return findLatLonPaths(obj, (_k, v) => v != null && !_.isNaN(Number(v))); return findLatLonPaths(obj, (_k, v) => v != null && !_.isNaN(Number(v)));