Skip to content

Instantly share code, notes, and snippets.

@michael-simons
Last active April 13, 2025 15:36
Show Gist options
  • Save michael-simons/8d47454c9586db88fb3a1cc7b8ce1cf9 to your computer and use it in GitHub Desktop.
Save michael-simons/8d47454c9586db88fb3a1cc7b8ce1cf9 to your computer and use it in GitHub Desktop.
If you ever want to encode a poly line against Google Earth / OSM Valhalla standards
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Gatherers;
public final class Polyline {
private final List<Point> points = new ArrayList<>();
private final int scale;
// Valhalla uses a scale of 6, Google is stupid and uses 5.
Polyline() {
this(6);
}
Polyline(int scale) {
this.scale = (int) Math.pow(10, scale);
}
void add(double x, double y) {
this.points.add(new Point((int) Math.floor(x * this.scale), (int) Math.floor(y * this.scale)));
}
@Override
public String toString() {
if (this.points.isEmpty()) {
return "";
}
var initial = this.points.getFirst().encode();
if (this.points.size() == 1) {
return initial;
}
var remainder = this.points.stream()
.gather(Gatherers.windowSliding(2))
.map(pair -> pair.getLast().offset(pair.getFirst()).encode())
.collect(Collectors.joining());
return initial + remainder;
}
public static void main(String... a) {
var polyline = new Polyline(5);
polyline.add(38.5, -120.2);
polyline.add(40.7, -120.95);
polyline.add(43.252, -126.453);
System.err.println(polyline);
}
record Point(int x, int y) {
private Point offset(Point other) {
return new Point(this.x - other.x(), this.y - other.y());
}
private String encode() {
return encode0(this.x) + encode0(this.y);
}
private String encode0(int v) {
var num = v << 1;
if (v < 0) {
num = ~num;
}
var result = new StringBuilder();
while (num >= 0x20) {
int nextValue = (0x20 | (num & 0x1f)) + 63;
result.append((char) (nextValue));
num >>= 5;
}
num += 63;
result.append((char) (num));
return result.toString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment