实现了天地图的部分功能
This commit is contained in:
parent
1270466056
commit
1f2dcf12f6
|
|
@ -66,4 +66,4 @@ build
|
|||
package-lock.json
|
||||
dist
|
||||
|
||||
test/app-domain
|
||||
test
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import MapWorldInstance from "./service/mapWorld/mapWorld";
|
||||
declare class MapWorldSDK {
|
||||
webKeyMap: Record<string, MapWorldInstance>;
|
||||
constructor();
|
||||
getInstance(key: string): MapWorldInstance;
|
||||
}
|
||||
declare const SDK: MapWorldSDK;
|
||||
export default SDK;
|
||||
export { MapWorldInstance, };
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import MapWorldInstance from "./service/mapWorld/mapWorld";
|
||||
class MapWorldSDK {
|
||||
webKeyMap;
|
||||
constructor() {
|
||||
this.webKeyMap = {};
|
||||
}
|
||||
getInstance(key) {
|
||||
if (this.webKeyMap[key]) {
|
||||
return this.webKeyMap[key];
|
||||
}
|
||||
const instance = new MapWorldInstance(key);
|
||||
Object.assign(this.webKeyMap, {
|
||||
[key]: instance,
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
const SDK = new MapWorldSDK();
|
||||
export default SDK;
|
||||
export { MapWorldInstance, };
|
||||
|
|
@ -5,6 +5,7 @@ import SmsSdk, { TencentSmsInstance, AliSmsInstance, CTYunSmsInstance } from './
|
|||
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||
export * from './service/amap/Amap';
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, MapwordSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, MapWorldInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export * from './types';
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import SmsSdk, { TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, } from '.
|
|||
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||
export * from './service/amap/Amap';
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, MapwordSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, MapWorldInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export * from './types';
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export declare class AmapInstance {
|
|||
from: [number, number];
|
||||
to: [number, number];
|
||||
}): Promise<any>;
|
||||
regeo(data: {
|
||||
regeo(params: {
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}): Promise<any>;
|
||||
|
|
@ -16,6 +16,11 @@ export declare class AmapInstance {
|
|||
keywords: string;
|
||||
subdistrict: string;
|
||||
}): Promise<any>;
|
||||
/**
|
||||
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
geocode(data: {
|
||||
address: string;
|
||||
city?: string;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ export class AmapInstance {
|
|||
}
|
||||
return jsonData;
|
||||
}
|
||||
async regeo(data) {
|
||||
const { longitude, latitude } = data;
|
||||
async regeo(params) {
|
||||
const { longitude, latitude } = params;
|
||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||
let response;
|
||||
try {
|
||||
|
|
@ -69,6 +69,11 @@ export class AmapInstance {
|
|||
}
|
||||
return jsonData;
|
||||
}
|
||||
/**
|
||||
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
async geocode(data) {
|
||||
const { address, city } = data;
|
||||
const url = `https://restapi.amap.com/v3/geocode/geo?address=${address}${city ? `&city=${city}` : ''}&key=${this.key}`;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
export default class MapWorldInstance {
|
||||
key: string;
|
||||
constructor(key: string);
|
||||
geo(): void;
|
||||
regeo(): void;
|
||||
/**
|
||||
* http://lbs.tianditu.gov.cn/server/search2.html
|
||||
* @param keyWord
|
||||
* @param areaId
|
||||
* @param start
|
||||
* @param count
|
||||
* @returns
|
||||
*/
|
||||
geo(keyWord: string, areaId?: string, start?: number, count?: number): Promise<Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}>>;
|
||||
regeo(params: {
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}): Promise<any>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,97 @@
|
|||
require('../../utils/fetch');
|
||||
import assert from 'assert';
|
||||
import { OakExternalException, OakNetworkException, } from '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;
|
||||
}
|
||||
export default class MapWorldInstance {
|
||||
key;
|
||||
constructor(key) {
|
||||
this.key = key;
|
||||
}
|
||||
geo() {
|
||||
/**
|
||||
* 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 OakNetworkException(`访问mapworld接口失败,「${url}」`);
|
||||
}
|
||||
const jsonData = await response.json();
|
||||
// 天地图的文档没有很规范的定义错误,只能根据测到的情况硬写
|
||||
if (!jsonData.status) {
|
||||
const { code, msg, resolve } = jsonData;
|
||||
if (msg) {
|
||||
throw new OakExternalException('mapworld', code, msg);
|
||||
}
|
||||
throw new OakExternalException('mapworld', '-1', `${JSON.stringify(jsonData)}`);
|
||||
}
|
||||
if (jsonData.status.infocode !== 1000) {
|
||||
throw new OakExternalException('mapworld', jsonData.status.infocode, jsonData.status.cndesc);
|
||||
}
|
||||
const { resultType, statistics, pois } = jsonData;
|
||||
if (resultType === 2) {
|
||||
// 如果以156000000(中国)作为搜索范围,可能会返回统计结果,用统计结果中的数据再次查询
|
||||
assert(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 {
|
||||
assert(resultType === 1);
|
||||
if (jsonData.count === '0') {
|
||||
return [];
|
||||
}
|
||||
assert(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],
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
regeo() {
|
||||
regeo(params) {
|
||||
throw new Error('not implement yet');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
import MapWorldInstance from "./service/mapWorld/mapWorld";
|
||||
declare class MapWorldSDK {
|
||||
webKeyMap: Record<string, MapWorldInstance>;
|
||||
constructor();
|
||||
getInstance(key: string): MapWorldInstance;
|
||||
}
|
||||
declare const SDK: MapWorldSDK;
|
||||
export default SDK;
|
||||
export { MapWorldInstance, };
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MapWorldInstance = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const mapWorld_1 = tslib_1.__importDefault(require("./service/mapWorld/mapWorld"));
|
||||
exports.MapWorldInstance = mapWorld_1.default;
|
||||
class MapWorldSDK {
|
||||
webKeyMap;
|
||||
constructor() {
|
||||
this.webKeyMap = {};
|
||||
}
|
||||
getInstance(key) {
|
||||
if (this.webKeyMap[key]) {
|
||||
return this.webKeyMap[key];
|
||||
}
|
||||
const instance = new mapWorld_1.default(key);
|
||||
Object.assign(this.webKeyMap, {
|
||||
[key]: instance,
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
const SDK = new MapWorldSDK();
|
||||
exports.default = SDK;
|
||||
|
|
@ -5,6 +5,7 @@ import SmsSdk, { TencentSmsInstance, AliSmsInstance, CTYunSmsInstance } from './
|
|||
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||
export * from './service/amap/Amap';
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export { AmapSDK, QiniuSDK, WechatSDK, CTYunSDK, ALiYunSDK, TencentYunSDK, MapwordSDK, CTYunInstance, WechatMpInstance, WechatPublicInstance, WechatWebInstance, QiniuCloudInstance, ALiYunInstance, TencentYunInstance, MapWorldInstance, SmsSdk, TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, };
|
||||
export * from './types';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CTYunSmsInstance = exports.AliSmsInstance = exports.TencentSmsInstance = exports.SmsSdk = exports.TencentYunInstance = exports.ALiYunInstance = exports.QiniuCloudInstance = exports.WechatWebInstance = exports.WechatPublicInstance = exports.WechatMpInstance = exports.CTYunInstance = exports.TencentYunSDK = exports.ALiYunSDK = exports.CTYunSDK = exports.WechatSDK = exports.QiniuSDK = exports.AmapSDK = void 0;
|
||||
exports.CTYunSmsInstance = exports.AliSmsInstance = exports.TencentSmsInstance = exports.SmsSdk = exports.MapWorldInstance = exports.TencentYunInstance = exports.ALiYunInstance = exports.QiniuCloudInstance = exports.WechatWebInstance = exports.WechatPublicInstance = exports.WechatMpInstance = exports.CTYunInstance = exports.MapwordSDK = exports.TencentYunSDK = exports.ALiYunSDK = exports.CTYunSDK = exports.WechatSDK = exports.QiniuSDK = exports.AmapSDK = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const WechatSDK_1 = tslib_1.__importStar(require("./WechatSDK"));
|
||||
exports.WechatSDK = WechatSDK_1.default;
|
||||
|
|
@ -26,5 +26,8 @@ Object.defineProperty(exports, "ALiYunInstance", { enumerable: true, get: functi
|
|||
const TencentYunSDK_1 = tslib_1.__importStar(require("./TencentYunSDK"));
|
||||
exports.TencentYunSDK = TencentYunSDK_1.default;
|
||||
Object.defineProperty(exports, "TencentYunInstance", { enumerable: true, get: function () { return TencentYunSDK_1.TencentYunInstance; } });
|
||||
const MapWorldSDK_1 = tslib_1.__importStar(require("./MapWorldSDK"));
|
||||
exports.MapwordSDK = MapWorldSDK_1.default;
|
||||
Object.defineProperty(exports, "MapWorldInstance", { enumerable: true, get: function () { return MapWorldSDK_1.MapWorldInstance; } });
|
||||
tslib_1.__exportStar(require("./service/amap/Amap"), exports);
|
||||
tslib_1.__exportStar(require("./types"), exports);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export declare class AmapInstance {
|
|||
from: [number, number];
|
||||
to: [number, number];
|
||||
}): Promise<any>;
|
||||
regeo(data: {
|
||||
regeo(params: {
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}): Promise<any>;
|
||||
|
|
@ -16,6 +16,11 @@ export declare class AmapInstance {
|
|||
keywords: string;
|
||||
subdistrict: string;
|
||||
}): Promise<any>;
|
||||
/**
|
||||
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
geocode(data: {
|
||||
address: string;
|
||||
city?: string;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class AmapInstance {
|
|||
}
|
||||
return jsonData;
|
||||
}
|
||||
async regeo(data) {
|
||||
const { longitude, latitude } = data;
|
||||
async regeo(params) {
|
||||
const { longitude, latitude } = params;
|
||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||
let response;
|
||||
try {
|
||||
|
|
@ -72,6 +72,11 @@ class AmapInstance {
|
|||
}
|
||||
return jsonData;
|
||||
}
|
||||
/**
|
||||
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||
* @param data
|
||||
* @returns
|
||||
*/
|
||||
async geocode(data) {
|
||||
const { address, city } = data;
|
||||
const url = `https://restapi.amap.com/v3/geocode/geo?address=${address}${city ? `&city=${city}` : ''}&key=${this.key}`;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,22 @@
|
|||
export default class MapWorldInstance {
|
||||
key: string;
|
||||
constructor(key: string);
|
||||
geo(): void;
|
||||
regeo(): void;
|
||||
/**
|
||||
* http://lbs.tianditu.gov.cn/server/search2.html
|
||||
* @param keyWord
|
||||
* @param areaId
|
||||
* @param start
|
||||
* @param count
|
||||
* @returns
|
||||
*/
|
||||
geo(keyWord: string, areaId?: string, start?: number, count?: number): Promise<Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}>>;
|
||||
regeo(params: {
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}): Promise<any>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,101 @@
|
|||
"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;
|
||||
}
|
||||
geo() {
|
||||
/**
|
||||
* 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],
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
regeo() {
|
||||
regeo(params) {
|
||||
throw new Error('not implement yet');
|
||||
}
|
||||
}
|
||||
exports.default = MapWorldInstance;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"devDependencies": {
|
||||
"@types/ali-oss": "^6.16.11",
|
||||
"@types/node": "^20.6.1",
|
||||
"@types/proj4": "^2.5.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.4.0",
|
||||
"typescript": "^5.2.2"
|
||||
|
|
@ -34,6 +35,7 @@
|
|||
"cos-wx-sdk-v5": "^1.7.1",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"oak-domain": "file:../oak-domain",
|
||||
"proj4": "^2.15.0",
|
||||
"tencentcloud-sdk-nodejs": "^4.0.746",
|
||||
"ts-md5": "^1.3.1"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import MapWorldInstance from "./service/mapWorld/mapWorld";
|
||||
|
||||
class MapWorldSDK {
|
||||
webKeyMap: Record<string, MapWorldInstance>;
|
||||
|
||||
constructor() {
|
||||
this.webKeyMap = {};
|
||||
}
|
||||
|
||||
getInstance(key: string) {
|
||||
if (this.webKeyMap[key]) {
|
||||
return this.webKeyMap[key];
|
||||
}
|
||||
const instance = new MapWorldInstance(key);
|
||||
Object.assign(this.webKeyMap, {
|
||||
[key]: instance,
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
const SDK = new MapWorldSDK();
|
||||
export default SDK;
|
||||
export {
|
||||
MapWorldInstance,
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import SmsSdk, {
|
|||
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||
|
||||
export * from './service/amap/Amap';
|
||||
export {
|
||||
|
|
@ -18,6 +19,7 @@ export {
|
|||
CTYunSDK,
|
||||
ALiYunSDK,
|
||||
TencentYunSDK,
|
||||
MapwordSDK,
|
||||
CTYunInstance,
|
||||
WechatMpInstance,
|
||||
WechatPublicInstance,
|
||||
|
|
@ -25,6 +27,7 @@ export {
|
|||
QiniuCloudInstance,
|
||||
ALiYunInstance,
|
||||
TencentYunInstance,
|
||||
MapWorldInstance,
|
||||
|
||||
SmsSdk,
|
||||
TencentSmsInstance,
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ export class AmapInstance {
|
|||
return jsonData;
|
||||
}
|
||||
|
||||
async regeo(data: { longitude: number; latitude: number }) {
|
||||
const { longitude, latitude } = data;
|
||||
async regeo(params: { longitude: number; latitude: number }) {
|
||||
const { longitude, latitude } = params;
|
||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||
let response: Response;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,141 @@
|
|||
require('../../utils/fetch');
|
||||
import assert from 'assert';
|
||||
import {
|
||||
OakExternalException,
|
||||
OakNetworkException,
|
||||
OakServerProxyException,
|
||||
} from 'oak-domain/lib/types/Exception';
|
||||
|
||||
function codeEnc(code: string) {
|
||||
return code.startsWith('156') ? code : `156${code}`;
|
||||
}
|
||||
|
||||
function codeDec(code: string) {
|
||||
return code.startsWith('156') ? code.slice(3) : code;
|
||||
}
|
||||
|
||||
export default class MapWorldInstance {
|
||||
key: string;
|
||||
|
||||
constructor(key: string) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
geo() {
|
||||
/**
|
||||
* http://lbs.tianditu.gov.cn/server/search2.html
|
||||
* @param keyWord
|
||||
* @param areaId
|
||||
* @param start
|
||||
* @param count
|
||||
* @returns
|
||||
*/
|
||||
async geo(keyWord: string, areaId?: string, start?: number, count?: number): Promise<Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}>> {
|
||||
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: Response;
|
||||
try {
|
||||
response = await global.fetch(url);
|
||||
} catch (err) {
|
||||
throw new OakNetworkException(`访问mapworld接口失败,「${url}」`);
|
||||
}
|
||||
const jsonData = await response.json();
|
||||
|
||||
// 天地图的文档没有很规范的定义错误,只能根据测到的情况硬写
|
||||
if (!jsonData.status) {
|
||||
const { code, msg, resolve } = jsonData;
|
||||
|
||||
if (msg) {
|
||||
throw new OakExternalException(
|
||||
'mapworld',
|
||||
code,
|
||||
msg
|
||||
);
|
||||
}
|
||||
throw new OakExternalException(
|
||||
'mapworld',
|
||||
'-1',
|
||||
`${JSON.stringify(jsonData)}`,
|
||||
);
|
||||
}
|
||||
if (jsonData.status.infocode !== 1000) {
|
||||
throw new OakExternalException(
|
||||
'mapworld',
|
||||
jsonData.status.infocode,
|
||||
jsonData.status.cndesc
|
||||
);
|
||||
}
|
||||
|
||||
const { resultType, statistics, pois } = jsonData;
|
||||
|
||||
if (resultType === 2) {
|
||||
// 如果以156000000(中国)作为搜索范围,可能会返回统计结果,用统计结果中的数据再次查询
|
||||
assert(statistics);
|
||||
const { allAdmins } = statistics;
|
||||
|
||||
const result: Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
longitude: number;
|
||||
latitude: number;
|
||||
}> = [];
|
||||
|
||||
let passed = 0;
|
||||
const getFromSub = async (idx: number): Promise<typeof result> => {
|
||||
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 {
|
||||
assert(resultType === 1);
|
||||
if (jsonData.count === '0') {
|
||||
return [];
|
||||
}
|
||||
assert(pois);
|
||||
|
||||
// 天地图返回的是wgs84坐标
|
||||
return pois.map(
|
||||
(ele: any) => {
|
||||
const { name, lonlat, countyCode, cityCode, provinceCode } = ele;
|
||||
|
||||
const tudes = lonlat.split(',').map(
|
||||
(ele: string) => parseFloat(ele)
|
||||
) as [number, number];
|
||||
return {
|
||||
poiName: name,
|
||||
areaId: codeDec(countyCode || cityCode || provinceCode),
|
||||
longitude: tudes[0],
|
||||
latitude: tudes[1],
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
regeo() {
|
||||
|
||||
regeo(params: { longitude: number; latitude: number }): Promise<any> {
|
||||
throw new Error('not implement yet');
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
import './testTianDitu';
|
||||
import './testTrans';
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
fetch(encodeURI('http://api.tianditu.gov.cn/v2/search?postStr={"keyWord":"星洲花园","queryType":12,"start":0,"count":1,"specify":"156330102","show": "2"}&type=query&tk=f2dc58487a896ed5623231cde51b3dda'))
|
||||
fetch(encodeURI('http://api.tianditu.gov.cn/v2/search?postStr={"keyWord":"浙江大学","queryType":12,"start":0,"count":10,"specify":"156330100","show":"2"}&type=query&tk='))
|
||||
.then(
|
||||
(result) => {
|
||||
console.log(result.status);
|
||||
|
|
|
|||
Loading…
Reference in New Issue