Improve display of boundaries like cities, states, etc.
This commit is contained in:
@@ -165,12 +165,35 @@ out center;
|
||||
normalizeOsmApiData(elements, targetId, targetType) {
|
||||
if (!elements || elements.length === 0) return null;
|
||||
|
||||
const mainElement = elements.find(
|
||||
let mainElement = elements.find(
|
||||
(el) => String(el.id) === String(targetId) && el.type === targetType
|
||||
);
|
||||
|
||||
if (!mainElement) return null;
|
||||
|
||||
// If it's a boundary relation, try to find the label or admin_centre node
|
||||
// and use that as the main element (better coordinates and tags).
|
||||
if (targetType === 'relation' && mainElement.members) {
|
||||
const labelMember = mainElement.members.find(
|
||||
(m) => m.role === 'label' && m.type === 'node'
|
||||
);
|
||||
const adminCentreMember = mainElement.members.find(
|
||||
(m) => m.role === 'admin_centre' && m.type === 'node'
|
||||
);
|
||||
|
||||
const targetMember = labelMember || adminCentreMember;
|
||||
|
||||
if (targetMember) {
|
||||
const targetNode = elements.find(
|
||||
(el) =>
|
||||
String(el.id) === String(targetMember.ref) && el.type === 'node'
|
||||
);
|
||||
if (targetNode) {
|
||||
mainElement = targetNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let lat = mainElement.lat;
|
||||
let lon = mainElement.lon;
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ module('Unit | Service | osm', function (hooks) {
|
||||
assert.strictEqual(result.osmType, 'way');
|
||||
});
|
||||
|
||||
test('normalizeOsmApiData calculates centroid for relations with member nodes', function (assert) {
|
||||
test('normalizeOsmApiData prioritizes label node for relations', function (assert) {
|
||||
let service = this.owner.lookup('service:osm');
|
||||
const elements = [
|
||||
{
|
||||
@@ -64,17 +64,38 @@ module('Unit | Service | osm', function (hooks) {
|
||||
],
|
||||
tags: { name: 'Test Relation' },
|
||||
},
|
||||
{ id: 1, type: 'node', lat: 10, lon: 10 },
|
||||
{ id: 2, type: 'node', lat: 30, lon: 30 },
|
||||
{ id: 1, type: 'node', lat: 10, lon: 10, tags: { name: 'Admin Centre' } },
|
||||
{ id: 2, type: 'node', lat: 30, lon: 30, tags: { name: 'Label Node' } },
|
||||
];
|
||||
|
||||
const result = service.normalizeOsmApiData(elements, 789, 'relation');
|
||||
|
||||
assert.strictEqual(result.title, 'Test Relation');
|
||||
assert.strictEqual(result.lat, 20); // (10+30)/2
|
||||
assert.strictEqual(result.lon, 20); // (10+30)/2
|
||||
assert.strictEqual(result.osmId, '789');
|
||||
assert.strictEqual(result.osmType, 'relation');
|
||||
assert.strictEqual(result.title, 'Label Node');
|
||||
assert.strictEqual(result.lat, 30);
|
||||
assert.strictEqual(result.lon, 30);
|
||||
assert.strictEqual(result.osmId, '2');
|
||||
assert.strictEqual(result.osmType, 'node');
|
||||
});
|
||||
|
||||
test('normalizeOsmApiData falls back to admin_centre node for relations', function (assert) {
|
||||
let service = this.owner.lookup('service:osm');
|
||||
const elements = [
|
||||
{
|
||||
id: 789,
|
||||
type: 'relation',
|
||||
members: [{ type: 'node', ref: 1, role: 'admin_centre' }],
|
||||
tags: { name: 'Test Relation' },
|
||||
},
|
||||
{ id: 1, type: 'node', lat: 10, lon: 10, tags: { name: 'Admin Centre' } },
|
||||
];
|
||||
|
||||
const result = service.normalizeOsmApiData(elements, 789, 'relation');
|
||||
|
||||
assert.strictEqual(result.title, 'Admin Centre');
|
||||
assert.strictEqual(result.lat, 10);
|
||||
assert.strictEqual(result.lon, 10);
|
||||
assert.strictEqual(result.osmId, '1');
|
||||
assert.strictEqual(result.osmType, 'node');
|
||||
});
|
||||
|
||||
test('normalizeOsmApiData calculates centroid for relations with member ways', function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user