varios studio setup marcadores google example agregar android google-maps polyline

studio - google maps api key android



Decodificación de polilínea con la nueva API de Google Maps (8)

Aquí está la implementación en iOS, para cualquiera que tenga curiosidad, que se basa completamente en la respuesta de @Fustigador, pero que se convirtió a iOS. Tenga en cuenta que no he formateado el código en consecuencia. Solo agregué algunas variables para devolver el objeto prometido.

- (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; }

Estoy dibujando una ruta entre dos puntos en un mapa. Recibo los puntos de esta manera:

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;

Recibo la respuesta de Google y obtengo el 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);

La respuesta que recibo de google: (en formato 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

Y finalmente, decodifico la Cadena recibida de esta manera, que encontré en muchas respuestas aquí en 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; }

Aquí es donde creo que está el error, porque configuro un para ver los puntos que se están decodificando, y la respuesta es algo como:

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

Obviamente, estos puntos están mal analizados. El resultado es, ninguna línea dibujada en ninguna parte.

Mi pregunta es ... ¿alguien sabe cómo analizar la respuesta de Google y traducirla a objetos LatLng (NO a objetos GeoPoints)?

¡Gracias!

EDITAR:

Esta es la cadena que está a punto de ser decodificada:

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

Si con formato LatLng te refieres a la forma en que se crean los objetos LatLng, puedes ver en el método decodePoly. Estos objetos latLng se agregan a los objetos PolylineOptions, y esto se agrega al mapa, de esta manera:

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);


Aquí está tu función en Visual Basic, que uso a menudo.

Structure LatLng Dim Lat As Decimal Dim Lon As Decimal End Structure Function decodePoly(ByRef encoded As String) As List(Of LatLng) Dim poly As List(Of LatLng) = New List(Of LatLng) Dim index As Integer = 0 Dim len As Integer = encoded.Length() Dim lat As Integer = 0 Dim lng As Integer = 0 While (index < len) Dim b As Integer Dim shift As Integer = 0 Dim result As Integer = 0 Do b = AscW(encoded.Chars(index)) - 63 index += 1 result = result Or (b And &H1F) << shift shift += 5 Loop While (b >= &H20) Dim dlat As Integer If (result And 1) <> 0 Then dlat = Not (result >> 1) Else dlat = result >> 1 End If lat += dlat shift = 0 result = 0 Do b = AscW(encoded.Chars(index)) - 63 index += 1 result = result Or (b And &H1F) << shift shift += 5 Loop While (b >= &H20) Dim dlng As Integer If (result And 1) <> 0 Then dlng = Not (result >> 1) Else dlng = result >> 1 End If lng += dlng Dim p As LatLng = New LatLng With {.Lat = (lat / 100000.0), .Lon = (lng / 100000.0)} poly.Add(p) End While decodePoly = poly End Function



Este método es útil para decodificar polilínea.

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; }

Así es como estoy haciendo polilínea.

JSONObject poly = route.getJSONObject("overview_polyline"); String polyline = poly.getString("points"); polyLineList = decodePoly(polyline);


Lo mismo en 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; }


Lo mismo en Pascal (Delfos):

var lat,lon,lat_f,lon_f:Double; var index:Integer; var len:Integer; var b:Integer; var shift:Integer; var result:Integer; var encoded:String; var dlat:Integer; var dlng:Integer; encoded:=''ibgqGq}ycIMvM''; len:= Length(encoded); lat:=0; lon:=0; While (index <=len) do begin b:=$20; shift:=0; result:=0; While (b >= $20) do begin b:=ord(encoded[index]); b:=b-63; index:= index+1; result:= result OR (b AND $1f) Shl shift; shift:=shift + 5; end; If (result And 1) <> 0 Then dlat:= Not (result Shr 1) Else dlat:= result Shr 1; lat:=lat+dlat; shift:= 0; result:= 0; b:=$20; While (b >= $20) do begin b:=ord(encoded[index]); b:=b-63; index:= index+1; result:= result OR (b AND $1f) Shl shift; shift:=shift + 5; end; If (result And 1) <> 0 Then dlng:= Not (result Shr 1) Else dlng:= result 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; end; //while


Para aquellos que necesitan esto ahora, hay una biblioteca de código abierto con muchas cosas útiles relacionadas con la API de Android de Google Maps, incluida la decodificación y codificación de polilíneas.

Compruébelo en Android Maps Utils y android-maps-utils . Para decodificación y codificación de uso:

PolyUtil.decode(String encodedPath); PolyUtil.encode(List<LatLng> path);


Publiqué una respuesta similar a esta pregunta en otra publicación para Android / Java. Decodificando el poly y devolviendo Latlng en lugar de Geopoints.