Карта Просмотр направлений рисования с помощью Google Directions API - декодирование полилиний - PullRequest
11 голосов
/ 15 июля 2011

Я пытаюсь использовать API указаний Google для отображения направлений в моем виде на карте, но у меня возникают трудности при получении данных из ответа JSON.Я могу получить строки «уровней» и «точек», но не могу понять, как декодировать их в точки на карте.

Любая помощь будет высоко ценится.

Ответы [ 3 ]

19 голосов
/ 15 июля 2011

У меня есть класс, который может декодировать их для вас, добавьте класс ниже, затем вызовите ваш код следующим образом:

int[] decodedZoomLevels = PolylineDecoder.decodeZoomLevels(levels);
GeoPoint[] gPts = PolylineDecoder.decodePoints(points, decodedZoomLevels.length);

, где points и levels - данные, которые вы извлекли из ответа JSON. Затем вы можете просмотреть массив геопоинтов, нарисовав линию между ними, чтобы отобразить ваши направления.

Надеюсь, это поможет! Kenny


РЕДАКТИРОВАТЬ: Казалось бы, API направлений Google больше не возвращает строку уровней масштабирования как часть ответа JSON, хотя, чтобы не волноваться, все, что мы использовали для этого, было для проверки количества точек, поэтому мы можем просто поместите их в список вроде:

public static List <GeoPoint> decodePoints(String encoded_points){
int index = 0;
int lat = 0;
int lng = 0;
List <GeoPoint> out = new ArrayList<GeoPoint>();

try {
    int shift;
    int result;
    while (index < encoded_points.length()) {
        shift = 0;
        result = 0;
        while (true) {
            int b = encoded_points.charAt(index++) - '?';
            result |= ((b & 31) << shift);
            shift += 5;
            if (b < 32)
                break;
        }
        lat += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);

        shift = 0;
        result = 0;
        while (true) {
            int b = encoded_points.charAt(index++) - '?';
            result |= ((b & 31) << shift);
            shift += 5;
            if (b < 32)
                break;
        }
        lng += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
        /* Add the new Lat/Lng to the Array. */
        out.add(new GeoPoint((lat*10),(lng*10)));
    }
    return out;
}catch(Exception e) {
    e.printStackTrace();
}
return out;
}

РЕДАКТИРОВАТЬ: СТАРЫЙ КОД

public class PolylineDecoder {
/**
 * Transform a encoded PolyLine to a Array of GeoPoints.
 * Java implementation of the original Google JS code.
 * @see Original encoding part: <a href="http://code.google.com/apis/maps/documentation/polylinealgorithm.html">http://code.google.com/apis/maps/documentation/polylinealgorithm.html</a>
 * @return Array of all GeoPoints decoded from the PolyLine-String.
 * @param encoded_points String containing the encoded PolyLine. 
 * @param countExpected Number of points that are encoded in the PolyLine. Easiest way is to use the length of the ZoomLevels-String. 
 * @throws DecodingException 
 */
public static GeoPoint[] decodePoints(String encoded_points, int countExpected){
    int index = 0;
    int lat = 0;
    int lng = 0;
    int cnt = 0;
    GeoPoint[] out = new GeoPoint[countExpected];

    try {
        int shift;
        int result;
        while (index < encoded_points.length()) {
            shift = 0;
            result = 0;
            while (true) {
                int b = encoded_points.charAt(index++) - '?';
                result |= ((b & 31) << shift);
                shift += 5;
                if (b < 32)
                    break;
            }
            lat += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);

            shift = 0;
            result = 0;
            while (true) {
                int b = encoded_points.charAt(index++) - '?';
                result |= ((b & 31) << shift);
                shift += 5;
                if (b < 32)
                    break;
            }
            lng += ((result & 1) != 0 ? ~(result >> 1) : result >> 1);
            /* Add the new Lat/Lng to the Array. */
            out[cnt++] = new GeoPoint((lat*10),(lng*10));
        }
        return out;
    }catch(Exception e) {
        e.printStackTrace();
    }
    return out;
}

public static int[] decodeZoomLevels(String encodedZoomLevels){
    int[] out = new int[encodedZoomLevels.length()];
    int index = 0;

    for(char c : encodedZoomLevels.toCharArray())
        out[index++] = c - '?';
    return out;

}
}
6 голосов
/ 23 мая 2014

Вы можете использовать служебную библиотеку Google Maps Android API .Он предлагает метод PolyUtil.decode(String encoded), который делает именно то, что вам нужно!

0 голосов
/ 29 сентября 2015

GeoPoint не работает для меня, я не могу найти библиотеку, которая его использует. Вот функция, которая вместо этого возвращает значения LatLng.

public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
    int len = encodedPath.length();

    final ArrayList<LatLng> path = new ArrayList<LatLng>();
    int index = 0;
    int lat = 0;
    int lng = 0;

    while (index < len) {
        int result = 1;
        int shift = 0;
        int b;
        do {
            b = encodedPath.charAt(index++) - 63 - 1;
            result += b << shift;
            shift += 5;
        } while (b >= 0x1f);
        lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);

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

        path.add(new LatLng(lat * 1e-5, lng * 1e-5));
    }

    return path;
}

Взял его из Утилита Google Maps Android API . Код можно найти здесь

Некоторые напоминания при тестировании с жестко закодированными строками в коде, Java не может правильно прочитать

"\"

вам нужно добавить еще одну косую черту, чтобы она правильно читалась Java.

"\\"

Просто на голову, потому что закодированные строки содержат странные символы.

...