mirror of https://gitee.com/antv-l7/antv-l7
feat: add popup add marker
This commit is contained in:
parent
cd44449cb6
commit
0679435c14
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Get Started
|
||||
order: 0
|
||||
---
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
title: 快速开始
|
||||
order: 0
|
||||
---
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
npm i @antv/l7-react
|
||||
```
|
||||
|
||||
### 示例
|
||||
|
||||
```javascript
|
||||
import { LineLayer, AMapScene } from '@antv/l7-react';
|
||||
export default React.memo(function Map() {
|
||||
const [data, setData] = React.useState();
|
||||
React.useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const response = await fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/32e1f3ab-8588-46cb-8a47-75afb692117d.json',
|
||||
);
|
||||
const raw = await response.json();
|
||||
setData(raw);
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<AMapScene
|
||||
map={{
|
||||
center: [110.19382669582967, 50.258134],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
zoom: 1,
|
||||
}}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
{data && (
|
||||
<LineLayer
|
||||
key={'2'}
|
||||
source={{
|
||||
data,
|
||||
}}
|
||||
size={{
|
||||
values: 1,
|
||||
}}
|
||||
color={{
|
||||
values: '#fff',
|
||||
}}
|
||||
shape={{
|
||||
values: 'line',
|
||||
}}
|
||||
style={{
|
||||
opacity: 1,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</AMapScene>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
```
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
import { ILngLat, IMapService, IPoint, IPopup, TYPES } from '@antv/l7-core';
|
||||
import {
|
||||
ILngLat,
|
||||
IMapService,
|
||||
IMarkerOption,
|
||||
IPoint,
|
||||
IPopup,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import {
|
||||
anchorTranslate,
|
||||
anchorType,
|
||||
|
@ -10,15 +17,6 @@ import { EventEmitter } from 'eventemitter3';
|
|||
import { Container } from 'inversify';
|
||||
|
||||
// marker 支持 dragger 未完成
|
||||
|
||||
export interface IMarkerOption {
|
||||
element: HTMLElement | undefined;
|
||||
anchor: anchorType;
|
||||
color: string;
|
||||
offsets: number[];
|
||||
draggable: boolean;
|
||||
extData?: any;
|
||||
}
|
||||
export default class Marker extends EventEmitter {
|
||||
private markerOption: IMarkerOption;
|
||||
private defaultMarker: boolean;
|
||||
|
|
|
@ -76,7 +76,7 @@ export default class Popup extends EventEmitter implements IPopup {
|
|||
return this.setDOMContent(frag);
|
||||
}
|
||||
|
||||
public setLnglat(lngLat: ILngLat): this {
|
||||
public setLnglat(lngLat: ILngLat | number[]): this {
|
||||
this.lngLat = lngLat as ILngLat;
|
||||
if (Array.isArray(lngLat)) {
|
||||
this.lngLat = {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { anchorType } from '@antv/l7-utils';
|
||||
import { Container, injectable } from 'inversify';
|
||||
import { ILngLat, IMapService, IPoint } from '../map/IMapService';
|
||||
import { IPopup } from './IPopupService';
|
||||
|
@ -9,6 +10,14 @@ export interface IMarkerScene {
|
|||
export interface IMarkerServiceCfg {
|
||||
container: HTMLElement;
|
||||
}
|
||||
export interface IMarkerOption {
|
||||
element: HTMLElement | undefined;
|
||||
anchor: anchorType;
|
||||
color: string;
|
||||
offsets: number[];
|
||||
draggable: boolean;
|
||||
extData?: any;
|
||||
}
|
||||
export interface IMarker {
|
||||
addTo(scene: Container): void;
|
||||
remove(): void;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Ajv from 'ajv';
|
||||
// import Ajv from 'ajv';
|
||||
import { injectable, postConstruct } from 'inversify';
|
||||
import { merge } from 'lodash';
|
||||
import { ILayerConfig } from '../layer/ILayerService';
|
||||
|
@ -78,10 +78,10 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
|
|||
};
|
||||
|
||||
// @see https://github.com/epoberezkin/ajv#options
|
||||
const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
verbose: true,
|
||||
});
|
||||
// const ajv = new Ajv({
|
||||
// allErrors: true,
|
||||
// verbose: true,
|
||||
// });
|
||||
|
||||
@injectable()
|
||||
export default class GlobalConfigService implements IGlobalConfigService {
|
||||
|
@ -95,12 +95,12 @@ export default class GlobalConfigService implements IGlobalConfigService {
|
|||
/**
|
||||
* 场景配置项校验器
|
||||
*/
|
||||
private sceneConfigValidator: Ajv.ValidateFunction;
|
||||
// private sceneConfigValidator: Ajv.ValidateFunction;
|
||||
|
||||
/**
|
||||
* 地图配置项校验器
|
||||
*/
|
||||
private mapConfigValidator: Ajv.ValidateFunction;
|
||||
// private mapConfigValidator: Ajv.ValidateFunction;
|
||||
|
||||
/**
|
||||
* 全部图层配置项缓存
|
||||
|
@ -112,9 +112,9 @@ export default class GlobalConfigService implements IGlobalConfigService {
|
|||
/**
|
||||
* 保存每一种 Layer 配置项的校验器
|
||||
*/
|
||||
private layerConfigValidatorCache: {
|
||||
[layerName: string]: Ajv.ValidateFunction;
|
||||
} = {};
|
||||
// private layerConfigValidatorCache: {
|
||||
// [layerName: string]: Ajv.ValidateFunction;
|
||||
// } = {};
|
||||
|
||||
public getSceneConfig(sceneId: string) {
|
||||
return this.sceneConfigCache[sceneId];
|
||||
|
@ -131,13 +131,13 @@ export default class GlobalConfigService implements IGlobalConfigService {
|
|||
};
|
||||
}
|
||||
|
||||
public validateSceneConfig(data: object) {
|
||||
return this.validate(this.sceneConfigValidator, data);
|
||||
}
|
||||
// public validateSceneConfig(data: object) {
|
||||
// return this.validate(this.sceneConfigValidator, data);
|
||||
// }
|
||||
|
||||
public validateMapConfig(data: object) {
|
||||
return this.validate(this.mapConfigValidator, data);
|
||||
}
|
||||
// public validateMapConfig(data: object) {
|
||||
// return this.validate(this.mapConfigValidator, data);
|
||||
// }
|
||||
|
||||
public getLayerConfig<IChildLayerConfig>(
|
||||
layerId: string,
|
||||
|
@ -157,45 +157,45 @@ export default class GlobalConfigService implements IGlobalConfigService {
|
|||
};
|
||||
}
|
||||
|
||||
public registerLayerConfigSchemaValidator(layerName: string, schema: object) {
|
||||
if (!this.layerConfigValidatorCache[layerName]) {
|
||||
this.layerConfigValidatorCache[layerName] = ajv.compile(schema);
|
||||
}
|
||||
}
|
||||
// public registerLayerConfigSchemaValidator(layerName: string, schema: object) {
|
||||
// if (!this.layerConfigValidatorCache[layerName]) {
|
||||
// this.layerConfigValidatorCache[layerName] = ajv.compile(schema);
|
||||
// }
|
||||
// }
|
||||
|
||||
public validateLayerConfig(layerName: string, data: object) {
|
||||
return this.validate(this.layerConfigValidatorCache[layerName], data);
|
||||
}
|
||||
// public validateLayerConfig(layerName: string, data: object) {
|
||||
// return this.validate(this.layerConfigValidatorCache[layerName], data);
|
||||
// }
|
||||
|
||||
public clean() {
|
||||
this.sceneConfigCache = {};
|
||||
this.layerConfigCache = {};
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
private registerSceneConfigSchemaValidator() {
|
||||
this.sceneConfigValidator = ajv.compile(sceneConfigSchema);
|
||||
this.mapConfigValidator = ajv.compile(mapConfigSchema);
|
||||
}
|
||||
// @postConstruct()
|
||||
// private registerSceneConfigSchemaValidator() {
|
||||
// this.sceneConfigValidator = ajv.compile(sceneConfigSchema);
|
||||
// this.mapConfigValidator = ajv.compile(mapConfigSchema);
|
||||
// }
|
||||
|
||||
private validate(
|
||||
validateFunc: Ajv.ValidateFunction | undefined,
|
||||
data: object,
|
||||
) {
|
||||
if (validateFunc) {
|
||||
const valid = validateFunc(data);
|
||||
if (!valid) {
|
||||
return {
|
||||
valid,
|
||||
errors: validateFunc.errors,
|
||||
errorText: ajv.errorsText(validateFunc.errors),
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
errors: null,
|
||||
errorText: null,
|
||||
};
|
||||
}
|
||||
// private validate(
|
||||
// validateFunc: Ajv.ValidateFunction | undefined,
|
||||
// data: object,
|
||||
// ) {
|
||||
// if (validateFunc) {
|
||||
// const valid = validateFunc(data);
|
||||
// if (!valid) {
|
||||
// return {
|
||||
// valid,
|
||||
// errors: validateFunc.errors,
|
||||
// errorText: ajv.errorsText(validateFunc.errors),
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// return {
|
||||
// valid: true,
|
||||
// errors: null,
|
||||
// errorText: null,
|
||||
// };
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Ajv from 'ajv';
|
||||
// import Ajv from 'ajv';
|
||||
import { PositionName } from '../component/IControlService';
|
||||
import { ILayerConfig } from '../layer/ILayerService';
|
||||
import { IMapWrapper } from '../map/IMapService';
|
||||
|
@ -10,11 +10,11 @@ export interface ISceneConfig extends IRenderConfig {
|
|||
logoVisible?: boolean;
|
||||
}
|
||||
|
||||
interface IValidateResult {
|
||||
valid: boolean;
|
||||
errors: Ajv.ErrorObject[] | null | undefined;
|
||||
errorText: string | null;
|
||||
}
|
||||
// interface IValidateResult {
|
||||
// valid: boolean;
|
||||
// errors: Ajv.ErrorObject[] | null | undefined;
|
||||
// errorText: string | null;
|
||||
// }
|
||||
|
||||
export interface IGlobalConfigService {
|
||||
/**
|
||||
|
@ -28,13 +28,13 @@ export interface IGlobalConfigService {
|
|||
* 校验用户传入的场景配置项
|
||||
* @param data 场景配置项
|
||||
*/
|
||||
validateSceneConfig(data: object): IValidateResult;
|
||||
// validateSceneConfig(data: object): IValidateResult;
|
||||
|
||||
/**
|
||||
* 校验用户传入的地图配置项
|
||||
* @param data 地图配置项
|
||||
*/
|
||||
validateMapConfig(data: object): IValidateResult;
|
||||
// validateMapConfig(data: object): IValidateResult;
|
||||
|
||||
/**
|
||||
* 获取图层配置项
|
||||
|
@ -66,13 +66,13 @@ export interface IGlobalConfigService {
|
|||
* @param layerName 图层名
|
||||
* @param schema 校验规则描述
|
||||
*/
|
||||
registerLayerConfigSchemaValidator(layerName: string, schema: object): void;
|
||||
// registerLayerConfigSchemaValidator(layerName: string, schema: object): void;
|
||||
|
||||
/**
|
||||
* 校验用户传入的图层配置项
|
||||
* @param data 图层配置项
|
||||
*/
|
||||
validateLayerConfig(layerName: string, data: object): IValidateResult;
|
||||
// validateLayerConfig(layerName: string, data: object): IValidateResult;
|
||||
|
||||
/**
|
||||
* 清除场景和图层配置项 Cache,但是需要保留校验器
|
||||
|
|
|
@ -1,144 +1,144 @@
|
|||
import { Container } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
import { TYPES } from '../../../index';
|
||||
import GlobalConfigService from '../ConfigService';
|
||||
import { IGlobalConfigService } from '../IConfigService';
|
||||
// import { Container } from 'inversify';
|
||||
// import 'reflect-metadata';
|
||||
// import { TYPES } from '../../../index';
|
||||
// import GlobalConfigService from '../ConfigService';
|
||||
// import { IGlobalConfigService } from '../IConfigService';
|
||||
|
||||
describe('ConfigService', () => {
|
||||
let container: Container;
|
||||
let configService: IGlobalConfigService;
|
||||
// describe('ConfigService', () => {
|
||||
// let container: Container;
|
||||
// let configService: IGlobalConfigService;
|
||||
|
||||
beforeAll(() => {
|
||||
container = new Container();
|
||||
container
|
||||
.bind<IGlobalConfigService>(TYPES.IGlobalConfigService)
|
||||
.to(GlobalConfigService);
|
||||
configService = container.get<IGlobalConfigService>(
|
||||
TYPES.IGlobalConfigService,
|
||||
);
|
||||
});
|
||||
// beforeAll(() => {
|
||||
// container = new Container();
|
||||
// container
|
||||
// .bind<IGlobalConfigService>(TYPES.IGlobalConfigService)
|
||||
// .to(GlobalConfigService);
|
||||
// configService = container.get<IGlobalConfigService>(
|
||||
// TYPES.IGlobalConfigService,
|
||||
// );
|
||||
// });
|
||||
|
||||
afterAll(() => {
|
||||
container.unbind(TYPES.IGlobalConfigService);
|
||||
});
|
||||
// afterAll(() => {
|
||||
// container.unbind(TYPES.IGlobalConfigService);
|
||||
// });
|
||||
|
||||
it("should validate scene's options according to JSON schema", () => {
|
||||
// const { valid, errorText } = configService.validateSceneConfig({
|
||||
// id: 0,
|
||||
// });
|
||||
// expect(valid).toBeFalsy();
|
||||
// expect(errorText).toMatch('id should be string');
|
||||
// it("should validate scene's options according to JSON schema", () => {
|
||||
// // const { valid, errorText } = configService.validateSceneConfig({
|
||||
// // id: 0,
|
||||
// // });
|
||||
// // expect(valid).toBeFalsy();
|
||||
// // expect(errorText).toMatch('id should be string');
|
||||
|
||||
expect(
|
||||
configService.validateSceneConfig({
|
||||
id: 'map',
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
});
|
||||
// expect(
|
||||
// configService.validateSceneConfig({
|
||||
// id: 'map',
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
// });
|
||||
|
||||
it("should validate map's `zoom` option", () => {
|
||||
const { valid, errorText } = configService.validateMapConfig({
|
||||
zoom: 100,
|
||||
minZoom: 100,
|
||||
maxZoom: -2,
|
||||
});
|
||||
expect(valid).toBeFalsy();
|
||||
expect(errorText).toMatch('zoom should be <= 24');
|
||||
expect(errorText).toMatch('minZoom should be <= 24');
|
||||
expect(errorText).toMatch('maxZoom should be >= -1');
|
||||
// it("should validate map's `zoom` option", () => {
|
||||
// const { valid, errorText } = configService.validateMapConfig({
|
||||
// zoom: 100,
|
||||
// minZoom: 100,
|
||||
// maxZoom: -2,
|
||||
// });
|
||||
// expect(valid).toBeFalsy();
|
||||
// expect(errorText).toMatch('zoom should be <= 24');
|
||||
// expect(errorText).toMatch('minZoom should be <= 24');
|
||||
// expect(errorText).toMatch('maxZoom should be >= -1');
|
||||
|
||||
expect(
|
||||
configService.validateMapConfig({
|
||||
zoom: 10,
|
||||
minZoom: 1,
|
||||
maxZoom: 15,
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
});
|
||||
// expect(
|
||||
// configService.validateMapConfig({
|
||||
// zoom: 10,
|
||||
// minZoom: 1,
|
||||
// maxZoom: 15,
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
// });
|
||||
|
||||
it("should validate map's `pitch` option", () => {
|
||||
const { valid, errorText } = configService.validateMapConfig({
|
||||
pitch: '1',
|
||||
});
|
||||
expect(valid).toBeFalsy();
|
||||
expect(errorText).toMatch('pitch should be number');
|
||||
// it("should validate map's `pitch` option", () => {
|
||||
// const { valid, errorText } = configService.validateMapConfig({
|
||||
// pitch: '1',
|
||||
// });
|
||||
// expect(valid).toBeFalsy();
|
||||
// expect(errorText).toMatch('pitch should be number');
|
||||
|
||||
expect(
|
||||
configService.validateMapConfig({
|
||||
pitch: 10,
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
});
|
||||
// expect(
|
||||
// configService.validateMapConfig({
|
||||
// pitch: 10,
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
// });
|
||||
|
||||
it("should validate map's `center` option", () => {
|
||||
const { valid, errorText } = configService.validateMapConfig({
|
||||
center: [1, 2, 3],
|
||||
});
|
||||
expect(valid).toBeFalsy();
|
||||
expect(errorText).toMatch('center should NOT have more than 2 items');
|
||||
// it("should validate map's `center` option", () => {
|
||||
// const { valid, errorText } = configService.validateMapConfig({
|
||||
// center: [1, 2, 3],
|
||||
// });
|
||||
// expect(valid).toBeFalsy();
|
||||
// expect(errorText).toMatch('center should NOT have more than 2 items');
|
||||
|
||||
const { valid: v2, errorText: e2 } = configService.validateMapConfig({
|
||||
center: [1],
|
||||
});
|
||||
expect(v2).toBeFalsy();
|
||||
expect(e2).toMatch('center should NOT have fewer than 2 items');
|
||||
// const { valid: v2, errorText: e2 } = configService.validateMapConfig({
|
||||
// center: [1],
|
||||
// });
|
||||
// expect(v2).toBeFalsy();
|
||||
// expect(e2).toMatch('center should NOT have fewer than 2 items');
|
||||
|
||||
const { valid: v3, errorText: e3 } = configService.validateMapConfig({
|
||||
center: 100,
|
||||
});
|
||||
expect(v3).toBeFalsy();
|
||||
expect(e3).toMatch('center should be array');
|
||||
// const { valid: v3, errorText: e3 } = configService.validateMapConfig({
|
||||
// center: 100,
|
||||
// });
|
||||
// expect(v3).toBeFalsy();
|
||||
// expect(e3).toMatch('center should be array');
|
||||
|
||||
expect(
|
||||
configService.validateMapConfig({
|
||||
center: [100, 100],
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
});
|
||||
// expect(
|
||||
// configService.validateMapConfig({
|
||||
// center: [100, 100],
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
// });
|
||||
|
||||
it("should validate layer's options according to JSON schema", () => {
|
||||
configService.registerLayerConfigSchemaValidator('testLayer', {
|
||||
properties: {
|
||||
opacity: {
|
||||
type: 'number',
|
||||
minimum: 0,
|
||||
maximum: 1,
|
||||
},
|
||||
enablePicking: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
});
|
||||
// it("should validate layer's options according to JSON schema", () => {
|
||||
// configService.registerLayerConfigSchemaValidator('testLayer', {
|
||||
// properties: {
|
||||
// opacity: {
|
||||
// type: 'number',
|
||||
// minimum: 0,
|
||||
// maximum: 1,
|
||||
// },
|
||||
// enablePicking: {
|
||||
// type: 'boolean',
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
const { valid, errorText } = configService.validateLayerConfig(
|
||||
'testLayer',
|
||||
{ opacity: 'invalid' },
|
||||
);
|
||||
expect(valid).toBeFalsy();
|
||||
expect(errorText).toMatch('opacity should be number');
|
||||
// const { valid, errorText } = configService.validateLayerConfig(
|
||||
// 'testLayer',
|
||||
// { opacity: 'invalid' },
|
||||
// );
|
||||
// expect(valid).toBeFalsy();
|
||||
// expect(errorText).toMatch('opacity should be number');
|
||||
|
||||
expect(
|
||||
configService.validateLayerConfig('testLayer', {
|
||||
opacity: 1.5,
|
||||
}).valid,
|
||||
).toBeFalsy();
|
||||
// expect(
|
||||
// configService.validateLayerConfig('testLayer', {
|
||||
// opacity: 1.5,
|
||||
// }).valid,
|
||||
// ).toBeFalsy();
|
||||
|
||||
expect(
|
||||
configService.validateLayerConfig('testLayer', {
|
||||
enablePicking: 1.5,
|
||||
}).valid,
|
||||
).toBeFalsy();
|
||||
// expect(
|
||||
// configService.validateLayerConfig('testLayer', {
|
||||
// enablePicking: 1.5,
|
||||
// }).valid,
|
||||
// ).toBeFalsy();
|
||||
|
||||
expect(
|
||||
configService.validateLayerConfig('testLayer', {
|
||||
opacity: 1.0,
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
// expect(
|
||||
// configService.validateLayerConfig('testLayer', {
|
||||
// opacity: 1.0,
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
|
||||
expect(
|
||||
configService.validateLayerConfig('testLayer', {
|
||||
opacity: 0.0,
|
||||
}).valid,
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
// expect(
|
||||
// configService.validateLayerConfig('testLayer', {
|
||||
// opacity: 0.0,
|
||||
// }).valid,
|
||||
// ).toBeTruthy();
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -117,13 +117,13 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
this.configService.setSceneConfig(this.id, sceneConfig);
|
||||
|
||||
// 校验场景配置项,失败则终止初始化过程
|
||||
const { valid, errorText } = this.configService.validateSceneConfig(
|
||||
this.configService.getSceneConfig(this.id),
|
||||
);
|
||||
if (!valid) {
|
||||
this.logger.error(errorText || '');
|
||||
return;
|
||||
}
|
||||
// const { valid, errorText } = this.configService.validateSceneConfig(
|
||||
// this.configService.getSceneConfig(this.id),
|
||||
// );
|
||||
// if (!valid) {
|
||||
// this.logger.error(errorText || '');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 初始化 ShaderModule
|
||||
this.shaderModuleService.registerBuiltinModules();
|
||||
|
|
|
@ -9,7 +9,7 @@ import PointLayer from './point';
|
|||
import PolygonLayer from './polygon';
|
||||
import RasterLayer from './raster';
|
||||
|
||||
import ConfigSchemaValidationPlugin from './plugins/ConfigSchemaValidationPlugin';
|
||||
// import ConfigSchemaValidationPlugin from './plugins/ConfigSchemaValidationPlugin';
|
||||
import DataMappingPlugin from './plugins/DataMappingPlugin';
|
||||
import DataSourcePlugin from './plugins/DataSourcePlugin';
|
||||
import FeatureScalePlugin from './plugins/FeatureScalePlugin';
|
||||
|
@ -27,10 +27,10 @@ import UpdateStyleAttributePlugin from './plugins/UpdateStyleAttributePlugin';
|
|||
* 校验传入参数配置项的正确性
|
||||
* @see /dev-docs/ConfigSchemaValidation.md
|
||||
*/
|
||||
container
|
||||
.bind<ILayerPlugin>(TYPES.ILayerPlugin)
|
||||
.to(ConfigSchemaValidationPlugin)
|
||||
.inRequestScope();
|
||||
// container
|
||||
// .bind<ILayerPlugin>(TYPES.ILayerPlugin)
|
||||
// .to(ConfigSchemaValidationPlugin)
|
||||
// .inRequestScope();
|
||||
/**
|
||||
* 获取 Source
|
||||
*/
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
import {
|
||||
IGlobalConfigService,
|
||||
ILayer,
|
||||
ILayerPlugin,
|
||||
ILogService,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import { inject, injectable } from 'inversify';
|
||||
// import {
|
||||
// IGlobalConfigService,
|
||||
// ILayer,
|
||||
// ILayerPlugin,
|
||||
// ILogService,
|
||||
// TYPES,
|
||||
// } from '@antv/l7-core';
|
||||
// import { inject, injectable } from 'inversify';
|
||||
|
||||
/**
|
||||
* Layer 初始化阶段以及重绘阶段首先校验传入参数,如果校验失败则中断后续插件处理。
|
||||
*/
|
||||
@injectable()
|
||||
export default class ConfigSchemaValidationPlugin implements ILayerPlugin {
|
||||
@inject(TYPES.IGlobalConfigService)
|
||||
private readonly configService: IGlobalConfigService;
|
||||
// /**
|
||||
// * Layer 初始化阶段以及重绘阶段首先校验传入参数,如果校验失败则中断后续插件处理。
|
||||
// */
|
||||
// @injectable()
|
||||
// export default class ConfigSchemaValidationPlugin implements ILayerPlugin {
|
||||
// @inject(TYPES.IGlobalConfigService)
|
||||
// private readonly configService: IGlobalConfigService;
|
||||
|
||||
@inject(TYPES.ILogService)
|
||||
private readonly logger: ILogService;
|
||||
// @inject(TYPES.ILogService)
|
||||
// private readonly logger: ILogService;
|
||||
|
||||
public apply(layer: ILayer) {
|
||||
layer.hooks.init.tap('ConfigSchemaValidationPlugin', () => {
|
||||
this.configService.registerLayerConfigSchemaValidator(
|
||||
layer.name as string,
|
||||
layer.getConfigSchemaForValidation(),
|
||||
);
|
||||
// public apply(layer: ILayer) {
|
||||
// layer.hooks.init.tap('ConfigSchemaValidationPlugin', () => {
|
||||
// this.configService.registerLayerConfigSchemaValidator(
|
||||
// layer.name as string,
|
||||
// layer.getConfigSchemaForValidation(),
|
||||
// );
|
||||
|
||||
const { valid, errorText } = this.configService.validateLayerConfig(
|
||||
layer.name as string,
|
||||
layer.getLayerConfig(),
|
||||
);
|
||||
// const { valid, errorText } = this.configService.validateLayerConfig(
|
||||
// layer.name as string,
|
||||
// layer.getLayerConfig(),
|
||||
// );
|
||||
|
||||
if (!valid) {
|
||||
this.logger.error(errorText || '');
|
||||
// 中断 init 过程
|
||||
return false;
|
||||
}
|
||||
});
|
||||
layer.hooks.beforeRender.tap('ConfigSchemaValidationPlugin', () => {
|
||||
// TODO: 配置项发生变化,需要重新校验
|
||||
});
|
||||
}
|
||||
}
|
||||
// if (!valid) {
|
||||
// this.logger.error(errorText || '');
|
||||
// // 中断 init 过程
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
// layer.hooks.beforeRender.tap('ConfigSchemaValidationPlugin', () => {
|
||||
// // TODO: 配置项发生变化,需要重新校验
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -23,14 +23,14 @@ export default class BaseMapWrapper<RawMap> implements IMapWrapper {
|
|||
|
||||
public setContainer(sceneContainer: Container, id: string | HTMLDivElement) {
|
||||
// // 首先使用全局配置服务校验地图参数
|
||||
const { valid, errorText } = this.configService.validateMapConfig(
|
||||
this.config,
|
||||
);
|
||||
// const { valid, errorText } = this.configService.validateMapConfig(
|
||||
// this.config,
|
||||
// );
|
||||
|
||||
if (!valid) {
|
||||
this.logger.error(errorText || '');
|
||||
return;
|
||||
}
|
||||
// if (!valid) {
|
||||
// this.logger.error(errorText || '');
|
||||
// return;
|
||||
// }
|
||||
// 绑定用户传入的原始地图参数
|
||||
sceneContainer.bind<Partial<IMapConfig>>(TYPES.MapConfig).toConstantValue({
|
||||
...this.config,
|
||||
|
|
|
@ -9,7 +9,7 @@ interface IMapSceneConig {
|
|||
className?: string;
|
||||
map: Partial<IMapConfig>;
|
||||
option?: Partial<ISceneConfig>;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
children?: React.ReactNode;
|
||||
onSceneLoaded?: (scene: Scene) => void;
|
||||
}
|
||||
const AMapScene = React.memo((props: IMapSceneConig) => {
|
||||
|
|
|
@ -18,4 +18,16 @@ const PointLayer = React.memo(function Layer(
|
|||
return BaseLayer('pointLayer', props);
|
||||
});
|
||||
|
||||
export { PolygonLayer, LineLayer, PointLayer };
|
||||
const HeatMapLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('heatmapLayer', props);
|
||||
});
|
||||
|
||||
const RasterLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('rasterLayer', props);
|
||||
});
|
||||
|
||||
export { PolygonLayer, LineLayer, PointLayer, HeatMapLayer, RasterLayer };
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import { ILayer, LineLayer, PointLayer, PolygonLayer, Scene } from '@antv/l7';
|
||||
import {
|
||||
HeatmapLayer,
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
RasterLayer,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { LayerContext } from '../LayerContext';
|
||||
import { useSceneValue } from '../SceneContext';
|
||||
|
@ -27,6 +35,7 @@ export default function BaseLayer(type: string, props: ILayerProps) {
|
|||
active,
|
||||
filter,
|
||||
options,
|
||||
onLayerLoad,
|
||||
} = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
const [layer, setLayer] = useState<ILayer>();
|
||||
|
@ -42,9 +51,20 @@ export default function BaseLayer(type: string, props: ILayerProps) {
|
|||
case 'pointLayer':
|
||||
l = new PointLayer(options);
|
||||
break;
|
||||
case 'heatmapLayer':
|
||||
l = new HeatmapLayer(options);
|
||||
break;
|
||||
case 'rasterLayer':
|
||||
l = new RasterLayer(options);
|
||||
break;
|
||||
default:
|
||||
l = new PolygonLayer(options);
|
||||
}
|
||||
l.on('inited', () => {
|
||||
if (onLayerLoad) {
|
||||
onLayerLoad(l, mapScene);
|
||||
}
|
||||
});
|
||||
setLayer(l);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import {
|
||||
BlendType,
|
||||
IActiveOption,
|
||||
ILayer,
|
||||
IScale,
|
||||
IScaleOptions,
|
||||
ISourceCFG,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import Active from './Active';
|
||||
import Color from './Color';
|
||||
import Filter from './Filter';
|
||||
|
@ -69,7 +72,8 @@ export interface ILayerProps {
|
|||
style?: Partial<IStyleOptions>;
|
||||
active?: IActiveOptions;
|
||||
filter?: Partial<IAttributeOptions>;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
onLayerLoad?: (layer: ILayer, scene: Scene) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export { Active, Color, Filter, Source, Size, Shape, Style, Scale };
|
||||
|
|
|
@ -9,7 +9,7 @@ interface IMapSceneConig {
|
|||
className?: string;
|
||||
map: Partial<IMapConfig>;
|
||||
option?: Partial<ISceneConfig>;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
children?: React.ReactNode;
|
||||
onSceneLoaded?: (scene: Scene) => void;
|
||||
}
|
||||
const MapboxScene = React.memo((props: IMapSceneConig) => {
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
import {
|
||||
IActiveOption,
|
||||
IImage,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IMarker,
|
||||
IMarkerOption,
|
||||
IPoint,
|
||||
Marker,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IMarkerProps {
|
||||
option?: IMarkerOption;
|
||||
lnglat: ILngLat | number[];
|
||||
onMarkerLoad?: (marker: IMarker) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
export default class MarkerComponet extends React.PureComponent<IMarkerProps> {
|
||||
private el: HTMLDivElement;
|
||||
private scene: Scene;
|
||||
private marker: IMarker;
|
||||
constructor(props: IMarkerProps) {
|
||||
super(props);
|
||||
this.el = document.createElement('div');
|
||||
}
|
||||
public componentDidMount() {
|
||||
const { lnglat, children, option, onMarkerLoad } = this.props;
|
||||
const marker = new Marker(option);
|
||||
if (lnglat) {
|
||||
marker.setLnglat(lnglat as ILngLat | IPoint);
|
||||
}
|
||||
if (children) {
|
||||
marker.setElement(this.el);
|
||||
}
|
||||
this.marker = marker;
|
||||
if (onMarkerLoad) {
|
||||
onMarkerLoad(marker);
|
||||
}
|
||||
this.scene.addMarker(marker);
|
||||
}
|
||||
public componentDidUpdate(prevProps: IMarkerProps) {
|
||||
const positionChanged =
|
||||
prevProps?.lnglat.toString() !== this.props?.lnglat.toString();
|
||||
|
||||
if (positionChanged) {
|
||||
this.marker.setLnglat(this.props.lnglat as ILngLat | IPoint);
|
||||
}
|
||||
}
|
||||
public componentWillUnmount() {
|
||||
if (this.marker) {
|
||||
this.marker.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
return React.createElement(
|
||||
SceneContext.Consumer,
|
||||
// @ts-ignore
|
||||
{},
|
||||
(scene: Scene) => {
|
||||
if (scene) {
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
return createPortal(this.props.children, this.el);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,36 +9,59 @@ import {
|
|||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IPopupProps {
|
||||
option: IPopupOption;
|
||||
lnglat: ILngLat;
|
||||
text: string;
|
||||
html: string;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
option?: IPopupOption;
|
||||
lnglat: number[];
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
export default React.memo(function LoadImage(props: IPopupProps) {
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
const { lnglat, html, text, children } = props;
|
||||
const [popup, setPopup] = React.useState<Popup>();
|
||||
const el = document.createElement('div');
|
||||
useEffect(() => {
|
||||
const p = new Popup(props.option);
|
||||
export default class PopupComponet extends React.PureComponent<IPopupProps> {
|
||||
private el: HTMLDivElement;
|
||||
private scene: Scene;
|
||||
private popup: Popup;
|
||||
constructor(props: IPopupProps) {
|
||||
super(props);
|
||||
this.el = document.createElement('div');
|
||||
}
|
||||
public componentDidMount() {
|
||||
const { lnglat, children, option } = this.props;
|
||||
const p = new Popup(option);
|
||||
|
||||
if (lnglat) {
|
||||
p.setLnglat(lnglat);
|
||||
}
|
||||
if (html) {
|
||||
p.setHTML(html);
|
||||
}
|
||||
if (text) {
|
||||
p.setText(text);
|
||||
}
|
||||
if (children) {
|
||||
p.setDOMContent(el);
|
||||
p.setDOMContent(this.el);
|
||||
}
|
||||
setPopup(p);
|
||||
}, []);
|
||||
return createPortal(children, el);
|
||||
});
|
||||
this.popup = p;
|
||||
this.scene.addPopup(p);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: IPopupProps) {
|
||||
const positionChanged =
|
||||
prevProps?.lnglat.toString() !== this.props?.lnglat.toString();
|
||||
|
||||
if (positionChanged) {
|
||||
this.popup.setLnglat(this.props.lnglat);
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.popup.remove();
|
||||
}
|
||||
|
||||
public render() {
|
||||
return React.createElement(
|
||||
SceneContext.Consumer,
|
||||
// @ts-ignore
|
||||
{},
|
||||
(scene: Scene) => {
|
||||
if (scene) {
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
return createPortal(this.props.children, this.el);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ interface IMapSceneConig {
|
|||
style?: Partial<React.CSSProperties>;
|
||||
className?: string;
|
||||
map: IMapWrapper;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
export default React.memo((props: IMapSceneConig) => {
|
||||
const { style, className, map } = props;
|
||||
|
|
|
@ -10,3 +10,5 @@ export { LayerEvent } from './component/LayerEvent';
|
|||
export { useSceneValue, SceneContext } from './component/SceneContext';
|
||||
export { useLayerValue, LayerContext } from './component/LayerContext';
|
||||
export { ColorComponent } from './component/Legend/color';
|
||||
export { default as Popup } from './component/Popup';
|
||||
export { default as Marker } from './component/Marker';
|
||||
|
|
|
@ -31,7 +31,7 @@ export default class World extends React.Component {
|
|||
id: 'map',
|
||||
logoVisible: false,
|
||||
map: new Mapbox({
|
||||
style: 'dark',
|
||||
style: 'light',
|
||||
center: [110.19382669582967, 30.258134],
|
||||
pitch: 0,
|
||||
zoom: 0,
|
||||
|
@ -55,7 +55,7 @@ export default class World extends React.Component {
|
|||
.shape('fill')
|
||||
.select(true)
|
||||
.style({
|
||||
opacity: 1.0,
|
||||
opacity: 0.8,
|
||||
});
|
||||
scene.addLayer(layer);
|
||||
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { LineLayer, Scene } from '@antv/l7-react';
|
||||
import { AMapScene, LineLayer, Marker, Popup } from '@antv/l7-react';
|
||||
import * as React from 'react';
|
||||
|
||||
export default React.memo(function Map() {
|
||||
// @ts-ignore
|
||||
const amap = new GaodeMap({
|
||||
center: [110.19382669582967, 50.258134],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
zoom: 3,
|
||||
});
|
||||
const [data, setData] = React.useState();
|
||||
React.useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const response = await fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/32e1f3ab-8588-46cb-8a47-75afb692117d.json',
|
||||
);
|
||||
const data = await response.json();
|
||||
setData(data);
|
||||
const raw = await response.json();
|
||||
setData(raw);
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<Scene
|
||||
map={amap}
|
||||
<AMapScene
|
||||
map={{
|
||||
center: [110.19382669582967, 50.258134],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
zoom: 1,
|
||||
}}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
|
@ -33,27 +30,32 @@ export default React.memo(function Map() {
|
|||
bottom: 0,
|
||||
}}
|
||||
>
|
||||
{data && (
|
||||
<LineLayer
|
||||
key={'2'}
|
||||
source={{
|
||||
data,
|
||||
}}
|
||||
size={{
|
||||
values: 1,
|
||||
}}
|
||||
color={{
|
||||
values: '#fff',
|
||||
}}
|
||||
shape={{
|
||||
values: 'line',
|
||||
}}
|
||||
style={{
|
||||
opacity: 1,
|
||||
}}
|
||||
/>
|
||||
<Popup lnglat={[110.1938, 50.25] as number[]}>
|
||||
<p>122222</p>
|
||||
</Popup>
|
||||
<Marker lnglat={[110.1938, 30.25] as number[]}>
|
||||
<p>122222</p>
|
||||
</Marker>
|
||||
<LineLayer
|
||||
key={'2'}
|
||||
source={{
|
||||
data,
|
||||
}}
|
||||
size={{
|
||||
values: 1,
|
||||
}}
|
||||
color={{
|
||||
values: '#fff',
|
||||
}}
|
||||
shape={{
|
||||
values: 'line',
|
||||
}}
|
||||
style={{
|
||||
opacity: 1,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Scene>
|
||||
</AMapScene>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue