最近在做网络爬虫,爬全国的POI数据,大约爬了3000多万条,但图吧的坐标都是加密的,类似“HHVSJRWVTTGDD”这样的字符串,还好我跟踪的代码,发现其转换方法,无奈只有js版本,就顺手写了一个python版本的解密算法,但图吧的坐标有自己的坐标系,为了通用,又需要转成wgs84吗,所以我将他们综合了一下。

1、JS版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var  vp = function(xT) {
var v6;
var pk = -1;
var fE = 0;
var ub = '';
var fH = '';
for (var i = 0; i < xT.length; i++) {
var n8 = parseInt(xT.charAt(i), 36) - 10;
if (n8 >= 17)
n8 = n8 - 7;
ub += (n8).toString(36);
if (n8 > fE) {
pk = i;
fE = n8
}
}
var n9 = parseInt(ub.substring(0, pk), 16);
var n0 = parseInt(ub.substring(pk + 1), 16);

v6 = new Array();
v6[0] = (n9 + n0 - parseInt(3409)) / 2;

v6[1] = (n0 - v6[0]) / 100000.0;

v6[0] /= 100000.0;
if (v6[0] > 180)
v6[0] -= 360;
return v6
}

function mapBar2WGS84(x, y) {
x = parseFloat(x) * 100000 % 36000000;
y = parseFloat(y) * 100000 % 36000000;
x1 = parseInt( - (((Math.cos(y / 100000)) * (x / 18000)) + ((Math.sin(x / 100000)) * (y / 9000))) + x);
y1 = parseInt( - (((Math.sin(y / 100000)) * (x / 18000)) + ((Math.cos(x / 100000)) * (y / 9000))) + y);
x2 = parseInt( - (((Math.cos(y1 / 100000)) * (x1 / 18000)) + ((Math.sin(x1 / 100000)) * (y1 / 9000))) + x + ((x > 0) ? 1 : -1));
y2 = parseInt( - (((Math.sin(y1 / 100000)) * (x1 / 18000)) + ((Math.cos(x1 / 100000)) * (y1 / 9000))) + y + ((y > 0) ? 1 : -1));
return [x2 / 100000.0, y2 / 100000.0];
}

console.log(vp("HHVSJRWVTTGDD"))
var x = vp("HHVSJRWVTTGDD")[0]
var y = vp("HHVSJRWVTTGDD")[1]
console.log(mapBar2WGS84(x,y))

2、Python版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import math

def itoa(num, radix):
result = ""
while num > 0:
result = "0123456789abcdefghijklmnopqrstuvwxyz"[num % radix] + result
num /= radix
return result

def baseN(num, b):
return ((num == 0) and "0") or (baseN(num // b, b).lstrip("0") + "0123456789abcdefghijklmnopqrstuvwxyz"[num % b])

def mapBarKey2XY(xT):
v6 = []
pk = -1
fE = 0
ub = ''
for inx, iiii in enumerate(xT):
n8 = int(iiii,36) - 10
if n8 >= 17:
n8 = n8 - 7
ub += baseN(n8,36)
if n8 > fE:
pk = inx
fE = n8

n9 = int(ub[0:pk], 16)
pks = 0-pk
n0 = int(ub[pks:], 16)

v6.append((n9 + n0 - 3409)/2)
v6.append((n0 - v6[0])/100000.0)
v6[0] = v6[0] / 100000.0

if v6[0] > 180:
v6[0] = v6[0] - 360

return v6

def mapBar2WGS84(lng, lat):
lng = float(lng) * 100000 % 36000000;
lat = float(lat) * 100000 % 36000000;
lng1 = int(- (((math.cos(lat / 100000)) * (lng / 18000)) + ((math.sin(lng / 100000)) * (lat / 9000))) + lng)
lat1 = int(- (((math.sin(lat / 100000)) * (lng / 18000)) + ((math.cos(lng / 100000)) * (lat / 9000))) + lat)
lng2 = int(- (((math.cos(lat1 / 100000)) * (lng1 / 18000)) + ((math.sin(lng1 / 100000)) * (lat1 / 9000))) + lng + (
1 if lng > 0 else -1))
lat2 = int(- (((math.sin(lat1 / 100000)) * (lng1 / 18000)) + ((math.cos(lng1 / 100000)) * (lat1 / 9000))) + lat + (
1 if lat > 0 else -1))
return lng2 / 100000.0, lat2 / 100000.0

print(mapBarKey2XY("HHVSJRWVTTGDD"))
print(mapBar2WGS84(mapBarKey2XY("HHVSJRWVTTGDD")[0],mapBarKey2XY("HHVSJRWVTTGDD")[1]))