2019年9月26日

C# Geometry 轉 Encoded Polyline Algorithm

因為,在開發 Google Map 時,在套疊資料較大的 Geometry 時,往往都會花比較多時間才能顯示於開發的 Google Map 上,而 Google 也提供了新的演算法,讓開發者在套圖的時候能更快速。

而我依照這個演算法,寫了 C# Asp.net 版本,首先,NuGet 的 套件管理器主控台,安裝 Install-Package Geolocation -Version 1.1.1。安裝完成後,就可以在 Bin 資料夾看到 Geolocation.dll 檔。然後,using 到你的專案上。


 

        using Geolocation;


        List points = new List();
        Coordinate coordinate = new Coordinate();

        coordinate.Latitude = 38.5;
        coordinate.Longitude = -120.2;
        points.Add(coordinate);


        Response.Write("38.5 -120.2 ->" + Encode(points) + "
");

    
    //解密
    public static List Decodee(string polylineString)
    {
        List list = new List();
        var polylineChars = polylineString.ToCharArray();
        var index = 0;
        var currentLat = 0;
        var currentLng = 0;

        while (index < polylineChars.Length)
        {
            var sum = 0;
            var shifter = 0;
            int nextFiveBits;
            do
            {
                nextFiveBits = polylineChars[index++] - 63;
                sum |= (nextFiveBits & 31) << shifter;
                shifter += 5;
            } while (nextFiveBits >= 32 && index < polylineChars.Length);

            if (index >= polylineChars.Length)
                break;

            currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);

            sum = 0;
            shifter = 0;
            do
            {
                nextFiveBits = polylineChars[index++] - 63;
                sum |= (nextFiveBits & 31) << shifter;
                shifter += 5;
            } while (nextFiveBits >= 32 && index < polylineChars.Length);

            if (index >= polylineChars.Length && nextFiveBits >= 32)
                break;

            currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);

            Coordinate coordinate = new Coordinate();
            coordinate.Latitude = Convert.ToDouble(currentLat) / 1E5;
            coordinate.Longitude = Convert.ToDouble(currentLng) / 1E5;
            list.Add(coordinate);
        }

        return list;
    }

    //加密
    public static string Encode(List points)
    {
        var str = new StringBuilder();

        var encodeDiff = (Action)(diff => {
            int shifted = diff << 1;
            if (diff < 0)
                shifted = ~shifted;
            int rem = shifted;
            while (rem >= 0x20)
            {
                str.Append((char)((0x20 | (rem & 0x1f)) + 63));
                rem >>= 5;
            }
            str.Append((char)(rem + 63));
        });

        int lastLat = 0;
        int lastLng = 0;
        foreach (var point in points)
        {
            int lat = (int)Math.Round(point.Latitude * 1E5);
            int lng = (int)Math.Round(point.Longitude * 1E5);
            encodeDiff(lat - lastLat);
            encodeDiff(lng - lastLng);
            lastLat = lat;
            lastLng = lng;
        }
        return str.ToString();
    }

比對後結果,感覺,Google Map Platform 網頁上第二和三筆是有問題的,不知道為什麼?

沒有留言:

張貼留言