重构了geo相关的定义
This commit is contained in:
parent
91cdd92881
commit
1447af1d37
|
|
@ -2,6 +2,8 @@ import { EntityDict, OperateOption, SelectOption, OperationResult, AggregationRe
|
|||
import { AmapInstance } from "oak-external-sdk/lib/service/amap/Amap";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { AsyncContext } from "oak-domain/lib/store/AsyncRowStore";
|
||||
import { MapService } from "./types/Map";
|
||||
import { GeoApi } from "./geo";
|
||||
export declare type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
||||
operate: <T extends keyof ED, OP extends OperateOption>(params: {
|
||||
entity: T;
|
||||
|
|
@ -51,19 +53,10 @@ export declare type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
|||
getImportationTemplate: (params: {
|
||||
id: string;
|
||||
}, context: AsyncContext<ED>) => Promise<ArrayBuffer>;
|
||||
searchPoi: (options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}) => Promise<{
|
||||
id: string;
|
||||
areaId: string;
|
||||
poiName: string;
|
||||
detail: string;
|
||||
coordinate: [number, number];
|
||||
}[]>;
|
||||
geoService: <ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>) => Promise<ReturnType<MapService[A]>>;
|
||||
loadRelations: (params: {
|
||||
entities: (keyof ED)[];
|
||||
}, context: AsyncContext<ED>) => Promise<ED['userRelation']['OpSchema'][]>;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
export declare function searchPoi(options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}): Promise<{
|
||||
id: string;
|
||||
areaId: string;
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import { EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { MapService } from './types/Map';
|
||||
export declare type GeoApi = 'geo' | 'regeo';
|
||||
export declare function registerGetMapService(fn: <ED extends BaseEntityDict & EntityDict>(context: AsyncContext<ED>) => Promise<MapService>): void;
|
||||
export declare function geoService<ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>): Promise<{
|
||||
poiName: string;
|
||||
coordinate: [number, number];
|
||||
areaId: string;
|
||||
} | {
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}[]>;
|
||||
|
|
|
|||
47
es/geo.js
47
es/geo.js
|
|
@ -1,38 +1,11 @@
|
|||
export async function searchPoi(options) {
|
||||
const { value, areaCode, indexFrom, count } = options;
|
||||
const form = new FormData();
|
||||
form.set('stName', value);
|
||||
if (areaCode) {
|
||||
form.set('code', areaCode);
|
||||
}
|
||||
if (indexFrom && count) {
|
||||
form.set('page', `${indexFrom / count}`);
|
||||
form.set('size', `${count}`);
|
||||
}
|
||||
const result = await fetch('https://dmfw.mca.gov.cn/9095/stname/listPub', {
|
||||
method: 'post',
|
||||
body: form,
|
||||
});
|
||||
const { records } = await result.json();
|
||||
const pois = await Promise.all(records.map(async (ele) => {
|
||||
let { area, standard_name, gdm, id, province_name, city_name, area_name, place_type, } = ele;
|
||||
// 对返回的area数据进行一些清洗,不规范
|
||||
if (area.length === 9) {
|
||||
if (area.endsWith('999')) {
|
||||
area = area.slice(0, 6);
|
||||
}
|
||||
}
|
||||
if (area === '000000') {
|
||||
// 搜索如长江这样的地理名称时会返回这样的数据,过滤掉
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
id,
|
||||
areaId: area,
|
||||
poiName: standard_name,
|
||||
coordinate: gdm.coordinates[0],
|
||||
detail: `${province_name}${city_name}${area_name}${standard_name}(${place_type})`,
|
||||
};
|
||||
}));
|
||||
return pois.filter((poi) => !!poi);
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
let GetMapServiceFn = undefined;
|
||||
export function registerGetMapService(fn) {
|
||||
GetMapServiceFn = fn;
|
||||
}
|
||||
export async function geoService(options, context) {
|
||||
assert(GetMapServiceFn, '未注入指定的GetMapServiceFn');
|
||||
const service = await GetMapServiceFn(context);
|
||||
const { api, params } = options;
|
||||
return await service[api](params);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { operate, select, fetchRows, count, aggregate } from './crud';
|
|||
import { amap } from './amap';
|
||||
import { getTranslations } from './locales';
|
||||
import { registerPorts, clearPorts, importEntity, exportEntity, getImportationTemplate } from './port';
|
||||
import { searchPoi } from './geo';
|
||||
import { geoService, registerGetMapService } from './geo';
|
||||
import { loadRelations } from './relation';
|
||||
import { crossBridge } from './utils';
|
||||
declare const aspectDict: {
|
||||
|
|
@ -16,10 +16,10 @@ declare const aspectDict: {
|
|||
importEntity: typeof importEntity;
|
||||
exportEntity: typeof exportEntity;
|
||||
getImportationTemplate: typeof getImportationTemplate;
|
||||
searchPoi: typeof searchPoi;
|
||||
geoService: typeof geoService;
|
||||
loadRelations: typeof loadRelations;
|
||||
crossBridge: typeof crossBridge;
|
||||
};
|
||||
export default aspectDict;
|
||||
export * from './AspectDict';
|
||||
export { registerPorts, clearPorts, };
|
||||
export { registerPorts, clearPorts, registerGetMapService, };
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { operate, select, fetchRows, count, aggregate } from './crud';
|
|||
import { amap } from './amap';
|
||||
import { getTranslations } from './locales';
|
||||
import { registerPorts, clearPorts, importEntity, exportEntity, getImportationTemplate } from './port';
|
||||
import { searchPoi } from './geo';
|
||||
import { geoService, registerGetMapService } from './geo';
|
||||
import { loadRelations } from './relation';
|
||||
import { crossBridge } from './utils';
|
||||
const aspectDict = {
|
||||
|
|
@ -16,10 +16,10 @@ const aspectDict = {
|
|||
importEntity,
|
||||
exportEntity,
|
||||
getImportationTemplate,
|
||||
searchPoi,
|
||||
geoService,
|
||||
loadRelations,
|
||||
crossBridge,
|
||||
};
|
||||
export default aspectDict;
|
||||
export * from './AspectDict';
|
||||
export { registerPorts, clearPorts, };
|
||||
export { registerPorts, clearPorts, registerGetMapService, };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import { MapService } from "../types/Map";
|
||||
import { AmapKeyType } from 'oak-external-sdk/lib/types/AMap';
|
||||
export default class AMap implements MapService {
|
||||
keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
count: number;
|
||||
}>;
|
||||
index: number;
|
||||
constructor(keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
}>);
|
||||
protected getKey(): string;
|
||||
regeo(param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}): Promise<{
|
||||
poiName: any;
|
||||
areaId: any;
|
||||
}>;
|
||||
geo(param: {
|
||||
name: string;
|
||||
areaId?: string;
|
||||
}): Promise<any>;
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import assert from 'assert';
|
||||
import AmapSDK from 'oak-external-sdk/lib/AmapSDK';
|
||||
import { WebServiceKeyWeight } from 'oak-external-sdk/lib/types/AMap';
|
||||
export default class AMap {
|
||||
keys;
|
||||
index;
|
||||
constructor(keys) {
|
||||
assert(keys.length > 0);
|
||||
this.keys = keys.map(ele => ({
|
||||
...ele,
|
||||
count: WebServiceKeyWeight[ele.type],
|
||||
}));
|
||||
this.index = 0;
|
||||
}
|
||||
getKey() {
|
||||
while (true) {
|
||||
const key = this.keys[this.index];
|
||||
if (key.count > 0) {
|
||||
key.count--;
|
||||
return key.key;
|
||||
}
|
||||
key.count = WebServiceKeyWeight[key.type];
|
||||
this.index = (this.index + 1) % this.keys.length;
|
||||
}
|
||||
}
|
||||
async regeo(param) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK.getInstance(key);
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { regeocode } = await instance.regeo(param);
|
||||
return {
|
||||
poiName: regeocode.formatted_address,
|
||||
areaId: regeocode.addressComponent.towncode,
|
||||
};
|
||||
}
|
||||
;
|
||||
async geo(param) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK.getInstance(key);
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { name, areaId } = param;
|
||||
const { geocodes } = await instance.geocode({
|
||||
address: name,
|
||||
city: areaId,
|
||||
});
|
||||
return geocodes.map((ele) => ({
|
||||
poiName: ele.formatted_address,
|
||||
areaId: ele.adcode,
|
||||
latitude: ele.location[0],
|
||||
longitude: ele.location[1],
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { Importation, Exportation } from 'oak-domain/lib/types/Port';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
export declare function registerPorts<ED extends EntityDict>(importations: Importation<ED, keyof ED, any, any>[], exportations: Exportation<ED, keyof ED, any, any>[]): void;
|
||||
export declare function registerPorts<ED extends EntityDict & BaseEntityDict>(importations: Importation<ED, keyof ED, any, any>[], exportations: Exportation<ED, keyof ED, any, any>[]): void;
|
||||
export declare function clearPorts(): void;
|
||||
export declare function importEntity<ED extends EntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function importEntity<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
entity: string;
|
||||
id: string;
|
||||
file: any;
|
||||
option: string;
|
||||
s2jOpts?: string;
|
||||
}, context: Cxt): Promise<ArrayBuffer | void>;
|
||||
export declare function exportEntity<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function exportEntity<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(params: {
|
||||
entity: T;
|
||||
id: string;
|
||||
filter?: ED[T]['Selection']['filter'];
|
||||
properties?: Record<string, any>;
|
||||
}, context: Cxt): Promise<ArrayBuffer>;
|
||||
export declare function getImportationTemplate<ED extends EntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function getImportationTemplate<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
id: string;
|
||||
}, context: Cxt): Promise<ArrayBuffer>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
export interface MapService {
|
||||
regeo: (param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}) => Promise<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
}>;
|
||||
geo: (param: {
|
||||
name: string;
|
||||
areaId?: string;
|
||||
}) => Promise<Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}>>;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
;
|
||||
export {};
|
||||
|
|
@ -2,6 +2,8 @@ import { EntityDict, OperateOption, SelectOption, OperationResult, AggregationRe
|
|||
import { AmapInstance } from "oak-external-sdk/lib/service/amap/Amap";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { AsyncContext } from "oak-domain/lib/store/AsyncRowStore";
|
||||
import { MapService } from "./types/Map";
|
||||
import { GeoApi } from "./geo";
|
||||
export declare type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
||||
operate: <T extends keyof ED, OP extends OperateOption>(params: {
|
||||
entity: T;
|
||||
|
|
@ -51,19 +53,10 @@ export declare type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
|||
getImportationTemplate: (params: {
|
||||
id: string;
|
||||
}, context: AsyncContext<ED>) => Promise<ArrayBuffer>;
|
||||
searchPoi: (options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}) => Promise<{
|
||||
id: string;
|
||||
areaId: string;
|
||||
poiName: string;
|
||||
detail: string;
|
||||
coordinate: [number, number];
|
||||
}[]>;
|
||||
geoService: <ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>) => Promise<ReturnType<MapService[A]>>;
|
||||
loadRelations: (params: {
|
||||
entities: (keyof ED)[];
|
||||
}, context: AsyncContext<ED>) => Promise<ED['userRelation']['OpSchema'][]>;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
export declare function searchPoi(options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}): Promise<{
|
||||
id: string;
|
||||
areaId: string;
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import { EntityDict } from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { MapService } from './types/Map';
|
||||
export declare type GeoApi = 'geo' | 'regeo';
|
||||
export declare function registerGetMapService(fn: <ED extends BaseEntityDict & EntityDict>(context: AsyncContext<ED>) => Promise<MapService>): void;
|
||||
export declare function geoService<ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>): Promise<{
|
||||
poiName: string;
|
||||
coordinate: [number, number];
|
||||
areaId: string;
|
||||
} | {
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}[]>;
|
||||
|
|
|
|||
52
lib/geo.js
52
lib/geo.js
|
|
@ -1,42 +1,16 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.searchPoi = void 0;
|
||||
async function searchPoi(options) {
|
||||
const { value, areaCode, indexFrom, count } = options;
|
||||
const form = new FormData();
|
||||
form.set('stName', value);
|
||||
if (areaCode) {
|
||||
form.set('code', areaCode);
|
||||
}
|
||||
if (indexFrom && count) {
|
||||
form.set('page', `${indexFrom / count}`);
|
||||
form.set('size', `${count}`);
|
||||
}
|
||||
const result = await fetch('https://dmfw.mca.gov.cn/9095/stname/listPub', {
|
||||
method: 'post',
|
||||
body: form,
|
||||
});
|
||||
const { records } = await result.json();
|
||||
const pois = await Promise.all(records.map(async (ele) => {
|
||||
let { area, standard_name, gdm, id, province_name, city_name, area_name, place_type, } = ele;
|
||||
// 对返回的area数据进行一些清洗,不规范
|
||||
if (area.length === 9) {
|
||||
if (area.endsWith('999')) {
|
||||
area = area.slice(0, 6);
|
||||
}
|
||||
}
|
||||
if (area === '000000') {
|
||||
// 搜索如长江这样的地理名称时会返回这样的数据,过滤掉
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
id,
|
||||
areaId: area,
|
||||
poiName: standard_name,
|
||||
coordinate: gdm.coordinates[0],
|
||||
detail: `${province_name}${city_name}${area_name}${standard_name}(${place_type})`,
|
||||
};
|
||||
}));
|
||||
return pois.filter((poi) => !!poi);
|
||||
exports.geoService = exports.registerGetMapService = void 0;
|
||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||
let GetMapServiceFn = undefined;
|
||||
function registerGetMapService(fn) {
|
||||
GetMapServiceFn = fn;
|
||||
}
|
||||
exports.searchPoi = searchPoi;
|
||||
exports.registerGetMapService = registerGetMapService;
|
||||
async function geoService(options, context) {
|
||||
(0, assert_1.assert)(GetMapServiceFn, '未注入指定的GetMapServiceFn');
|
||||
const service = await GetMapServiceFn(context);
|
||||
const { api, params } = options;
|
||||
return await service[api](params);
|
||||
}
|
||||
exports.geoService = geoService;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { operate, select, fetchRows, count, aggregate } from './crud';
|
|||
import { amap } from './amap';
|
||||
import { getTranslations } from './locales';
|
||||
import { registerPorts, clearPorts, importEntity, exportEntity, getImportationTemplate } from './port';
|
||||
import { searchPoi } from './geo';
|
||||
import { geoService, registerGetMapService } from './geo';
|
||||
import { loadRelations } from './relation';
|
||||
import { crossBridge } from './utils';
|
||||
declare const aspectDict: {
|
||||
|
|
@ -16,10 +16,10 @@ declare const aspectDict: {
|
|||
importEntity: typeof importEntity;
|
||||
exportEntity: typeof exportEntity;
|
||||
getImportationTemplate: typeof getImportationTemplate;
|
||||
searchPoi: typeof searchPoi;
|
||||
geoService: typeof geoService;
|
||||
loadRelations: typeof loadRelations;
|
||||
crossBridge: typeof crossBridge;
|
||||
};
|
||||
export default aspectDict;
|
||||
export * from './AspectDict';
|
||||
export { registerPorts, clearPorts, };
|
||||
export { registerPorts, clearPorts, registerGetMapService, };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.clearPorts = exports.registerPorts = void 0;
|
||||
exports.registerGetMapService = exports.clearPorts = exports.registerPorts = void 0;
|
||||
const tslib_1 = require("tslib");
|
||||
const crud_1 = require("./crud");
|
||||
const amap_1 = require("./amap");
|
||||
|
|
@ -9,6 +9,7 @@ const port_1 = require("./port");
|
|||
Object.defineProperty(exports, "registerPorts", { enumerable: true, get: function () { return port_1.registerPorts; } });
|
||||
Object.defineProperty(exports, "clearPorts", { enumerable: true, get: function () { return port_1.clearPorts; } });
|
||||
const geo_1 = require("./geo");
|
||||
Object.defineProperty(exports, "registerGetMapService", { enumerable: true, get: function () { return geo_1.registerGetMapService; } });
|
||||
const relation_1 = require("./relation");
|
||||
const utils_1 = require("./utils");
|
||||
const aspectDict = {
|
||||
|
|
@ -22,7 +23,7 @@ const aspectDict = {
|
|||
importEntity: port_1.importEntity,
|
||||
exportEntity: port_1.exportEntity,
|
||||
getImportationTemplate: port_1.getImportationTemplate,
|
||||
searchPoi: geo_1.searchPoi,
|
||||
geoService: geo_1.geoService,
|
||||
loadRelations: relation_1.loadRelations,
|
||||
crossBridge: utils_1.crossBridge,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import { MapService } from "../types/Map";
|
||||
import { AmapKeyType } from 'oak-external-sdk/lib/types/AMap';
|
||||
export default class AMap implements MapService {
|
||||
keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
count: number;
|
||||
}>;
|
||||
index: number;
|
||||
constructor(keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
}>);
|
||||
protected getKey(): string;
|
||||
regeo(param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}): Promise<{
|
||||
poiName: any;
|
||||
areaId: any;
|
||||
}>;
|
||||
geo(param: {
|
||||
name: string;
|
||||
areaId?: string;
|
||||
}): Promise<any>;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const assert_1 = tslib_1.__importDefault(require("assert"));
|
||||
const AmapSDK_1 = tslib_1.__importDefault(require("oak-external-sdk/lib/AmapSDK"));
|
||||
const AMap_1 = require("oak-external-sdk/lib/types/AMap");
|
||||
class AMap {
|
||||
keys;
|
||||
index;
|
||||
constructor(keys) {
|
||||
(0, assert_1.default)(keys.length > 0);
|
||||
this.keys = keys.map(ele => ({
|
||||
...ele,
|
||||
count: AMap_1.WebServiceKeyWeight[ele.type],
|
||||
}));
|
||||
this.index = 0;
|
||||
}
|
||||
getKey() {
|
||||
while (true) {
|
||||
const key = this.keys[this.index];
|
||||
if (key.count > 0) {
|
||||
key.count--;
|
||||
return key.key;
|
||||
}
|
||||
key.count = AMap_1.WebServiceKeyWeight[key.type];
|
||||
this.index = (this.index + 1) % this.keys.length;
|
||||
}
|
||||
}
|
||||
async regeo(param) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK_1.default.getInstance(key);
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { regeocode } = await instance.regeo(param);
|
||||
return {
|
||||
poiName: regeocode.formatted_address,
|
||||
areaId: regeocode.addressComponent.towncode,
|
||||
};
|
||||
}
|
||||
;
|
||||
async geo(param) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK_1.default.getInstance(key);
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { name, areaId } = param;
|
||||
const { geocodes } = await instance.geocode({
|
||||
address: name,
|
||||
city: areaId,
|
||||
});
|
||||
return geocodes.map((ele) => ({
|
||||
poiName: ele.formatted_address,
|
||||
areaId: ele.adcode,
|
||||
latitude: ele.location[0],
|
||||
longitude: ele.location[1],
|
||||
}));
|
||||
}
|
||||
}
|
||||
exports.default = AMap;
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
import { EntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { Importation, Exportation } from 'oak-domain/lib/types/Port';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
export declare function registerPorts<ED extends EntityDict>(importations: Importation<ED, keyof ED, any, any>[], exportations: Exportation<ED, keyof ED, any, any>[]): void;
|
||||
export declare function registerPorts<ED extends EntityDict & BaseEntityDict>(importations: Importation<ED, keyof ED, any, any>[], exportations: Exportation<ED, keyof ED, any, any>[]): void;
|
||||
export declare function clearPorts(): void;
|
||||
export declare function importEntity<ED extends EntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function importEntity<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
entity: string;
|
||||
id: string;
|
||||
file: any;
|
||||
option: string;
|
||||
s2jOpts?: string;
|
||||
}, context: Cxt): Promise<ArrayBuffer | void>;
|
||||
export declare function exportEntity<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function exportEntity<ED extends EntityDict & BaseEntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>>(params: {
|
||||
entity: T;
|
||||
id: string;
|
||||
filter?: ED[T]['Selection']['filter'];
|
||||
properties?: Record<string, any>;
|
||||
}, context: Cxt): Promise<ArrayBuffer>;
|
||||
export declare function getImportationTemplate<ED extends EntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
export declare function getImportationTemplate<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>>(params: {
|
||||
id: string;
|
||||
}, context: Cxt): Promise<ArrayBuffer>;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
export interface MapService {
|
||||
regeo: (param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}) => Promise<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
}>;
|
||||
geo: (param: {
|
||||
name: string;
|
||||
areaId?: string;
|
||||
}) => Promise<Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}>>;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
;
|
||||
|
|
@ -2,6 +2,8 @@ import { EntityDict, OperateOption, SelectOption, OperationResult, AggregationRe
|
|||
import { AmapInstance } from "oak-external-sdk/lib/service/amap/Amap";
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { AsyncContext } from "oak-domain/lib/store/AsyncRowStore";
|
||||
import { MapService } from "./types/Map";
|
||||
import { GeoApi } from "./geo";
|
||||
|
||||
export type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
||||
operate: <T extends keyof ED, OP extends OperateOption>(
|
||||
|
|
@ -69,13 +71,10 @@ export type AspectDict<ED extends EntityDict & BaseEntityDict> = {
|
|||
properties?: Record<string, any>;
|
||||
}, context: AsyncContext<ED>) => Promise<ArrayBuffer>;
|
||||
getImportationTemplate: (params: { id: string }, context: AsyncContext<ED>) => Promise<ArrayBuffer>;
|
||||
searchPoi: (options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}) => Promise<{ id: string; areaId: string; poiName: string; detail: string; coordinate: [number, number] }[]>;
|
||||
geoService: <ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>) => Promise<ReturnType<MapService[A]>>;
|
||||
loadRelations: (params: {
|
||||
entities: (keyof ED)[],
|
||||
}, context: AsyncContext<ED>) => Promise<ED['userRelation']['OpSchema'][]>;
|
||||
|
|
|
|||
108
src/geo.ts
108
src/geo.ts
|
|
@ -1,90 +1,28 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import {
|
||||
EntityDict,
|
||||
} from 'oak-domain/lib/types';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { MapService } from './types/Map';
|
||||
|
||||
/**
|
||||
* 根据poiName搜索地理位置
|
||||
* @param options
|
||||
* https://dmfw.mca.gov.cn/interface.html
|
||||
*/
|
||||
type DmfwPoi = {
|
||||
id: string;
|
||||
area: string;
|
||||
standard_name: string;
|
||||
gdm: {
|
||||
coordinates: [[number, number]];
|
||||
};
|
||||
place_type: string;
|
||||
place_code: string;
|
||||
area_name: string;
|
||||
city_name: string;
|
||||
province_name: string;
|
||||
};
|
||||
export type GeoApi = 'geo' | 'regeo';
|
||||
|
||||
export async function searchPoi(options: {
|
||||
value: string;
|
||||
areaCode?: string;
|
||||
indexFrom?: number;
|
||||
count?: number;
|
||||
typeCode?: string;
|
||||
}): Promise<
|
||||
{
|
||||
id: string;
|
||||
areaId: string;
|
||||
poiName: string;
|
||||
coordinate: [number, number];
|
||||
}[]
|
||||
> {
|
||||
const { value, areaCode, indexFrom, count } = options;
|
||||
const form = new FormData();
|
||||
form.set('stName', value);
|
||||
if (areaCode) {
|
||||
form.set('code', areaCode);
|
||||
}
|
||||
if (indexFrom && count) {
|
||||
form.set('page', `${indexFrom / count}`);
|
||||
form.set('size', `${count}`);
|
||||
}
|
||||
let GetMapServiceFn: (<ED extends BaseEntityDict & EntityDict, C extends AsyncContext<ED>>(context: C) => Promise<MapService>) | undefined = undefined;
|
||||
|
||||
const result = await fetch('https://dmfw.mca.gov.cn/9095/stname/listPub', {
|
||||
method: 'post',
|
||||
body: form,
|
||||
});
|
||||
const { records } = await result.json();
|
||||
const pois = await Promise.all(
|
||||
records.map(async (ele: DmfwPoi) => {
|
||||
let {
|
||||
area,
|
||||
standard_name,
|
||||
gdm,
|
||||
id,
|
||||
province_name,
|
||||
city_name,
|
||||
area_name,
|
||||
place_type,
|
||||
} = ele;
|
||||
// 对返回的area数据进行一些清洗,不规范
|
||||
if (area.length === 9) {
|
||||
if (area.endsWith('999')) {
|
||||
area = area.slice(0, 6);
|
||||
}
|
||||
}
|
||||
if (area === '000000') {
|
||||
// 搜索如长江这样的地理名称时会返回这样的数据,过滤掉
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
areaId: area,
|
||||
poiName: standard_name,
|
||||
coordinate: gdm.coordinates[0],
|
||||
detail: `${province_name}${city_name}${area_name}${standard_name}(${place_type})`,
|
||||
};
|
||||
})
|
||||
);
|
||||
return pois.filter((poi) => !!poi) as {
|
||||
id: string;
|
||||
areaId: string;
|
||||
poiName: string;
|
||||
coordinate: [number, number];
|
||||
}[];
|
||||
export function registerGetMapService(
|
||||
fn: <ED extends BaseEntityDict & EntityDict>(context: AsyncContext<ED>) => Promise<MapService>
|
||||
) {
|
||||
GetMapServiceFn = fn;
|
||||
}
|
||||
|
||||
export async function geoService<ED extends BaseEntityDict & EntityDict, A extends GeoApi>(options: {
|
||||
api: A;
|
||||
params: Parameters<MapService[A]>[0];
|
||||
}, context: AsyncContext<ED>) {
|
||||
assert(GetMapServiceFn, '未注入指定的GetMapServiceFn');
|
||||
const service = await GetMapServiceFn<ED, AsyncContext<ED>>(context);
|
||||
|
||||
const { api, params } = options;
|
||||
return await service[api](params as any);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { operate, select, fetchRows, count, aggregate } from './crud';
|
|||
import { amap } from './amap';
|
||||
import { getTranslations } from './locales';
|
||||
import { registerPorts, clearPorts, importEntity, exportEntity, getImportationTemplate } from './port';
|
||||
import { searchPoi } from './geo';
|
||||
import { geoService, registerGetMapService } from './geo';
|
||||
import { loadRelations } from './relation';
|
||||
import { crossBridge } from './utils';
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ const aspectDict = {
|
|||
importEntity,
|
||||
exportEntity,
|
||||
getImportationTemplate,
|
||||
searchPoi,
|
||||
geoService,
|
||||
loadRelations,
|
||||
crossBridge,
|
||||
};
|
||||
|
|
@ -27,4 +27,5 @@ export * from './AspectDict';
|
|||
export {
|
||||
registerPorts,
|
||||
clearPorts,
|
||||
registerGetMapService,
|
||||
};
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
import { MapService } from "../types/Map";
|
||||
import assert from 'assert';
|
||||
import AmapSDK from 'oak-external-sdk/lib/AmapSDK';
|
||||
import { AmapKeyType, WebServiceKeyWeight } from 'oak-external-sdk/lib/types/AMap';
|
||||
|
||||
export default class AMap implements MapService {
|
||||
keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
count: number;
|
||||
}>;
|
||||
index: number;
|
||||
|
||||
constructor(keys: Array<{
|
||||
key: string;
|
||||
type: AmapKeyType;
|
||||
}>) {
|
||||
assert(keys.length > 0);
|
||||
this.keys = keys.map(
|
||||
ele => ({
|
||||
...ele,
|
||||
count: WebServiceKeyWeight[ele.type],
|
||||
})
|
||||
);
|
||||
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
protected getKey() {
|
||||
while (true) {
|
||||
const key = this.keys[this.index];
|
||||
if (key.count > 0) {
|
||||
key.count --;
|
||||
return key.key;
|
||||
}
|
||||
key.count = WebServiceKeyWeight[key.type];
|
||||
this.index = (this.index + 1) % this.keys.length;
|
||||
}
|
||||
}
|
||||
|
||||
async regeo(param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK.getInstance(key);
|
||||
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { regeocode } = await instance.regeo(param)
|
||||
|
||||
return {
|
||||
poiName: regeocode.formatted_address,
|
||||
areaId: regeocode.addressComponent.towncode,
|
||||
}
|
||||
};
|
||||
|
||||
async geo(param: { name: string; areaId?: string }) {
|
||||
const key = this.getKey();
|
||||
const instance = AmapSDK.getInstance(key);
|
||||
|
||||
/**
|
||||
* https://lbs.amap.com/api/webservice/guide/api/georegeo
|
||||
*/
|
||||
const { name, areaId } = param;
|
||||
const { geocodes } = await instance.geocode({
|
||||
address: name,
|
||||
city: areaId,
|
||||
});
|
||||
|
||||
return geocodes.map(
|
||||
(ele: any) =>({
|
||||
poiName: ele.formatted_address,
|
||||
areaId: ele.adcode,
|
||||
latitude: ele.location[0],
|
||||
longitude: ele.location[1],
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
13
src/port.ts
13
src/port.ts
|
|
@ -1,5 +1,6 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { EntityDict, SelectOption } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { Importation, Exportation } from 'oak-domain/lib/types/Port';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
import { read, utils, write, readFile, Sheet2JSONOpts } from 'xlsx';
|
||||
|
|
@ -8,7 +9,7 @@ import { read, utils, write, readFile, Sheet2JSONOpts } from 'xlsx';
|
|||
const Importations: Record<string, any> = {};
|
||||
const Exportations: Record<string, any> = {};
|
||||
|
||||
export function registerPorts<ED extends EntityDict>(
|
||||
export function registerPorts<ED extends EntityDict & BaseEntityDict>(
|
||||
importations: Importation<ED, keyof ED, any, any>[],
|
||||
exportations: Exportation<ED, keyof ED, any, any>[]
|
||||
) {
|
||||
|
|
@ -42,18 +43,18 @@ export function clearPorts() {
|
|||
}
|
||||
}
|
||||
|
||||
function getImportation<ED extends EntityDict, T extends keyof ED>(id: string) {
|
||||
function getImportation<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(id: string) {
|
||||
assert(Importations.hasOwnProperty(id), `id为[${id}]的importation不存在`);
|
||||
return Importations[id] as Importation<ED, T, any, any>;
|
||||
}
|
||||
|
||||
function getExportation<ED extends EntityDict, T extends keyof ED>(id: string) {
|
||||
function getExportation<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(id: string) {
|
||||
assert(Exportations.hasOwnProperty(id), `id为[${id}]的exportation不存在`);
|
||||
return Exportations[id] as Exportation<ED, T, any, any>;
|
||||
}
|
||||
|
||||
export async function importEntity<
|
||||
ED extends EntityDict,
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
Cxt extends AsyncContext<ED>
|
||||
>(
|
||||
params: {
|
||||
|
|
@ -110,7 +111,7 @@ export async function importEntity<
|
|||
}
|
||||
|
||||
export async function exportEntity<
|
||||
ED extends EntityDict,
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
T extends keyof ED,
|
||||
Cxt extends AsyncContext<ED>
|
||||
>(
|
||||
|
|
@ -156,7 +157,7 @@ export async function exportEntity<
|
|||
}
|
||||
|
||||
export async function getImportationTemplate<
|
||||
ED extends EntityDict,
|
||||
ED extends EntityDict & BaseEntityDict,
|
||||
Cxt extends AsyncContext<ED>
|
||||
>(params: { id: string }, context: Cxt): Promise<ArrayBuffer> {
|
||||
const id = params.id;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
import { EntityDict } from 'oak-domain/lib/base-app-domain';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
||||
|
||||
export interface MapService {
|
||||
regeo: (param: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}) => Promise<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
}>;
|
||||
|
||||
geo: (param: {
|
||||
name: string;
|
||||
areaId?: string;
|
||||
}) => Promise<
|
||||
Array<{
|
||||
poiName: string;
|
||||
areaId: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
}>
|
||||
>;
|
||||
};
|
||||
Loading…
Reference in New Issue