All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.opentripplanner.util.PolylineEncoder Maven / Gradle / Ivy
package org.opentripplanner.util;
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.List;
import org.opentripplanner.util.model.EncodedPolylineBean;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.MultiLineString;
public class PolylineEncoder {
public static EncodedPolylineBean createEncodings(double[] lat, double[] lon) {
return createEncodings(new PointAdapterList(lat, lon));
}
public static EncodedPolylineBean createEncodings(double[] lat, double[] lon, int level) {
return createEncodings(new PointAdapterList(lat, lon), level);
}
public static EncodedPolylineBean createEncodings(double[] lat, double[] lon, int offset,
int length, int level) {
return createEncodings(new PointAdapterList(lat, lon, offset, length), level);
}
public static EncodedPolylineBean createEncodings(Iterable points) {
return createEncodings(points, -1);
}
public static EncodedPolylineBean createEncodings(Geometry geometry) {
if (geometry instanceof LineString) {
LineString string = (LineString) geometry;
Coordinate[] coordinates = string.getCoordinates();
return createEncodings(new CoordinateList(coordinates));
} else if (geometry instanceof MultiLineString) {
MultiLineString mls = (MultiLineString) geometry;
return createEncodings(new CoordinateList(mls.getCoordinates()));
} else {
throw new IllegalArgumentException(geometry.toString());
}
}
/**
* If level < 0, then {@link EncodedPolylineBean#getLevels()} will be null.
*
* @param points
* @param level
* @return
*/
public static EncodedPolylineBean createEncodings(Iterable points, int level) {
StringBuilder encodedPoints = new StringBuilder();
StringBuilder encodedLevels = new StringBuilder();
int plat = 0;
int plng = 0;
int count = 0;
for (Coordinate point : points) {
int late5 = floor1e5(point.y);
int lnge5 = floor1e5(point.x);
int dlat = late5 - plat;
int dlng = lnge5 - plng;
plat = late5;
plng = lnge5;
encodedPoints.append(encodeSignedNumber(dlat)).append(encodeSignedNumber(dlng));
if (level >= 0)
encodedLevels.append(encodeNumber(level));
count++;
}
String pointsString = encodedPoints.toString();
String levelsString = level >= 0 ? encodedLevels.toString() : null;
return new EncodedPolylineBean(pointsString, levelsString, count);
}
public static List decode(EncodedPolylineBean polyline) {
String pointString = polyline.getPoints();
double lat = 0;
double lon = 0;
int strIndex = 0;
List points = new ArrayList();
while (strIndex < pointString.length()) {
int[] rLat = decodeSignedNumberWithIndex(pointString, strIndex);
lat = lat + rLat[0] * 1e-5;
strIndex = rLat[1];
int[] rLon = decodeSignedNumberWithIndex(pointString, strIndex);
lon = lon + rLon[0] * 1e-5;
strIndex = rLon[1];
points.add(new Coordinate(lon, lat));
}
return points;
}
/*****************************************************************************
* Private Methods
****************************************************************************/
private static final int floor1e5(double coordinate) {
return (int) Math.floor(coordinate * 1e5);
}
public static String encodeSignedNumber(int num) {
int sgn_num = num << 1;
if (num < 0) {
sgn_num = ~(sgn_num);
}
return (encodeNumber(sgn_num));
}
public static int decodeSignedNumber(String value) {
int[] r = decodeSignedNumberWithIndex(value, 0);
return r[0];
}
public static int[] decodeSignedNumberWithIndex(String value, int index) {
int[] r = decodeNumberWithIndex(value, index);
int sgn_num = r[0];
if ((sgn_num & 0x01) > 0) {
sgn_num = ~(sgn_num);
}
r[0] = sgn_num >> 1;
return r;
}
public static String encodeNumber(int num) {
StringBuffer encodeString = new StringBuffer();
while (num >= 0x20) {
int nextValue = (0x20 | (num & 0x1f)) + 63;
encodeString.append((char) (nextValue));
num >>= 5;
}
num += 63;
encodeString.append((char) (num));
return encodeString.toString();
}
public static int decodeNumber(String value) {
int[] r = decodeNumberWithIndex(value, 0);
return r[0];
}
public static int[] decodeNumberWithIndex(String value, int index) {
if (value.length() == 0)
throw new IllegalArgumentException("string is empty");
int num = 0;
int v = 0;
int shift = 0;
do {
v = value.charAt(index++) - 63;
num |= (v & 0x1f) << shift;
shift += 5;
} while (v >= 0x20);
return new int[] { num, index };
}
private static class PointAdapterList extends AbstractList {
private double[] lat;
private double[] lon;
private int offset;
private int length;
public PointAdapterList(double[] lat, double[] lon) {
this(lat, lon, 0, lat.length);
}
public PointAdapterList(double[] lat, double[] lon, int offset, int length) {
this.lat = lat;
this.lon = lon;
this.offset = offset;
this.length = length;
}
@Override
public Coordinate get(int index) {
return new Coordinate(lon[offset + index], lat[offset + index]);
}
@Override
public int size() {
return length;
}
}
private static class CoordinateList extends AbstractList {
private Coordinate[] coordinates;
public CoordinateList(Coordinate[] coordinates) {
this.coordinates = coordinates;
}
@Override
public Coordinate get(int index) {
return coordinates[index];
}
@Override
public int size() {
return coordinates.length;
}
}
}