Skip to content

Instantly share code, notes, and snippets.

@linggom
Last active August 29, 2015 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save linggom/aedbfe6ecd7c592951d8 to your computer and use it in GitHub Desktop.
Save linggom/aedbfe6ecd7c592951d8 to your computer and use it in GitHub Desktop.
/**
* An utility to encode the point in GoogleMap API
* Reference see this {@link https://developers.google.com/maps/documentation/utilities/polylinealgorithm?csw=1}
* @author SRIN
*
*/
public class MapUtil {
/**
* Step 1 : Take the decimal value and multiply it by 1e5, rounding the
* result
*
* @param value
* double value of a point
* @return decimal value after multiply it by 1e5 and rounding the result
*/
private static int floor(double value) {
return (int) java.lang.Math.round(value * 1e5);
}
/**
* Step 3 : Convert the decimal value to binary. Note that a negative value
* must be calculated using its two's complement by inverting the binary
* value and adding one to the result
*
* Step 4 : Left-shift the binary value one bit
*
* Step 5 : If the original
* decimal value is negative, invert this encoding
*
* @param number of the decimal value
* @return the encoded point
*/
private static String encodeSignedNumber(int num) {
int sgn_num = num << 1;
if (num < 0) {
sgn_num = ~(sgn_num); // inverse the bit : ~(101) will be 010
}
return (encodeNumber(sgn_num));
}
/**
* Step 7 : Place the 5-bit chunks into reverse order
* Step 8 : OR each value with 0x20 if another bit chunk
* Step 9 : Convert each value to decimal
* Step 10 : Add 63 to each value
* @param num of decimal value
* @return
*/
private static String encodeNumber(int num) {
StringBuffer encodeString = new StringBuffer();
while (num >= 0x20) {
encodeString.append((char) ((0x20 | (num & 0x1f)) + 63));
num >>= 5;
}
encodeString.append((char) (num + 63));
return encodeString.toString();
}
/**
* encoded the single double value
* @param value single value from a point
* @return
*/
private static String encoded(double value) {
int floor = floor(value);
return encodeSignedNumber(floor);
}
/**
* encoded given latitude and longitude of points.
*
* @param glatlngs
* Object with latitude and long given
* @return encoded string for the url
*/
public static String encoded(GLatLong... glatlngs) {
String enc = "";
GLatLong prev = null;
for (GLatLong gLatLong : glatlngs) {
if (prev == null) {
enc += encoded(gLatLong.getLat()) + encoded(gLatLong.getLng());
} else {
enc += encoded(gLatLong.getLat() - prev.getLat())
+ encoded(gLatLong.getLng() - prev.getLng());
}
prev = gLatLong;
}
return enc;
}
/**
* Internal class to set a latitude and longitude of a point
*
* @author SRIN
*
*/
public static class GLatLong {
private double lat;
private double lng;
public double getLat() {
return lat;
}
private void setLat(double lat) {
this.lat = lat;
}
public double getLng() {
return lng;
}
private void setLng(double lng) {
this.lng = lng;
}
public GLatLong(double lat, double lng) {
setLat(lat);
setLng(lng);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment