Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@
"@clack/prompts": "1.7.0",
"@faker-js/faker": "^10.5.0",
"@heroicons/react": "2.2.0",
"@maplibre/maplibre-gl-style-spec": "^24.8.1",
"@placemarkio/check-geojson": "0.1.14",
"@playwright/test": "1.61.1",
"@react-email/ui": "^6.6.4",
Expand Down
57 changes: 57 additions & 0 deletions app/src/data/generated/topicDocs/byTableName.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,25 @@ const data = {
},
],
},
{
key: 'width_confidence',
type: 'string',
label: 'Konfidenz Breite',
purpose: 'qa',
values: [
{
value: 'high',
label: 'Direkt gemessen',
description: 'Wert stammt aus dem OSM-Tag `width`.',
},
{
value: 'low',
label: 'Geschätzt',
description:
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
],
},
{
key: 'oneway',
type: 'string',
Expand Down Expand Up @@ -9938,6 +9957,25 @@ const data = {
},
],
},
{
key: 'width_confidence',
type: 'string',
label: 'Konfidenz Breite',
purpose: 'qa',
values: [
{
value: 'high',
label: 'Direkt gemessen',
description: 'Wert stammt aus dem OSM-Tag `width`.',
},
{
value: 'low',
label: 'Geschätzt',
description:
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
],
},
{
key: 'oneway',
type: 'string',
Expand Down Expand Up @@ -11297,6 +11335,25 @@ const data = {
},
],
},
{
key: 'width_confidence',
type: 'string',
label: 'Konfidenz Breite',
purpose: 'qa',
values: [
{
value: 'high',
label: 'Direkt gemessen',
description: 'Wert stammt aus dem OSM-Tag `width`.',
},
{
value: 'low',
label: 'Geschätzt',
description:
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
],
},
{
key: 'surface',
type: 'string',
Expand Down
18 changes: 16 additions & 2 deletions app/src/data/generated/topicDocs/inspectorDescriptions.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const data = {
'Seitlicher Versatz der Liniengeometrie in Metern. Der Wert wird im Processing aus der halben Straßenbreite berechnet; positive Werte liegen links der Referenzlinie, negative rechts.',
},
values: {
width_confidence: {
high: 'Wert stammt aus dem OSM-Tag `width`.',
low: 'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
oneway: {
assumed_no:
'Keine explizite OSM-Angabe zur Verkehrsrichtung vorhanden. Aus Führungsform und Umfeld wird hier beide Richtungen als wahrscheinlich angenommen.',
Expand Down Expand Up @@ -108,7 +112,12 @@ const data = {
mapillary_traffic_sign:
'Mapillary-Bild-IDs für Verkehrszeichen (technisch bereinigt). Mehrere IDs sind als semikolongetrennte Liste möglich. Im Inspector wird pro ID ein Link erzeugt, z. B. `https://www.mapillary.com/app/?pKey=<ID>&focus=photo&z=15`.',
},
values: {},
values: {
width_confidence: {
high: 'Wert stammt aus dem OSM-Tag `width`.',
low: 'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
},
},
atlas_roadsPathClasses: {
keys: {
Expand All @@ -125,7 +134,12 @@ const data = {
mapillary_traffic_sign:
'Mapillary-Bild-IDs für Verkehrszeichen (technisch bereinigt). Mehrere IDs sind als semikolongetrennte Liste möglich. Im Inspector wird pro ID ein Link erzeugt, z. B. `https://www.mapillary.com/app/?pKey=<ID>&focus=photo&z=15`.',
},
values: {},
values: {
width_confidence: {
high: 'Wert stammt aus dem OSM-Tag `width`.',
low: 'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
},
},
},
atlas_trafficSigns: {
keys: {
Expand Down
21 changes: 20 additions & 1 deletion app/src/data/generated/topicDocs/inspectorTranslations.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const data = {
'atlas_barriers--railway=rail': 'Bahnstrecke',
'atlas_barriers--railway=subway': 'U-Bahn',
'atlas_barriers--railway=tram': 'Straßenbahn',
'atlas_barriers--title': 'Daten zu Linien-Barrieren',
'atlas_barriers--title': 'Daten zu Flächen-Barrieren',
'atlas_barriers--tunnel--key': 'Tunnel',
'atlas_barriers--tunnel=avalanche_protector': 'Lawinenschutzgalerie',
'atlas_barriers--tunnel=building_passage': 'Gebäudedurchfahrt',
Expand Down Expand Up @@ -462,6 +462,12 @@ const data = {
'atlas_bikelanes--traffic_sign=none': 'Unbeschildert',
'atlas_bikelanes--tunnel--key': 'Tunnel',
'atlas_bikelanes--tunnel=yes': 'Ja',
'atlas_bikelanes--width_confidence--key': 'Konfidenz Breite',
'atlas_bikelanes--width_confidence=high': 'Direkt gemessen',
'atlas_bikelanes--width_confidence=high--description': 'Wert stammt aus dem OSM-Tag `width`.',
'atlas_bikelanes--width_confidence=low': 'Geschätzt',
'atlas_bikelanes--width_confidence=low--description':
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
'atlas_bikelanes--width_effective--key': 'Effektive Breite',
'atlas_bikelanes--width_source--key': 'Quelle Breite',
'atlas_bikelanes--width_source=ALKIS': 'Aus ALKIS Daten ausgemessen',
Expand Down Expand Up @@ -1444,6 +1450,12 @@ const data = {
'atlas_roads--traffic_sign=none': 'Unbeschildert',
'atlas_roads--tunnel--key': 'Tunnel',
'atlas_roads--tunnel=yes': 'Ja',
'atlas_roads--width_confidence--key': 'Konfidenz Breite',
'atlas_roads--width_confidence=high': 'Direkt gemessen',
'atlas_roads--width_confidence=high--description': 'Wert stammt aus dem OSM-Tag `width`.',
'atlas_roads--width_confidence=low': 'Geschätzt',
'atlas_roads--width_confidence=low--description':
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
'atlas_roads--width_effective--key': 'Effektive Breite',
'atlas_roads--width_source--key': 'Quelle Breite',
'atlas_roads--width_source=ALKIS': 'Aus ALKIS Daten ausgemessen',
Expand Down Expand Up @@ -1733,6 +1745,13 @@ const data = {
'atlas_roadsPathClasses--todos--key': 'Todo-Liste',
'atlas_roadsPathClasses--traffic_sign--key': 'Beschilderung',
'atlas_roadsPathClasses--traffic_sign=none': 'Unbeschildert',
'atlas_roadsPathClasses--width_confidence--key': 'Konfidenz Breite',
'atlas_roadsPathClasses--width_confidence=high': 'Direkt gemessen',
'atlas_roadsPathClasses--width_confidence=high--description':
'Wert stammt aus dem OSM-Tag `width`.',
'atlas_roadsPathClasses--width_confidence=low': 'Geschätzt',
'atlas_roadsPathClasses--width_confidence=low--description':
'Wert stammt aus dem OSM-Tag `est_width`, weil `width` fehlt oder nicht geparst werden konnte.',
'atlas_roadsPathClasses--width_source--key': 'Quelle Breite',
'atlas_roadsPathClasses--width_source=ALKIS': 'Aus ALKIS Daten ausgemessen',
'atlas_roadsPathClasses--width_source=ARCore':
Expand Down
27 changes: 27 additions & 0 deletions app/src/data/generated/topicDocs/masterportalByTableName.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,15 @@ const data = {
ARCore: 'Mit dem Handy-Metermaß von StreetComplete gemessen',
},
},
width_confidence: {
name: 'Konfidenz Breite',
condition: 'contains',
type: 'string',
format: {
high: 'Direkt gemessen',
low: 'Geschätzt',
},
},
oneway: {
name: 'Verkehrsrichtung',
condition: 'contains',
Expand Down Expand Up @@ -3621,6 +3630,15 @@ const data = {
ARCore: 'Mit dem Handy-Metermaß von StreetComplete gemessen',
},
},
width_confidence: {
name: 'Konfidenz Breite',
condition: 'contains',
type: 'string',
format: {
high: 'Direkt gemessen',
low: 'Geschätzt',
},
},
oneway: {
name: 'Verkehrsrichtung',
condition: 'contains',
Expand Down Expand Up @@ -4241,6 +4259,15 @@ const data = {
ARCore: 'Mit dem Handy-Metermaß von StreetComplete gemessen',
},
},
width_confidence: {
name: 'Konfidenz Breite',
condition: 'contains',
type: 'string',
format: {
high: 'Direkt gemessen',
low: 'Geschätzt',
},
},
surface: {
name: 'Oberfläche',
condition: 'contains',
Expand Down
80 changes: 80 additions & 0 deletions processing/topics/helper/__tests__/derive_width.test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
describe('derive_width', function()
require('topics.helper.osm2pgsql')
local derive_width = require('topics.helper.derive_width')

describe('with width tag', function()
it('returns high confidence and keeps source:width', function()
local result = derive_width({
width = '3.5 m',
['source:width'] = 'Handy-Ausmessen',
})
assert.are.same(result, {
width = 3.5,
width_source = 'Handy-Ausmessen',
width_confidence = 'high',
})
end)

it('prefers width over est_width', function()
local result = derive_width({
width = '4 m',
est_width = '6 m',
})
assert.are.same(result, {
width = 4,
width_source = nil,
width_confidence = 'high',
})
end)
end)

describe('with est_width fallback', function()
it('returns low confidence when width is missing', function()
local result = derive_width({
est_width = '6m',
['source:width'] = 'estimation',
})
assert.are.same(result, {
width = 6,
width_source = 'estimation',
width_confidence = 'low',
})
end)

it('falls back to est_width when width is unparsable', function()
local result = derive_width({
width = 'fehlerhafter Text',
est_width = '5',
})
assert.are.same(result, {
width = 5,
width_source = nil,
width_confidence = 'low',
})
end)
end)

describe('with no usable width', function()
it('returns nils when both tags are missing', function()
local result = derive_width({})
assert.are.same(result, {
width = nil,
width_source = nil,
width_confidence = nil,
})
end)

it('returns nils when both tags are unparsable', function()
local result = derive_width({
width = 'invalid_width',
est_width = 'invalid_est_width',
['source:width'] = 'ALKIS',
})
assert.are.same(result, {
width = nil,
width_source = nil,
width_confidence = nil,
})
end)
end)
end)
46 changes: 46 additions & 0 deletions processing/topics/helper/derive_width.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
local parse_length = require('topics.helper.parse_length')
local SANITIZE_TAGS = require('topics.helper.sanitize_tags')

---@alias DeriveWidthConfidence 'high'|'low'
---@class DeriveWidthResultEmpty
---@field width nil
---@field width_source nil
---@field width_confidence nil
---@class DeriveWidthResult
---@field width number
---@field width_source string|nil
---@field width_confidence DeriveWidthConfidence
---@alias DeriveWidthResultUnion DeriveWidthResultEmpty|DeriveWidthResult

---Derive road width from OSM `width` or fallback `est_width`, plus confidence and OSM `source:width`.
---@param tags OsmTags
---@return DeriveWidthResultUnion
local function derive_width(tags)
local width_source = SANITIZE_TAGS.safe_string(tags['source:width'])

local width = parse_length(tags.width)
if width then
return {
width = width,
width_source = width_source,
width_confidence = 'high',
}
end

width = parse_length(tags.est_width)
if width then
return {
width = width,
width_source = width_source,
width_confidence = 'low',
}
end

return {
width = nil,
width_source = nil,
width_confidence = nil,
}
end

return derive_width
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local derive_traffic_signs = require('topics.helper.derive_traffic_signs')
local derive_width = require('topics.helper.derive_width')
local SANITIZE_TAGS = require('topics.helper.sanitize_tags')
local parse_length = require('topics.helper.parse_length')
local merge_table = require('topics.helper.merge_table')
Expand All @@ -11,13 +12,12 @@ local function road_classification(object_tags)
road = road_classification_road_value(object_tags),
oneway = SANITIZE_TAGS.oneway_road(object_tags),
oneway_bicycle = SANITIZE_TAGS.oneway_bicycle(object_tags['oneway:bicycle']),
width = parse_length(object_tags.width),
width_source = SANITIZE_TAGS.safe_string(object_tags['source:width']),
width_effective = parse_length(object_tags['width:effective']),
bridge = SANITIZE_TAGS.boolean_yes(object_tags.bridge),
tunnel = SANITIZE_TAGS.boolean_yes(object_tags.tunnel),
}

merge_table(result_tags, derive_width(object_tags))
merge_table(result_tags, derive_traffic_signs(object_tags))

return result_tags
Expand Down
2 changes: 2 additions & 0 deletions topic-docs/roads_bikelanes/bikelanes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ attributes:
ref: roads.width_effective
- key: width_source
ref: roads.width_source
- key: width_confidence
ref: roads.width_confidence
- key: oneway
label: Verkehrsrichtung
values:
Expand Down
Loading
Loading