🎉Community Raffle - Win $25

An exclusive raffle opportunity for active members like you! Complete your profile, answer questions and get your first accepted badge to enter the raffle.
Join and Win

Decode Google Encoded Polyline using Execute Script

User: "pgirgis"
New Altair Community Member
Updated by Jocelyn

I worked on decoding an encoded Google Polyline using the execute script operator.  I have incldued the script below for anyone wishing to use it.  It is based upon https://github.com/scoutant/polyline-decoder however has some changes to address the incompatibility with Execute Script.

 

An example using the script where the exampleSet has a field called geofence with the encoded polyline is at the end.

 

import com.rapidminer.tools.Ontology;
import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;
import java.util.Iterator;

 

public class PolylineUtils {

public static String toString(List<Point> polyline) {
String str = "[ ";
for( Point p : polyline) {
str += p;
}
return str + " ]";
}

public static String toMarkers(List<Point> polyline) {
String str = "";
for( Point p : polyline) {
str += "|" + p.getLat()+","+p.getLng();
}
return str.substring(1, str.length());
}

}

public class Point implements Serializable {
private static final long serialVersionUID = 1L;
private final double lat;
private final double lng;

public Point(double lat, double lng) {
this.lat = lat;
this.lng = lng;
}

public double getLat() {
return lat;
}

public double getLng() {
return lng;
}

@Override
public String toString() {
return "(" + lat + ", " + lng + ")";
}


public static String toGeoJSON(List<Point> points) {
StringBuilder buff = new StringBuilder("[");
Iterator<Point> itr = points.iterator();
while (itr.hasNext()) {
buff.append(toGeoJSON(itr.next()));
if (itr.hasNext()) {
buff.append(",");
}
}
buff.append("]");
return buff.toString();
}

public static String toGeoJSON(Point point) {
return "[" + point.getLng() + "," + point.getLat() + "]";
}


@Override
public boolean equals(Object o) {
if (!(o instanceof Point)) {
return false;
}
Point that = (Point) o;
if (Math.abs(that.getLat() - lat) > 0.001) {
return false;
}
return Math.abs(that.getLng() - lng) <= 0.001;
}

@Override
public int hashCode() {
int hash = 5;
hash = 37 * hash + (int) (Double.doubleToLongBits(this.lat) ^ (Double.doubleToLongBits(this.lat) >>> 32));
hash = 37 * hash + (int) (Double.doubleToLongBits(this.lng) ^ (Double.doubleToLongBits(this.lng) >>> 32));
return hash;
}

}

public class PolylineDecoder {
private static final double DEFAULT_PRECISION = 1E5;

public List<Point> decode(String encoded) {
return decode(encoded, DEFAULT_PRECISION);
}


public List<Point> decode(String encoded, double precision) {
List<Point> track = new ArrayList<Point>();
int index = 0;
int lat = 0, lng = 0;

while (index < encoded.length()) {
int b, shift = 0, result = 0;
while ({
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
b >= 0x20
}());
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;

shift = 0;
result = 0;
while ({
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
b >= 0x20
}());
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;

Point p = new Point((double) lat / precision, (double) lng / precision);
track.add(p);
}
return track;
}

}

 

// To get the exampleset as an input

ExampleSet exampleSet = input[0];

// Get all attributes
Attributes atts = exampleSet.getAttributes();

// Select the attribute to process - use name to link to data
Attribute att1 = atts.get("geofence");

// Create new attributes
Attribute att2 = AttributeFactory.createAttribute("geofence_decoded", Ontology.STRING);
atts.addRegular(att2);
exampleSet.getExampleTable().addAttribute(att2);

for (Example example : exampleSet) {
String geofenceString = example.getNominalValue(att1);
PolylineDecoder decoder = new PolylineDecoder();
String result = decoder.decode(geofenceString);
example.setValue(att2, result);


}

return exampleSet;

 

Find more posts tagged with

Comments

No comments on this post.