LoginSignup
2
1

Google Directions API の encoded poly line をデコード

Last updated at Posted at 2021-05-18

Google Directions API を使用すると、地図上の経路を返してくれます。

https://maps.googleapis.com/maps/api/directions/json?origin=東京&destination=大阪&key=YOUR_API_KEY

image.png

返してはくれるのですが、ルートは

{
   "geocoded_waypoints" : [
      {
         "geocoder_status" : "OK",
         "place_id" : "ChIJXSModoWLGGARILWiCfeu2M0",
         "types" : [ "colloquial_area", "locality", "political" ]
      },

 :
 :
                     "polyline" : {
                        "points" : "qywxEesatYm@]_@Q_Ag@mAo@k@]oAw@a@W]Qa@UaA_@GCcBu@CA[Mo@U[KQCEAI?IBYL[ZWREB}@j@CBm@^MFA@[PWNGDYNe@Xs@`@[TSNUNWRUNUPOJi@\\a@\\IHWPWRQLo@d@A@WTSNKJA?QPIHGJKNEFGPADCDCJCJGRCNANA@AHCXE\\AHCVAJAHBX"
                     },
 :
 :

qywxEesatYm@]... のようにエンコードされた形で返ってきます。
エンコードルールはこちら

エンコードされた結果はこちらのページでデコードできるのですが、自動で変換するためのソースコードをこちらにアップしてくれている方がいました。

今回はこれをUnityから使えるようC#にコンバートしてみました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace TmLib
{
    static public class TmMapsLib
    {
        //https://stackoverflow.com/questions/15924834/decoding-polyline-with-new-google-maps-api
        public struct LatLng
        {
            public double lat;
            public double lng;
            public LatLng(double _lat, double _lng)
            {
                lat = _lat;
                lng = _lng;
            }
        }
        static public List<LatLng> DecodePoly(string encoded)
        {
            List<LatLng> poly = new List<LatLng>();
            int index = 0, len = encoded.Length;
            int lat = 0, lng = 0;
            char[] charArr = encoded.ToCharArray();

            while (index < len)
            {
                int b, shift = 0, result = 0;
                do
                {
                    b = charArr[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 = charArr[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;
        }
    }
}

使い方はこんな感じです

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PolyLineDecodeTest : MonoBehaviour
{
    string points = "}gwrEkzexXRIBABAJEDCDCDGHKDG?AFMBK@E@I?G?Q?GAICQAACGACCGEIEIEEGEACAAEEGISOUQMKUUKMCCOOQKw@q@IKWUY_@KYAAEEIMIOIOIQMWGMGMCAMYSa@Q]EKIQCEMWWi@Ym@GKKSKU_@q@IQUa@A?Ua@QUOWIKGKEEEESWQWMSIKWa@AAUa@EGMWMWGKSc@?AQa@MYM]Se@GQQe@GSIQOg@IQIUOc@IUEOY{@_@oAGOGSGQ_@oAMe@Og@A?Mg@Oe@Og@EI_@qA_@kA[}@?COa@ACGMKUISEKAEIOISGKKSACSc@GOIOKWGMAAEMEKGQCGGSGSGSMg@GSCM?AEQKk@Ic@QeAUoACQCWM{@CYEWASAGAI?AKqACa@Gu@IuACc@G{@OiC?OC_AAUAo@AkBAwB?_@?K?i@?k@Ak@?S?k@?E?s@?W?YA[?y@?G?_@A[ASAQCe@AGAOM{@I_@Ma@Qk@M[ACIQ[k@EGq@_AQSg@i@q@s@k@q@OMCCACCCAC]g@IMACCCIMIQGMEKIQEOGOK_@K_@AEIa@CIG_@Ii@AGYoBG]Kq@CSEUIc@?CScAIc@Ka@Om@CKSq@EQQe@GSWy@IUGOQe@EIK[i@wA]_AIUGO_@cA_@aA[{@Qe@ACACEOc@mAg@qAEMa@gAACc@mAa@gAQe@Qe@Oa@Y{@[{@?AOi@Mc@CCACCKCKEOK_@AIKe@Ka@GWCOAEEUIi@Ko@M_ACUGg@?CMoA?EIuAEgAAQAQAKCiACk@AS?UCk@Ak@Ck@EwA?MAM?SAQAQAQ?I?IKoDQuGEeA?QGsB?SASAOIyCAY?OKyCEqBCi@Ag@AY?AAO?MMyECi@AWCmAAo@?m@AG?GEoA?GA{@A[Ac@?EAk@Aq@AqA?AAi@?W?_A?aB?g@?c@?a@FuDDoA?SB}@?W@K?K?O?O?G?m@?_@?KAgA?OAc@KsF?WAk@?i@?o@?K?K@S?Q?S?UBwA@i@@k@?y@?M?k@?UCg@Ag@AYCO?GEa@C[AOK{@E_@Iu@Ee@E[E[CUQ_B?ACQCSIm@Eg@EWK{@Gk@E[AMGi@WuBAIGi@AIESCQAIAGEYEUEU?CQu@Me@CMEMWaAKe@GOCK[iACKACSs@Ma@g@gBKc@Su@_@uAo@yBIYK[EMCKISGSAGCG?A_@gAACYy@[y@[w@GOSe@[w@[s@Sg@e@eASe@{@mBSc@g@gAEICIISKQAECCmAqCSe@CEc@aAaAyBg@gASc@?CS_@?ASa@?AGMKUWk@CGCGIUKSEIEMGM_@y@Sc@Se@Sc@GMM[Q]CIiAgCSe@O]CEQe@MYACACSc@Qe@Sc@]y@m@aBAECEEKEKGQGSc@kAQe@Qe@Oc@?AQe@Oe@]cAAEAGAACEGQEUQe@CKAEAE_@mAo@uBOe@AAMe@Oe@_@mAAEACCG?AAAOe@Og@CKKYOg@GUGOOe@Og@Mc@ACACCGK]_@mAOg@_@mASo@K]?A[cACGSq@Wy@Og@g@aBYy@Og@Oe@GSGSOg@Me@?AGQQo@Mg@Os@CEAICKEOGWKe@?CAA]aBGWI]S{@?CAEAECKACGYCKCKAGCOAC?CQu@GUCOEMI_@k@iC}@cEOo@I[AIAGGUQ{@WiAOo@Ki@]}AOo@Om@AICIIa@Sy@Sy@W_AIYACAECIM]K_@CGIY_@cAOe@CGkB}EM_@MY{@_CKUq@iBEKEM{@}BKWeAwCc@iAMa@CEEGCIGSK[GWIUIYMg@CM]aBCMCOEWYcBGYW{AUwAKk@O}@Qy@?AAKMu@Ig@Ki@O}@EUO{@O}@AGSmAKo@Kq@G_@UsAc@oCEWSoAAIG[?EAEAGSuAIs@CWCW?GCQAQM_BCm@AWCe@EgACm@AS?UASAOOuDAO?OAYEy@Cs@Ca@Aa@AIC_ACk@Ci@?MAOAO?G?G?ACg@Cm@AaAAk@AS?m@?u@?_@?S?W@G?c@@c@?E@O@[?WD_B?KBk@@i@@W?K?E@G?G?G?M?KBu@Ba@@i@@o@@M?MDuA@k@Bk@DcB?]B}@@Y@W?M@M?U@W?K@KJoD?EJsD?I@K@i@@S?WBk@@k@Bu@?K@KB}@@O@M?KB[HiAFm@BUDYBMFc@F_@Ha@J_@Li@VaAd@wABIFSBGBIBEBGRg@HSNa@\\u@Ra@b@{@h@_An@eAtA}BrBgD|@yA`@o@DIDIDIFGFKFILU`@q@Xg@P[R[vBsDDGBEBEFI";
    // Start is called before the first frame update
    void Start()
    {

        List<TmLib.TmMapsLib.LatLng> list = TmLib.TmMapsLib.DecodePoly(points);
        foreach(TmLib.TmMapsLib.LatLng latlng in list)
        {
            Debug.Log(latlng.lat+","+latlng.lng);
        }
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

image.png

また、OpenStreetMap APIを使用しても同様なエンコード文字列を返してくれます。

https://router.project-osrm.org/route/v1/driving/

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1