Repository navigation
feat(web-standalone): antenna height from the tallest building within 50 m of a repeater - #128
Merged
Merged
Conversation
The line-of-sight check put every observer's antenna at 12 m (#74). Sampled against 3D BAG, 32 of 60 fixture observers stand within 12 m of a building, roof median 10.2 m above ground, p90 25 m; the constant is right for about half of them and low for a quarter. bag3d.py (stdlib, tested): WGS84 to RD New and back (within 1 m on the Westertoren and the Martinitoren), the buildings in a 3D BAG CityJSON response with their footprints in metres via the response transform, point-in-footprint, and roof_for_point(). server.py serves /proxy/3dbag/roof?lat=&lon=, one 30 m bbox query per node cached for a day, no roof outside the Netherlands, 400 on bad input. On activation the page looks up the same nodes the link budget covers and sets roofHeightM where the node stands inside a footprint; terrainLosFactor() starts the beam at roof plus a 3 m mast for those and at 12 m for the rest. The cluster status says how many, the observer popup shows the antenna height and its source, and a dragged node drops its roof with its radius. Dockerfile and .dockerignore ship the module; README and AGENTS name the source. The other half of #74, building geometry in the line-of-sight profile, is measured and not built: dense sampling calls 6 of 10 real receptions blocked or partial, so more resolution penalises the true cell under the current knife-edge model. Numbers in the issue. Verified: pytest 11 passed; the live route returns 35.5 m for the fixture building, 75.9 m on the Westertoren, no roof for Paris; in the page a locked cluster of 14 nodes makes 14 lookups, 3 stand on a building, two of them active with antennas at 39 m and 13.8 m, the rest at 12 m, status "3 of 14 observers stand on a building per 3D BAG, the rest assume 12 m", no console errors. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the one underfoot Advertised positions are metres off and a mast can stand next to the building it serves, so "the footprint the point is inside" missed most of them. The roof now comes from the tallest building whose footprint comes within 50 m of the node, ties to the nearer one, and the popup says how far that roof is. bag3d.py: footprint_distance() (0 inside, else the nearest edge), tallest_near() over one or more response pages, roof_for_point() with a radius and a distance_m. server.py follows rel=next up to 4 pages of 100 features, radius 50 m. Tests for the distance, the radius cut-off and the taller building on a later page winning: 13 passed. Verified live: on the fixture deep link's region 1, 13 of 14 observers have a building within 50 m, the farthest at 47.2 m; antennas range from 10.6 m (a 7.6 m roof 23 m away) to 39 m (a 36 m roof underfoot). The Amsterdam-centre lookup takes 7.5 s for two pages the first time and 0.01 s from cache after. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #74, the antenna-height half. The other half, building geometry in the line-of-sight profile, is measured and not built; numbers in #74 (comment): dense sampling calls 6 of 10 real receptions blocked or partial, so more resolution penalises the true cell under the current knife-edge model.
The line-of-sight check put every observer's antenna at 12 m. Sampled against 3D BAG, 32 of 60 fixture observers stand within 12 m of a building, roof median 10.2 m above ground, p90 25 m; the constant is right for about half of them and low for a quarter.
Change
bag3d.py(stdlib, tested): WGS84 to RD New and back (within 1 m on the Westertoren and the Martinitoren), the buildings in a 3D BAG CityJSON response with their footprints in metres via the response transform, distance from a point to a footprint (0 inside), and the tallest building whose footprint comes within a radius, ties to the nearer one.server.py:/proxy/3dbag/roof?lat=&lon=, a 100 m box around the node, up to 4 pages of 100 features, radius 50 m, cached for a day per position; no roof outside the Netherlands; 400 on bad input.roofHeightMandroofDistanceM;terrainLosFactor()starts the beam at roof plus a 3 m mast for those and at 12 m for the rest. The cluster status says how many; the observer popup shows the antenna height, its source and the distance to that roof; a dragged node drops its roof with its radius..dockerignoreship the module; README and AGENTS name the source; changelog entry.Why 50 m and the tallest, not the footprint underfoot: advertised positions are metres off and a mast can stand next to the building it serves. At 100 m, 3 of 8 observers on the test region picked a taller building 60 to 90 m away; at 50 m they keep the one beside them.
Verified
pytest web-standalone/tests: 13 passed.lat=x.Not measurable
The effect on estimates: the accuracy harness does not run the terrain pass (#68, #72). This lands on the argument that a 25 m antenna at 25 m beats a 25 m antenna at 12 m in a diffraction profile, not on a number.
🤖 Generated with Claude Code