Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用新的谷歌地图API解码多段线_Android_Google Maps_Polyline - Fatal编程技术网

Android 使用新的谷歌地图API解码多段线

Android 使用新的谷歌地图API解码多段线,android,google-maps,polyline,Android,Google Maps,Polyline,我正在地图上两点之间画一条路线。我通过以下方式获得积分: StringBuilder urlString = new StringBuilder(); urlString.append("http://maps.googleapis.com/maps/api/directions/json"); urlString.append("?origin=");// from urlString.append(Double.toString

我正在地图上两点之间画一条路线。我通过以下方式获得积分:

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;
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);
我从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);
很明显,这些点解析得很糟糕。结果是,任何地方都没有画线

我的问题是。。。有人知道如何解析来自谷歌的答案,并将其转换为LatLng对象(而不是GeoPoints对象)吗

编辑:

这是将要解码的字符串:

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对象,并通过以下方式将其添加到地图:

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;
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);
PolylineOption ruta=新的PolylineOptions();

对于(inti=0;i我更改了我在谷歌搜索了很长时间后发现的用于此项的decodePoly,现在正确绘制了路线

改变

LatLng p = new LatLng((int) (((double) lat /1E5)* 1E6), (int) (((double) lng/1E5   * 1E6)));
为了


现在开始工作。

这是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;
}
-(GMSPath*)decodedPolylinePathFromEncodedPolylineString:(NSString*)encodedPolylineString{
NSString*decodedPolylineString=@”;
GMSMutablePath*decodedPolylinePath=[GMSMutablePath new];
CLLocationCoordinate2D解码坐标;
CLLocationDegrees纬度、经度;
int指数=0;
NSU整数len=encodedPolylineString.length;
int lat=0,lng=0;
while(指数>1):(结果>>1));
lat+=dlat;
移位=0;
结果=0;
做{
b=[encodedPolylineString characterAtIndex:index++]-63;
结果|=(b&0x1f)=0x20);
int-dlng=((结果&1)!=0?~(结果>>1):(结果>>1));
液化天然气+=液化天然气;
纬度=((双)纬度/1E5));
经度=((双)液化天然气/1E5));
decodedCoordinate=CLLocationCoordinate2DMake(纬度、经度);
decodedPolylineString=[NSString stringWithFormat:@“%f%f”,纬度,经度];
;
NSLog(@“%@”,decodedPolylineString);
[decodedPolylinePath addCoordinate:decodedCoordinate];
}
返回decodedPolylinePath;
}
与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;
    }
函数解码多段线(编码){
如果(!编码){
返回[];
}
var poly=[];
var指数=0,len=encoded.length;
var lat=0,lng=0;
while(指数>1):(结果>>1);
lat+=dlat;
移位=0;
结果=0;
做{
b=encoded.charCodeAt(index++)-63;
结果=结果|((b&0x1f)=0x20);
var dlng=(结果&1)!=0?~(结果>>1):(结果>>1);
液化天然气+=液化天然气;
var p={
纬度:纬度/1e5,
经度:lng/1e5,
};
聚推(p);
}
返回多边形;
}

对于那些现在需要的人,有一个开源库,里面有很多关于谷歌地图Android API的有用信息,包括多段线的解码和编码

请在和处查看。 对于解码和编码使用:

PolyUtil.decode(String encodedPath);
PolyUtil.encode(List<LatLng> path);
PolyUtil.decode(字符串编码路径);
PolyUtil.encode(列表路径);
与Pascal(Delphi)相同:

函数DecodeLine(inputstring:String):String;
变量
lat,lon,lat_f,lon_f:双精度;
索引:整数;
len:整数;
b:整数;
移位:整数;
解码结果:整数;
编码:字符串;
dlat:整数;
dlng:整数;
开始
结果:='';
编码:=输入字符串;
len:=长度(编码);
指数:=1;
lat:=0;
lon:=0;
当(指数=20美元)开始时
b:=ord(编码[索引]);
b:=b-63;
公司(指数),;
decodeResult:=decodeResult或(b和$1f)Shl移位;
班次:=班次+5;
结束;
如果(解码结果和1)为0,则
dlat:=非(解码结果shr 1)
其他的
dlat:=解码结果shr 1;
lat:=lat+dlat;
移位:=0;
解码结果:=0;
乙:=二十元;;
当(b>=$20)开始时
b:=ord(编码[索引]);
b:=b-63;
公司(指数),;
decodeResult:=decodeResult或(b和$1f)Shl移位;
班次:=班次+5;
结束;
如果(解码结果和1)为0,则
dlng:=非(解码结果shr 1)
其他的
dlng:=解码结果shr 1;
lon:=lon+dlng;
{点的坐标用于我们的目的}
lon_f:=lon/100000.0;
lat_f:=lat/100000.0;
如果结果为“”,则
结果:=结果+',';
结果:=结果+'('+FloatToStr(lon_f)+'-'+FloatToStr(lat_f)+');
end;//while
结束;
程序TForm1.按钮1单击(发送方:TObject);
变量
str:字符串;
开始
//做事
str:=DecodeLine('ibgqGq}ycIMvM');
ShowMessage(str);
结束;

此方法对于解码多段线非常有用

 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);
私有列表解码多边形(字符串编码){
List poly=new ArrayList();
int index=0,len=encoded.length();
int lat=0,lng=0;
while(指数>1):(结果>>1));
lat+=dlat;
移位=0;
结果=0;
做{
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;
 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);
private List<GeoPoint> decodePoly(String encoded){
     
     List<GeoPoint> poly = new ArrayList<GeoPoint>();
     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;

            GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));
            poly.add(p);
     } 
     return poly;
}