凯立德K码转经纬度

来源:互联网 发布:java web 日志管理 编辑:程序博客网 时间:2024/05/17 07:54

公司web应用要需要把 K 码转成经纬度,网上搜了一下,这方面的资料不多,多数介绍都不全面。根据网上的说法,自己有琢磨了一天,终于搞清了K码原委,基本原理叙述如下。


K码能标识的范围为 东经 70-140度,北纬 5-75度这块区域, 以这块区域的中心点东经105 北纬40 (105,40)为对称点,把这块区域划分为四个象限,分别标示为 5, 6 ,7 ,8 象限, 每个象限都有自己的参考点,5象限的参考点是(105,40),6象限的参考点是(70,40),7象限的参考点是(70,5),8象限的参考点是(105,5)。

K码计算方法如下, 把每个位置的经纬度和该位置所在的象限的参考点的经纬度分别相减,结果两个差值肯定不小于0,把经度相减的差值乘以3600再乘以10(得到的结果以0.1秒为单位),把该结果换算成凯立德自定义的34进制(特别注意,凯立德34进制是 低位在前,高位在后,和十进制高位在前低位在后相反),换算的结果是4位的34进制数(不足四维补0)。下面K码转 经纬度的代码,有C++ 的,有java的


kcode.h


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>


#define IS_NUM(al) al != 'l' && al != 'o' && ( (al >= '0' && al <= '9') || (al >= 'a' && al <= 'z'))


static char maps[34] = {
'0','1','2','3','4',
'5','6','7','8','9',
'a','b','c','d','e',
'f','g','h','i','j',
'k','m','n','p','q',
'r','s','t','u','v',
'w','x','y','z'
};


static short r_maps[123];


void init_r_maps();


int convert34to10(const char* num34, int len);


int convert(char* num34, int len, float& ltu, float& lat);


int pow34(int i);


kcode.cpp

#include "kcode.h"


int main(int argc, char **argv)
{
if(argc != 2)
{
printf("Usage: %s <KCode>\n", argv[0]);
return 0;
}
init_r_maps();


float lu,la;
convert((char*)argv[1],9,lu,la);
printf("%f,%f\n",lu,la);


return 0;
}




int convert34to10(const char* num34, int len)
{
int num10 = 0;
for(int i = 0; i < len; ++i)
{
assert(IS_NUM(num34[i]));
num10 += r_maps[ num34[i] ] * pow34(i);
}


return num10;
}


int convert(char* num34, int len, float& ltu, float& lat)
{
printf("%s\n", num34);
assert(len == 9);
int quad = *num34;


printf("-----quad = %c\n", *num34);


char *pltu = num34 + 1;
char *plat = num34 + 5;
switch(quad)
{
case '5':
ltu = convert34to10(pltu, 4);
lat = convert34to10(plat, 4);


ltu = (float)ltu / (3600 * 10) + 105;
lat = (float)lat / (3600 * 10) + 40;
break;
case '6':
ltu = convert34to10(pltu, 4);
lat = convert34to10(plat, 4);
ltu = (float)ltu / (3600 * 10) + 70;
lat = (float)lat / (3600 * 10) + 40;
break;
case '7':
ltu = convert34to10(pltu, 4);
lat = convert34to10(plat, 4);
ltu = (float)ltu / (3600 * 10) + 70;
lat = (float)lat / (3600 * 10) + 5;
break;
case '8':
ltu = convert34to10(pltu, 4);
lat = convert34to10(plat, 4);
ltu = (float)ltu / (3600 * 10) + 105;
lat = (float)lat / (3600 * 10) + 5;
break;
}


return 0;
}


void init_r_maps()
{
memset(r_maps, 0, 255);
r_maps['0'] = 0;
r_maps['1'] = 1;
r_maps['2'] = 2;
r_maps['3'] = 3;
r_maps['4'] = 4;
r_maps['5'] = 5;
r_maps['6'] = 6;
r_maps['7'] = 7;
r_maps['8'] = 8;
r_maps['9'] = 9;
r_maps['a'] = 10;
r_maps['b'] = 11;
r_maps['c'] = 12;
r_maps['d'] = 13;
r_maps['e'] = 14;
r_maps['f'] = 15;


r_maps['g'] = 16;
r_maps['h'] = 17;
r_maps['i'] = 18;
r_maps['j'] = 19;
r_maps['k'] = 20;
r_maps['m'] = 21;
r_maps['n'] = 22;
r_maps['p'] = 23;


r_maps['q'] = 24;
r_maps['r'] = 25;
r_maps['s'] = 26;
r_maps['t'] = 27;
r_maps['u'] = 28;
r_maps['v'] = 29;
r_maps['w'] = 30;
r_maps['x'] = 31;
r_maps['y'] = 32;
r_maps['z'] = 33;
}


int pow34(int i)
{
int sum = 1;
while(i > 0)
{
sum *= 34;
--i;
}
return sum;
}


java版本 

KCodeTest.java


import java.util.*;


public class KCodeTest
{
public static void main(String[] args)
{
KCode kc = new KCode();


kc.Convert("8a8e9fjyd");
System.out.println(kc.GetLongitude());
System.out.println(kc.GetLatitude());
}
}




class KCode 
{
public KCode()
{
map34['0'] = 0;
map34['1'] = 1;
map34['2'] = 2;
map34['3'] = 3;
map34['4'] = 4;
map34['5'] = 5;
map34['6'] = 6;
map34['7'] = 7;
map34['8'] = 8;
map34['9'] = 9;
map34['a'] = 10;
map34['b'] = 11;
map34['c'] = 12;
map34['d'] = 13;
map34['e'] = 14;
map34['f'] = 15;
map34['g'] = 16;
map34['h'] = 17;
map34['i'] = 18;
map34['j'] = 19;
map34['k'] = 20;
map34['m'] = 21;
map34['n'] = 22;
map34['p'] = 23;
map34['q'] = 24;
map34['r'] = 25;
map34['s'] = 26;
map34['t'] = 27;
map34['u'] = 28;
map34['v'] = 29;
map34['w'] = 30;
map34['x'] = 31;
map34['y'] = 32;
map34['z'] = 33;
}

public double GetLongitude()
{
return longitude;
}

public double GetLatitude()
{
return latitude;
}

public int Convert(String kcode)
{
if(kcode.length() != 9)
{
return -1;
}

int lut,lat;

char quad = kcode.charAt(0);
switch(quad)
{
case '5':
lut = Convert34to10(kcode.substring(1, 5));
lat = Convert34to10(kcode.substring(5, 9));
longitude = (double)lut / (3600 * 10) + 105;
latitude = (double)lat / (3600 * 10) + 40;
break;
case '6':
lut = Convert34to10(kcode.substring(1, 5));
lat = Convert34to10(kcode.substring(5, 9));
longitude = (double)lut / (3600 * 10) + 70;
latitude = (double)lat / (3600 * 10) + 40;
break;
case '7':
lut = Convert34to10(kcode.substring(1, 5));
lat = Convert34to10(kcode.substring(5, 9));
longitude = (double)lut / (3600 * 10) + 70;
latitude = (double)lat / (3600 * 10) + 5;
break;
case '8':
lut = Convert34to10(kcode.substring(1, 5));
lat = Convert34to10(kcode.substring(5, 9));
longitude = (double)lut / (3600 * 10) + 105;
latitude = (double)lat / (3600 * 10) + 5;
break;
default:
}
return 0;
}

private int Convert34to10(String str34)
{
int sum = 0;
for(int i = 0; i < str34.length(); ++i)
{
if( (str34.charAt(i) != 'l' && str34.charAt(i) != 'o') && 
((str34.charAt(i) >= '0' && str34.charAt(i) <= '9') ||
(str34.charAt(i) >= 'a' && str34.charAt(i) <= 'z'))
)
{
sum += map34[ str34.charAt(i)] *  pow34(i);
}
else
{
System.out.println("invalid chaa");
return -1;
}
}
return sum;
}

private int pow34(int i)
{
int sum = 1;
while(i > 0)
{
sum *= 34;
--i;
}
return sum;
}

private double longitude;
private double latitude;
private byte[] map34 = new byte[123];







0 0