Skip to content

Add encode/decode for the Google Encoded Polyline format#32

Open
gistrec wants to merge 1 commit into
masterfrom
feature/polyline-encoding
Open

Add encode/decode for the Google Encoded Polyline format#32
gistrec wants to merge 1 commit into
masterfrom
feature/polyline-encoding

Conversation

@gistrec

@gistrec gistrec commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Summary

Ports PolyUtil.encode/decode (Google Encoded Polyline Algorithm Format) from android-maps-utils — first of the upstream-parity features planned for 1.1.0 (next: simplify + is_closed_polygon, which will reuse decode in tests).

  • New header <geo/encoding.hpp> — keeps <geo/poly.hpp> free of <string>/<vector>. Pulled in by the <geo/geo.hpp> umbrella; picked up automatically by the CMake install and the build2 hxx{**} glob.
  • geo::encode(const Path&)std::string — same Path contract as the other container functions; coordinates quantized to 1e-5° (~1 m).
  • geo::decode(std::string_view)std::vector<LatLng> — bounds-checked: a string truncated mid-point yields the points decoded so far and drops the incomplete trailing point (the Java original throws IndexOutOfBounds). Malformed input is memory-safe but yields unspecified coordinates (the format has no checksum).

Portability notes

  • The Java/Kotlin implementation relies on wrapping two's-complement int arithmetic; left-shifting a negative signed value is UB in C++17, so the zig-zag/varint accumulation is done in unsigned types — bit-identical to upstream on well-formed input.
  • r >> 1 on a negative value (arithmetic shift) is implementation-defined in C++17 but guaranteed on every supported compiler (GCC/Clang/MSVC) and standardized in C++20; noted in a comment.

Docs

Test plan

  • Encoding.encode: byte-for-byte match with the reference strings from the Encoded Polyline Algorithm Format docs (_p~iF~ps|U_ulLnnqC_mqNvxq@, ?~oia@), quantization collapse.
  • Encoding.decode: reference string, empty input, two truncation variants (mid-chunk and between chunks).
  • Encoding.encode_decode_roundtrip: poles, antimeridian, sub-quantum coordinates (error ≤ 5e-6°).
  • Full suite: 37/37 locally; clean under -Wall -Wextra -Wpedantic -Wconversion -Werror.
  • CI matrix (gcc/clang/macos/windows + install/consumer + build2).

Port of PolyUtil.encode/decode from android-maps-utils, in a new
<geo/encoding.hpp> header so <geo/poly.hpp> stays free of
<string>/<vector>. The zig-zag/varint arithmetic is done in unsigned
types: the Java original relies on wrapping int arithmetic, and
left-shifting a negative signed value is UB in C++17.

decode is bounds-checked: a string truncated mid-point yields the
points decoded so far and drops the incomplete trailing point (the
Java original throws IndexOutOfBounds there).

Tests cover the reference strings from the Encoded Polyline Algorithm
Format docs byte-for-byte, truncation, and quantized round-trips
across the poles and the antimeridian.
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.

1 participant