Repository navigation
Conversation
A new internal package that places a position in a named area drawn in a GeoJSON file: Polygon and MultiPolygon with holes, [lon, lat] order, a layer per feature, the smallest area of a layer winning where areas overlap, airport codes for observers without a position, and unique codes across layers. Stubs only; every test fails on its assertions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
ParseGeoJSON reads a FeatureCollection (Polygon and MultiPolygon, holes respected, [lon, lat] order); each feature's properties give its code, label, layer (default "region") and the airport codes of observers that report no position. New refuses a code used twice, in any layer. Locate checks each polygon's bounding box first, then the even-odd test on its outer ring and holes, and returns the smallest containing area of the layer, so nested areas resolve to the most specific. Size is the shoelace area with longitude scaled by latitude: enough to order overlaps. BenchmarkLocate (six areas of 2,000 vertices): 2.1 us/op, 0 allocs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
areasFile names a GeoJSON FeatureCollection next to config.json. Its areas join config.json's (converted from their [lat, lon] order) in one map kept on the config; a code in both, a missing file or bad JSON are refused. /api/config/areas lists file areas with their layer, and area= accepts a file area's code. Stubs only: the tests fail on their assertions. Also wires internal/areamap into the server module and the Dockerfile, and adds Map.Has to the package (red there too). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
config.json's areas are one polygon or box each, which cannot hold a
coastline, islands or a hole. areasFile names a GeoJSON FeatureCollection
beside config.json whose features become areas too: Polygon and
MultiPolygon with holes, a layer per feature, airport codes for observers
that report no position.
- LoadAreaMap builds one map from config.json's areas (layer "region",
converted from their [lat, lon] order) and the file, and keeps it on the
config. A code in both, a missing file or bad GeoJSON stops startup with
the reason, rather than running with areas silently missing.
- /api/config/areas lists file areas after config.json's, each entry now
carrying its layer ("region" for config.json areas). Additive: existing
fields unchanged.
- area= accepts a file area's code, matched by node position against its
geometry through the same cache. config.json areas keep their existing
polygon and box path unchanged.
Documented in config.example.json (areasFile + _comment_areasFile),
docs/api-spec.md, and an example file, docs/examples/areas.example.geojson,
which a test loads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
Ports the meshcore.scotmesh.net peering rules to a generic package placed by areamap areas: advert position, the sender's node record, the first relay of 2 bytes or more (a shared prefix only when every holder agrees), the zero-hop observer, otherwise unknown. Stub returns zero values so every test fails on its assertions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
Generic port of the meshcore.scotmesh.net peering rules, placed by areamap areas in one layer: - origin: advert position, else the sender's node record, else the majority first relay of 2 bytes or more (a shared prefix only when every placed holder stands in one area), else the zero-hop observer's area, else unknown - heard: one entry per receiving area with distinct observers, relayed in by its own repeater or heard straight across, the relay it came from, and an optional home-area boundary relay (gate) - via: every area whose placeable repeaters passed it on Lookups lower-case into a stack buffer and per-packet state lives in fixed arrays, so Derive allocates only the record's two slices: BenchmarkDerive 1.1 µs/op, 224 B/op, 2 allocs/op. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H
Owner
Author
|
Superseded by #16, which carries this as its own commits alongside the rest of the Data tab (one PR, as asked). |
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.
This is the second of six PRs for the Data tab (plan).
Stacked on #14. This branch contains #14's four commits. Review #14 first; once it is merged, this PR's diff shrinks to the two
internal/origincommits.What it adds
A new package,
internal/origin(its own module, depending only onareamap). It works out where a packet started and how each area heard it. It is plain functions over a packet, its observations and the node positions. Nothing calls it yet; PR 3 (the data index) will.Where it started. The first rule that gives an answer wins:
How each area heard it, one entry per receiving area:
Homeis set.Via: every area whose placeable repeaters passed the packet on.
Observers without a position are placed by their own node record, then by the areas'
iatalists. Areas come from one areamap layer.Tests
Deriveto at most 2 allocations per packet.scripts/allmod.sh vetandtest(18 of 18 modules) and the Dockerfile COPY invariant check. gofmt is clean.Benchmark
Lookups lower-case into a stack buffer, and per-packet tallies live in fixed arrays. The only allocations are the record's
HeardandViaslices.Gate: agreement with the running implementation
I ran the last 24 hours of pre-prod packets through both meshcore.scotmesh.net's
internal/peeringand this package:The plan's threshold was within 1%. On that data,
Deriveaveraged 4.9 µs per packet.The only intended difference: an advert placed by the sender's node record reports basis
node. meshcored reported it asadvert.🤖 Generated with Claude Code
https://claude.ai/code/session_01KaR4xu8gVykQBkH8yG8m6H