com.spoiledmilk.ibikecph.map.SMHttpRequest.java Source code

Java tutorial

Introduction

Here is the source code for com.spoiledmilk.ibikecph.map.SMHttpRequest.java

Source

// Copyright (C) 2013 City of Copenhagen.
//
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at 
// http://mozilla.org/MPL/2.0/.
package com.spoiledmilk.ibikecph.map;

import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import org.osmdroid.api.IGeoPoint;

import android.location.Location;
import android.os.Handler;
import android.os.Message;

import com.fasterxml.jackson.databind.JsonNode;
import com.spoiledmilk.ibikecph.util.Config;
import com.spoiledmilk.ibikecph.util.HttpUtils;
import com.spoiledmilk.ibikecph.util.LOG;
import com.spoiledmilk.ibikecph.util.Util;

public class SMHttpRequest {

    protected static final int GEOCODER_SEARCH_RADIUS = 50;

    public static final int REQUEST_GET_ROUTE = 2;
    public static final int REQUEST_FIND_NEAREST_LOC = 3;
    public static final int REQUEST_FIND_PLACES_FOR_LOC = 4;
    public static final int REQUEST_GET_RECALCULATED_ROUTE = 5;

    static Handler handler;

    private RouteInfo z10Route = null;

    static class Result {
        Object response;
        SMHttpRequestListener listener;

        public Result(Object response, SMHttpRequestListener listener) {
            this.response = response;
            this.listener = listener;
        }
    }

    public static class Address {
        public String street;
        public String houseNumber;
        public String zip;
        public String city;
        public double lat;
        public double lon;

        public Address(String street, String houseNumber, String zip, String city, double lat, double lon) {
            this.street = street;
            this.houseNumber = houseNumber;
            this.zip = zip;
            this.city = city;
            this.lat = lat;
            this.lon = lon;
        }
    }

    public static class RouteInfo {
        public JsonNode jsonRoot;
        public Location start;
        public Location end;

        public RouteInfo(JsonNode jsonRoot, Location start, Location end) {
            this.jsonRoot = jsonRoot;
            this.start = start;
            this.end = end;
        }
    }

    public SMHttpRequest() {

        handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                Result res = (Result) msg.obj;
                if (res == null)
                    return false;

                switch (msg.what) {
                case REQUEST_GET_ROUTE:
                    break;
                case REQUEST_FIND_NEAREST_LOC:
                    break;
                case REQUEST_FIND_PLACES_FOR_LOC:
                    break;
                case REQUEST_GET_RECALCULATED_ROUTE:
                    break;
                }

                if (res.listener != null)
                    res.listener.onResponseReceived(msg.what, res.response);

                return true;
            }
        });
    }

    public void getRoute(final Location start, final Location end, List<Location> viaPoints,
            final SMHttpRequestListener listener) {
        getRoute(start, end, viaPoints, null, null, null, listener, REQUEST_GET_ROUTE, 18, false);
    }

    public void getRecalculatedRoute(final Location start, final Location end, List<Location> viaPoints,
            String chksum, final SMHttpRequestListener listener) {
        getRoute(start, end, viaPoints, chksum, null, null, listener, REQUEST_GET_RECALCULATED_ROUTE, 18, false);
    }

    public void getRecalculatedRoute(final Location start, final Location end, List<Location> viaPoints,
            final String chksum, final String startHint, final String hint, final SMHttpRequestListener listener) {
        getRoute(start, end, viaPoints, chksum, startHint, hint, listener, REQUEST_GET_RECALCULATED_ROUTE, 18,
                false);
    }

    public void getRoute(final Location start, final Location end, final List<Location> viaPoints,
            final String chksum, final String startHint, final String hint, final SMHttpRequestListener listener,
            final int msgType, final int z, final boolean isFromZ10) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url;
                if (startHint != null) {
                    url = String.format(Locale.US,
                            "%s/viaroute?z=" + z + "&alt=false&loc=%.6f,%.6f&hint=" + startHint + "",
                            Config.OSRM_SERVER,

                            start.getLatitude(), start.getLongitude());
                } else {
                    url = String.format(Locale.US, "%s/viaroute?z=" + z + "&alt=false&loc=%.6f,%.6f",
                            Config.OSRM_SERVER, start.getLatitude(), start.getLongitude());
                }

                if (viaPoints != null) {
                    Iterator<Location> it = viaPoints.iterator();
                    while (it.hasNext()) {
                        Location loc = it.next();
                        url += String.format(Locale.US, "&loc=%.6f,%.6f", loc.getLatitude(), loc.getLongitude());
                    }
                }

                if (chksum != null) {
                    if (hint != null) {
                        url += String.format(Locale.US, "&loc=%.6f,%.6f&hint=%s&instructions=true&checksum=%s",
                                end.getLatitude(), end.getLongitude(), hint, chksum);
                    } else {
                        url += String.format(Locale.US, "&loc=%.6f,%.6f&instructions=true&checksum=%s",
                                end.getLatitude(), end.getLongitude(), chksum);
                    }
                } else
                    url += String.format(Locale.US, "&loc=%.6f,%.6f&instructions=true", end.getLatitude(),
                            end.getLongitude());
                LOG.d("Routes request = " + url);
                RouteInfo ri = new RouteInfo(HttpUtils.get(url), start, end);
                if (ri == null || ri.jsonRoot == null || ri.jsonRoot.path("status").asInt(-1) != 0) {
                    // try to get the route with the z = 10
                    if (!isFromZ10)
                        getRouteZ10(start, end, viaPoints, chksum, startHint, hint, listener, msgType);
                    else
                        sendMsg(msgType, z10Route, listener);
                } else
                    // Route found
                    sendMsg(msgType, ri, listener);

            }
        }).start();
    }

    public void getRouteZ10(final Location start, final Location end, final List<Location> viaPoints,
            final String chksum, final String startHint, final String hint, final SMHttpRequestListener listener,
            final int msgType) {
        z10Route = null;
        String url;
        if (startHint != null) {
            url = String.format(Locale.US, "%s/viaroute?z=10&alt=false&loc=%.6f,%.6f&hint=" + startHint + "",
                    Config.OSRM_SERVER,

                    start.getLatitude(), start.getLongitude());
        } else {
            url = String.format(Locale.US, "%s/viaroute?z=10&alt=false&loc=%.6f,%.6f", Config.OSRM_SERVER,
                    start.getLatitude(), start.getLongitude());
        }

        if (viaPoints != null) {
            Iterator<Location> it = viaPoints.iterator();
            while (it.hasNext()) {
                Location loc = it.next();
                url += String.format(Locale.US, "&loc=%.6f,%.6f", loc.getLatitude(), loc.getLongitude());
            }
        }

        if (chksum != null) {
            if (hint != null) {
                url += String.format(Locale.US, "&loc=%.6f,%.6f&hint=%s&instructions=true&checksum=%s",
                        end.getLatitude(), end.getLongitude(), hint, chksum);
            } else {
                url += String.format(Locale.US, "&loc=%.6f,%.6f&instructions=true&checksum=%s", end.getLatitude(),
                        end.getLongitude(), chksum);
            }
        } else
            url += String.format(Locale.US, "&loc=%.6f,%.6f&instructions=true", end.getLatitude(),
                    end.getLongitude());

        RouteInfo ri = new RouteInfo(HttpUtils.get(url), start, end);
        z10Route = ri;
        if (ri == null || ri.jsonRoot == null || ri.jsonRoot.path("status").asInt(-1) != 0) {
            // Can't find the route
            sendMsg(msgType, ri, listener);
        } else {
            // try again with the z = 18 and a checksum hint
            String checksum = "", endHint = "", hintStart = "";

            if (ri.jsonRoot.has("hint_data") && ri.jsonRoot.get("hint_data").has("checksum"))
                checksum = ri.jsonRoot.get("hint_data").get("checksum").asText();
            if (ri.jsonRoot.has("hint_data") && ri.jsonRoot.get("hint_data").has("locations")) {
                JsonNode locations = ri.jsonRoot.get("hint_data").get("locations");
                hintStart = locations.get(0).asText();
                endHint = locations.get(locations.size() - 1).asText();
            }
            getRoute(start, end, viaPoints, checksum, hintStart, endHint, listener, msgType, 18, true);
        }
    }

    public void findNearestPoint(final IGeoPoint loc, final SMHttpRequestListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = String.format(Locale.US, "%s/nearest?loc=%.6f,%.6f", Config.OSRM_SERVER,
                        loc.getLatitudeE6() / (float) 1E6, loc.getLongitudeE6() / (float) 1E6);
                JsonNode response = HttpUtils.get(url);
                Location loc = null;
                if (response != null && response.path("mapped_coordinate").get(0) != null
                        && response.path("mapped_coordinate").get(1) != null) {
                    LOG.d("response: " + response.toString());
                    loc = Util.locationFromCoordinates(response.path("mapped_coordinate").get(0).asDouble(),
                            response.path("mapped_coordinate").get(1).asDouble());
                }
                sendMsg(REQUEST_FIND_NEAREST_LOC, (Object) loc, listener);
            }
        }).start();
    }

    public void findPlacesForLocation(final Location loc, final SMHttpRequestListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                String url = String.format(Locale.US, "%s/%f,%f.json", Config.GEOCODER, loc.getLatitude(),
                        loc.getLongitude()); // ,%d
                                                                                                                                        // ,
                                                                                                                                        // GEOCODER_SEARCH_RADIUS
                JsonNode response = HttpUtils.get(url);
                Address a = null;
                if (response != null) {
                    if (response.size() > 0) {
                        a = new Address(response.path("vejnavn").path("navn").asText(),
                                response.path("husnr").asText(), response.path("postnummer").path("nr").asText(),
                                response.path("kommune").path("navn").asText(), loc.getLatitude(),
                                loc.getLongitude());
                    } else {
                        a = new Address(
                                Util.limitDecimalPlaces(loc.getLatitude(), 4) + "\n"
                                        + Util.limitDecimalPlaces(loc.getLongitude(), 4),
                                "", "", "", loc.getLatitude(), loc.getLongitude());
                    }
                } else {
                    a = new Address(
                            Util.limitDecimalPlaces(loc.getLatitude(), 4) + "\n"
                                    + Util.limitDecimalPlaces(loc.getLongitude(), 4),
                            "", "", "", loc.getLatitude(), loc.getLongitude());
                }
                sendMsg(REQUEST_FIND_PLACES_FOR_LOC, a, listener);
            }
        }).start();
    }

    public void sendMsg(int what, Object response, SMHttpRequestListener listener) {
        if (listener != null) {
            Message msg = new Message();
            msg.what = what;
            msg.obj = new Result(response, listener);
            handler.sendMessage(msg);
        }
    }
}