geo2point.sh 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #!/bin/bash
  2. # Baidu Maps Coordinates Utils
  3. # https://github.com/caiguanhao/baidu-maps-coord-utils
  4. BC=$(which bc)
  5. if [[ ${#BC} -eq 0 ]]; then
  6. echo "Install bc first."
  7. exit 1
  8. fi
  9. set -- ${1//\\\//\/} ${@:2} # replace \/ to /
  10. if [[ ${#1} -eq 15 ]]; then
  11. GEO=$1
  12. else
  13. echo "Please provide one GEO string (15 characters long, for example:"\
  14. "\".=LmIPNBjMOxcA;\")."
  15. exit 1
  16. fi
  17. TYPES=("=" "." "-" "*")
  18. GEOTYPE=-1
  19. if [[ ${GEO:0:1} == ${TYPES[1]} ]]; then
  20. GEOTYPE=2
  21. else
  22. if [[ ${GEO:0:1} == ${TYPES[2]} ]]; then
  23. GEOTYPE=1
  24. else
  25. if [[ ${GEO:0:1} == ${TYPES[3]} ]]; then
  26. GEOTYPE=0
  27. fi
  28. fi
  29. fi
  30. #echo ${GEOTYPE}
  31. GEO=${GEO:1}
  32. CHAR_CODE_FROM()
  33. {
  34. FIRST_CHAR_CODE=$(printf "%d" "'${1:0:1}")
  35. local RESULT=-1
  36. if [[ $FIRST_CHAR_CODE -ge $(printf "%d" "'A") ]] &&
  37. [[ $FIRST_CHAR_CODE -le $(printf "%d" "'Z") ]]
  38. then
  39. RESULT=$(( $FIRST_CHAR_CODE - $(printf "%d" "'A") ))
  40. else
  41. if [[ $FIRST_CHAR_CODE -ge $(printf "%d" "'a") ]] &&
  42. [[ $FIRST_CHAR_CODE -le $(printf "%d" "'z") ]]
  43. then
  44. RESULT=$(( 26 + $FIRST_CHAR_CODE - $(printf "%d" "'a") ))
  45. else
  46. if [[ $FIRST_CHAR_CODE -ge $(printf "%d" "'0") ]] &&
  47. [[ $FIRST_CHAR_CODE -le $(printf "%d" "'9") ]]
  48. then
  49. RESULT=$(( 52 + $FIRST_CHAR_CODE - $(printf "%d" "'0") ))
  50. else
  51. if [[ ${1:0:1} == "+" ]]; then
  52. RESULT=62
  53. elif [[ ${1:0:1} == "/" ]]; then
  54. RESULT=63
  55. fi
  56. fi
  57. fi
  58. fi
  59. eval "${3}=\$RESULT"
  60. }
  61. CONVERT()
  62. {
  63. local RESULT=0
  64. local T=0
  65. local F=0
  66. for ((C=0; C < 6 ; C++))
  67. do
  68. CHAR_CODE_FROM "${1:$(( 1 + $C )):1}" TO E
  69. if [[ $E -lt 0 ]]; then
  70. eval "${5}=$(( -1 - $C ))"
  71. return
  72. fi
  73. T=$(( $T + ( $E << ( 6 * $C ) ) ))
  74. CHAR_CODE_FROM "${1:$(( 7 + $C )):1}" TO E
  75. if [[ $E -lt 0 ]]; then
  76. eval "${5}=$(( -7 - $C ))"
  77. return
  78. fi
  79. F=$(( $F + ( $E << ( 6 * $C ) ) ))
  80. done
  81. eval "${3}+=(\$T)"
  82. eval "${3}+=(\$F)"
  83. eval "${5}=0"
  84. }
  85. K=0
  86. LENGTH=${#GEO}
  87. INT_G=0
  88. ARRAY_L=()
  89. while [[ $K -lt $LENGTH ]]; do
  90. if [[ ${GEO:$K:1} == ${TYPES[0]} ]]; then
  91. if [[ $(($LENGTH - $K)) -lt 13 ]]; then
  92. break
  93. fi
  94. CONVERT ${GEO:$K:13} TO ARRAY_L WITH_RETURN_CODE INT_G
  95. if [[ $INT_G -lt 0 ]]; then
  96. break
  97. fi
  98. (( K = K + 13 ))
  99. else
  100. if [[ ${GEO:$K:1} == ";" ]]; then
  101. ARRAY_L=(
  102. $(echo "scale=2; ${ARRAY_L[0]} / 100" | $BC )
  103. $(echo "scale=2; ${ARRAY_L[1]} / 100" | $BC )
  104. )
  105. echo "${ARRAY_L[0]}, ${ARRAY_L[1]}"
  106. exit 0
  107. else
  108. break
  109. fi
  110. fi
  111. done
  112. exit 1
  113. # Baidu's JavaScript:
  114. #
  115. # var aK = 0;
  116. # var bo = 1;
  117. # var aF = 2;
  118. # var at = ["=", ".", "-", "*"];
  119. # parseGeo = function (cF, cI) {
  120. # if (typeof cF != "string" || !cF) {
  121. # return
  122. # }
  123. # var cK = cF.split("|");
  124. # var T;
  125. # var cD;
  126. # var cB;
  127. # if (cK.length == 1) {
  128. # T = Q(cF)
  129. # } else {
  130. # T = Q(cK[2]);
  131. # cD = Q(cK[0]);
  132. # cB = Q(cK[1])
  133. # }
  134. # var cG = {
  135. # type: T.geoType
  136. # };
  137. # if (cI) {
  138. # switch (cG.type) {
  139. # case aF:
  140. # var cH = new b3(T.geo[0][0], T.geo[0][1]);
  141. # var cJ = a2.convertMC2LL(cH);
  142. # cG.point = cJ;
  143. # cG.points = [cJ];
  144. # break;
  145. # case bo:
  146. # cG.points = [];
  147. # var cL = T.geo[0];
  148. # for (var cE = 0, cC = cL.length - 1; cE < cC; cE += 2) {
  149. # var cM = new b3(cL[cE], cL[cE + 1]);
  150. # cM = a2.convertMC2LL(cM);
  151. # cG.points.push(cM)
  152. # }
  153. # cD = new b3(cD.geo[0][0], cD.geo[0][1]);
  154. # cB = new b3(cB.geo[0][0], cB.geo[0][1]);
  155. # cD = a2.convertMC2LL(cD);
  156. # cB = a2.convertMC2LL(cB);
  157. # cG.bounds = new bE(cD, cB);
  158. # break;
  159. # default:
  160. # break
  161. # }
  162. # }
  163. # return cG
  164. # };
  165. # function Q(cI) {
  166. # var cH = aj(cI.charAt(0));
  167. # var cB = cI.substr(1);
  168. # var cK = 0;
  169. # var T = cB.length;
  170. # var cL = [];
  171. # var cF = [];
  172. # var cG = [];
  173. # while (cK < T) {
  174. # if (cB.charAt(cK) == at[0]) {
  175. # if ((T - cK) < 13) {
  176. # return 0
  177. # }
  178. # cG = cr(cB.substr(cK, 13), cL);
  179. # if (cG < 0) {
  180. # return 0
  181. # }
  182. # cK += 13
  183. # } else {
  184. # if (cB.charAt(cK) == ";") {
  185. # cF.push(cL.slice(0));
  186. # cL.length = 0;
  187. # ++cK
  188. # } else {
  189. # if ((T - cK) < 8) {
  190. # return 0
  191. # }
  192. # cG = aL(cB.substr(cK, 8), cL);
  193. # if (cG < 0) {
  194. # return 0
  195. # }
  196. # cK += 8
  197. # }
  198. # }
  199. # }
  200. # for (var cE = 0, cC = cF.length; cE < cC; cE++) {
  201. # for (var cD = 0, cJ = cF[cE].length; cD < cJ; cD++) {
  202. # cF[cE][cD] /= 100
  203. # }
  204. # }
  205. # return {
  206. # geoType: cH,
  207. # geo: cF
  208. # }
  209. # }
  210. # function aj(cB) {
  211. # var T = -1;
  212. # if (cB == at[1]) {
  213. # T = aF
  214. # } else {
  215. # if (cB == at[2]) {
  216. # T = bo
  217. # } else {
  218. # if (cB == at[3]) {
  219. # T = aK
  220. # }
  221. # }
  222. # }
  223. # return T
  224. # }
  225. # function cr(cD, cB) {
  226. # var T = 0;
  227. # var cF = 0;
  228. # var cE = 0;
  229. # for (var cC = 0; cC < 6; cC++) {
  230. # cE = X(cD.substr(1 + cC, 1));
  231. # if (cE < 0) {
  232. # return -1 - cC
  233. # }
  234. # T += cE << (6 * cC);
  235. # cE = X(cD.substr(7 + cC, 1));
  236. # if (cE < 0) {
  237. # return -7 - cC
  238. # }
  239. # cF += cE << (6 * cC)
  240. # }
  241. # cB.push(T);
  242. # cB.push(cF);
  243. # return 0
  244. # }
  245. # function X(cB) {
  246. # var T = cB.charCodeAt(0);
  247. # if (cB >= "A" && cB <= "Z") {
  248. # return T - "A".charCodeAt(0)
  249. # } else {
  250. # if (cB >= "a" && cB <= "z") {
  251. # return (26 + T - "a".charCodeAt(0))
  252. # } else {
  253. # if (cB >= "0" && cB <= "9") {
  254. # return (52 + T - "0".charCodeAt(0))
  255. # } else {
  256. # if (cB == "+") {
  257. # return 62
  258. # } else {
  259. # if (cB == "/") {
  260. # return 63
  261. # }
  262. # }
  263. # }
  264. # }
  265. # }
  266. # return -1
  267. # }