Androidアプリにルート表示する(その6)
デコーダに関する問い合わせが多いので、恥かしながら公開しちゃいます。
本業はハードエンジニアなので質は問わないでくださいね m(--)m
デコード処理
public class decoder {
public static boolean LogPrint,LogPrint2; //デバッグ用フラグ
public static ArrayList<GeoPoint> decPolylines(StringBuffer polylines)
{
ArrayList<Double> point = decode(polylines);
ArrayList<GeoPoint> ret = new ArrayList<GeoPoint>();
int lat=(int)(point.get(0)*1E6);
int lng=(int)(point.get(1)*1E6);
ret.add(new GeoPoint(lat,lng));
for(int i=2;i<point.size();)
{
lat=lat+(int)(point.get(i++)*1E6);
lng=lng+(int)(point.get(i++)*1E6);
ret.add(new GeoPoint(lat,lng));
}
return ret;
}
private static ArrayList<Double> decode(StringBuffer input)
{
ArrayList<Double> ret =new ArrayList<Double>();
ArrayList<Byte> bit =new ArrayList<Byte>();
ArrayList<Byte> num =new ArrayList<Byte>();
// エスケープされている「\」を削除
while(true)
{
int i=input.indexOf("\\"+"\\");
if(i>0)
{
input.deleteCharAt(i);
}else{
break;
}
}
if(LogPrint2){System.out.println(input.toString()+"");}
for(int i=0;i<input.length();i++)
{
if(LogPrint){
System.out.print(input.charAt(i));
System.out.print(",");
System.out.print((int)input.charAt(i));
System.out.print(",");
myUtil.printBit(input.charAt(i));
System.out.println("");
}
bit.add((byte)(input.charAt(i)-63));
}
if(LogPrint){myUtil.printBit(bit,8);}
for(int i=0;i<bit.size();i++)
{
if((bit.get(i)&0x20)!=0)
{
num.add((byte) (bit.get(i)&0x1F));
}else{
num.add((byte) (bit.get(i)&0x1F));
ret.add(bit2double(num));
num.clear();
}
}
return ret;
}
private static double bit2double(ArrayList<Byte>num)
{
int bit=0;
if(LogPrint){myUtil.printBit(num,6);}
for(int i=0;i<num.size() ;i++)
{
bit=bit<<5;
bit=num.get(num.size()-i-1)|bit;
}
if(LogPrint){myUtil.printBit(bit,8);}
if((bit&0x01)==1) //負値の判定 最下位ビット=1
{
bit=~bit;
bit=bit>>1;
}else{
bit=bit>>1;
}
if(LogPrint2){System.out.println(bit);}
return (double)(bit/1E5);
}
}
呼び出し側の関連処理
GeoPoint fromP =new GeoPoint((int)(35.658586*1E6),(int)(139.745386*1E6));
GeoPoint toP =new GeoPoint((int)(35.709949*1E6),(int)(139.810681*1E6));
StringBuffer poly = new StringBuffer(route.points);
本業はハードエンジニアなので質は問わないでくださいね m(--)m
デコード処理
public class decoder {
public static boolean LogPrint,LogPrint2; //デバッグ用フラグ
public static ArrayList<GeoPoint> decPolylines(StringBuffer polylines)
{
ArrayList<Double> point = decode(polylines);
ArrayList<GeoPoint> ret = new ArrayList<GeoPoint>();
int lat=(int)(point.get(0)*1E6);
int lng=(int)(point.get(1)*1E6);
ret.add(new GeoPoint(lat,lng));
for(int i=2;i<point.size();)
{
lat=lat+(int)(point.get(i++)*1E6);
lng=lng+(int)(point.get(i++)*1E6);
ret.add(new GeoPoint(lat,lng));
}
return ret;
}
private static ArrayList<Double> decode(StringBuffer input)
{
ArrayList<Double> ret =new ArrayList<Double>();
ArrayList<Byte> bit =new ArrayList<Byte>();
ArrayList<Byte> num =new ArrayList<Byte>();
// エスケープされている「\」を削除
while(true)
{
int i=input.indexOf("\\"+"\\");
if(i>0)
{
input.deleteCharAt(i);
}else{
break;
}
}
if(LogPrint2){System.out.println(input.toString()+"");}
for(int i=0;i<input.length();i++)
{
if(LogPrint){
System.out.print(input.charAt(i));
System.out.print(",");
System.out.print((int)input.charAt(i));
System.out.print(",");
myUtil.printBit(input.charAt(i));
System.out.println("");
}
bit.add((byte)(input.charAt(i)-63));
}
if(LogPrint){myUtil.printBit(bit,8);}
for(int i=0;i<bit.size();i++)
{
if((bit.get(i)&0x20)!=0)
{
num.add((byte) (bit.get(i)&0x1F));
}else{
num.add((byte) (bit.get(i)&0x1F));
ret.add(bit2double(num));
num.clear();
}
}
return ret;
}
private static double bit2double(ArrayList<Byte>num)
{
int bit=0;
if(LogPrint){myUtil.printBit(num,6);}
for(int i=0;i<num.size() ;i++)
{
bit=bit<<5;
bit=num.get(num.size()-i-1)|bit;
}
if(LogPrint){myUtil.printBit(bit,8);}
if((bit&0x01)==1) //負値の判定 最下位ビット=1
{
bit=~bit;
bit=bit>>1;
}else{
bit=bit>>1;
}
if(LogPrint2){System.out.println(bit);}
return (double)(bit/1E5);
}
}
呼び出し側の関連処理
public class geoPolyline {
String points;
String levels;
}
新旧交代!さて何処から何処へのルート検索でしょうか?
GeoPoint fromP =new GeoPoint((int)(35.658586*1E6),(int)(139.745386*1E6));
GeoPoint toP =new GeoPoint((int)(35.709949*1E6),(int)(139.810681*1E6));
ルート検索結果からポリラインを抽出します。
geoPolyline route = gmap.getPolylines(gmap.getRouteJSON(fromP,toP));
points文字列をデコード処理に掛けます。
StringBuffer poly = new StringBuffer(route.points);
ArrayList<GeoPoint> point = decoder.decPolylines(poly);
地図上に描画すればOK!
for(int i=0; i < point.size()-1;i++)
{
GeoPoint p1 = point.get(i);
GeoPoint p2 = point.get(i+1);
lineOverlay polyline = new lineOverlay(p1,p2,3,Color.CYAN,128);
list.add(polyline);
}
コメント
コメントを投稿