127 lines
5.1 KiB
JavaScript
127 lines
5.1 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
const tslib_1 = require("tslib");
|
||
require('../../utils/fetch');
|
||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||
const Exception_1 = require("oak-domain/lib/types/Exception");
|
||
function codeEnc(code) {
|
||
return code.startsWith('156') ? code : `156${code}`;
|
||
}
|
||
function codeDec(code) {
|
||
return code.startsWith('156') ? code.slice(3) : code;
|
||
}
|
||
class MapWorldInstance {
|
||
key;
|
||
constructor(key) {
|
||
this.key = key;
|
||
}
|
||
/**
|
||
* http://lbs.tianditu.gov.cn/server/search2.html
|
||
* @param keyWord
|
||
* @param areaId
|
||
* @param start
|
||
* @param count
|
||
* @returns
|
||
*/
|
||
async geo(keyWord, areaId, start, count) {
|
||
const start2 = start || 0;
|
||
const count2 = count || 100;
|
||
const url = `http://api.tianditu.gov.cn/v2/search?postStr={"keyWord":"${keyWord}","queryType":12,"start":${start2},"count":${count2},"specify": "${codeEnc(areaId || '000000')}","show":"2"}&type=query&tk=${this.key}`;
|
||
let response;
|
||
try {
|
||
response = await global.fetch(url);
|
||
}
|
||
catch (err) {
|
||
throw new Exception_1.OakNetworkException(`访问mapworld接口失败,「${url}」`);
|
||
}
|
||
const jsonData = await response.json();
|
||
// 天地图的文档没有很规范的定义错误,只能根据测到的情况硬写
|
||
if (!jsonData.status) {
|
||
const { code, msg, resolve } = jsonData;
|
||
if (msg) {
|
||
throw new Exception_1.OakExternalException('mapworld', code, msg);
|
||
}
|
||
throw new Exception_1.OakExternalException('mapworld', '-1', `${JSON.stringify(jsonData)}`);
|
||
}
|
||
if (jsonData.status.infocode !== 1000) {
|
||
throw new Exception_1.OakExternalException('mapworld', jsonData.status.infocode, jsonData.status.cndesc);
|
||
}
|
||
const { resultType, statistics, pois } = jsonData;
|
||
if (resultType === 2) {
|
||
// 如果以156000000(中国)作为搜索范围,可能会返回统计结果,用统计结果中的数据再次查询
|
||
(0, assert_1.default)(statistics);
|
||
const { allAdmins } = statistics;
|
||
const result = [];
|
||
let passed = 0;
|
||
const getFromSub = async (idx) => {
|
||
const admin = allAdmins[idx];
|
||
if (admin) {
|
||
const { adminCode, count: adminCount } = admin;
|
||
if (passed + adminCount < start2) {
|
||
// 这个sub已经被pass
|
||
passed += adminCount;
|
||
return await getFromSub(idx + 1);
|
||
}
|
||
else {
|
||
const start3 = start2 - passed;
|
||
result.push(...(await this.geo(keyWord, `${adminCode}`, start3, count2)));
|
||
if (result.length === count2) {
|
||
return result;
|
||
}
|
||
await getFromSub(idx + 1);
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
return await getFromSub(0);
|
||
}
|
||
else {
|
||
(0, assert_1.default)(resultType === 1);
|
||
if (jsonData.count === '0') {
|
||
return [];
|
||
}
|
||
(0, assert_1.default)(pois);
|
||
// 天地图返回的是wgs84坐标
|
||
return pois.map((ele) => {
|
||
const { name, lonlat, countyCode, cityCode, provinceCode } = ele;
|
||
const tudes = lonlat.split(',').map((ele) => parseFloat(ele));
|
||
return {
|
||
poiName: name,
|
||
areaId: codeDec(countyCode || cityCode || provinceCode),
|
||
longitude: tudes[0],
|
||
latitude: tudes[1],
|
||
};
|
||
});
|
||
}
|
||
}
|
||
async regeo(params) {
|
||
const url = `http://api.tianditu.gov.cn/geocoder?postStr={"lon":${params.longitude},"lat":${params.latitude},"ver":1}&type=geocode&tk=${this.key}`;
|
||
let response;
|
||
try {
|
||
response = await global.fetch(url);
|
||
}
|
||
catch (err) {
|
||
throw new Exception_1.OakNetworkException(`访问mapworld接口失败,「${url}」`);
|
||
}
|
||
const jsonData = await response.json();
|
||
// 天地图的文档没有很规范的定义错误,只能根据测到的情况硬写
|
||
if (!jsonData.status) {
|
||
const { code, msg } = jsonData;
|
||
if (msg) {
|
||
throw new Exception_1.OakExternalException('mapworld', code, msg);
|
||
}
|
||
throw new Exception_1.OakExternalException('mapworld', '-1', `${JSON.stringify(jsonData)}`);
|
||
}
|
||
const { status, msg, result } = jsonData;
|
||
if (status !== '0') {
|
||
throw new Exception_1.OakExternalException('mapworld', status, msg);
|
||
}
|
||
const { addressComponent, formatted_address } = result;
|
||
return {
|
||
poiName: formatted_address,
|
||
areaId: codeDec(addressComponent.county_code || addressComponent.city_code || addressComponent.province_code),
|
||
};
|
||
}
|
||
}
|
||
exports.default = MapWorldInstance;
|