实现了天地图的部分功能
This commit is contained in:
parent
1270466056
commit
1f2dcf12f6
|
|
@ -66,4 +66,4 @@ build
|
||||||
package-lock.json
|
package-lock.json
|
||||||
dist
|
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 CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||||
|
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||||
export * from './service/amap/Amap';
|
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';
|
export * from './types';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import SmsSdk, { TencentSmsInstance, AliSmsInstance, CTYunSmsInstance, } from '.
|
||||||
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
import CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||||
|
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||||
export * from './service/amap/Amap';
|
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';
|
export * from './types';
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export declare class AmapInstance {
|
||||||
from: [number, number];
|
from: [number, number];
|
||||||
to: [number, number];
|
to: [number, number];
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
regeo(data: {
|
regeo(params: {
|
||||||
longitude: number;
|
longitude: number;
|
||||||
latitude: number;
|
latitude: number;
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
|
|
@ -16,6 +16,11 @@ export declare class AmapInstance {
|
||||||
keywords: string;
|
keywords: string;
|
||||||
subdistrict: string;
|
subdistrict: string;
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
geocode(data: {
|
geocode(data: {
|
||||||
address: string;
|
address: string;
|
||||||
city?: string;
|
city?: string;
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ export class AmapInstance {
|
||||||
}
|
}
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
async regeo(data) {
|
async regeo(params) {
|
||||||
const { longitude, latitude } = data;
|
const { longitude, latitude } = params;
|
||||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
|
|
@ -69,6 +69,11 @@ export class AmapInstance {
|
||||||
}
|
}
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async geocode(data) {
|
async geocode(data) {
|
||||||
const { address, city } = data;
|
const { address, city } = data;
|
||||||
const url = `https://restapi.amap.com/v3/geocode/geo?address=${address}${city ? `&city=${city}` : ''}&key=${this.key}`;
|
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 {
|
export default class MapWorldInstance {
|
||||||
key: string;
|
key: string;
|
||||||
constructor(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 {
|
export default class MapWorldInstance {
|
||||||
key;
|
key;
|
||||||
constructor(key) {
|
constructor(key) {
|
||||||
this.key = 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 CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||||
|
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||||
export * from './service/amap/Amap';
|
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';
|
export * from './types';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
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 tslib_1 = require("tslib");
|
||||||
const WechatSDK_1 = tslib_1.__importStar(require("./WechatSDK"));
|
const WechatSDK_1 = tslib_1.__importStar(require("./WechatSDK"));
|
||||||
exports.WechatSDK = WechatSDK_1.default;
|
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"));
|
const TencentYunSDK_1 = tslib_1.__importStar(require("./TencentYunSDK"));
|
||||||
exports.TencentYunSDK = TencentYunSDK_1.default;
|
exports.TencentYunSDK = TencentYunSDK_1.default;
|
||||||
Object.defineProperty(exports, "TencentYunInstance", { enumerable: true, get: function () { return TencentYunSDK_1.TencentYunInstance; } });
|
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("./service/amap/Amap"), exports);
|
||||||
tslib_1.__exportStar(require("./types"), exports);
|
tslib_1.__exportStar(require("./types"), exports);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export declare class AmapInstance {
|
||||||
from: [number, number];
|
from: [number, number];
|
||||||
to: [number, number];
|
to: [number, number];
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
regeo(data: {
|
regeo(params: {
|
||||||
longitude: number;
|
longitude: number;
|
||||||
latitude: number;
|
latitude: number;
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
|
|
@ -16,6 +16,11 @@ export declare class AmapInstance {
|
||||||
keywords: string;
|
keywords: string;
|
||||||
subdistrict: string;
|
subdistrict: string;
|
||||||
}): Promise<any>;
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
geocode(data: {
|
geocode(data: {
|
||||||
address: string;
|
address: string;
|
||||||
city?: string;
|
city?: string;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ class AmapInstance {
|
||||||
}
|
}
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
async regeo(data) {
|
async regeo(params) {
|
||||||
const { longitude, latitude } = data;
|
const { longitude, latitude } = params;
|
||||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
|
|
@ -72,6 +72,11 @@ class AmapInstance {
|
||||||
}
|
}
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 高德这个接口搜索能力很弱,但高级接口要收费,只能先暂时用着
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
async geocode(data) {
|
async geocode(data) {
|
||||||
const { address, city } = data;
|
const { address, city } = data;
|
||||||
const url = `https://restapi.amap.com/v3/geocode/geo?address=${address}${city ? `&city=${city}` : ''}&key=${this.key}`;
|
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 {
|
export default class MapWorldInstance {
|
||||||
key: string;
|
key: string;
|
||||||
constructor(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";
|
"use strict";
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
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 {
|
class MapWorldInstance {
|
||||||
key;
|
key;
|
||||||
constructor(key) {
|
constructor(key) {
|
||||||
this.key = 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;
|
exports.default = MapWorldInstance;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/ali-oss": "^6.16.11",
|
"@types/ali-oss": "^6.16.11",
|
||||||
"@types/node": "^20.6.1",
|
"@types/node": "^20.6.1",
|
||||||
|
"@types/proj4": "^2.5.5",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
|
|
@ -34,6 +35,7 @@
|
||||||
"cos-wx-sdk-v5": "^1.7.1",
|
"cos-wx-sdk-v5": "^1.7.1",
|
||||||
"isomorphic-fetch": "^3.0.0",
|
"isomorphic-fetch": "^3.0.0",
|
||||||
"oak-domain": "file:../oak-domain",
|
"oak-domain": "file:../oak-domain",
|
||||||
|
"proj4": "^2.15.0",
|
||||||
"tencentcloud-sdk-nodejs": "^4.0.746",
|
"tencentcloud-sdk-nodejs": "^4.0.746",
|
||||||
"ts-md5": "^1.3.1"
|
"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 CTYunSDK, { CTYunInstance } from './CTYunSDK';
|
||||||
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
import ALiYunSDK, { ALiYunInstance } from './ALiYunSDK';
|
||||||
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
import TencentYunSDK, { TencentYunInstance } from './TencentYunSDK';
|
||||||
|
import MapwordSDK, { MapWorldInstance } from './MapWorldSDK';
|
||||||
|
|
||||||
export * from './service/amap/Amap';
|
export * from './service/amap/Amap';
|
||||||
export {
|
export {
|
||||||
|
|
@ -18,6 +19,7 @@ export {
|
||||||
CTYunSDK,
|
CTYunSDK,
|
||||||
ALiYunSDK,
|
ALiYunSDK,
|
||||||
TencentYunSDK,
|
TencentYunSDK,
|
||||||
|
MapwordSDK,
|
||||||
CTYunInstance,
|
CTYunInstance,
|
||||||
WechatMpInstance,
|
WechatMpInstance,
|
||||||
WechatPublicInstance,
|
WechatPublicInstance,
|
||||||
|
|
@ -25,6 +27,7 @@ export {
|
||||||
QiniuCloudInstance,
|
QiniuCloudInstance,
|
||||||
ALiYunInstance,
|
ALiYunInstance,
|
||||||
TencentYunInstance,
|
TencentYunInstance,
|
||||||
|
MapWorldInstance,
|
||||||
|
|
||||||
SmsSdk,
|
SmsSdk,
|
||||||
TencentSmsInstance,
|
TencentSmsInstance,
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,8 @@ export class AmapInstance {
|
||||||
return jsonData;
|
return jsonData;
|
||||||
}
|
}
|
||||||
|
|
||||||
async regeo(data: { longitude: number; latitude: number }) {
|
async regeo(params: { longitude: number; latitude: number }) {
|
||||||
const { longitude, latitude } = data;
|
const { longitude, latitude } = params;
|
||||||
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
const url = `https://restapi.amap.com/v3/geocode/regeo?location=${longitude},${latitude}&key=${this.key}`;
|
||||||
let response: Response;
|
let response: Response;
|
||||||
try {
|
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 {
|
export default class MapWorldInstance {
|
||||||
key: string;
|
key: string;
|
||||||
|
|
||||||
constructor(key: string) {
|
constructor(key: string) {
|
||||||
this.key = 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: 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(
|
.then(
|
||||||
(result) => {
|
(result) => {
|
||||||
console.log(result.status);
|
console.log(result.status);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue