encode_vertex() computed exactly the same thing as encode_quadkey(),
so there is no reason to have both. Give encode_quadkey() the branch-free
implementation, which also speeds up the default encode_index, and have
the shared node code call it directly. The unit test now compares it
against the old bit-at-a-time loop and checks that decode_quadkey()
reverses it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2nBqZisxNQfmEmon3vE9v
Encode the shared nodes as quadkeys, as the comment on struct node
already said they were, with a branch-free bit interleave, so that
vertices that are near each other are near each other in the sorted list
too. Search the list with an inlined std::lower_bound instead of bsearch.
Size the Bloom filter by the number of nodes, at about 16 bits each and
at most 32MB, instead of always using 34MB, so that it can usually stay
in the cache, and set three bits for each node, chosen by a mixing hash,
within a single 64-bit word, so that each check still touches only one
cache line but has far fewer false positives than a single bit.
In the pass that marks the vertices with whether they are shared nodes,
this is about 1.7x faster with 70 thousand nodes and 1.9x faster with
3 million.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P2nBqZisxNQfmEmon3vE9v
* Track output position at the file level instead of within each tile
* Track file position where the child tile data begins
* Add option and document its intended behavior
* Changing the detail loop to account for stopping early
* I forgot I already added an option for this
* Stop early if we can make a complete tile
* Add a test of zoom truncation with limited feature count
* Forgot to commit the actual code change
* Make room for a vertex count in the header of each serialized tile
* Estimate tile complexity; don't try truncating when unlikely to work
* Be more conservative, because ever retrying a tile is a big speed hit
* If stopping early, don't simplify or clean; leave that to overzoom
* Add tiny polygon reduction / dust to overzoom
* Don't try to stop early in the children if we dropped anything by rate
* Fflush here too before pwriting
* Don't stop early if we ended up dropping any features.
Rework the can-the-next-zoom-stop-early logic to avoid going
one zoom further than needed.
* Fix warning
* Fix warnings
* Oops, checking for the wrong expected return value
* Cleanup from adding line simplification in overzoom
* Current (wrong) behavior when combining coalescing and truncating
* Keep a list of parent tiles to skip rather than truncating
* Now the coalesced tiles in z12 get children in z13
* Don't double-count feature dropping when the zoom level is retried
* Correct README description
* Remove todo about special case below basezoom, which is accounted for
* Be a little more aggressive in drop-densest determination
* Scale tile feature limit for megatiles in the same way as byte limit
* Fully deprecate -detect-shared-borders into an alias
* Track the distances found in the douglas-peucker recursion
* Serialize and deserialize the distance with the vertices
* Revert "Serialize and deserialize the distance with the vertices"
This reverts commit 753f1b7909.
* Revert "Track the distances found in the douglas-peucker recursion"
This reverts commit e5361f8c22.
* Revert "Fully deprecate -detect-shared-borders into an alias"
This reverts commit 0698aeb766.
* Better tracking of whether we failed to make a full-detail tile
* Put a bloom filter in front of the binary search for shared nodes
* Forgot to take out this printf
* Improve dispatch of tiling tasks
* Still dispatch the biggest tasks first
* Track zoom truncation in the strategies list in the tileset metadata
* Prescan for small deltas before doing proper simplification
* Revert "Prescan for small deltas before doing proper simplification"
This reverts commit d1d8238b83.
* Update version and changelog
* Rename to --generate-variable-depth-tile-pyramid
* Put all of this back in geometry.cpp for conflict resolution
* Stabilize line simplification to behave the same regardless of winding
* Round instead of truncating when clipping lines
* Restore non-Wagyu polygon clipping from prior to 2fdec7d2
* Make it round, not truncate, which reverts the last commit's test diffs
* Clip in floating point, not integers, which makes no difference
* Track nodes added at tile edges during clipping
* Scale geometry up before wagyu to prevent changes from precision loss
* Actually do the shared edge detection
* Fix cases where nodes were not being added at the tile boundary
* One more place I should have rounded
* Narrow down where the discrepancy comes in
* Revert "Narrow down where the discrepancy comes in"
This reverts commit 221c4c5fc0ac9a6567e091c6a94b3d87dc8ade83.
* Another attempt to narrow it down
* The discrepancy seems to be introduced in reordering. No obvious bug
* Was still truncating instead of rounding in projection
* Also makes no difference...
* Just forget that line reversal exists for a minute
* Just reversal no coalescing
* Try clipping in integers instead of floating point
* Don't simplify after coalescing if they said no simplification
* Check whether behavior is consistent with intentional simplification
* Replace more floating point with integer
* Are these three features enough to demonstrate the problem?
* Add a few more nearby borders
* All the features that touch tile 6/16/23
* Stay in integers in line simplification
* More attempts to solve failures to simplify consistently
* Fix most of the overflow errors
* Fix known cases of integer overflow
* All the tests change again
* Pull clipping and scaling code back out into clip.cpp
* Resolve the test conflicts
* Stabilize choice of which three points to keep with different windings
* Almost right, I think!
* Fix collapse of islands to shards
* Self-intersections in the same feature don't count
* Revert "Self-intersections in the same feature don't count"
This reverts commit e04b19916e.
* Don't scale down geometry if we are going to look for shared nodes
* Fix the missing multiply that was keeping simplification from happening
* Fix one more opportunity for overflow
* Somehow I deleted this test?
* Lost this test too
* Clean up debugging printfs
* Restore code sequence from main to make it reviewable
* Remove unneeded rounding
* Update documentation
* This test is no longer useful
* Back to floating point Douglas-Peucker to fix undersimplification
* Try an older ubuntu
* Revert "Try an older ubuntu"
This reverts commit 13fefacfd7.
* Log OS info
* Remove tests that are no longer needed
* Oops, did need that one after all
* Fix the arm vs x86 discrepancy?
* Try another quantization
* Cleanup from review
* Add a test for the actual purpose of this PR
* Round coordinates instead of truncating them
* Update all the tests for coordinate rounding changes
* Curses, integer division still truncates
* Fix tests
* Also round instead of shifting when looking for no-op linetos
* Should I worry that the same change for moveto doesn't change any tests?
* Also round instead of shifting when scaling down to maxzoom resolution
* Replace another explicit shift, for origin point
* Round instead of shift when writing clipped geometries to the next zoom
* Fix low-zoom gridding and smaller-than-a-pixel checks
* Don't guess an excessively large maxzoom when there is only one feature
* Add a test for guessing the maxzoom of a single point
* Explicitly sort by index if no other order distinguishes features
* Another affected test
* Stop adding features to a tile if it can't possibly work
* Add --integer and --fraction options to tippecanoe-decode
* Carry the strategies field from tileset metadata through tile-join
* Update changelog
* Assign different codes to different kinds of error exits