Карта Просмотр направлений рисования с использованием Google Directions API - декодирование полилиний

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

Любая помощь приветствуется.

4 ответа

Решение

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

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;

}
}

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

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.

"\\"

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

ниже код декодирует любую закодированную ломаную линию

      private List<LatLng> decodePoly(String encoded) {
    List<LatLng> poly = new ArrayList<>();
    int index = 0, len = encoded.length();
    int lat = 0, lng = 0;

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

        LatLng p = new LatLng((((double) lat / 1E5)),
                (((double) lng / 1E5)));
        poly.add(p);
    }

    return poly;
}
Другие вопросы по тегам