经纬度转凯立德 K 码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经纬度转凯立德 K 码相关的知识,希望对你有一定的参考价值。

由于GPS信号位置均是经纬度球面坐标,国家从安全角度考虑不允许直接引用,因此凯立德为了方便导航者易于导航,就把经纬度坐标网格化,每一个网格单位代表纵横向0.1秒。

K码的具体格式如下:

 

1. K码是9位码;

2. K码将地图分成了四块进行编码,中心点在内蒙的阿拉善左旗境内;经纬度是东经105度0分0秒;北纬40度0分0秒

3. 以该点为中心分别在东西方向和南北方向画一条线当横纵(XY)坐标轴,那么第一象限(即东北方向的那块)的K码的第1位是5,第2、3、4象限的K码的第一位分别是6、7、8。

4. K码的第2-5位表示东西方向上的坐标,第6-9位代表南北方向上的坐标。

5. K码是一个凯立德特有的34进制数,(在KLD K码输入界面有说明:26个字母加10个阿拉伯数字,再去掉不用的L和O共34个字符),这个34进制数从左向右从低位向高位排列

6. 中心点的K码有4个,分别是500000000、6uy1y0000、7uy1yuy1y、80000uy1y。分别代表原点或中心点四个象限的K码。及X、Y轴正方向起始坐标0秒或代码为0000,X、Y轴负方向最大坐标为1260000秒或代码为uy1y

 

VC++的代码如下:

KCode.h 

 1 #ifndef _KLD_K_CODE_CALC_H_  
 2 #define _KLD_K_CODE_CALC_H_  
 3   
 4 typedef struct{  
 5     int iIndex;  
 6     TCHAR cKCode;  
 7 }MyKCode_T;  
 8   
 9 #define KLD_KCODE_SYSTEM            34  
10 #define KOCDE_MAX_LENGTH            4  
11 #define KCODE_CENTER_LAT            (40.0)  
12 #define KCODE_CENTER_LON            (105.0)  
13 #define KCODE_X_Y_MAX_NAGATIVE      1260000  
14   
15   
16 BOOL ConvertDuFenMiaoToDu(double dLatLonDu,double dLatLonFen,double dLatLonMiao,double &dLatLon);  
17 BOOL ConvertTo34System(DWORD dwNumber,TCHAR *pKCode,BOOL bNegative);  
18 BOOL ConvertTo34System2(DWORD dwNumber,TCHAR *pKCode,BOOL bNegative);   // 与 ConvertTo34System 功能相同,采用对照表的方式实现  
19   
20 BOOL KCodeToZeroPoint(double dLat,double dLon,TCHAR *pKCode,int iKCodeSize);  
21   
22 /* 
23 调用示例: 
24 double dLon = 0.0; 
25 double dLat = 0.0; 
26 TCHAR cTmpBuffer[2 * KOCDE_MAX_LENGTH + 2]; 
27  
28 ZeroMemory(cTmpBuffer,sizeof(TCHAR) * (2 * KOCDE_MAX_LENGTH + 2)); 
29 ConvertDuFenMiaoToDu(101.0,7.0,26.33,dLon); 
30 ConvertDuFenMiaoToDu(29.0,39.0,51.76,dLat); 
31 // ConvertDuFenMiaoToDu(40.0,0.0,0.0,dLat);     // 坐标轴上的点测试 
32 KCodeToZeroPoint(dLat,dLon,cTmpBuffer,2 * KOCDE_MAX_LENGTH + 2); 
33 */  
34   
35 #endif  

源代码:

KCode.cpp 

  1 #include "stdafx.h"  
  2 #include "KCode.h"  
  3   
  4 MyKCode_T gMyKCode[KLD_KCODE_SYSTEM] =   
  5 {  
  6     {0, 0},  
  7     {1, 1},  
  8     {2, 2},  
  9     {3, 3},  
 10     {4, 4},  
 11     {5, 5},  
 12     {6, 6},  
 13     {7, 7},  
 14     {8, 8},  
 15     {9, 9},  
 16     {10,a},  
 17     {11,b},  
 18     {12,c},  
 19     {13,d},  
 20     {14,e},  
 21     {15,f},  
 22     {16,g},  
 23     {17,h},  
 24     {18,i},  
 25     {19,j},  
 26     {20,k},   // no L  
 27     {21,m},  
 28     {22,n},   // no character O  
 29     {23,p},  
 30     {24,q},  
 31     {25,r},  
 32     {26,s},  
 33     {27,t},  
 34     {28,u},  
 35     {29,v},  
 36     {30,w},  
 37     {31,x},  
 38     {32,y},  
 39     {33,z},  
 40 };  
 41   
 42 BOOL ConvertDuFenMiaoToDu(double dLatLonDu,double dLatLonFen,double dLatLonMiao,double &dLatLon)  
 43 {  
 44     BOOL bRet = TRUE;  
 45   
 46     // 输入有效性判断  
 47     {  
 48     }  
 49   
 50     dLatLon = dLatLonDu + (dLatLonFen + (dLatLonMiao / 60.0)) / 60.0;  
 51   
 52     return bRet;  
 53 }  
 54   
 55 BOOL ConvertTo34System2(DWORD dwNumber,TCHAR *pKCode,BOOL bNegative)  
 56 {  
 57     BOOL bRet = TRUE;  
 58     DWORD dwDivideBy34 = dwNumber;  
 59     int iModeOf34 = 0;  
 60     int iCount = 0;  
 61     int i = 0;  
 62   
 63     // dwDivideBy34 = 1260000;  
 64   
 65     do  
 66     {  
 67         iModeOf34 = dwDivideBy34 % 34;  
 68         dwDivideBy34 = dwDivideBy34 / 34;  
 69   
 70         for(i = 0;i < KLD_KCODE_SYSTEM;i++)  
 71         {  
 72             if(iModeOf34 == gMyKCode[i].iIndex)  
 73             {  
 74                 pKCode[iCount] = gMyKCode[i].cKCode;  
 75                 iCount++;  
 76                 if(1 == iCount && bNegative)  
 77                 {  
 78                     pKCode[0]--;  
 79                 }  
 80   
 81                 break;  
 82             }  
 83         }  
 84   
 85     }while(dwDivideBy34 > 0);  
 86   
 87     return bRet;  
 88 }  
 89   
 90 BOOL ConvertTo34System(DWORD dwNumber,TCHAR *pKCode,BOOL bNegative)  
 91 {  
 92     BOOL bRet = TRUE;  
 93     DWORD dwDivideBy34 = dwNumber;  
 94     int iModeOf34 = 0;  
 95     int iCount = 0;  
 96   
 97     do  
 98     {  
 99         iModeOf34 = dwDivideBy34 % 34;  
100         dwDivideBy34 = dwDivideBy34 / 34;  
101   
102         if(iModeOf34 <= 9)  
103         {  
104             pKCode[iCount] = 0 + iModeOf34;  
105         }  
106         else if(iModeOf34 >= 10 && iModeOf34 <= 20)  
107         {  
108             pKCode[iCount] = a + (iModeOf34 - 10);  
109         }  
110         else if(iModeOf34 >= 21 && iModeOf34 <= 22)  
111         {  
112             pKCode[iCount] = m + (iModeOf34 - 21);  
113         }  
114         else if(iModeOf34 >= 23 && iModeOf34 <= 33)  
115         {  
116             pKCode[iCount] = p + (iModeOf34 - 23);  
117         }  
118         iCount++;  
119         if(1 == iCount && bNegative)  
120         {  
121             pKCode[0]--;  
122         }  
123   
124     }while(dwDivideBy34 > 0);  
125   
126     return bRet;  
127 }  
128   
129 /* 
130  * 说明: iKCodeSize 的大小包含最后的 NULL 
131 */  
132 BOOL KCodeToZeroPoint(double dLat,double dLon,TCHAR *pKCode,int iKCodeSize)  
133 {  
134     BOOL bRet = TRUE;  
135     DWORD dwTmpLat = 0;  
136     DWORD dwTmpLon = 0;  
137     BOOL bIsNegative = FALSE;  
138     TCHAR pKCodeLat[KOCDE_MAX_LENGTH + 1];  
139     TCHAR pKCodeLon[KOCDE_MAX_LENGTH + 1];  
140   
141     // 输入有效性判断  
142     {  
143         if(iKCodeSize < (2 * KOCDE_MAX_LENGTH + 1))  
144         {  
145             return bRet;  
146         }  
147         if(NULL == pKCode)  
148         {  
149             bRet = FALSE;  
150             return bRet;  
151         }  
152     }  
153   
154     ZeroMemory(pKCodeLat,sizeof(TCHAR) * (KOCDE_MAX_LENGTH + 1));  
155     ZeroMemory(pKCodeLon,sizeof(TCHAR) * (KOCDE_MAX_LENGTH + 1));  
156   
157     if(NULL != pKCodeLat)  
158     {  
159         double dDiff = (dLat - KCODE_CENTER_LAT);  
160   
161         if(dDiff < 0)  
162         {  
163             bIsNegative = TRUE;  
164             dDiff = -dDiff;  
165             dwTmpLat = (DWORD)((dDiff * 3600) * 10);        // 以 0.1 秒为单位  
166             dwTmpLat = KCODE_X_Y_MAX_NAGATIVE - dwTmpLat;  
167         }  
168         else  
169         {  
170             bIsNegative = FALSE;  
171             dwTmpLat = (DWORD)((dDiff * 3600) * 10);        // 以 0.1 秒为单位  
172         }  
173         ConvertTo34System(dwTmpLat,pKCodeLat,bIsNegative);  
174     }  
175   
176     if(NULL != pKCodeLon)  
177     {  
178         double dDiff = (dLon - KCODE_CENTER_LON);  
179   
180         if(dDiff < 0)  
181         {  
182             bIsNegative = TRUE;  
183             dDiff = -dDiff;  
184             dwTmpLon = (DWORD)((dDiff * 3600) * 10);        // 以 0.1 秒为单位  
185             dwTmpLon = KCODE_X_Y_MAX_NAGATIVE - dwTmpLon;  
186         }  
187         else  
188         {  
189             bIsNegative = FALSE;  
190             dwTmpLon = (DWORD)((dDiff * 3600) * 10);        // 以 0.1 秒为单位  
191         }  
192         ConvertTo34System(dwTmpLon,pKCodeLon,bIsNegative);  
193     }  
194   
195     if(KCODE_CENTER_LAT == dLat || KCODE_CENTER_LON == dLon)  
196     {  
197         if(KCODE_CENTER_LAT == dLat && KCODE_CENTER_LON == dLon)  
198         {  
199             pKCode[0] = 5;  
200         }  
201         else if(KCODE_CENTER_LAT == dLat)  
202         {  
203             if(dLon > KCODE_CENTER_LON)  
204             {  
205                 pKCode[0] = 6;  
206             }  
207             else  
208             {  
209                 pKCode[0] = 8;  
210             }  
211         }  
212         else if(KCODE_CENTER_LON == dLon)  
213         {  
214             if(dLat > KCODE_CENTER_LAT)  
215             {  
216                 pKCode[0] = 5;  
217             }  
218             else  
219             {  
220                 pKCode[0] = 7;  
221             }  
222         }  
223     }  
224     else  
225     {  
226         if(dLat > KCODE_CENTER_LAT)  
227         {  
228             if(dLon > KCODE_CENTER_LON)  
229             {  
230                 pKCode[0] = 5;  
231             }  
232             else  
233             {  
234                 pKCode[0] = 6;  
235             }  
236         }  
237         else  
238         {  
239             if(dLon > KCODE_CENTER_LON)  
240             {  
241                 pKCode[0] = 8;  
242             }  
243             else  
244             {  
245                 pKCode[0] = 7;  
246             }  
247         }  
248     }  
249     wcscat_s(pKCode,iKCodeSize,pKCodeLon);  
250     wcscat_s(pKCode,iKCodeSize,pKCodeLat);  
251     printf("K Code is: %s\r\n",pKCode);  
252   
253     return bRet;  
254 }  


  

说明:以下是后补的:

 1 // P76-P79行和P119-P122行存在边界值错误的问题。
 2 // 修改为:
 3 if(1 == iCount && bNegative)
 4 {
 5     if(0 == pKCode[0])
 6     {
 7         pKCode[0] = z;
 8     }
 9     else if(a == pKCode[0])
10     {
11         pKCode[0] = 9;
12     }
13     else if(m == pKCode[0])
14     {
15         pKCode[0] = k;
16     }
17     else if(p == pKCode[0])
18     {
19         pKCode[0] = n;
20     }
21     else
22     {
23         pKCode[0]--;
24     }
25 }
26 // 但此算法只是猜的,不知真正的实现是否是样。
27 // 有待后继实际数值来验证。

 

以上是关于经纬度转凯立德 K 码的主要内容,如果未能解决你的问题,请参考以下文章

凯立德导航For Android V6.7上线

pbootcms对接微信扫码登录代码核心片段和步骤(前后端)

IT人的立功,立言,立德三不朽

如何将纬度和经度转换为莫顿码(z 阶曲线)

程序人生一个IT人的立功,立言,立德三不朽

一个IT人的立功,立言,立德三不朽