• GoogleMap 编码折线算法 BCB实现


    公司一直用BCB做开发的. 用到了此算法.结果在Google搜索上找到的几乎全是Java版的.所以决定自己写.下面是我的代码. 现贴出来供大家参考下.

    //---------------------------------------------------------------------------

    #include <vcl.h>
    #pragma hdrstop

    #include "math.h"
    #include "GooglePolyline.h"
    #include "Minux\MMath.h" //这个可以.去掉.是为了.调用下面.Round函数用的.

    //---------------------------------------------------------------------------
    /*二进制转换为十进制(8位)*/
    int __fastcall BintoDec(char* b)
    {
            int j = 0,v = 0;
            int Len = strlen(b);
            if (Len < 1) return Len;
            for(int i=Len-1; i>=0; i--)
            {
                    if (b[i]=='1')
                            v += (int)pow(2,j);
                    j++;
            }
            return v;
    }
    //---------------------------------------------------------------------------

    String __fastcall Rights(String Value, int iLen)
    {
            int i;
            i = Value.Length() - iLen + 1;
            if (i<=0) i = 1;
            String ret = Value.SubString(i,iLen);
            return ret;
    }
    //---------------------------------------------------------------------------
    String __fastcall EncodePolyline(double* LngBuf, double* LatBuf, unsigned int BufLen)
    {
            double TmpLng, TmpLat;
            String ret;
            for (int i=0, iLoop=BufLen; i<iLoop; i++)
            {
                    TmpLng = LngBuf[i];
                    TmpLat = LatBuf[i];
                    if (i != 0)
                    {
                            TmpLng = LngBuf[i] - LngBuf[i-1];
                            TmpLat = LatBuf[i] - LatBuf[i-1];
                    }
                    ret += EncodePoint(TmpLng);
                    ret += EncodePoint(TmpLat);
            }
            return ret;
    }
    //---------------------------------------------------------------------------
    String __fastcall EncodePoint(double col)
    {
            /*1.取初始有符号值  col */
            /*2.将其取十进制值乘以 1e5,并取整:*/
       // Round是自定义函数.此处如果用Int取整的.话.三位小数时就会出.问题.用的到的朋友自己.Google下看把.
        int num = (Round)(col * 100000); 

            /*3.将十进制值转换为二进制值*/
            char buf[128]; itoa(num,buf,2);
            /*4.末位+0*/
            strcat(buf,"0");
            /*5.如果原来的十进制值是负数,则对以下编码求反.并去除前面的0*/
            if (num<0)
            {
                    for(int i=0,iLoop=strlen(buf);i<iLoop;i++)
                    {
                            if (buf[i]=='0')
                                    buf[i] = '1';
                            else
                                    buf[i] = '0';
                    }
            }
            char *ptr, c = '1';
            ptr = strchr(buf,c);
            if (ptr==NULL) return "";  //问题

            String str = ptr;
            int Len = strlen(ptr);
            /*6.将该二进制值分为 5 位一组的块(从右侧开始)*/
            /*7.将这些 5 位一组的块倒序放置*/
            /*8.如果后面还有一个位块,则将每个值与 0x20 进行“或”操作 (OR)*/
            /*9.将每个值转换为十进制*/
            /*10. 每个值+63 并将每个值转换为其对应的 ASCII 字符*/
            int cord = Len/5;
            int remainder = Len%5;
            if (cord*5 < Len)
            {
                    cord += 1;  //组数
            }
            if (remainder==1) str = "0000" + str;
            if (remainder==2) str = "000" + str;
            if (remainder==3) str = "00" + str;
            if (remainder==4) str = "0" + str;
            TStringList* ts = new TStringList;
            String ret;
            for(int i=0,iLoop=cord; i<iLoop; i++)
            {
                    ts->Add(Rights(str,5));
                    str = str.SubString(1,str.Length()-5);
                    int x = BintoDec(ts->Strings[i].c_str());
                    if (i!=cord-1)
                            x = x | 0x20;
                    x = x + 63;
                    ret += String(char(x));
            }
            delete ts;
            return ret;
    }
    //---------------------------------------------------------------------------
    String __fastcall EncodeLevels(int* LevBuf, int BufLen)
    {
            int TmpLev;
            String ret;
            for(int i=0, iLoop=BufLen; i<iLoop; i++)
            {
                    ret += EncodeLevel(LevBuf[i]);
            }
            return ret;
    }
    //---------------------------------------------------------------------------
    String __fastcall EncodeLevel(int Level)
    {
            char buf[128];
            itoa(Level,buf,2);
            char *ptr, c = '1';
            ptr = strchr(buf,c);
            if (ptr==NULL) return ""; //问题

            String str = ptr;
            int Len = strlen(ptr);
            int cord = Len/5;
            int remainder = Len%5;
            if (cord*5 < Len)
            {
                    cord += 1;  //组数
            }
            if (remainder==1) str = "0000" + str;
            if (remainder==2) str = "000" + str;
            if (remainder==3) str = "00" + str;
            if (remainder==4) str = "0" + str;
            TStringList* ts = new TStringList;
            String ret;
            for(int i=0,iLoop=cord; i<iLoop; i++)
            {
                    ts->Add(Rights(str,5));
                    str = str.SubString(1,str.Length()-5);
                    int x = BintoDec(ts->Strings[i].c_str());
                    if (i!=cord-1)
                            x = x | 0x20;
                    x = x + 63;
                    ret += String(char(x));
            }
            delete ts;
            return ret;
    }
    //---------------------------------------------------------------------------

    已经通过 .Google算法.实例.测试.
    http://code.google.com/intl/zh-CN/apis/maps/documentation/polylinealgorithm.html

  • 相关阅读:
    T-SQL over()函数在单个表中的聚合
    jQuery EasyUI DataGrid API 中文文档
    ASP.Net UpdatePanel控件(转)
    java多线程系类:基础篇:03Thread中的start()和run()的区别
    java多线程系类:基础篇:02常用的实现多线程的两种方式
    java多线程系类:基础篇:01基本概念:
    完全二叉树的概念
    007商城项目:商品列表查询-需求分析,以及Spinmvc的访问知识
    006商城项目:该项目的路径访问问题
    githup上传代码
  • 原文地址:https://www.cnblogs.com/vin2008/p/1679074.html
Copyright © 2020-2023  润新知