Skip to content

feat: implement est_width parsing and sidebar display#289

Draft
Momototoro wants to merge 3 commits into
FixMyBerlin:developfrom
Momototoro:dev-est_width
Draft

feat: implement est_width parsing and sidebar display#289
Momototoro wants to merge 3 commits into
FixMyBerlin:developfrom
Momototoro:dev-est_width

Conversation

@Momototoro

@Momototoro Momototoro commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

So hier jetzt das Erste:
https://github.com/FixMyBerlin/private-issues/issues/280
Ist hauptsaechlich gevibecoded also ich verstehe auch nicht alles weil ich mich auch nicht tief genug in Tilda eingearbeitet habe.
Habe aber den Implementation plan immer schoen durch einen Grill Prozess durch geschickt.

PR Review: dev-est_width

Branch Summary

  • Base Branch: develop
  • Core Changes: Implements robust parsing of street widths from OSM (handling units like cm and m), falls back to est_width when the default width tag is missing, logs parsing errors to a dedicated database table, and displays the width's confidence and source in the sidebar inspector and export files.

Changed Files (19 total)

File Status Description
parse_width.lua New Pure utility to parse width strings (e.g. converting 250 cm -> 2.5 m) and normalizing decimals.
width_errors.lua New Logic and table definition (width_errors) to log unparsable width tags.
RoadClassification.lua Modified Integrates parser fallback from width -> est_width, setting width_confidence and width_source.
roads_bikelanes.lua Modified Adds width_confidence and width_source columns to roads/roadsPathClasses tables.
ExcludeByWidth.lua Modified Migrates to use the new parse_width utility.
RoadWidth.lua Modified Refactored fallback width calculations to use the new parser.
TagsTableRowCompositWidth.tsx Modified Updates the width row to render the source and confidence inline inside parentheses.
translationsWdith.const.ts Modified Adds translation keys for width_confidence (Geschätzt, Direkt gemessen) and common sources.
ConditionalFormattedValue.tsx Modified Configures source-independent translations for width_confidence and width_source.
export.$regionSlug.$tableName.ts Modified Dynamically queries and includes width_confidence and width_source columns in exports.
ParseWidth.test.lua New Lua unit tests for the width parsing utility.
RoadClassification.test.lua New Lua unit tests validating fallback logic and confidence assignment.
Various .gen files Modified Rebuild of auto-generated topic docs and translation mappings.

Implementation Details & Code Highlights

1. Robust Unit Parsing (parse_width.lua)

We normalize comma decimals and convert non-meter units like cm or km to meter floats:

local val, unit = osm2pgsql.split_unit(clean_value, 'm')
if val then
  if unit == 'cm' then
    return val / 100
  elseif unit == 'm' then
    return val
  elseif unit == 'km' then
    return val * 1000
  end
end

2. OSM Metadata Fallback (RoadClassification.lua)

We fallback to est_width if width is empty/unparsable, and assign high vs low confidence categories:

if object_tags.width then
  local parsed = parse_width(object_tags.width, object, 'width')
  if parsed then
    width = parsed
    width_confidence = "high"
  end
end
if not width and object_tags.est_width then
  local parsed = parse_width(object_tags.est_width, object, 'est_width')
  if parsed then
    width = parsed
    width_confidence = "low"
  end
end
result_tags.width_confidence = width_confidence
result_tags.width_source = SANITIZE_TAGS.safe_string(object_tags['source:width'])

3. Database Schema Migration (roads_bikelanes.lua)

The parsed attributes are saved into dedicated columns on the roads and roadsPathClasses tables:

local roadsTable = osm2pgsql.define_table({
  name = 'roads',
  columns = {
    -- ...
    { column = 'width_confidence', type = 'text' },
    { column = 'width_source', type = 'text' },
  }
})

4. Inline Inspector Display (TagsTableRowCompositWidth.tsx)

In the sidebar inspector, we display the source and the confidence value inline in parentheses inside a collapsible disclosure:

{properties[widthConfidence] && (
  <>
    {' ('}
    <ConditionalFormattedValue
      sourceId={sourceId}
      tagKey={widthConfidence}
      tagValue={properties[widthConfidence]}
    />
    {')'}
  </>
)}

Output Example: Quelle: Orthofoto 2024 (Direkt gemessen)

@Momototoro Momototoro requested a review from tordans June 8, 2026 09:32

@tordans tordans left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase against develop.

) : (
<code>{secureWidthSource}</code>
)}
{properties[widthConfidence] && (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert

'traffic_sign:backward',
'confidence', // true key is `maxspeed_confidence`, `surface_confidence`, … but we overwrite that when passing props
'width_source',
'width_confidence',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase => Docs

Comment on lines +54 to +55
{ column = 'width_confidence', type = 'text' },
{ column = 'width_source', type = 'text' },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regel: Unsere Tabellen haben immer den gleichen Shape id, tags, meta, geom, minzoom

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Tags rein

FROM information_schema.columns
WHERE table_name = '${tableName}'
AND column_name IN ('osm_id', 'osm_type')
AND column_name IN ('osm_id', 'osm_type', 'width_confidence', 'width_source')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Weg, siehe unten

@@ -0,0 +1,87 @@
describe("parse_width", function()
require('init')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

weg nach rebase

require('init')
require('osm2pgsql')

local logged_errors = {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kann jetzt raus

Comment thread processing/topics/helper/osm2pgsql.lua Outdated
-- return osm2pgsql.define_table(_options)
-- end

function osm2pgsql.define_table(options)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raus

@@ -0,0 +1,101 @@
describe('RoadClassification', function()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fehlt inner describe blcok weil alels ja nicht road clas.… teste sondern with

local width = nil
local width_confidence = nil

if object_tags.width then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor to local function surface_direct(tags)

Nach Rebase:

    width = parse_length(object_tags.width),
    width_source = SANITIZE_TAGS.safe_string(object_tags['source:width']),
    width_effective = parse_length(object_tags['width:effective']),

neues muster:

local FOO = derive_witdth(tags)

local result_tags = {
    width = foo.width
    width_source = FOO.source
    width_confience = foo.conficnde
}
  local surface_tags_result = SURFACE_TAGS.surface_tags_with_parent(object.tags, object._parent_tags)

…
    surface = surface_tags_result.value,
    surface_confidence = surface_tags_result.confidence,
    surface_source = surface_tags_result.source,

Comment thread processing/run-tests.sh
# Make sure we have the latest lua path at hand.
# Szenario: We just added a lua helper in a new folder but did not run the full processing, yet
bun run ./processing/run-tests-update-lua-package-paths.ts
NODE_PATH=./app/node_modules bun run ./processing/run-tests-update-lua-package-paths.ts

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

raus, bun verwendne
brew install bun

@tordans tordans marked this pull request as draft June 23, 2026 09:02
momo and others added 3 commits July 5, 2026 17:38
Co-authored-by: Cursor <cursoragent@cursor.com>
bunx tsc was resolving to a global TypeScript 5 install on WSL instead
of the project's TypeScript 6 package, which only exposes the tsc6 bin.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants