/* -------------------------------------------------------------------------
OpenTripPlanner GWT Client
Copyright (C) 2015 Mecatran - info@mecatran.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
------------------------------------------------------------------------- */
package com.mecatran.otp.gwt.client.utils;
import java.util.ArrayList;
import java.util.List;
import com.mecatran.otp.gwt.client.model.Wgs84LatLonBean;
public class PolylineEncoder {
public static String encode(Wgs84LatLonBean[] points) {
StringBuilder encodedPoints = new StringBuilder();
int oLate5 = 0;
int oLnge5 = 0;
for (Wgs84LatLonBean p : points) {
int pLate5 = floor1e5(p.getLat());
int pLnge5 = floor1e5(p.getLon());
int dLate5 = pLate5 - oLate5;
int dLnge5 = pLnge5 - oLnge5;
oLate5 = pLate5;
oLnge5 = pLnge5;
encodedPoints.append(encodeSignedNumber(dLate5)).append(
encodeSignedNumber(dLnge5));
}
return encodedPoints.toString();
}
private static final int floor1e5(double coordinate) {
return (int) Math.floor(coordinate * 1e5);
}
private static String encodeSignedNumber(int num) {
int sgn_num = num << 1;
if (num < 0) {
sgn_num = ~(sgn_num);
}
return (encodeNumber(sgn_num));
}
private 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 Wgs84LatLonBean[] decode(String encodedGeometry) {
List<Wgs84LatLonBean> points = new ArrayList<Wgs84LatLonBean>();
int index = 0, len = encodedGeometry.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encodedGeometry.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encodedGeometry.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
Wgs84LatLonBean point = new Wgs84LatLonBean((((double) lat / 1E5)),
(((double) lng / 1E5)));
points.add(point);
}
Wgs84LatLonBean[] retval = new Wgs84LatLonBean[points.size()];
for (int i = 0; i < retval.length; i++)
retval[i] = points.get(i);
return retval;
}
}