我正在绘制地图中两点之间的路线。我这样得到了积分:
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin=");// from
urlString.append(Double.toString(src.latitude));
urlString.append(",");
urlString.append(Double.toString(src.longitude));
urlString.append("&destination=");// to
urlString.append(Double.toString(dest.latitude));
urlString.append(",");
urlString.append(Double.toString(dest.longitude));
urlString.append("&sensor=false&mode=");
if (tipo != null) {
urlString.append(tipo);
}
return urlString.toString;
我收到了Google的回复,并获得了JSON:
resp = new JSONObject(builder.toString());
Log.i("Location", "Contenido del kml: "+resp);
JSONArray routeObject = resp.getJSONArray("routes");
JSONObject routes = routeObject.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
ArrayList<LatLng> puntos=decodePoly(encodedString);
我从谷歌获得的回复:(采用JSON格式):
Response: {"status":"OK","routes":[{"waypoint_order":[],"summary":"R-3 and A-3","bounds":{"southwest":{"lng":-3.676540000000001,"lat":40.00040000000001},"northeast":{"lng":-2.99933,"lat":40.43357}},"legs":[{"duration":{"value":3267,"text":"54 mins"},"distance":{"value":85039,"text":"85.0 km"},"end_location":{"lng":-2.99933,"lat":40.00040000000001},"start_address":"Calle del General Díaz Porlier, 91, 28006 Madrid, Spain","end_address":"Camino Veinticuatro, 2, 16400 Tarancón, Cuenca, Spain","start_location":{"lng":-3.676540000000001,"lat":40.43331000000001},"via_waypoint":[],"steps":[{"html_instructions":"Head <b>north<\/b> on <b>Calle del Gral Díaz Porlier<\/b> toward <b>Calle de Maldonado<\/b>","duration":{"value":6,"text":"1 min"},"distance":{"value":29,"text":"29 m"},"end_location":{"lng":-3.676520000000001,"lat":40.43357},"polyline":{"points":"ecxuFjamUs@C"},"travel_mode":"DRIVING","start_location":{"lng":-3.676540000000001,"lat":40.43331000000001}},{"html_instructions":"Take the 1st <b>right<\/b> onto <b>Calle de Maldonado<\/b>","duration":{"value":62,"text":"1 min"},"distance":{"value":266,"text":"0.3 km"},"end_location":{"lng":-3.6734,"lat":40.43345},"polyline":{"points":"ydxuFfamUPkG@a@JuGGk@"},"travel_mode":"DRIVING","start_location":{"lng":-3.676520000000001,"lat":40.43357}},{"html_instructions":"Take the 2nd <b>right<\/b> onto <b>Calle de Fco. Silvela<\/b>","duration":{"value":57,"text":"1 min"},"distance":{"value":245,"text":"0.2 km"},"end_location":{"lng":-3.671830000000001,"lat":40.4316},"polyline":{"points":"adxuFvmlURQl@e@zAoATSTMf@]pBeBLK"},"travel_mode":"DRIVING","start_location":{"lng":-3.6734,"lat":40.43345}},{"html_instructions":"Slight <b>right<\/b> onto <b>Calle de Francisco Silvela<\/b>","duration":{"value":51,"text":"1 min"},"distance":{"value":437,"text":"0.4 km"},"end_location":{"lng":-3.66913,"lat":40.42827},"polyline":{"points":"oxwuF|clUJADAFCbBkAjAeA`BoA^[XUPMLMFEnAeALIdBuAZUPMXS"},"travel_mode":"DRIVING","start_location":{"lng":-3.671830000000001,"lat":40.4316}},{"html_instructions":"Turn <b>right<\/b> onto <b>Pl. de Manuel Becerra<\/b>","duration":{"value":32,"text":"1 min"},"distance":{"value":154,"text":"0.2 km"},"end_location":{"lng":-3.668380000000001,"lat":40.42827},"polyline":{"points":"ucwuF`skU@?@@@@@?@@@?FBD?F@FAFAFADEDCFGDGDIBI@I@K@KAI?IAGAGAGCGCC?ACEEEIGGEICI?I?G@IBGD"},"travel_mode":"DRIVING","start_location":{"lng":-3.66913,"lat":40.42827}},{"html_instructions":"Turn <b>right<\/b> onto <b>Calle Alcala<\/b>","duration":{"value":61,"text":"1 min"},"distance":{"value":709,"text":"0.7 km"},"end_location":{"lng":-3.66107,"lat":40.43126000000001},"polyline":{"points":"ucwuFjnkUo@}A_AcCiEeLKYq@mBYq@[o@u@kB?KAQ]aAI[EQQu@Gc@QwAM_BEa@AU"},"travel_mode":"DRIVING","start_location":{"lng":-3.668380000000001,"lat":40.42827}},{"html_instructions":"Turn <b>right<\/b> onto the ramp to <b>M-30\/A-3\/A-4<\/b>","duration":{"value":44,"text":"1 min"},"distance":{"value":453,"text":"0.5 km"},"end_location":{"lng":-3.660580000000001,"lat":40.42720000000001},"polyline":{"points":"kvwuFt`jU\\CjIg@nBKD?rCOvDY"},"travel_mode":"DRIVING","start_location":{"lng":-3.66107,"lat":40.43126000000001}},{"html_instructions":"Continue straight","duration":{"value":45,"text":"1 min"},"distance":{"value":1009,"text":"1.0 km"},"end_location":{"lng":-3.659120000000001,"lat":40.41822000000001},"polyline":{"points":"_}vuFr}iUzKgBvCe@t@KvGm@hDUbAMPCZElAM|D_@^En@EjBEd@Df@DnAD"},"travel_mode":"DRIVING","start_location":{"lng":-3.660580000000001,"lat":40.42720000000001}},{"html_instructions":"Take exit <b>7B<\/b> to merge onto <b>M-23<\/b> toward <b>Vicálvaro\/R-3\/Valencia<\/b>","duration":{"value":117,"text":"2 mins"},"distance":{"value":2552,"text":"2.6 km"},"end_location":{"lng":-3.63392,"lat":40.41499},"polyline":{"points":"{duuFntiUFHB@^PDBFFFDDFDFBDDFBH@BBJ@F@H?F@H?FAH?FAF?FADAFAFCDADADEFCFEDEDEDEBEBEBGBE@G@E@G?G?EAG?GCGAGCEEGEEEEEEGEICIEIAKCKAK?K?MDgA?G?E?KJq@BODY@CBODW?C@I@AFe@F_@V{An@gED[@C?EHe@Ho@@G?A^{BjA}HF[tAiGzBwIdAcEVgApAuFr@sEF]Ju@DW?EDUHa@f@qEFo@f@iGXmHDgFCgGG{DM
最后,我以这种方式解码收到的String,我在Stackoverflow中找到了很多答案:
private ArrayList<LatLng> decodePoly(String encoded) {
Log.i("Location", "String received: "+encoded);
ArrayList<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
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 {
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((int) (((double) lat /1E5)* 1E6), (int) (((double) lng/1E5 * 1E6)));
poly.add(p);
}
for(int i=0;i<poly.size();i++){
Log.i("Location", "Point sent: Latitude: "+poly.get(i).latitude+" Longitude: "+poly.get(i).longitude);
}
return poly;
}
这是我认为错误的地方,因为我设置了一个for来查看正在解码的点,答案是这样的:
04-10 13:33:54.578: I/Location(25065): Point sent: Latitude: 90.0 Longitude: -110.0
04-10 13:33:54.578: I/Location(25065): Point sent: Latitude: 90.0 Longitude: -120.0
04-10 13:33:54.578: I/Location(25065): Point sent: Latitude: 90.0 Longitude: 100.0
04-10 13:33:54.578: I/Location(25065): Point sent: Latitude: 90.0 Longitude: 120.0
04-10 13:33:54.578: I/Location(25065): Point sent: Latitude: 90.0 Longitude: 40.0
显然,这些要点都很难解析。结果是,没有任何地方绘制线条。
我的问题是......有人知道如何解析谷歌的答案,并将其翻译成LatLng对象(不是GeoPoints对象)吗?
谢谢!
编辑:
这是即将解码的String:
04-10 13:50:51.608: I/Location(25065): String to decode: gcxuFjamUq@CPkGLwHJ}@hCuBdEeDf@SrJuHnG{Ed@Fr@q@AmAm@k@e@DaIaSiEuLqAwJ~Mw@~ZwDtZuC`FKbCVjA`ANdAs@nBw@Py@]c@oAT}DhC{PlBcM~GaY|DyS`BmPRy]yBu\UsNvAqObAuEnC}KpAqIh@gK[}NcByWXoRt@}GlDeWvFcq@nFi`@~G}\|@aDdDoLn`@}gAfe@upA`JyV|CiN~@uId@{ZyBwVkBmOwB{^AsNt@iWb@qYcCyS_DkPmAaK{@gRN{RbCkWrFgUbHmPxLsP|JwIpPwN|G}JfE}I|C_KlCsNvAwSFaQj@i]jCmXbHg\pIgSpGaLnN}P`JsHfVaNbQkHtZyIrOsCnTaCx\aA`i@b@nSRz]K`J{AxJiDfNkJjU{WbKkJpGeEpVkPpEiEzMcQjQw]nJyM~IoJ`IoKnH{NrOaWtIeJdNgNrLcPjKqOhIuI~MeJxKgErR{Cn]EjQkBjHqBfJeE|\yTlI_JvEqJxHsS|Xuc@~IeR|EiRr@kEz@sNOoL_B}Lk@mCsFgKkCoGwAsG]}N`CuO`D}GjHoHtFwC|HgBhFg@fJ}BtHaF~D_FjLqSfGqE|FcBnGEnEv@xK`BzNeAxQfAlJ{@jIwEjE}FvBuF|B{NtCsNrBgEdHiIdGuIxDoFpGkFhDaBrHyBbF[pHPlDg@jEuBnCkCtFgKjEqEfIcGpC{D|GoNdAcExAkSjBgDrCsBpDa@vHLfSAfBk@nE_F|Im`@tO_ZxCyEzJmKtHyElG_ClZeF|j@sIlQaD|EuChGkHnK{MdIsMfPwa@bDeJpD_RpFsz@nA}IrCqIrYoa@|BeGlEiYpD}HbKoRfCyKdBwUjEmo@zBkKzDyJvCeQdB}LJqGmAqQJ_Gx@uFtHkO`ImMfMmXtFySpCkXRuN]aYVoT~@}LxB{NvD{OjJaYbFsLnCcEtLoMfJyXzIiXbIiL~D_EzQcMjDeF|AcFhA_M`BkXpC_KjCsDnDeClQcHvEgElFqJfF_Jp\mWzd@k]`WkWlVy`@nOcTz`@_s@rP_ZbNkQ~Tu^jJaUhCuIpHgUrPi\zd@uq@~McQh\e]vTaU~KcF~KoGhG{KzF{HzGmDbDwBfDiEzB}GbEmTrBsHpCuFxe@oq@xb@el@tDgC`ZeJnXkHrKmB~EeB~C{A`Ce@bCUrBoAnAuGSqIn@yEhDeOrCuQ|A}EvAwFdDgAfGSrHUJ\p@Bj@_A|Ao@tCsD|C}Rj@wAdCuW~Ds]VCJw@OUpEc_@jDKbDwB
如果使用LatLng格式,则表示创建LatLng对象的方式,您可以在decodePoly方法中看到。这些latLng对象被添加到PolylineOptions对象中,并以这种方式添加到地图中:
PolylineOption ruta=new PolylineOptions();
for(int i=0;i<puntos.size();i++){
ruta.add(new LatLng(puntos.get(i).latitude, puntos.get(i).longitude));
}//puntos is an array where the array returned by the decodePoly method are stored
ruta.color(Color.RED).width(7);
Polyline polygon=mapa.addPolyline(ruta);
我改变了我在谷歌长时间搜索后找到的这个我正在使用的decodePoly,现在路线被正确绘制了。
更改
LatLng p = new LatLng((int) (((double) lat /1E5)* 1E6), (int) (((double) lng/1E5 * 1E6)));
对于
LatLng p = new LatLng((((double) lat / 1E5)),(((double) lng / 1E5)));
现在有效。
对于那些现在需要这个的人来说,有一个开源库,其中包含许多有关Google Maps Android API的有用信息,包括折线和编码折线。
在Android Maps Utils和Android Maps Util Github查看。对于解码和编码使用:
PolyUtil.decode(String encodedPath);
PolyUtil.encode(List<LatLng> path);
在Javascript中相同
function decodePolyline(encoded) {
if (!encoded) {
return [];
}
var poly = [];
var index = 0, len = encoded.length;
var lat = 0, lng = 0;
while (index < len) {
var b, shift = 0, result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result = result | ((b & 0x1f) << shift);
shift += 5;
} while (b >= 0x20);
var dlat = (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result = result | ((b & 0x1f) << shift);
shift += 5;
} while (b >= 0x20);
var dlng = (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
lng += dlng;
var p = {
latitude: lat / 1e5,
longitude: lng / 1e5,
};
poly.push(p);
}
return poly;
}
此方法可用于解码折线
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, shift = 0, result = 0;
do {
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 {
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;
}
这就是我得到折线的方式
JSONObject poly = route.getJSONObject("overview_polyline");
String polyline = poly.getString("points");
polyLineList = decodePoly(polyline);
在Pascal(Delphi)中也是如此:
function DecodeLine(inputstring: String): String;
var
lat, lon, lat_f, lon_f: Double;
index: Integer;
len: Integer;
b: Integer;
shift: Integer;
decodeResult: Integer;
encoded: String;
dlat: Integer;
dlng: Integer;
begin
Result := '';
encoded := inputstring;
len := Length(encoded);
index := 1;
lat := 0;
lon := 0;
while (index <= len) do begin
b := $20;
shift := 0;
decodeResult := 0;
while (b >= $20) do begin
b := ord(encoded[index]);
b := b - 63;
inc(index);
decodeResult := decodeResult or (b and $1f) Shl shift;
shift := shift + 5;
end;
if (decodeResult and 1) <> 0 then
dlat := not (decodeResult shr 1)
else
dlat := decodeResult shr 1;
lat := lat+dlat;
shift := 0;
decodeResult := 0;
b := $20;
while (b >= $20) do begin
b := ord(encoded[index]);
b := b-63;
inc(index);
decodeResult := decodeResult or (b and $1f) Shl shift;
shift := shift + 5;
end;
if (decodeResult and 1) <> 0 then
dlng := not (decodeResult shr 1)
else
dlng := decodeResult shr 1;
lon := lon + dlng;
{ The coordinates of the point are used for our purposes }
lon_f := lon/100000.0;
lat_f := lat/100000.0;
if Result <> '' then
Result := Result + ', ';
Result := Result + '(' + FloatToStr(lon_f) + ' - ' + FloatToStr(lat_f) + ')';
end; //while
end;
procedure TForm1.Button1Click(Sender: TObject);
var
str: String;
begin
// Do stuff
str := DecodeLine('ibgqGq}ycIMvM');
ShowMessage(str);
end;
这是iOS中的实现,对于任何好奇的人来说,完全基于@Fustigador的答案,但转换为iOS。请注意,我没有相应地格式化代码。为了返回承诺的对象,我只添加了一些变量。
- (GMSPath *)decodedPolylinePathFromEncodedPolylineString:(NSString *)encodedPolylineString {
NSString *decodedPolylineString = @"";
GMSMutablePath *decodedPolylinePath = [GMSMutablePath new];
CLLocationCoordinate2D decodedCoordinate;
CLLocationDegrees latitude, longitude;
int index = 0;
NSUInteger len = encodedPolylineString.length;
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = [encodedPolylineString characterAtIndex: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 = [encodedPolylineString characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
latitude = (((double) lat / 1E5));
longitude = (((double) lng / 1E5));
decodedCoordinate = CLLocationCoordinate2DMake(latitude, longitude);
decodedPolylineString = [NSString stringWithFormat:@"%f%f", latitude, longitude];
;
NSLog(@"%@",decodedPolylineString);
[decodedPolylinePath addCoordinate:decodedCoordinate];
}
return decodedPolylinePath;
}