package com.jtaxi.services.providers;
import android.graphics.Color;
import android.location.Address;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.PolylineOptions;
import com.jtaxi.ProjectConfig;
import com.jtaxi.helper.Console;
import com.jtaxi.services.http.HttpClientProvider;
import com.jtaxi.services.http.HttpRequestContainer;
import com.jtaxi.services.http.InternalJsonResponseHandler;
import com.jtaxi.services.http.RequestAction;
import com.jtaxi.services.http.client.RequestParams;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
/**
* User: Roman Yefimchuk
* Date: 1/4/14
* Time: 1:35 AM
*/
public class RouteWayProvider {
private static final String TAG = "Route Way Provider";
private static final float DEFAULT_WIDTH = 5;
private static final int DEFAULT_COLOR = Color.BLUE;
private static final String REQUEST_URl = "http://maps.googleapis.com/maps/api/directions/json";
private static final String ORIGIN = "origin";
private static final String DESTINATION = "destination";
private static final String SENSOR = "sensor";
private static final String STATUS = "status";
private static final String ERROR_MESSAGE = "error_message";
private static final String STATUS_OK = "OK";
private static final String ROUTES = "routes";
private static final String LEGS = "legs";
private static final String STEPS = "steps";
private static final String POLYLINE = "polyline";
private static final String POINTS = "points";
private static final int INDEX = 0;
private RouteWayProvider() {
}
private static String formatPoint(Address address) {
return address.getLatitude() + "," + address.getLongitude();
}
private static List<LatLng> decodePolyline(String points) {
int len = points.length();
int index = 0;
List<LatLng> decoded = new ArrayList<LatLng>();
int lat = 0;
int lng = 0;
while (index < len) {
int b;
int shift = 0;
int result = 0;
do {
b = points.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 = points.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dLng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dLng;
LatLng latLng = new LatLng(lat / 100000d, lng / 100000d);
decoded.add(latLng);
}
return decoded;
}
public static void obtainRouteWay(final Address origin, final Address destination, final Callback callback) {
obtainRouteWay(origin, destination, 0, callback);
}
public static void obtainRouteWay(final Address origin, final Address destination, final int polylineWidth,
final Callback callback) {
HttpClientProvider.sendHttpRequest(new HttpRequestContainer() {
@Override
public RequestAction sendRequest(HttpClientProvider.AsyncHttpClientWrapper client) {
final RequestParams params = new RequestParams();
params.put(ORIGIN, formatPoint(origin));
params.put(DESTINATION, formatPoint(destination));
params.put(SENSOR, String.valueOf(true));
return client.get(REQUEST_URl, params, new InternalJsonResponseHandler() {
@Override
public void onSuccess(JSONObject response) {
try {
String status = response.getString(STATUS);
if (status.equals(STATUS_OK)) {
JSONArray routes = response.getJSONArray(ROUTES);
{
JSONObject routeItem = routes.getJSONObject(INDEX);
JSONArray legs = routeItem.getJSONArray(LEGS);
{
JSONObject legsItem = legs.getJSONObject(INDEX);
{
JSONArray steps = legsItem.getJSONArray(STEPS);
int length = steps.length();
List<LatLng> pointsList = new ArrayList<LatLng>();
for (int stepIndex = 0; stepIndex < length; stepIndex++) {
JSONObject step = steps.getJSONObject(stepIndex);
{
JSONObject polyline = step.getJSONObject(POLYLINE);
String points = polyline.getString(POINTS);
List<LatLng> decodedPoints = decodePolyline(points);
pointsList.addAll(decodedPoints);
}
}
PolylineOptions polylineOptions = null;
if (callback != null) {
if (pointsList.isEmpty()) {
callback.onSuccess(polylineOptions);
} else {
polylineOptions = new PolylineOptions();
polylineOptions.addAll(pointsList);
polylineOptions.color(DEFAULT_COLOR);
if (polylineWidth > 0) {
polylineOptions.width(polylineWidth);
} else {
polylineOptions.width(DEFAULT_WIDTH);
}
callback.onSuccess(polylineOptions);
}
}
}
}
}
} else {
String errorMessage = response.getString(ERROR_MESSAGE);
if (callback != null) {
callback.onFailure(errorMessage);
}
}
} catch (Exception e) {
if (ProjectConfig.DEBUG) {
Console.d(TAG, "URL: " + REQUEST_URl + "?" + params);
e.printStackTrace();
}
if (callback != null) {
String message = e.getMessage();
if (message != null && message.length() != 0) {
callback.onFailure(message);
} else {
Class exceptionClass = e.getClass();
message = exceptionClass.getName();
callback.onFailure(message);
}
}
}
}
@Override
public void onFailure(String message) {
if (callback != null) {
callback.onFailure(message);
}
}
}.toAsyncHandler());
}
});
}
public static interface Callback {
public void onSuccess(PolylineOptions polylineOptions);
public void onFailure(String message);
}
}