mirror of https://gitee.com/antv-l7/antv-l7
Merge pull request #525 from antvis/chore_uptate_project
chore(l7): remove react,draw, boundary moudule
This commit is contained in:
commit
ea57fd163a
|
@ -18,9 +18,6 @@ exports.onCreateWebpackConfig = ({ getConfig }) => {
|
|||
'@antv/l7-renderer': path.resolve(__dirname, 'packages/renderer/src'),
|
||||
'@antv/l7-scene': path.resolve(__dirname, 'packages/scene/src'),
|
||||
'@antv/l7-source': path.resolve(__dirname, 'packages/source/src'),
|
||||
'@antv/l7-utils': path.resolve(__dirname, 'packages/utils/src'),
|
||||
'@antv/l7-react': path.resolve(__dirname, 'packages/react/src'),
|
||||
'@antv/l7-draw': path.resolve(__dirname, 'packages/draw/src'),
|
||||
'@antv/l7-district': path.resolve(__dirname, 'packages/boundary/src')
|
||||
};
|
||||
'@antv/l7-utils': path.resolve(__dirname, 'packages/utils/src')
|
||||
}
|
||||
};
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@antv/g2": "^3.5.9",
|
||||
"@antv/l7-draw": "^2.2.37",
|
||||
"@antv/l7-react": "^2.2.37",
|
||||
"@antv/l7-district": "^2.2.37",
|
||||
"@antv/gatsby-theme-antv": "^0.10.71",
|
||||
"@babel/cli": "^7.6.4",
|
||||
"@babel/core": "^7.6.4",
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
# `district`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const district = require('district');
|
||||
|
||||
// TODO: DEMONSTRATE API
|
||||
```
|
|
@ -1,34 +0,0 @@
|
|||
// import { WorldLayer } from '@antv/l7-district';
|
||||
describe('baseLayer', () => {
|
||||
it('set option', () => {
|
||||
const option = {
|
||||
adcode: [],
|
||||
data: [
|
||||
{
|
||||
name: 1,
|
||||
code: 2,
|
||||
},
|
||||
{
|
||||
name: 2,
|
||||
code: 3,
|
||||
},
|
||||
{
|
||||
name: 3,
|
||||
code: 4,
|
||||
},
|
||||
],
|
||||
};
|
||||
// @ts-ignore
|
||||
// const layer = new WorldLayer(null, option);
|
||||
// layer.setOption({
|
||||
// data: [
|
||||
// {
|
||||
// name: 1,
|
||||
// code: 4,
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
// // @ts-ignore
|
||||
// expect(layer.options.data.length).toBe(1);
|
||||
});
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
{
|
||||
"name": "@antv/l7-district",
|
||||
"version": "2.2.37",
|
||||
"description": "L7 district moudules",
|
||||
"keywords": [],
|
||||
"author": "thinkinggis <lzx199065@gmail.com>",
|
||||
"license": "ISC",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/l7-district.js",
|
||||
"types": "es/index.d.ts",
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"dist",
|
||||
"lib",
|
||||
"es",
|
||||
"README.md"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/antvis/L7.git"
|
||||
},
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.build.json",
|
||||
"clean": "rimraf dist; rimraf es; rimraf lib;",
|
||||
"build": "run-p build:*",
|
||||
"build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"build:cdn": "node_modules/.bin/rollup -c",
|
||||
"test": "jest",
|
||||
"sync": "tnpm sync"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/l7": "2.2.37",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"@turf/circle": "^6.0.1",
|
||||
"@turf/distance": "^6.0.1",
|
||||
"@turf/helpers": "^6.1.4",
|
||||
"@turf/midpoint": "^5.1.5",
|
||||
"@turf/turf": "^5.1.6",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"geobuf": "^3.0.1",
|
||||
"lodash": "^4.6.2",
|
||||
"pbf": "^3.2.1",
|
||||
"simplify-geojson": "^1.0.3"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/antvis/L7/issues"
|
||||
},
|
||||
"homepage": "https://github.com/antvis/L7#readme",
|
||||
"devDependencies": {
|
||||
"postcss": "^7.0.27",
|
||||
"postcss-url": "^8.0.0",
|
||||
"rollup": "^2.3.3",
|
||||
"rollup-plugin-less": "^1.1.2"
|
||||
},
|
||||
"gitHead": "20154fe30d512024b03ac5e40f77731bc0580bb0"
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
import pkg from './package.json';
|
||||
import typescript from 'rollup-plugin-typescript';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import buble from 'rollup-plugin-buble';
|
||||
import postcss from 'rollup-plugin-postcss';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import url from 'postcss-url';
|
||||
export default {
|
||||
input: './src/index.ts',
|
||||
plugins: [
|
||||
// less(),
|
||||
typescript({
|
||||
exclude: 'node_modules/**',
|
||||
typescript: require('typescript')
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: false
|
||||
}),
|
||||
postcss({
|
||||
plugins: [
|
||||
url({ url: 'inline' })
|
||||
]
|
||||
}),
|
||||
commonjs({
|
||||
namedExports: {
|
||||
eventemitter3: [ 'EventEmitter' ],
|
||||
lodash: [ 'merge', 'mergeWith', 'clone', 'isObject' ]
|
||||
}
|
||||
}),
|
||||
buble({
|
||||
transforms: { generator: false }
|
||||
}),
|
||||
terser()
|
||||
],
|
||||
external: [
|
||||
'@antv/l7'
|
||||
],
|
||||
output: [
|
||||
{
|
||||
format: 'umd',
|
||||
name: 'L7.District',
|
||||
file: pkg.unpkg,
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/l7': 'L7'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
// tslint:disable-next-line:no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
let DataLevel = 2; // d
|
||||
const dataLevel2: { [key: string]: any } = {
|
||||
world: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ad26cd25-96ea-40fd-935d-7e21a5c08893.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/62f61f5f-cca7-4137-845d-13c8f9969664.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/90c51eb3-04d7-402f-bd05-95e4bd27dd62.bin',
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
},
|
||||
country: {
|
||||
CHN: {
|
||||
1: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/25228941-b2ac-4591-b07d-8261ac08d06f.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/70ec087e-c48a-4b76-8825-6452f17bae7a.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/0024caaf-86b2-4e75-a3d1-6d2146490b67.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/36832a45-68f8-4b51-b006-9dec71f92a23.json',
|
||||
},
|
||||
},
|
||||
2: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/522c6496-c711-4581-88db-c3741cd39abd.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f6a4e2b1-359b-43a6-921c-39d2088d1dab.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f6a4e2b1-359b-43a6-921c-39d2088d1dab.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/0024caaf-86b2-4e75-a3d1-6d2146490b67.bin',
|
||||
},
|
||||
},
|
||||
3: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/516b2703-d692-44e6-80dd-b3f5df0186e7.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
countryLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
nationalBoundaries2: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f2189cc4-662b-4358-8573-36f0f918b7ca.json',
|
||||
},
|
||||
island: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/fe49b393-1147-4769-94ed-70471f4ff15d.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
province: {
|
||||
110000: '',
|
||||
},
|
||||
};
|
||||
const dataLevel1: { [key: string]: any } = {
|
||||
world: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/35bb8365-1926-471c-b357-db2c02ff3a81.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8ec671c3-a4f9-4fdf-8e88-85d2ab1d8930.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/90c51eb3-04d7-402f-bd05-95e4bd27dd62.bin',
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
},
|
||||
country: {
|
||||
CHN: {
|
||||
1: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/380370e0-76aa-4240-8874-5732de77e71d.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/70ec087e-c48a-4b76-8825-6452f17bae7a.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/36832a45-68f8-4b51-b006-9dec71f92a23.json',
|
||||
},
|
||||
},
|
||||
2: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/feeb1f06-11c6-4495-84c9-f41ea6f77123.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
3: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/24a9ee83-2be1-4fc1-b187-769ac939269d.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
countryLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
nationalBoundaries2: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/f2189cc4-662b-4358-8573-36f0f918b7ca.json',
|
||||
},
|
||||
island: {
|
||||
type: 'json',
|
||||
url:
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/fe49b393-1147-4769-94ed-70471f4ff15d.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
province: {
|
||||
110000: '',
|
||||
},
|
||||
};
|
||||
|
||||
const DataLevelMap: { [key: string]: any } = {
|
||||
1: dataLevel1, // 高精度数据
|
||||
2: dataLevel2,
|
||||
};
|
||||
|
||||
function setDataConfig(config: any, level: number = DataLevel) {
|
||||
merge(DataLevelMap[level], config);
|
||||
}
|
||||
function getDataConfig(level: number = DataLevel) {
|
||||
return DataLevelMap[level];
|
||||
}
|
||||
|
||||
function setDataLevel(level: number) {
|
||||
DataLevel = level;
|
||||
}
|
||||
|
||||
const DataConfig = DataLevelMap[DataLevel];
|
||||
export { setDataConfig, setDataLevel, getDataConfig, DataConfig };
|
|
@ -1,17 +0,0 @@
|
|||
// import { DataConfig, setDataConfig } from './config_1';
|
||||
import CityLayer from './layer/city';
|
||||
import CountryLayer from './layer/country';
|
||||
import CountyLayer from './layer/county';
|
||||
import DrillDownLayer from './layer/drillDown';
|
||||
import ProvinceLayer from './layer/province';
|
||||
import WorldLayer from './layer/world';
|
||||
export {
|
||||
WorldLayer,
|
||||
CountryLayer,
|
||||
ProvinceLayer,
|
||||
CityLayer,
|
||||
CountyLayer,
|
||||
DrillDownLayer,
|
||||
};
|
||||
export * from './config';
|
||||
export * from './layer/interface';
|
|
@ -1,380 +0,0 @@
|
|||
import {
|
||||
ILayer,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
// @ts-ignore
|
||||
import geobuf from 'geobuf';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import isObject from 'lodash/isObject';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import mergeWith from 'lodash/mergeWith';
|
||||
// @ts-ignore
|
||||
import Pbf from 'pbf';
|
||||
// @ts-ignore
|
||||
import simplify from 'simplify-geojson';
|
||||
import { setDataLevel } from '../config';
|
||||
import { AttributeType, IDistrictLayerOption } from './interface';
|
||||
|
||||
function mergeCustomizer(objValue: any, srcValue: any) {
|
||||
if (Array.isArray(srcValue)) {
|
||||
return srcValue;
|
||||
}
|
||||
}
|
||||
export default class BaseLayer extends EventEmitter {
|
||||
public fillLayer: ILayer;
|
||||
public lineLayer: ILayer;
|
||||
public labelLayer: ILayer;
|
||||
public bubbleLayer: ILayer;
|
||||
protected scene: Scene;
|
||||
protected options: IDistrictLayerOption;
|
||||
protected layers: ILayer[] = [];
|
||||
protected fillData: any;
|
||||
protected bubbleData: any;
|
||||
private popup: IPopup;
|
||||
|
||||
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.options = mergeWith(this.getDefaultOption(), option, mergeCustomizer);
|
||||
setDataLevel(this.options.geoDataLevel);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.layers.forEach((layer) => this.scene.removeLayer(layer));
|
||||
this.layers.length = 0;
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.layers.forEach((layer) => layer.show());
|
||||
}
|
||||
public hide() {
|
||||
this.layers.forEach((layer) => layer.hide());
|
||||
}
|
||||
|
||||
public setOption(newOption: { [key: string]: any }) {
|
||||
this.options = mergeWith(this.options, newOption, mergeCustomizer);
|
||||
}
|
||||
|
||||
public getFillData() {
|
||||
return this.fillData;
|
||||
}
|
||||
|
||||
public updateData(
|
||||
newData?: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
this.setOption({
|
||||
data: newData,
|
||||
joinBy: joinByField,
|
||||
});
|
||||
const { data = [], joinBy } = this.options;
|
||||
this.fillLayer.setData(this.fillData, {
|
||||
transforms:
|
||||
data.length === 0
|
||||
? []
|
||||
: [
|
||||
{
|
||||
type: 'join',
|
||||
sourceField: joinBy[1], // data1 对应字段名
|
||||
targetField: joinBy[0], // data 对应字段名 绑定到的地理数据
|
||||
data,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// 气泡图也需要更新
|
||||
if (this.bubbleLayer) {
|
||||
this.bubbleLayer.setData(this.bubbleData, {
|
||||
transforms:
|
||||
data.length === 0
|
||||
? []
|
||||
: [
|
||||
{
|
||||
type: 'join',
|
||||
sourceField: joinBy[1], // data1 对应字段名
|
||||
targetField: joinBy[0], // data 对应字段名 绑定到的地理数据
|
||||
data,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
protected async fetchData(data: { url: any; type: string }) {
|
||||
if (data.type === 'pbf') {
|
||||
const buffer = await (await fetch(data.url)).arrayBuffer();
|
||||
let geojson = geobuf.decode(new Pbf(buffer));
|
||||
if (this.options.simplifyTolerance !== false) {
|
||||
geojson = simplify(geojson, this.options.simplifyTolerance);
|
||||
}
|
||||
return geojson;
|
||||
} else {
|
||||
return isObject(data.url) ? data.url : (await fetch(data.url)).json();
|
||||
}
|
||||
}
|
||||
protected getDefaultOption(): IDistrictLayerOption {
|
||||
return {
|
||||
zIndex: 0,
|
||||
visible: true,
|
||||
geoDataLevel: 2,
|
||||
depth: 1,
|
||||
adcode: [],
|
||||
joinBy: ['name', 'name'],
|
||||
simplifyTolerance: false,
|
||||
label: {
|
||||
enable: true,
|
||||
color: '#000',
|
||||
field: 'name',
|
||||
size: 10,
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
textAllowOverlap: true,
|
||||
opacity: 1,
|
||||
textOffset: [0, 0],
|
||||
padding: [5, 5],
|
||||
},
|
||||
bubble: {
|
||||
enable: false,
|
||||
shape: 'circle',
|
||||
color: '#1AA9FF',
|
||||
size: 15,
|
||||
style: {
|
||||
opacity: 1,
|
||||
stroke: '#fff',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
fill: {
|
||||
scale: null,
|
||||
color: '#ddd',
|
||||
style: {
|
||||
opacity: 1.0,
|
||||
},
|
||||
activeColor: false,
|
||||
},
|
||||
autoFit: true,
|
||||
showBorder: true,
|
||||
stroke: '#bdbdbd',
|
||||
strokeVisible: true,
|
||||
strokeWidth: 0.6,
|
||||
cityStroke: '#636363',
|
||||
cityStrokeWidth: 0.6,
|
||||
countyStrokeWidth: 0.6,
|
||||
provinceStrokeWidth: 0.6,
|
||||
provinceStroke: '#f0f0f0',
|
||||
provinceStrokeVisible: true,
|
||||
countyStroke: '#525252',
|
||||
coastlineStroke: '#4190da',
|
||||
coastlineWidth: 0.6,
|
||||
nationalStroke: '#c994c7',
|
||||
nationalWidth: 0.5,
|
||||
chinaNationalStroke: 'gray',
|
||||
chinaNationalWidth: 1,
|
||||
popup: {
|
||||
enable: true,
|
||||
openTriggerEvent: 'mousemove',
|
||||
closeTriggerEvent: 'mouseout',
|
||||
option: {},
|
||||
Html: (properties: any) => {
|
||||
return `${properties.name}`;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected addFillLayer(fillCountry: any) {
|
||||
// 添加省份填充
|
||||
const { popup, data = [], fill, autoFit, joinBy, visible } = this.options;
|
||||
this.fillData = fillCountry;
|
||||
const fillLayer = new PolygonLayer({
|
||||
autoFit,
|
||||
visible,
|
||||
}).source(fillCountry, {
|
||||
transforms:
|
||||
data.length === 0
|
||||
? []
|
||||
: [
|
||||
{
|
||||
type: 'join',
|
||||
sourceField: joinBy[1], // data1 对应字段名
|
||||
targetField: joinBy[0], // data 对应字段名 绑定到的地理数据
|
||||
data,
|
||||
},
|
||||
],
|
||||
});
|
||||
this.setLayerAttribute(fillLayer, 'color', fill.color as AttributeType);
|
||||
this.setLayerAttribute(fillLayer, 'filter', fill.filter as AttributeType);
|
||||
if (fill.scale && isObject(fill.color)) {
|
||||
fillLayer.scale('color', {
|
||||
type: fill.scale,
|
||||
field: fill.color.field as string,
|
||||
});
|
||||
}
|
||||
fillLayer.shape('fill').style(fill.style);
|
||||
|
||||
if (fill.activeColor) {
|
||||
fillLayer.active({
|
||||
color: fill.activeColor as string,
|
||||
});
|
||||
}
|
||||
this.fillLayer = fillLayer;
|
||||
this.layers.push(fillLayer);
|
||||
this.scene.addLayer(fillLayer);
|
||||
if (this.options.bubble && this.options.bubble?.enable !== false) {
|
||||
const labeldata = fillCountry.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
|
||||
this.bubbleData = labeldata;
|
||||
this.addBubbleLayer(labeldata);
|
||||
}
|
||||
if (popup.enable) {
|
||||
this.addPopup();
|
||||
}
|
||||
|
||||
this.emit('loaded');
|
||||
}
|
||||
|
||||
protected addFillLine(provinceLine: any) {
|
||||
const { stroke, strokeWidth, zIndex, visible } = this.options;
|
||||
const layer2 = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible,
|
||||
})
|
||||
.source(provinceLine)
|
||||
.color(stroke)
|
||||
.size(strokeWidth)
|
||||
.style({
|
||||
opacity: 1,
|
||||
});
|
||||
this.scene.addLayer(layer2);
|
||||
this.layers.push(layer2);
|
||||
this.lineLayer = layer2;
|
||||
}
|
||||
|
||||
protected addLabelLayer(labelData: any, type: string = 'json') {
|
||||
const labelLayer = this.addLabel(labelData, type);
|
||||
this.scene.addLayer(labelLayer);
|
||||
this.layers.push(labelLayer);
|
||||
this.labelLayer = labelLayer;
|
||||
}
|
||||
|
||||
protected addBubbleLayer(labelData: any, type: string = 'json') {
|
||||
const { bubble, zIndex, data = [], joinBy, visible } = this.options;
|
||||
const bubbleLayer = new PointLayer({
|
||||
zIndex: zIndex + 0.3,
|
||||
visible,
|
||||
}).source(labelData, {
|
||||
parser: {
|
||||
type,
|
||||
coordinates: 'center',
|
||||
},
|
||||
transforms:
|
||||
data.length === 0
|
||||
? []
|
||||
: [
|
||||
{
|
||||
type: 'join',
|
||||
sourceField: joinBy[1], // data1 对应字段名
|
||||
targetField: joinBy[0], // data 对应字段名 绑定到的地理数据
|
||||
data,
|
||||
},
|
||||
],
|
||||
});
|
||||
this.setLayerAttribute(bubbleLayer, 'color', bubble.color as AttributeType);
|
||||
this.setLayerAttribute(bubbleLayer, 'size', bubble.size as AttributeType);
|
||||
this.setLayerAttribute(bubbleLayer, 'shape', bubble.shape as AttributeType);
|
||||
this.setLayerAttribute(
|
||||
bubbleLayer,
|
||||
'filter',
|
||||
bubble.filter as AttributeType,
|
||||
);
|
||||
if (bubble.scale) {
|
||||
bubbleLayer.scale(bubble.scale.field, {
|
||||
type: bubble.scale.type,
|
||||
});
|
||||
}
|
||||
bubbleLayer.style(bubble.style);
|
||||
this.scene.addLayer(bubbleLayer);
|
||||
this.layers.push(bubbleLayer);
|
||||
this.bubbleLayer = bubbleLayer;
|
||||
return bubbleLayer;
|
||||
}
|
||||
|
||||
protected addLabel(labelData: any, type: string = 'json') {
|
||||
const { label, zIndex, visible } = this.options;
|
||||
const labelLayer = new PointLayer({
|
||||
zIndex: zIndex + 5,
|
||||
visible,
|
||||
})
|
||||
.source(labelData, {
|
||||
parser: {
|
||||
type,
|
||||
coordinates: 'center',
|
||||
},
|
||||
})
|
||||
.shape(label.field as StyleAttrField, 'text')
|
||||
.style(label);
|
||||
this.setLayerAttribute(labelLayer, 'color', label.color as AttributeType);
|
||||
this.setLayerAttribute(labelLayer, 'size', label.size as AttributeType);
|
||||
this.setLayerAttribute(labelLayer, 'filter', label.filter);
|
||||
return labelLayer;
|
||||
}
|
||||
|
||||
protected addPopup() {
|
||||
const { popup } = this.options;
|
||||
let popupLayer;
|
||||
if (popup.triggerLayer) {
|
||||
popupLayer =
|
||||
popup.triggerLayer === 'bubble' ? this.bubbleLayer : this.fillLayer;
|
||||
} else {
|
||||
popupLayer = this.options.bubble.enable
|
||||
? this.bubbleLayer
|
||||
: this.fillLayer;
|
||||
}
|
||||
popupLayer.on(popup.openTriggerEvent as string, (e) => {
|
||||
const html = popup.Html
|
||||
? popup.Html(e.feature.properties ? e.feature.properties : e.feature)
|
||||
: '';
|
||||
this.popup = new Popup({
|
||||
closeButton: false,
|
||||
...popup.option,
|
||||
})
|
||||
.setLnglat(e.lngLat)
|
||||
.setHTML(html);
|
||||
this.scene.addPopup(this.popup);
|
||||
});
|
||||
|
||||
popupLayer.on(popup.closeTriggerEvent as string, (e) => {
|
||||
if (this.popup) {
|
||||
this.popup.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setLayerAttribute(
|
||||
layer: ILayer,
|
||||
type: 'color' | 'size' | 'shape' | 'filter',
|
||||
attr: AttributeType | undefined,
|
||||
) {
|
||||
if (!attr) {
|
||||
return;
|
||||
}
|
||||
if (isObject(attr)) {
|
||||
// @ts-ignore
|
||||
layer[type](attr.field, attr.values);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
layer[type](attr);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
|
||||
import { adcodeType, IDistrictLayerOption } from './interface';
|
||||
import ProvinceLayer from './province';
|
||||
|
||||
export interface IProvinceLayerOption extends IDistrictLayerOption {
|
||||
adcode: adcodeType;
|
||||
}
|
||||
export default class CityLayer extends ProvinceLayer {
|
||||
protected getDefaultOption(): IProvinceLayerOption {
|
||||
const config = super.getDefaultOption();
|
||||
return merge({}, config, {
|
||||
adcode: ['110000'],
|
||||
depth: 3,
|
||||
});
|
||||
}
|
||||
protected filterData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.features.filter((fe: any) => {
|
||||
const code = fe.properties.adcode_cit;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return { type: 'FeatureCollection', features };
|
||||
}
|
||||
|
||||
protected filterLabelData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.filter((fe: any) => {
|
||||
const code = fe.adcode_cit;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return features;
|
||||
}
|
||||
}
|
|
@ -1,278 +0,0 @@
|
|||
import { AttributeType, LineLayer, PointLayer, Scene } from '@antv/l7';
|
||||
import { getDataConfig } from '../index';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
|
||||
export default class CountryLayer extends BaseLayer {
|
||||
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
|
||||
super(scene, option);
|
||||
const { depth, showBorder } = this.options;
|
||||
this.addProvinceFill();
|
||||
this.addProvinceLabel();
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
if (showBorder) {
|
||||
this.addProvinceLine(countryConfig.provinceLine);
|
||||
if (depth === 2 * 1) {
|
||||
this.addCityBorder(countryConfig.fill);
|
||||
}
|
||||
if (depth === 3 * 1) {
|
||||
this.addCountyBorder(countryConfig.fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
protected async addProvinceFill() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
this.addFillLayer(fillData);
|
||||
}
|
||||
protected async addProvinceLabel() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillLabel = countryConfig.label
|
||||
? await this.fetchData(countryConfig.label)
|
||||
: null;
|
||||
if (fillLabel && this.options.label?.enable) {
|
||||
this.addLabelLayer(
|
||||
fillLabel.filter((v: any) => {
|
||||
return v.name !== '澳门';
|
||||
}),
|
||||
);
|
||||
this.addMCLabel();
|
||||
}
|
||||
}
|
||||
// 国界,省界
|
||||
protected async addProvinceLine(cfg: any) {
|
||||
const lineData = await this.fetchData(cfg);
|
||||
const border1 = lineData.features.filter((feature: any) => {
|
||||
const type = feature.properties.type;
|
||||
return type === '1';
|
||||
});
|
||||
// 香港 澳门
|
||||
const border2 = lineData.features.filter((feature: any) => {
|
||||
const type = feature.properties.type;
|
||||
return type === '4';
|
||||
});
|
||||
const borderFc = {
|
||||
type: 'FeatureCollection',
|
||||
features: border1,
|
||||
};
|
||||
|
||||
const borderFc2 = {
|
||||
type: 'FeatureCollection',
|
||||
features: border2,
|
||||
};
|
||||
|
||||
const nationalBorder = lineData.features.filter((feature: any) => {
|
||||
const type = feature.properties.type;
|
||||
return type !== '1' && type !== '4';
|
||||
});
|
||||
const nationalFc = {
|
||||
type: 'FeatureCollection',
|
||||
features: nationalBorder,
|
||||
};
|
||||
this.addNationBorder(nationalFc, borderFc, borderFc2);
|
||||
}
|
||||
|
||||
// 国界,省界
|
||||
// protected addFillLine(lineData: any) {
|
||||
// const border1 = lineData.features.filter((feature: any) => {
|
||||
// const type = feature.properties.type;
|
||||
// return type === '1' || type === '4';
|
||||
// });
|
||||
// const borderFc = {
|
||||
// type: 'FeatureCollection',
|
||||
// features: border1,
|
||||
// };
|
||||
// const nationalBorder = lineData.features.filter((feature: any) => {
|
||||
// const type = feature.properties.type;
|
||||
// return type !== '1' && type !== '4';
|
||||
// });
|
||||
// const nationalFc = {
|
||||
// type: 'FeatureCollection',
|
||||
// features: nationalBorder,
|
||||
// };
|
||||
// this.addNationBorder(nationalFc, borderFc);
|
||||
// }
|
||||
|
||||
private async loadData() {
|
||||
const { depth } = this.options;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
const fillLabel = countryConfig.label
|
||||
? await this.fetchData(countryConfig.label)
|
||||
: null;
|
||||
return [fillData, fillLabel];
|
||||
}
|
||||
// 省级行政区划
|
||||
private async addNationBorder(
|
||||
boundaries: any,
|
||||
boundaries2: any,
|
||||
boundaries3: any,
|
||||
) {
|
||||
const {
|
||||
nationalStroke,
|
||||
provinceStroke,
|
||||
provinceStrokeWidth,
|
||||
nationalWidth,
|
||||
chinaNationalStroke,
|
||||
chinaNationalWidth,
|
||||
coastlineStroke,
|
||||
coastlineWidth,
|
||||
showBorder,
|
||||
stroke,
|
||||
strokeWidth,
|
||||
visible,
|
||||
zIndex,
|
||||
} = this.options;
|
||||
// 添加国界线
|
||||
const lineLayer = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible: visible && showBorder,
|
||||
})
|
||||
.source(boundaries)
|
||||
.size('type', (v: string) => {
|
||||
if (v === '3') {
|
||||
return provinceStrokeWidth;
|
||||
} else if (v === '2') {
|
||||
return coastlineWidth;
|
||||
} else if (v === '0') {
|
||||
return chinaNationalWidth;
|
||||
} else {
|
||||
return '#fff';
|
||||
}
|
||||
})
|
||||
.shape('line')
|
||||
.color('type', (v: string) => {
|
||||
if (v === '3') {
|
||||
return provinceStroke; // 省界
|
||||
} else if (v === '2') {
|
||||
return coastlineStroke; // 海岸线
|
||||
} else if (v === '0') {
|
||||
return chinaNationalStroke; // 中国国界线
|
||||
} else {
|
||||
return '#fff';
|
||||
}
|
||||
});
|
||||
// 添加未定国界
|
||||
const lineLayer2 = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible: visible && showBorder,
|
||||
})
|
||||
.source(boundaries2)
|
||||
.size(chinaNationalWidth)
|
||||
.shape('line')
|
||||
.color(chinaNationalStroke)
|
||||
.style({
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
});
|
||||
|
||||
// 添加澳门香港界限
|
||||
const lineLayer3 = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible: visible && showBorder,
|
||||
})
|
||||
.source(boundaries3)
|
||||
.size(provinceStrokeWidth)
|
||||
.shape('line')
|
||||
.color(provinceStroke)
|
||||
.style({
|
||||
lineType: 'dash',
|
||||
dashArray: [4, 2, 2, 2],
|
||||
});
|
||||
|
||||
this.scene.addLayer(lineLayer);
|
||||
this.scene.addLayer(lineLayer2);
|
||||
this.scene.addLayer(lineLayer3);
|
||||
this.layers.push(lineLayer, lineLayer2, lineLayer3);
|
||||
}
|
||||
// 市边界
|
||||
private async addCityBorder(cfg: any) {
|
||||
const border1 = await this.fetchData(cfg);
|
||||
const { cityStroke, cityStrokeWidth, visible } = this.options;
|
||||
const cityline = new LineLayer({
|
||||
zIndex: 2,
|
||||
visible,
|
||||
})
|
||||
.source(border1)
|
||||
.color(cityStroke)
|
||||
.size(cityStrokeWidth)
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
});
|
||||
this.scene.addLayer(cityline);
|
||||
this.layers.push(cityline);
|
||||
}
|
||||
|
||||
// 县级边界
|
||||
private async addCountyBorder(cfg: any) {
|
||||
const border1 = await this.fetchData(cfg);
|
||||
const { countyStrokeWidth, countyStroke, visible } = this.options;
|
||||
const cityline = new LineLayer({
|
||||
zIndex: 2,
|
||||
visible,
|
||||
})
|
||||
.source(border1)
|
||||
.color(countyStroke)
|
||||
.size(countyStrokeWidth)
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
});
|
||||
this.scene.addLayer(cityline);
|
||||
this.layers.push(cityline);
|
||||
}
|
||||
|
||||
private addMCLabel() {
|
||||
const data = [
|
||||
{
|
||||
name: '澳门',
|
||||
center: [113.537747, 22.187009],
|
||||
},
|
||||
];
|
||||
const labelLayer1 = this.addText(data, { maxZoom: 2.9 }, [-45, -10]);
|
||||
const labelLayer2 = this.addText(data, { minZoom: 3, maxZoom: 4 }, [
|
||||
-35,
|
||||
-10,
|
||||
]);
|
||||
const labelLayer = this.addText(data, { minZoom: 4.1 }, [0, 0]);
|
||||
this.scene.addLayer(labelLayer);
|
||||
this.scene.addLayer(labelLayer1);
|
||||
this.scene.addLayer(labelLayer2);
|
||||
this.layers.push(labelLayer, labelLayer1, labelLayer2);
|
||||
}
|
||||
|
||||
private addText(labelData: any, option: any, offset: [number, number]) {
|
||||
const { label, zIndex, visible } = this.options;
|
||||
const labelLayer = new PointLayer({
|
||||
zIndex: zIndex + 0.4,
|
||||
visible,
|
||||
...option,
|
||||
})
|
||||
.source(labelData, {
|
||||
parser: {
|
||||
type: 'json',
|
||||
coordinates: 'center',
|
||||
},
|
||||
})
|
||||
.color(label.color as AttributeType)
|
||||
.shape('name', 'text')
|
||||
.size(label.size as AttributeType)
|
||||
.style({
|
||||
opacity: label.opacity,
|
||||
stroke: label.stroke,
|
||||
strokeWidth: label.strokeWidth,
|
||||
textAllowOverlap: label.textAllowOverlap,
|
||||
textOffset: offset,
|
||||
});
|
||||
return labelLayer;
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
import { adcodeType, IDistrictLayerOption } from './interface';
|
||||
import ProvinceLayer from './province';
|
||||
|
||||
export interface IProvinceLayerOption extends IDistrictLayerOption {
|
||||
adcode: adcodeType;
|
||||
}
|
||||
export default class CityLayer extends ProvinceLayer {
|
||||
protected getDefaultOption(): IProvinceLayerOption {
|
||||
const config = super.getDefaultOption();
|
||||
return merge({}, config, {
|
||||
adcode: ['110100'],
|
||||
depth: 3,
|
||||
});
|
||||
}
|
||||
protected filterData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.features.filter((fe: any) => {
|
||||
const code = fe.properties.adcode;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return { type: 'FeatureCollection', features };
|
||||
}
|
||||
|
||||
protected filterLabelData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.filter((fe: any) => {
|
||||
const code = fe.adcode;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return features;
|
||||
}
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import mergeWith from 'lodash/mergeWith';
|
||||
import CityLayer from './city';
|
||||
import CountryLayer from './country';
|
||||
import { adcodeType, IDrillDownOption } from './interface';
|
||||
import ProvinceLayer from './province';
|
||||
function mergeCustomizer(objValue: any, srcValue: any) {
|
||||
if (Array.isArray(srcValue)) {
|
||||
return srcValue;
|
||||
}
|
||||
}
|
||||
export default class DrillDownLayer {
|
||||
private options: Partial<IDrillDownOption>;
|
||||
private cityLayer: ProvinceLayer;
|
||||
private countyLayer: CityLayer;
|
||||
private provinceLayer: CountryLayer;
|
||||
private scene: Scene;
|
||||
private drillState: 0 | 1 | 2 = 0;
|
||||
private layers: any = [];
|
||||
constructor(scene: Scene, option: Partial<IDrillDownOption>) {
|
||||
this.options = mergeWith(this.getDefaultOption(), option, mergeCustomizer);
|
||||
this.scene = scene;
|
||||
this.provinceLayer = new CountryLayer(
|
||||
scene,
|
||||
this.getLayerOption('province'),
|
||||
);
|
||||
this.cityLayer = new ProvinceLayer(scene, this.getLayerOption('city'));
|
||||
this.countyLayer = new CityLayer(scene, this.getLayerOption('county'));
|
||||
this.scene.setMapStatus({ doubleClickZoom: false });
|
||||
if (!this.options.customTrigger) {
|
||||
this.provinceLayer.on('loaded', () => {
|
||||
this.addCountryEvent();
|
||||
this.layers.push(this.provinceLayer);
|
||||
});
|
||||
this.cityLayer.on('loaded', () => {
|
||||
this.addProvinceEvent();
|
||||
this.layers.push(this.cityLayer);
|
||||
});
|
||||
this.countyLayer.on('loaded', () => {
|
||||
this.addCityEvent();
|
||||
this.layers.push(this.cityLayer);
|
||||
});
|
||||
}
|
||||
}
|
||||
public getDefaultOption() {
|
||||
return {
|
||||
drillDepth: 2,
|
||||
customTrigger: false,
|
||||
drillDownTriggerEvent: 'click',
|
||||
drillUpTriggerEvent: 'undblclick',
|
||||
provinceData: [],
|
||||
cityData: [],
|
||||
countyData: [],
|
||||
city: {
|
||||
adcode: [],
|
||||
},
|
||||
county: {
|
||||
adcode: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
public addCountryEvent() {
|
||||
const { drillDownTriggerEvent } = this.options;
|
||||
// 省级下钻到市
|
||||
this.provinceLayer.fillLayer.on(
|
||||
drillDownTriggerEvent as string,
|
||||
(e: any) => {
|
||||
this.provinceLayer.hide();
|
||||
this.drillDown(e.feature.properties.adcode);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public addProvinceEvent() {
|
||||
const { drillDownTriggerEvent, drillUpTriggerEvent } = this.options;
|
||||
this.cityLayer.fillLayer.on(drillUpTriggerEvent as string, () => {
|
||||
this.drillUp();
|
||||
});
|
||||
this.cityLayer.fillLayer.on(drillDownTriggerEvent as string, (e: any) => {
|
||||
this.drillDown(e.feature.properties.adcode);
|
||||
});
|
||||
}
|
||||
|
||||
public addCityEvent() {
|
||||
const { drillDownTriggerEvent, drillUpTriggerEvent } = this.options;
|
||||
this.countyLayer.fillLayer.on(drillUpTriggerEvent as string, () => {
|
||||
this.drillUp();
|
||||
});
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.layers.forEach((layer: any) => layer.show());
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.layers.forEach((layer: any) => layer.hide());
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.layers.forEach((layer: any) => layer.destroy());
|
||||
}
|
||||
|
||||
public showProvinceView(
|
||||
adcode: adcodeType,
|
||||
newData?: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
this.cityLayer.show();
|
||||
this.cityLayer.updateDistrict(adcode, newData, joinByField);
|
||||
this.cityLayer.fillLayer.fitBounds();
|
||||
this.countyLayer.hide();
|
||||
this.drillState = 1;
|
||||
}
|
||||
public showCityView(
|
||||
code: adcodeType,
|
||||
newData?: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
this.countyLayer.show();
|
||||
let adcode = `${code}`;
|
||||
if (adcode.substr(2, 2) === '00') {
|
||||
adcode = adcode.substr(0, 2) + '0100';
|
||||
}
|
||||
// 更新县级行政区划
|
||||
this.countyLayer.updateDistrict(adcode, newData, joinByField);
|
||||
this.countyLayer.fillLayer.fitBounds();
|
||||
this.cityLayer.hide();
|
||||
this.drillState = 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向上
|
||||
*/
|
||||
public drillUp() {
|
||||
switch (this.drillState) {
|
||||
case 2:
|
||||
this.cityLayer.show();
|
||||
this.cityLayer.fillLayer.fitBounds();
|
||||
this.countyLayer.hide();
|
||||
this.drillState = 1;
|
||||
break;
|
||||
case 1:
|
||||
this.provinceLayer.show();
|
||||
this.provinceLayer.fillLayer.fitBounds();
|
||||
this.cityLayer.hide();
|
||||
this.drillState = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
public drillDown(
|
||||
adcode: adcodeType,
|
||||
newData?: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
const { drillDepth } = this.options;
|
||||
if (this.drillState === drillDepth) {
|
||||
return;
|
||||
}
|
||||
switch (this.drillState) {
|
||||
case 0:
|
||||
this.showProvinceView(adcode, newData, joinByField);
|
||||
break;
|
||||
case 1:
|
||||
this.showCityView(adcode, newData, joinByField);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public updateData(
|
||||
layer: 'province' | 'city' | 'county',
|
||||
newData: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
switch (layer) {
|
||||
case 'province':
|
||||
this.provinceLayer.updateData(newData, joinByField);
|
||||
break;
|
||||
case 'city':
|
||||
this.cityLayer.updateData(newData, joinByField);
|
||||
break;
|
||||
case 'county':
|
||||
this.countyLayer.updateData(newData, joinByField);
|
||||
}
|
||||
}
|
||||
|
||||
private getLayerOption(type: 'province' | 'city' | 'county') {
|
||||
const { joinBy, label, bubble, fill, popup, geoDataLevel } = this.options;
|
||||
const datatype = (type + 'Data') as
|
||||
| 'provinceData'
|
||||
| 'cityData'
|
||||
| 'countyData';
|
||||
return {
|
||||
data: this.options[datatype],
|
||||
joinBy,
|
||||
label,
|
||||
bubble,
|
||||
fill,
|
||||
popup,
|
||||
geoDataLevel,
|
||||
...this.options[type],
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
import {
|
||||
IPopupOption,
|
||||
ScaleTypeName,
|
||||
StyleAttributeField,
|
||||
StyleAttributeOption,
|
||||
} from '@antv/l7';
|
||||
export type anchorType =
|
||||
| 'right'
|
||||
| 'top-right'
|
||||
| 'left'
|
||||
| 'bottom-right'
|
||||
| 'left'
|
||||
| 'top-left'
|
||||
| 'bottom-left'
|
||||
| 'bottom'
|
||||
| 'bottom-right'
|
||||
| 'bottom-left'
|
||||
| 'top'
|
||||
| 'top-right'
|
||||
| 'top-left'
|
||||
| 'center';
|
||||
export interface ILabelOption {
|
||||
enable: boolean;
|
||||
color: AttributeType;
|
||||
field: string;
|
||||
size: AttributeType;
|
||||
stroke: string;
|
||||
strokeWidth: number;
|
||||
textAllowOverlap: boolean;
|
||||
padding: [number, number];
|
||||
strokeOpacity: number;
|
||||
fontWeight: number;
|
||||
spacing: number;
|
||||
textAnchor: anchorType;
|
||||
textOffset: [number, number];
|
||||
opacity: number;
|
||||
filter: AttributeType;
|
||||
}
|
||||
|
||||
export interface IAttributeOption {
|
||||
field: StyleAttributeField;
|
||||
values: StyleAttributeOption;
|
||||
}
|
||||
|
||||
export type AttributeType = IAttributeOption | string | number;
|
||||
export interface IPopupOptions {
|
||||
enable: boolean;
|
||||
openTriggerEvent: TriggeEventType;
|
||||
closeTriggerEvent: TriggeEventType;
|
||||
triggerLayer: 'fill' | 'bubble';
|
||||
option?: Partial<IPopupOption>;
|
||||
Html: (properties: any) => string;
|
||||
}
|
||||
|
||||
export interface IFillOptions {
|
||||
scale: ScaleTypeName | null;
|
||||
// field: string | null;
|
||||
color: AttributeType;
|
||||
values: StyleAttributeOption;
|
||||
style: any;
|
||||
activeColor: string | boolean;
|
||||
filter: AttributeType;
|
||||
}
|
||||
export type TriggeEventType =
|
||||
| 'mousemove'
|
||||
| 'click'
|
||||
| 'mousedown'
|
||||
| 'mouseenter'
|
||||
| 'mouseout'
|
||||
| 'dblclick'
|
||||
| 'contextmenu'
|
||||
| 'mouseup';
|
||||
|
||||
export type DrillUpTriggeEventType =
|
||||
| 'mousemove'
|
||||
| 'unclick'
|
||||
| 'unmousedown'
|
||||
| 'undblclick'
|
||||
| 'uncontextmenu'
|
||||
| 'unmouseup';
|
||||
export interface IBubbleOption {
|
||||
enable: boolean;
|
||||
shape: AttributeType;
|
||||
size: AttributeType;
|
||||
color: AttributeType;
|
||||
filter: AttributeType;
|
||||
scale: {
|
||||
field: string;
|
||||
type: ScaleTypeName;
|
||||
};
|
||||
style: {
|
||||
opacity: number;
|
||||
stroke: string;
|
||||
strokeWidth: number;
|
||||
};
|
||||
}
|
||||
export type adcodeType = string[] | string | number | number[];
|
||||
export interface IDistrictLayerOption {
|
||||
zIndex: number;
|
||||
visible: boolean;
|
||||
geoDataLevel: 1 | 2;
|
||||
data?: Array<{ [key: string]: any }>;
|
||||
joinBy: [string, string];
|
||||
adcode: adcodeType;
|
||||
simplifyTolerance: number | boolean;
|
||||
depth: 0 | 1 | 2 | 3;
|
||||
label: Partial<ILabelOption>;
|
||||
bubble: Partial<IBubbleOption>;
|
||||
fill: Partial<IFillOptions>;
|
||||
showBorder: boolean;
|
||||
autoFit: boolean;
|
||||
stroke: string;
|
||||
strokeVisible: boolean;
|
||||
strokeWidth: number;
|
||||
provinceStroke: string;
|
||||
provinceStrokeVisible: boolean;
|
||||
cityStroke: string;
|
||||
provinceStrokeWidth: number;
|
||||
cityStrokeWidth: number;
|
||||
countyStroke: string;
|
||||
countyStrokeWidth: number;
|
||||
coastlineStroke: string;
|
||||
coastlineWidth: number;
|
||||
nationalStroke: string;
|
||||
nationalWidth: number;
|
||||
chinaNationalStroke: string;
|
||||
chinaNationalWidth: number;
|
||||
popup: Partial<IPopupOptions>;
|
||||
}
|
||||
interface IDrawOption {
|
||||
joinBy: [string, string];
|
||||
label: Partial<ILabelOption>;
|
||||
bubble: Partial<IBubbleOption>;
|
||||
fill: Partial<IFillOptions>;
|
||||
}
|
||||
export interface IDrillDownOption {
|
||||
drillDepth: 0 | 1 | 2;
|
||||
geoDataLevel: 1 | 2;
|
||||
customTrigger: boolean;
|
||||
drillDownTriggerEvent: TriggeEventType;
|
||||
drillUpTriggerEvent: TriggeEventType & DrillUpTriggeEventType;
|
||||
provinceData?: Array<{ [key: string]: any }>;
|
||||
cityData?: Array<{ [key: string]: any }>;
|
||||
countyData?: Array<{ [key: string]: any }>;
|
||||
joinBy: [string, string];
|
||||
label: Partial<ILabelOption>;
|
||||
bubble: Partial<IBubbleOption>;
|
||||
fill: Partial<IFillOptions>;
|
||||
popup: Partial<IPopupOptions>;
|
||||
province: Partial<IDrawOption>;
|
||||
city: Partial<IDrawOption>;
|
||||
county: Partial<IDrawOption>;
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
import { getDataConfig } from '../';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { adcodeType, IDistrictLayerOption } from './interface';
|
||||
|
||||
export interface IProvinceLayerOption extends IDistrictLayerOption {
|
||||
adcode: adcodeType;
|
||||
}
|
||||
export default class ProvinceLayer extends BaseLayer {
|
||||
private fillRawData: any;
|
||||
private lineRawData: any;
|
||||
private labelRawData: any;
|
||||
constructor(scene: Scene, option: Partial<IProvinceLayerOption> = {}) {
|
||||
super(scene, option);
|
||||
this.addProvinceFillLayer();
|
||||
// this.addProvinceLineLayer();
|
||||
}
|
||||
// 通过adcode 更新
|
||||
public updateDistrict(
|
||||
adcode: adcodeType,
|
||||
newData?: Array<{ [key: string]: any }>,
|
||||
joinByField?: [string, string],
|
||||
) {
|
||||
if (!adcode && Array.isArray(adcode) && adcode.length === 0) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
const { label, showBorder } = this.options;
|
||||
this.setOption({ adcode });
|
||||
const fillData = this.filterData(this.fillRawData, adcode);
|
||||
const lineData = this.filterData(this.lineRawData, adcode);
|
||||
const labelData = this.filterLabelData(this.labelRawData, adcode);
|
||||
if (this.options.bubble && this.options.bubble?.enable !== false) {
|
||||
const bubbleData = fillData.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
this.bubbleLayer.setData(bubbleData);
|
||||
}
|
||||
this.fillData = fillData;
|
||||
this.updateData(newData, joinByField);
|
||||
if (showBorder) {
|
||||
this.lineLayer.setData(lineData);
|
||||
}
|
||||
if (label.enable) {
|
||||
this.labelLayer.setData(labelData);
|
||||
}
|
||||
|
||||
this.show();
|
||||
}
|
||||
|
||||
protected getDefaultOption(): IProvinceLayerOption {
|
||||
const config = super.getDefaultOption();
|
||||
return merge({}, config, {
|
||||
adcode: ['110000'],
|
||||
depth: 2,
|
||||
label: {
|
||||
field: 'NAME_CHN',
|
||||
textAllowOverlap: false,
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props: any) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected filterData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.features.filter((fe: any) => {
|
||||
const code = fe.properties.adcode_pro;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return { type: 'FeatureCollection', features };
|
||||
}
|
||||
|
||||
protected filterLabelData(data: any, adcode: adcodeType) {
|
||||
const adcodeArray = Array.isArray(adcode) ? adcode : [adcode];
|
||||
const features = data.filter((fe: any) => {
|
||||
const code = fe.adcode_pro;
|
||||
return (
|
||||
adcodeArray.indexOf(code) !== -1 ||
|
||||
adcodeArray.indexOf('' + code) !== -1
|
||||
);
|
||||
});
|
||||
return features;
|
||||
}
|
||||
private async addProvinceFillLayer() {
|
||||
const { depth, adcode, label, showBorder } = this
|
||||
.options as IProvinceLayerOption;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
|
||||
this.labelRawData = fillData.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
const data = this.filterData(fillData, adcode);
|
||||
this.fillData = data;
|
||||
const labelData = this.filterLabelData(this.labelRawData, adcode);
|
||||
this.fillRawData = fillData;
|
||||
this.addFillLayer(data);
|
||||
if (label.enable) {
|
||||
this.addLabelLayer(labelData);
|
||||
}
|
||||
this.lineRawData = fillData;
|
||||
if (showBorder) {
|
||||
this.addFillLine(data);
|
||||
}
|
||||
}
|
||||
|
||||
private async addProvinceLineLayer() {
|
||||
const { depth, adcode } = this.options as IProvinceLayerOption;
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[
|
||||
depth
|
||||
];
|
||||
const fillData = await this.fetchData(countryConfig.line);
|
||||
const data = this.filterData(fillData, adcode);
|
||||
this.lineRawData = fillData;
|
||||
this.addFillLine(data);
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { getDataConfig } from '../';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
export default class WorldLayer extends BaseLayer {
|
||||
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
|
||||
super(scene, option);
|
||||
this.loadData().then(([fillData, lineData, fillLabel]) => {
|
||||
this.addFillLayer(fillData);
|
||||
if (this.options.showBorder) {
|
||||
this.addFillLine(lineData);
|
||||
}
|
||||
if (this.options.label?.enable) {
|
||||
this.addLabelLayer(fillLabel, 'json');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public addFillLine(data: any) {
|
||||
// 未定国界
|
||||
const bord1 = data.features.filter((feature: any) => {
|
||||
return (
|
||||
feature.properties.type === '10' ||
|
||||
feature.properties.type === '1' ||
|
||||
feature.properties.type === '11' ||
|
||||
feature.properties.type === '8'
|
||||
);
|
||||
});
|
||||
const bordFc = {
|
||||
type: 'FeatureCollection',
|
||||
features: bord1,
|
||||
};
|
||||
// 已确定国界
|
||||
const nationalBorder = data.features.filter((feature: any) => {
|
||||
return (
|
||||
feature.properties.type !== '10' &&
|
||||
feature.properties.type !== '1' &&
|
||||
feature.properties.type !== '11' &&
|
||||
feature.properties.type !== '8'
|
||||
);
|
||||
});
|
||||
const nationalFc = {
|
||||
type: 'FeatureCollection',
|
||||
features: nationalBorder,
|
||||
};
|
||||
this.addNationBorder(nationalFc, bordFc);
|
||||
}
|
||||
|
||||
private async loadData() {
|
||||
const countryConfig = getDataConfig(this.options.geoDataLevel).world;
|
||||
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
const lineData = await this.fetchData(countryConfig.line);
|
||||
// const fillLabel = await this.fetchData(countryConfig.label);
|
||||
const fillLabel = fillData.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
return [fillData, lineData, fillLabel];
|
||||
}
|
||||
private addNationBorder(boundaries: any, boundaries2: any) {
|
||||
const {
|
||||
nationalStroke,
|
||||
nationalWidth,
|
||||
coastlineStroke,
|
||||
chinaNationalStroke,
|
||||
chinaNationalWidth,
|
||||
coastlineWidth,
|
||||
visible,
|
||||
zIndex,
|
||||
} = this.options;
|
||||
// 添加国界线
|
||||
const lineLayer = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible,
|
||||
})
|
||||
.source(boundaries)
|
||||
// .size(0.6)
|
||||
.size('type', (v: string) => {
|
||||
if (v === '0') {
|
||||
return chinaNationalWidth; // 中国国界线
|
||||
} else if (v === '2' || v === '9') {
|
||||
return coastlineWidth; // 中国海岸线
|
||||
} else if (v === '7') {
|
||||
return nationalWidth; // 国外国界
|
||||
} else {
|
||||
return nationalWidth;
|
||||
}
|
||||
})
|
||||
.color('type', (v: string) => {
|
||||
if (v === '0') {
|
||||
return chinaNationalStroke; // 中国国界线
|
||||
} else if (v === '2' || v === '9') {
|
||||
return coastlineStroke; // 中国海岸线
|
||||
} else if (v === '7') {
|
||||
return nationalStroke; // 国外国界
|
||||
} else {
|
||||
return nationalStroke;
|
||||
}
|
||||
});
|
||||
// 添加未定国界
|
||||
const lineLayer2 = new LineLayer({
|
||||
zIndex: zIndex + 0.1,
|
||||
visible,
|
||||
})
|
||||
.source(boundaries2)
|
||||
.size('type', (v: string) => {
|
||||
if (v === '1') {
|
||||
return chinaNationalWidth;
|
||||
} else {
|
||||
return nationalWidth;
|
||||
}
|
||||
})
|
||||
.shape('line')
|
||||
.color('type', (v: string) => {
|
||||
if (v === '1') {
|
||||
return chinaNationalStroke;
|
||||
} else {
|
||||
return nationalStroke;
|
||||
}
|
||||
})
|
||||
.style({
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
});
|
||||
|
||||
this.scene.addLayer(lineLayer);
|
||||
this.scene.addLayer(lineLayer2);
|
||||
|
||||
this.layers.push(lineLayer, lineLayer2);
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"declarationDir": "./es",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.1.12](https://github.com/antvis/L7/compare/v2.1.11...v2.1.12) (2020-04-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **heatmap:** 修复热力图某些设备上黑色 fix [#278](https://github.com/antvis/L7/issues/278) ([b8f5899](https://github.com/antvis/L7/commit/b8f58992d1fce38fdaac9d82ebfbec14e35298bd))
|
||||
* 绘制组件高德地图mousedown事件不能监听的问题 ([1eb3313](https://github.com/antvis/L7/commit/1eb3313919b2c7c9162bee70a249846b897ef4b4))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.11](https://github.com/antvis/L7/compare/v2.1.10...v2.1.11) (2020-04-07)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-draw
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.8](https://github.com/antvis/L7/compare/v2.1.7...v2.1.8) (2020-03-26)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-draw
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.7](https://github.com/antvis/L7/compare/v2.1.6...v2.1.7) (2020-03-26)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-draw
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.5](https://github.com/antvis/L7/compare/v2.1.4...v2.1.5) (2020-03-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* observerable打包问题 ([412e2a8](https://github.com/antvis/L7/commit/412e2a83f78a9a448f0a5b65ccaf2ea97f78b47a))
|
|
@ -1,56 +0,0 @@
|
|||
# `draw`
|
||||
地图绘制组件,支持点、线、面的绘制编辑,
|
||||
|
||||
## 使用
|
||||
|
||||
l7-draw 需要引用
|
||||
|
||||
```
|
||||
import { DrawControl } from '@antv/l7-draw';
|
||||
|
||||
```
|
||||
CDN 版本引用
|
||||
|
||||
```html
|
||||
<head>
|
||||
<! --引入最新版的L7-Draw -->
|
||||
<script src = 'https://unpkg.com/@antv/l7-draw'></script>
|
||||
</head>
|
||||
```
|
||||
|
||||
### example
|
||||
|
||||
```javascript
|
||||
|
||||
import { Scene } from '@antv/l7';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { DrawControl } from '@antv/l7-draw';
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMap({
|
||||
pitch: 0,
|
||||
style: 'dark', // hosted style id
|
||||
center: [112.874, 32.76], // starting position
|
||||
zoom: 12, // starting zoom
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const drawControl = new DrawControl(scene, {
|
||||
position: 'topright',
|
||||
layout: 'horizontal', // horizontal vertical
|
||||
controls: {
|
||||
point: true,
|
||||
polygon: true,
|
||||
line: true,
|
||||
circle: true,
|
||||
rect: true,
|
||||
delete: true,
|
||||
},
|
||||
});
|
||||
scene.addControl(drawControl);
|
||||
});
|
||||
|
||||
```
|
|
@ -1,50 +0,0 @@
|
|||
import { Feature, Geometry, point, Properties } from '@turf/helpers';
|
||||
import {
|
||||
createCircle,
|
||||
createPoint,
|
||||
createPolygon,
|
||||
createRect,
|
||||
} from '../../src/util/create_geometry';
|
||||
const circleData = {
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
units: 'kilometers',
|
||||
steps: 4,
|
||||
id: '1',
|
||||
pointFeatures: [
|
||||
{
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: { type: 'Point', coordinates: [113, 40] },
|
||||
},
|
||||
],
|
||||
active: true,
|
||||
type: 'circle',
|
||||
radius: 1115.6518229264275,
|
||||
startPoint: { lng: 112, lat: 30 },
|
||||
endPoint: { lng: 113, lat: 40 },
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[112, 40.03328403184138],
|
||||
[100.45355724910682, 29.495378543228927],
|
||||
[112, 19.966715968158613],
|
||||
[123.54644275089319, 29.495378543228927],
|
||||
[112, 40.03328403184138],
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
describe('creat_geometry', () => {
|
||||
it('creatCircle', () => {
|
||||
const circle = createCircle([112, 30], [113, 40], {
|
||||
units: 'kilometers',
|
||||
steps: 4,
|
||||
id: '1',
|
||||
pointFeatures: [point([113, 40])],
|
||||
});
|
||||
expect(circleData).toEqual(circle);
|
||||
});
|
||||
});
|
|
@ -1,85 +0,0 @@
|
|||
import { Feature, Geometry, Properties } from '@turf/helpers';
|
||||
import moveFeature from '../../src/util/move_featrues';
|
||||
describe('moveFeature', () => {
|
||||
const delta = {
|
||||
lng: 1,
|
||||
lat: 1,
|
||||
};
|
||||
const pointFeature: Feature<Geometry, Properties> = {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [130, 47],
|
||||
},
|
||||
};
|
||||
const polyon: Feature<Geometry, Properties> = {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[49.5703125, 45.583289756006316],
|
||||
[71.3671875, 45.583289756006316],
|
||||
[71.3671875, 57.136239319177434],
|
||||
[49.5703125, 57.136239319177434],
|
||||
[49.5703125, 45.583289756006316],
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const line: Feature<Geometry, Properties> = {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: [
|
||||
[54.31640625, 62.91523303947614],
|
||||
[71.015625, 62.59334083012024],
|
||||
[70.48828125, 58.07787626787517],
|
||||
[77.16796875, 54.36775852406841],
|
||||
[83.3203125, 58.26328705248601],
|
||||
[83.3203125, 66.37275500247455],
|
||||
[94.74609375, 66.65297740055279],
|
||||
[94.74609375, 62.512317938386914],
|
||||
],
|
||||
},
|
||||
};
|
||||
it('move Point', () => {
|
||||
const res = moveFeature([pointFeature], delta) as Array<
|
||||
Feature<Geometry, Properties>
|
||||
>;
|
||||
expect(res[0]?.geometry?.coordinates).toEqual([131, 48]);
|
||||
});
|
||||
it('move BBox', () => {
|
||||
const res = moveFeature([polyon], delta) as Array<
|
||||
Feature<Geometry, Properties>
|
||||
>;
|
||||
expect(res[0]?.geometry?.coordinates).toEqual([
|
||||
[
|
||||
[50.5703125, 46.583289756006316],
|
||||
[72.3671875, 46.583289756006316],
|
||||
[72.3671875, 58.136239319177434],
|
||||
[50.5703125, 58.136239319177434],
|
||||
[50.5703125, 46.583289756006316],
|
||||
],
|
||||
]);
|
||||
});
|
||||
it('move line', () => {
|
||||
const res = moveFeature([line], delta) as Array<
|
||||
Feature<Geometry, Properties>
|
||||
>;
|
||||
expect(res[0]?.geometry?.coordinates).toEqual([
|
||||
[55.31640625, 63.91523303947614],
|
||||
[72.015625, 63.59334083012024],
|
||||
[71.48828125, 59.07787626787517],
|
||||
[78.16796875, 55.36775852406841],
|
||||
[84.3203125, 59.26328705248601],
|
||||
[84.3203125, 67.37275500247455],
|
||||
[95.74609375, 67.65297740055279],
|
||||
[95.74609375, 63.512317938386914],
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -1,60 +0,0 @@
|
|||
{
|
||||
"name": "@antv/l7-draw",
|
||||
"version": "2.2.37",
|
||||
"description": "L7 Draw moudules",
|
||||
"keywords": [],
|
||||
"author": "thinkinggis <lzx199065@gmail.com>",
|
||||
"license": "ISC",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"unpkg": "dist/l7-draw.js",
|
||||
"types": "es/index.d.ts",
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"dist",
|
||||
"lib",
|
||||
"es",
|
||||
"README.md"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/antvis/L7.git"
|
||||
},
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.build.json",
|
||||
"clean": "rimraf dist; rimraf es; rimraf lib;",
|
||||
"build": "run-p build:*",
|
||||
"build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"build:cdn": "node_modules/.bin/rollup -c",
|
||||
"lint:ts": "run-p -c lint:ts-*",
|
||||
"test": "jest",
|
||||
"sync": "tnpm sync"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/l7": "2.2.37",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"@turf/circle": "^6.0.1",
|
||||
"@turf/distance": "^6.0.1",
|
||||
"@turf/helpers": "^6.1.4",
|
||||
"@turf/midpoint": "^5.1.5",
|
||||
"@turf/turf": "^5.1.6",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"lodash": "^4.6.2"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/antvis/L7/issues"
|
||||
},
|
||||
"homepage": "https://github.com/antvis/L7#readme",
|
||||
"devDependencies": {
|
||||
"postcss": "^7.0.27",
|
||||
"postcss-url": "^8.0.0",
|
||||
"rollup": "^2.3.3",
|
||||
"rollup-plugin-less": "^1.1.2"
|
||||
},
|
||||
"gitHead": "20154fe30d512024b03ac5e40f77731bc0580bb0"
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
import pkg from './package.json';
|
||||
import typescript from 'rollup-plugin-typescript';
|
||||
import resolve from 'rollup-plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import buble from 'rollup-plugin-buble';
|
||||
import postcss from 'rollup-plugin-postcss';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import url from 'postcss-url';
|
||||
export default {
|
||||
input: './src/index.ts',
|
||||
plugins: [
|
||||
// less(),
|
||||
typescript({
|
||||
exclude: 'node_modules/**',
|
||||
typescript: require('typescript')
|
||||
}),
|
||||
resolve({
|
||||
preferBuiltins: false
|
||||
}),
|
||||
postcss({
|
||||
plugins: [
|
||||
url({ url: 'inline' })
|
||||
]
|
||||
}),
|
||||
commonjs({
|
||||
namedExports: {
|
||||
eventemitter3: [ 'EventEmitter' ],
|
||||
lodash: [ 'merge', 'clone' ]
|
||||
}
|
||||
}),
|
||||
buble({
|
||||
transforms: { generator: false }
|
||||
}),
|
||||
terser()
|
||||
],
|
||||
external: [
|
||||
'@antv/l7'
|
||||
],
|
||||
output: [
|
||||
{
|
||||
format: 'umd',
|
||||
name: 'L7.Draw',
|
||||
file: pkg.unpkg,
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/l7': 'L7'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
.l7-control-draw {
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
box-shadow: 0 0 0 1px rgba(0,0,0,.1);
|
||||
display: flex;
|
||||
button {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 20px 20px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: block;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
border: 0;
|
||||
margin: 1px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:not(:disabled):hover {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
button:focus {
|
||||
box-shadow: 0 0 2px 2px #0096ff;
|
||||
}
|
||||
.draw-point {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NjYxMTY0NjA0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDExOTQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI5MzUiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTQ5LjI1IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNjA5LjUzNiA3MDcuMDcyYTE5NS4wNzIgMTk1LjA3MiAwIDEgMSAwLTM5MC4xNDQgMTk1LjA3MiAxOTUuMDcyIDAgMCAxIDAgMzkwLjE0NHoiIGZpbGw9IiMyYzJjMmMiIHAtaWQ9IjI5MzYiPjwvcGF0aD48cGF0aCBkPSJNMTA0OC40MDUzMzMgNDE0LjQ2NGExNDYuMjYxMzMzIDE0Ni4yNjEzMzMgMCAxIDEgMC0yOTIuNTIyNjY3IDE0Ni4yNjEzMzMgMTQ2LjI2MTMzMyAwIDAgMSAwIDI5Mi41MjI2Njd6TTE3MC42NjY2NjcgOTk5LjU5NDY2N2ExNDYuMjYxMzMzIDE0Ni4yNjEzMzMgMCAxIDEgMC0yOTIuNTIyNjY3IDE0Ni4yNjEzMzMgMTQ2LjI2MTMzMyAwIDAgMSAwIDI5Mi41MjI2Njd6IG0wLTY4Mi42NjY2NjdBMTQ2LjI2MTMzMyAxNDYuMjYxMzMzIDAgMSAxIDE3MC42NjY2NjcgMjQuNDA1MzMzYTE0Ni4yNjEzMzMgMTQ2LjI2MTMzMyAwIDAgMSAwIDI5Mi41MjI2Njd6IiBmaWxsPSIjMmMyYzJjIiBwLWlkPSIyOTM3Ij48L3BhdGg+PC9zdmc+');
|
||||
}
|
||||
.draw-line {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NjYxMDY5NTk0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjIxOTMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNOTAwLjkzIDMwMC4yOThjLTQxLjA2NyAwLTc0LjQ3IDMzLjQyOS03NC40NyA3NC40OTEgMCAxMCAxLjk5MiAxOS41MzMgNS41ODEgMjguMjU3bC0yMjAuMjYyIDIwNS4xOGE3My45OSA3My45OSAwIDAgMC00MS4yMzItMTIuNTA0IDc0LjE3IDc0LjE3IDAgMCAwLTIyLjQ1MSAzLjQ1MWwtNzAuMTEzLTEzOS42MzhhNzQuMTM4IDc0LjEzOCAwIDAgMCA4LjE0Ni0zMy45MmMwLTQxLjA2Mi0zMy4zODMtNzQuNDktNzQuNDQ1LTc0LjQ5cy03NC40NDUgMzMuNDI4LTc0LjQ0NSA3NC40OWMwIDMuODI1IDAuMjkyIDcuNjA0IDAuODU1IDExLjMxNkwxNjAuODYgNjI3LjIyYTczLjg4NyA3My44ODcgMCAwIDAtMzkuNzk4LTExLjU5N2MtNDEuMDYyIDAtNzQuNDcgMzMuNDIzLTc0LjQ3IDc0LjQ5IDAgNDEuMDgzIDMzLjQwOCA3NC41MTcgNzQuNDcgNzQuNTE3IDQxLjA0MiAwIDc0LjQyLTMzLjQyOCA3NC40Mi03NC41MTZhNzQuMjMgNzQuMjMgMCAwIDAtMy4yOTMtMjEuODk5bDE3MS40MzMtMTg1LjcxMmE3NC40NTUgNzQuNDU1IDAgMCAwIDc2LjMzNCAxMi4wNzhsNjcuMzkgMTM2LjE5MmE3NC4xNjggNzQuMTY4IDAgMCAwLTExLjIzOCAzOS40NWMwIDQxLjA4MiAzMy4zODIgNzQuNTE2IDc0LjQ0NCA3NC41MTYgNDEuMDY4IDAgNzQuNDQ1LTMzLjQyOSA3NC40NDUtNzQuNTE3YTc0LjM0MiA3NC4zNDIgMCAwIDAtMi43MjQtMTkuOTE2bDIyNC42NzEtMjA5LjI2NWE3My45NjQgNzMuOTY0IDAgMCAwIDMzLjk5MiA4LjI0OGM0MS4wNDIgMCA3NC40MTktMzMuNDI4IDc0LjQxOS03NC40OS0wLjAxLTQxLjA2OC0zMy4zODgtNzQuNTAyLTc0LjQyNC03NC41MDJ6TTEyMS4wNjkgNzEzLjA0MmEyMi45MTcgMjIuOTE3IDAgMCAxIDAtNDUuODMgMjIuOTMyIDIyLjkzMiAwIDAgMSAyMi44NzYgMjIuOTAzYy0wLjAwNSAxMi42NDYtMTAuMjg2IDIyLjkyNy0yMi44NzYgMjIuOTI3eiBtMjc2LjMxLTI2OS41MzdhMjIuODYgMjIuODYgMCAwIDEtOC41OS0xNy44OSAyMi45MzggMjIuOTM4IDAgMCAxIDIyLjkwMS0yMi45MDEgMjIuOTEyIDIyLjkxMiAwIDAgMSAyMi44NzYgMjIuOTAxYzAgNi4wNDctMi4zMiAxMS43MjUtNi41MDcgMTYuMDFsLTAuMiAwLjE4NWMtOS4wNjggOS4wNTItMjUuMDQyIDYuMDc3LTMwLjQ4IDEuNjk1ek01NzAuNTUzIDY5My4xNGEyMi45MjIgMjIuOTIyIDAgMCAxLTIyLjg3Ni0yMi45MjcgMjIuNzMzIDIyLjczMyAwIDAgMSA4LjI4LTE3LjYyM2MwLjMzNy0wLjI0IDAuNjg1LTAuNDgxIDEuMDEzLTAuNzQyIDAuMi0wLjE1OSAwLjM5LTAuMzIzIDAuNTg0LTAuNDkyYTIyLjY0IDIyLjY0IDAgMCAxIDEyLjk5NC00LjA0NSAyMi45MjcgMjIuOTI3IDAgMCAxIDIyLjg4MSAyMi45MDIgMjIuOTM4IDIyLjkzOCAwIDAgMS0yMi44NzYgMjIuOTI3eiBtMzMwLjM3OS0yOTUuNDVjLTEyLjY1MiAwLTIyLjkwMi0xMC4yOC0yMi45MDItMjIuOXMxMC4yNS0yMi45MDMgMjIuOTAyLTIyLjkwM2EyMi45MjcgMjIuOTI3IDAgMCAxIDIyLjg3IDIyLjkwMiAyMi45MjcgMjIuOTI3IDAgMCAxLTIyLjg3IDIyLjkwMnoiIHAtaWQ9IjIxOTQiPjwvcGF0aD48L3N2Zz4=');
|
||||
}
|
||||
.draw-polygon {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NjI5MzI3Nzc1IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE3MzkiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNDIxLjE0OSA5OTAuNDA0bC0xNDMuMzE4LTEzNy4xNS00My42NzktNDEuNzY0TDMxLjg0OSA2MTcuODUzbDIzNC4wNzQtNDg1LjQ4OCAxMjUuMTQxIDE3LjAyNiAxMDMuNjE0IDE0LjA0MS04LjA1NyA1OS40NTYtMTAzLjYzLTE0LjA0My04MS45Ni0xMS4xNTEtOTguMTAzIDIwMy40MzItOTguMTA1IDIwMy41MTkgMTcwLjgwNiAxNjMuNDkgNDMuNjgxIDQxLjc2NiAzNi4xNTcgMzQuNjE2IDc1LjY5OCA3Mi40IDM2LjUyOS0xOS42MjEgNTUuNzE4LTI5Ljk3MSA1MS43MDctMjcuNzM2IDUxLjgzNC0yNy45NjcgMTcuMTEtOS4xMTQgMTcuMTg4LTkuMyAzNC40NzYtMTguNDggMTcuMjM5LTkuMyAzNC41NDItMTguNTA1IDE3LjMxNS05LjM4NyAxNy4yNTYtOS4yMDEgNDYuOTgtMjUuMjkzLTQuOTk1LTI3LjM3NS04LjgzNi00OC45NjYtMTUuMzQxLTg0Ljg5MSA1OS4wNDQtMTAuNjcgMTUuMzQyIDg0Ljg5OCA4LjgyNyA0OC45MTggMTIuODMxIDcwLjMyOC0zMy43MTcgMTguMDQ5LTUxLjgyNyAyNy45MDQtMTcuMjM2IDkuMTktMTcuMjcyIDkuMzY1LTM0LjQ5MyAxOC40NzgtMzQuNTMxIDE4LjU3Ni0xNy4yMTMgOS4yMi0xNy4yOTIgOS4zNTYtMTcuMDk3IDkuMTA2LTE3LjIxOCA5LjMzNXoiIGZpbGw9IiMzRTNBMzkiIHAtaWQ9IjE3NDAiPjwvcGF0aD48cGF0aCBkPSJNNzUyLjUyNCA1NS40MzRoNjB2MzcwLjMyM2gtNjB6IiBmaWxsPSIjM0UzQTM5IiBwLWlkPSIxNzQxIj48L3BhdGg+PHBhdGggZD0iTTU5Ny4zODUgMjA1LjY5N2gzNzAuMjc5djYwSDU5Ny4zODV6IiBmaWxsPSIjM0UzQTM5IiBwLWlkPSIxNzQyIj48L3BhdGg+PC9zdmc+');
|
||||
}
|
||||
.draw-rect {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NjI5Mjk5NTYxIiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjEwMDEiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNzY1LjIzNCA2OS40MTdoNjB2MzcwLjYwNWgtNjB6IiBmaWxsPSIjM0UzQTM5IiBwLWlkPSIxMDAyIj48L3BhdGg+PHBhdGggZD0iTTYxNC4xOTMgMjE5LjgwN2gzNjIuMTI4djYwSDYxNC4xOTN6IiBmaWxsPSIjM0UzQTM5IiBwLWlkPSIxMDAzIj48L3BhdGg+PHBhdGggZD0iTTgyNS4yMzQgOTc1LjkzNkg4OS44MTlWMjI0LjcwN2gzNjcuNzA4djYwSDE0OS44MTl2NjMxLjIyOWg2MTUuNDE1VjYwMC4yOTloNjB6IiBmaWxsPSIjM0UzQTM5IiBwLWlkPSIxMDA0Ij48L3BhdGg+PC9zdmc+');
|
||||
}
|
||||
.draw-circle {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NjI5MjYwMDI2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI3NzYiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNTEyIDg4MS4wNjY2NjdBMzY5LjA2NjY2NyAzNjkuMDY2NjY3IDAgMSAxIDg4MS4wNjY2NjcgNTEyIDM2OS40OTMzMzMgMzY5LjQ5MzMzMyAwIDAgMSA1MTIgODgxLjA2NjY2N3ogbTAtNjgyLjY2NjY2N0EzMTMuNiAzMTMuNiAwIDEgMCA4MjUuNiA1MTIgMzE0LjAyNjY2NyAzMTQuMDI2NjY3IDAgMCAwIDUxMiAxOTguNHoiIGZpbGw9IiIgcC1pZD0iMjc3NyI+PC9wYXRoPjwvc3ZnPg==');
|
||||
}
|
||||
.draw-delete {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTg1NzMwNDEyNjU0IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjQ4MDQiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTI4IiBoZWlnaHQ9IjEyOCI+PGRlZnM+PHN0eWxlIHR5cGU9InRleHQvY3NzIj48L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNMjEzLjMzMzMzMyAyODIuODM3MzMzYzAtMjAuNjkzMzMzIDE2LjE3MDY2Ny0zNy40MTg2NjcgMzYuMDk2LTM3LjQxODY2NmgxODAuNDh2LTM3LjM3NmMwLTIwLjY1MDY2NyAxNi4yMTMzMzMtMzcuMzc2IDM2LjEzODY2Ny0zNy4zNzZoNzIuMTkyYzE5Ljk2OCAwIDM2LjEzODY2NyAxNi43MjUzMzMgMzYuMTM4NjY3IDM3LjM3NnYzNy4zNzZoMTgwLjQ4YzE5Ljk2OCAwIDM2LjA5NiAxNi43MjUzMzMgMzYuMDk2IDM3LjQxODY2NnYzNy4zNzZIMjEzLjMzMzMzM3YtMzcuMzc2eiBtNTQxLjUyNTMzNCAxMTIuMTI4djQyMC45OTJjMCAyMC42MDgtMTYuMTI4IDM3LjM3Ni0zNi4wOTYgMzcuMzc2SDI4NS41MjUzMzNjLTE5LjkyNTMzMyAwLTM2LjA5Ni0xNi43NjgtMzYuMDk2LTM3LjM3NlYzNTcuNTQ2NjY3aDUwNS40MjkzMzR2MzcuMzc2ek0zOTMuODU2IDQ2OS43NmMwLTIwLjY1MDY2Ny0xNi4xNzA2NjctMzcuNDE4NjY3LTM2LjA5Ni0zNy40MTg2NjctMTkuOTY4IDAtMzYuMTM4NjY3IDE2Ljc2OC0zNi4xMzg2NjcgMzcuNDE4NjY3djI3MS40MDI2NjdjMCAyMC42NTA2NjcgMTYuMjEzMzMzIDM3LjQxODY2NyAzNi4xMzg2NjcgMzcuNDE4NjY2IDE5LjkyNTMzMyAwIDM2LjA5Ni0xNi43NjggMzYuMDk2LTM3LjQxODY2NlY0NjkuNzZ6IG0xNDQuMzg0IDBjMC0yMC42NTA2NjctMTYuMTI4LTM3LjQxODY2Ny0zNi4wOTYtMzcuNDE4NjY3LTE5LjkyNTMzMyAwLTM2LjA5NiAxNi43NjgtMzYuMDk2IDM3LjQxODY2N3YyNzEuNDAyNjY3YzAgMjAuNjUwNjY3IDE2LjE3MDY2NyAzNy40MTg2NjcgMzYuMDk2IDM3LjQxODY2NiAxOS45NjggMCAzNi4wOTYtMTYuNzY4IDM2LjA5Ni0zNy40MTg2NjZWNDY5Ljc2eiBtMTQ0LjQyNjY2NyAwYzAtMjAuNjUwNjY3LTE2LjE3MDY2Ny0zNy40MTg2NjctMzYuMDk2LTM3LjQxODY2Ny0xOS45NjggMC0zNi4wOTYgMTYuNzY4LTM2LjA5NiAzNy40MTg2Njd2MjcxLjQwMjY2N2MwIDIwLjY1MDY2NyAxNi4xMjggMzcuNDE4NjY3IDM2LjA5NiAzNy40MTg2NjYgMTkuOTI1MzMzIDAgMzYuMDk2LTE2Ljc2OCAzNi4wOTYtMzcuNDE4NjY2VjQ2OS43NnoiIHAtaWQ9IjQ4MDUiPjwvcGF0aD48L3N2Zz4=');
|
||||
}
|
||||
|
||||
}
|
||||
.horizontal {
|
||||
flex-direction: row;
|
||||
button:focus:first-child {
|
||||
border-radius: 4px 0px 0px 4px;
|
||||
}
|
||||
button:focus:last-child {
|
||||
border-radius: 0px 4px 4px 4px;
|
||||
}
|
||||
button+button {
|
||||
border-left: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
button:focus:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
button:focus:last-child {
|
||||
border-radius: 0px 0px 4px 4px;
|
||||
}
|
||||
button+button {
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg5738" width="20" height="20" version="1.1"><defs id="defs5740"><linearGradient id="linearGradient4184" x1="3003" x2="3017" y1="10" y2="10" gradientTransform="translate(1,2.6171874e-6)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4103"/><linearGradient id="linearGradient4103"><stop id="stop4105" offset="0" stop-color="#000" stop-opacity="1"/><stop id="stop4107" offset="1" stop-color="#000" stop-opacity="0"/></linearGradient></defs><metadata id="metadata5743"/><g id="layer1" transform="translate(0,-1032.3622)"><path color="#000" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" id="rect9198" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="M 12.050781 2 C 11.795262 2 11.539542 2.0971762 11.34375 2.2929688 L 10.298828 3.3378906 C 9.9072437 3.7294757 9.9072437 4.360368 10.298828 4.7519531 L 15.248047 9.7011719 C 15.639631 10.092757 16.270525 10.092757 16.662109 9.7011719 L 17.707031 8.65625 C 18.098616 8.2646649 18.098616 7.6337726 17.707031 7.2421875 L 12.757812 2.2929688 C 12.56202 2.0971762 12.306301 2 12.050781 2 z M 8 8 C 7 8 7 9 7.5 9.5 C 7.833333 9.8333 8.5 10.5 8.5 10.5 L 7.5 11.5 C 7.5 11.5 7 12 7.5 12.5 C 8 13 8.5 12.5 8.5 12.5 L 9.5 11.5 L 10.5 12.5 C 11 13 12 13 12 12 L 12 8 L 8 8 z M 4 10.003906 C 3.74451 10.003906 3.4906916 10.103039 3.2949219 10.298828 L 2.2988281 11.294922 C 1.9072888 11.6865 1.9072888 12.315453 2.2988281 12.707031 L 3.296875 13.707031 C 3.6884144 14.098609 4.3193981 14.098609 4.7109375 13.707031 L 5.7070312 12.710938 C 6.0985706 12.31936 6.0985706 11.688453 5.7070312 11.296875 L 4.7070312 10.298828 C 4.5112616 10.103039 4.25549 10.003906 4 10.003906 z M 7.9960938 14 C 7.7405942 14 7.4848395 14.097187 7.2890625 14.292969 L 6.2949219 15.289062 C 5.9033679 15.680626 5.9033679 16.311561 6.2949219 16.703125 L 7.2929688 17.701172 C 7.6845227 18.092735 8.3135242 18.092735 8.7050781 17.701172 L 9.7011719 16.705078 C 10.092726 16.313515 10.092726 15.684532 9.7011719 15.292969 L 8.703125 14.292969 C 8.507348 14.097187 8.2515933 14 7.9960938 14 z" clip-rule="nonzero" color-interpolation="sRGB" color-interpolation-filters="linearRGB" color-rendering="auto" display="inline" enable-background="accumulate" image-rendering="auto" opacity="1" overflow="visible" shape-rendering="auto" text-rendering="auto" transform="translate(0,1032.3622)" visibility="visible"/></g></svg>
|
Before Width: | Height: | Size: 2.6 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg19167" width="20" height="20" version="1.1" viewBox="0 0 20 20"><metadata id="metadata19172"/><g id="layer1" transform="translate(0,-1032.3622)"><path id="rect6467" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="3" d="m 13.5,1035.8622 c -1.380712,0 -2.5,1.1193 -2.5,2.5 0,0.3208 0.04614,0.6244 0.15625,0.9063 l -3.75,3.75 c -0.281836,-0.1102 -0.585421,-0.1563 -0.90625,-0.1563 -1.380712,0 -2.5,1.1193 -2.5,2.5 0,1.3807 1.119288,2.5 2.5,2.5 1.380712,0 2.5,-1.1193 2.5,-2.5 0,-0.3208 -0.04614,-0.6244 -0.15625,-0.9062 l 3.75,-3.75 c 0.281836,0.1101 0.585421,0.1562 0.90625,0.1562 1.380712,0 2.5,-1.1193 2.5,-2.5 0,-1.3807 -1.119288,-2.5 -2.5,-2.5 z" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/></g></svg>
|
Before Width: | Height: | Size: 896 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg19167" width="20" height="20" version="1.1" viewBox="0 0 20 20"><metadata id="metadata19172"/><g id="layer1" transform="translate(0,-1032.3622)"><path id="path12561" fill="#000" fill-opacity="1" fill-rule="evenodd" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="m 36,1040.3622 c 6e-6,3.3093 -5.988612,10 -5.988612,10 0,0 -5.998776,-6.668 -6.011345,-9.9772 -0.01257,-3.3092 2.656576,-6.0039 5.965792,-6.0227 3.309189,-0.019 6.00884,2.6452 6.033992,5.9543" clip-rule="nonzero" color="#000" color-interpolation="sRGB" color-interpolation-filters="linearRGB" color-rendering="auto" display="inline" enable-background="accumulate" image-rendering="auto" opacity="1" overflow="visible" shape-rendering="auto" text-rendering="auto" visibility="visible" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none"/><path id="path12563" fill="#fff" fill-opacity="1" fill-rule="evenodd" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="m 34.000115,1040.3622 c -5e-6,2.2062 -3.992523,7.0001 -3.992523,7.0001 0,0 -3.999291,-4.7787 -4.007679,-6.9849 -0.0084,-2.2062 1.771082,-4.0027 3.97731,-4.0153 2.20621,-0.013 4.006037,1.7635 4.022777,3.9697" clip-rule="nonzero" color="#000" color-interpolation="sRGB" color-interpolation-filters="linearRGB" color-rendering="auto" display="inline" enable-background="accumulate" image-rendering="auto" opacity="1" overflow="visible" shape-rendering="auto" text-rendering="auto" visibility="visible" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none"/><path id="path12568" fill="#000" fill-opacity="1" fill-rule="evenodd" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="M 9.9667969,1014.3622 C 6.6575809,1014.381 3.98743,1017.0764 4,1020.3856 c 0.012569,3.3092 6.011719,8.9766 6.011719,8.9766 0,0 5.988287,-5.6907 5.988281,-9 l 0,-0.045 c -0.02515,-3.3091 -2.724014,-5.9741 -6.0332031,-5.9551 z m 0.00977,2 c 2.2062061,-0.013 4.0066931,1.7626 4.0234331,3.9688 l 0,0.031 c -5e-6,2.2062 -3.992188,6 -3.992188,6 0,0 -3.999424,-3.7782 -4.007812,-5.9844 -0.0084,-2.2062 1.7703345,-4.003 3.9765625,-4.0156 z" clip-rule="nonzero" color="#000" color-interpolation="sRGB" color-interpolation-filters="linearRGB" color-rendering="auto" display="inline" enable-background="accumulate" image-rendering="auto" opacity="1" overflow="visible" shape-rendering="auto" text-rendering="auto" visibility="visible" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none"/><path id="path17305" fill="#000" fill-opacity="1" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="butt" stroke-linejoin="bevel" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="M 10 2 C 6.686292 2 4 4.6863 4 8 C 4 11.3137 10 17 10 17 C 10 17 16 11.3137 16 8 C 16 4.6863 13.313708 2 10 2 z M 10 4 C 12.071068 4 13.75 5.6789 13.75 7.75 C 13.75 9.2053278 11.93111 11.644393 10.830078 13 L 9.1699219 13 C 8.0688903 11.644393 6.25 9.2053278 6.25 7.75 C 6.25 5.6789 7.928932 4 10 4 z" opacity="1" transform="translate(0,1032.3622)" style="marker:none"/></g></svg>
|
Before Width: | Height: | Size: 3.4 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg19167" width="20" height="20" version="1.1" viewBox="0 0 20 20"><metadata id="metadata19172"/><g id="layer1" transform="translate(0,-1032.3622)"><path id="rect7797" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width=".5" d="m 5,1039.3622 0,6 2,2 6,0 2,-2 0,-6 -2,-2 -6,0 z m 3,0 4,0 1,1 0,4 -1,1 -4,0 -1,-1 0,-4 z" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/><circle id="path4364" cx="6" cy="1046.362" r="2" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="1.6" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/><circle id="path4368" cx="14" cy="1046.362" r="2" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="1.6" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/><circle id="path4370" cx="6" cy="1038.362" r="2" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="1.6" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/><circle id="path4372" cx="14" cy="1038.362" r="2" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="1.6" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/></g></svg>
|
Before Width: | Height: | Size: 1.5 KiB |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" id="svg5738" width="20" height="20" version="1.1" viewBox="0 0 20 20"><metadata id="metadata5743"/><g id="layer1" transform="translate(0,-1032.3622)"><path id="rect2439-7" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-width="1" d="m 10,1035.7743 c -0.7849253,8e-4 -1.4968376,0.4606 -1.8203125,1.1758 l -3.1796875,0 -1,1 0,1 12,0 0,-1 -1,-1 -3.179688,0 c -0.323475,-0.7152 -1.035387,-1.175 -1.820312,-1.1758 z m -5,4.5879 0,7 c 0,1 1,2 2,2 l 6,0 c 1,0 2,-1 2,-2 l 0,-7 -2,0 0,5.5 -1.5,0 0,-5.5 -3,0 0,5.5 -1.5,0 0,-5.5 z" color="#000" display="inline" enable-background="accumulate" overflow="visible" visibility="visible" style="marker:none"/></g></svg>
|
Before Width: | Height: | Size: 756 B |
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg5738" width="20" height="20" version="1.1"><defs id="defs5740"><linearGradient id="linearGradient4184" x1="3003" x2="3017" y1="10" y2="10" gradientTransform="translate(1,2.6171874e-6)" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient4103"/><linearGradient id="linearGradient4103"><stop id="stop4105" offset="0" stop-color="#000" stop-opacity="1"/><stop id="stop4107" offset="1" stop-color="#000" stop-opacity="0"/></linearGradient></defs><metadata id="metadata5743"/><g id="layer1" transform="translate(0,-1032.3622)"><path color="#000" style="isolation:auto;mix-blend-mode:normal;solid-color:#000;solid-opacity:1;marker:none" id="rect9198" fill="#000" fill-opacity="1" fill-rule="nonzero" stroke="none" stroke-dasharray="none" stroke-dashoffset="0" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="4" stroke-opacity="1" stroke-width="2" d="M 12.005859 2 C 11.75036 2 11.494605 2.097187 11.298828 2.2929688 L 10.302734 3.2890625 C 9.9111804 3.680626 9.9111804 4.3115615 10.302734 4.703125 L 11.302734 5.7011719 C 11.694288 6.0927354 12.32329 6.0927354 12.714844 5.7011719 L 13.710938 4.7050781 C 14.102491 4.3135146 14.102491 3.6825791 13.710938 3.2910156 L 12.712891 2.2929688 C 12.517114 2.097187 12.261359 2 12.005859 2 z M 16.001953 5.9941406 C 15.746463 5.9941406 15.490692 6.0932735 15.294922 6.2890625 L 14.298828 7.2851562 C 13.907289 7.6767342 13.907289 8.3056877 14.298828 8.6972656 L 15.296875 9.6972656 C 15.688414 10.088844 16.319398 10.088844 16.710938 9.6972656 L 17.707031 8.7011719 C 18.098571 8.3095939 18.098571 7.6786873 17.707031 7.2871094 L 16.708984 6.2890625 C 16.513215 6.0932735 16.257443 5.9941406 16.001953 5.9941406 z M 9 7 C 8 7 8 8 8.5 8.5 C 8.833333 8.8333 9.5 9.5 9.5 9.5 L 8.5 10.5 C 8.5 10.5 8 11 8.5 11.5 C 9 12 9.5 11.5 9.5 11.5 L 10.5 10.5 L 11.5 11.5 C 12 12 13 12 13 11 L 13 7 L 9 7 z M 4.0488281 10.001953 C 3.7933087 10.001953 3.5375891 10.099129 3.3417969 10.294922 L 2.2988281 11.337891 C 1.9072437 11.729476 1.9072437 12.360368 2.2988281 12.751953 L 7.2480469 17.701172 C 7.6396313 18.092757 8.270525 18.092757 8.6621094 17.701172 L 9.7050781 16.658203 C 10.096663 16.266618 10.096663 15.635726 9.7050781 15.244141 L 4.7558594 10.294922 C 4.5600672 10.099129 4.3043475 10.001953 4.0488281 10.001953 z" clip-rule="nonzero" color-interpolation="sRGB" color-interpolation-filters="linearRGB" color-rendering="auto" display="inline" enable-background="accumulate" image-rendering="auto" opacity="1" overflow="visible" shape-rendering="auto" text-rendering="auto" transform="translate(0,1032.3622)" visibility="visible"/></g></svg>
|
Before Width: | Height: | Size: 2.7 KiB |
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* @Author: lzxue
|
||||
* @Date: 2020-04-03 19:24:16
|
||||
* @Last Modified by: lzxue
|
||||
* @Last Modified time: 2020-06-22 17:33:14
|
||||
*/
|
||||
import { Control, DOM, IControlOption, PositionType, Scene } from '@antv/l7';
|
||||
import './css/draw.less';
|
||||
import {
|
||||
DrawCircle,
|
||||
DrawDelete,
|
||||
DrawFeature,
|
||||
DrawLine,
|
||||
DrawPoint,
|
||||
DrawPolygon,
|
||||
DrawRect,
|
||||
} from './modes';
|
||||
import { IDrawFeatureOption } from './modes/draw_feature';
|
||||
const DrawType: {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
point: DrawPoint,
|
||||
line: DrawLine,
|
||||
polygon: DrawPolygon,
|
||||
circle: DrawCircle,
|
||||
rect: DrawRect,
|
||||
};
|
||||
import { isObject, polygon } from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes } from './util/constant';
|
||||
export interface IControls {
|
||||
[key: string]: boolean | IDrawFeatureOption;
|
||||
}
|
||||
|
||||
export interface IDrawControlOption extends IControlOption {
|
||||
pickBuffer: number;
|
||||
controls: IControls;
|
||||
layout: 'horizontal' | 'vertical';
|
||||
style: any;
|
||||
}
|
||||
export class DrawControl extends Control {
|
||||
private draw: {
|
||||
[key: string]: DrawFeature;
|
||||
} = {};
|
||||
private currentDraw: DrawFeature;
|
||||
private scene: Scene;
|
||||
constructor(scene: Scene, options: Partial<IDrawControlOption>) {
|
||||
super(options);
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
position: PositionType.TOPLEFT,
|
||||
controls: {
|
||||
point: true,
|
||||
line: true,
|
||||
polygon: true,
|
||||
rect: true,
|
||||
circle: true,
|
||||
delete: true,
|
||||
},
|
||||
name: 'draw',
|
||||
};
|
||||
}
|
||||
|
||||
public onAdd(): HTMLElement {
|
||||
const { layout } = this.controlOption;
|
||||
const controlClass = 'l7-control-draw' + ' ' + layout;
|
||||
const { controls } = this.controlOption as IDrawControlOption;
|
||||
const container = DOM.create('div', controlClass) as HTMLElement;
|
||||
this.addControls(controls, container);
|
||||
|
||||
// 代理每个绘制组件的事件
|
||||
|
||||
this.addControlEvent();
|
||||
// 监听组件 选中, 编辑
|
||||
return container;
|
||||
}
|
||||
|
||||
public onRemove() {
|
||||
for (const draw in this.draw) {
|
||||
if (this.draw[draw]) {
|
||||
this.draw[draw].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getDraw(type: string): DrawFeature | null {
|
||||
const { controls } = this.controlOption as IDrawControlOption;
|
||||
if (controls[type]) {
|
||||
return this.draw[type];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public getAllData() {
|
||||
const res: { [key: string]: any } = {};
|
||||
for (const draw in this.draw) {
|
||||
if (this.draw[draw]) {
|
||||
res[draw] = this.draw[draw].getData();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public removeAllData() {
|
||||
for (const draw in this.draw) {
|
||||
if (this.draw[draw]) {
|
||||
this.draw[draw].removeAllData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private addControls(controls: IControls, container: HTMLElement) {
|
||||
const { style } = this.controlOption as IDrawControlOption;
|
||||
for (const type in controls) {
|
||||
if (DrawType[type] && controls[type] !== false) {
|
||||
const drawOption: Partial<IDrawFeatureOption> = isObject(controls[type])
|
||||
? (controls[type] as Partial<IDrawFeatureOption>)
|
||||
: {};
|
||||
if (style) {
|
||||
drawOption.style = style;
|
||||
}
|
||||
const draw = new DrawType[type](this.scene, drawOption);
|
||||
draw.on(DrawEvent.MODE_CHANGE, this.onModeChange.bind(null, type));
|
||||
this.draw[type] = draw;
|
||||
this.createButton(
|
||||
draw.title,
|
||||
'draw-' + type,
|
||||
container,
|
||||
'click',
|
||||
this.onButtonClick.bind(null, type),
|
||||
);
|
||||
} else if (type === 'delete' && controls[type] !== false) {
|
||||
const draw = new DrawDelete(this.scene);
|
||||
draw.on(DrawEvent.MODE_CHANGE, this.onModeChange.bind(null, type));
|
||||
this.createButton(
|
||||
draw.title,
|
||||
'draw-' + type,
|
||||
container,
|
||||
'mousedown',
|
||||
this.onDeleteMode.bind(null, type),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private addControlEvent() {
|
||||
for (const draw in this.draw) {
|
||||
if (this.draw[draw]) {
|
||||
['draw.create', 'draw.update', 'draw.delete'].forEach(
|
||||
(type: string) => {
|
||||
this.draw[draw].on(type, (feature) => {
|
||||
this.emit(type, {
|
||||
drawType: draw,
|
||||
feature,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
private createButton(
|
||||
tile: string,
|
||||
className: string,
|
||||
container: HTMLElement,
|
||||
eventType: string,
|
||||
fn: (...arg: any[]) => any,
|
||||
) {
|
||||
const link = DOM.create('button', className, container);
|
||||
link.title = tile;
|
||||
link.addEventListener(eventType, fn, false);
|
||||
return link;
|
||||
}
|
||||
|
||||
private onButtonClick = (type: string, e: MouseEvent) => {
|
||||
for (const draw in this.draw) {
|
||||
if (draw === type) {
|
||||
this.draw[draw].enable();
|
||||
} else {
|
||||
this.draw[draw].disable();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private onDeleteMode = (type: string, e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
if (!this.currentDraw) {
|
||||
return;
|
||||
}
|
||||
this.currentDraw.deleteMode.enable();
|
||||
return false;
|
||||
};
|
||||
|
||||
private onModeChange = (type: string, mode: string) => {
|
||||
if (mode === DrawModes.SIMPLE_SELECT) {
|
||||
this.currentDraw = this.draw[type];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
export * from './modes/index';
|
||||
export * from './draw_control';
|
|
@ -1,168 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
PointLayer,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
featureCollection,
|
||||
Geometries,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import { createCircle, createPoint } from '../util/create_geometry';
|
||||
import moveFeatures, { movePoint } from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
|
||||
export default class DrawCircle extends DrawFeature {
|
||||
protected startPoint: ILngLat;
|
||||
protected endPoint: ILngLat;
|
||||
protected pointFeatures: Feature[];
|
||||
protected centerLayer: ILayer;
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'circle';
|
||||
}
|
||||
|
||||
public drawFinish() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public setCurrentFeature(feature: Feature) {
|
||||
this.currentFeature = feature as Feature;
|
||||
// @ts-ignore
|
||||
this.pointFeatures = feature.properties.pointFeatures;
|
||||
// @ts-ignore
|
||||
this.startPoint = feature.properties.startPoint;
|
||||
// @ts-ignore
|
||||
this.endPoint = feature.properties.endPoint;
|
||||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '绘制圆',
|
||||
};
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
if (this.drawStatus !== 'Drawing') {
|
||||
this.drawLayer.emit('unclick', null);
|
||||
}
|
||||
this.startPoint = e.lngLat;
|
||||
this.setCursor('grabbing');
|
||||
this.initCenterLayer();
|
||||
this.centerLayer.setData([this.startPoint]);
|
||||
};
|
||||
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
this.endPoint = e.lngLat;
|
||||
const feature = this.createFeature() as Feature<Geometries, Properties>;
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
const feature = this.createFeature(`${this.getUniqId()}`);
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.disable();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): void {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
this.drawLayer.updateData(featureCollection(newFeature));
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
const newStartPoint = movePoint(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
delta,
|
||||
);
|
||||
this.startPoint = {
|
||||
lat: newStartPoint[1],
|
||||
lng: newStartPoint[0],
|
||||
};
|
||||
const newEndPoint = movePoint(
|
||||
[this.endPoint.lng, this.endPoint.lat],
|
||||
delta,
|
||||
);
|
||||
const endPointObj = {
|
||||
lat: newEndPoint[1],
|
||||
lng: newEndPoint[0],
|
||||
};
|
||||
newFeature[0].properties = {
|
||||
...newFeature[0].properties,
|
||||
startPoint: this.startPoint,
|
||||
endPoint: endPointObj,
|
||||
pointFeatures: newPointFeture,
|
||||
};
|
||||
this.centerLayer.setData([this.startPoint]);
|
||||
this.setCurrentFeature(newFeature[0]);
|
||||
const changeFeature = {
|
||||
...newFeature[0],
|
||||
};
|
||||
this.emit(DrawEvent.CHANGE, changeFeature);
|
||||
}
|
||||
|
||||
protected createFeature(id: string = '0'): Feature {
|
||||
const points = createPoint([this.endPoint]);
|
||||
const feature = createCircle(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
[this.endPoint.lng, this.endPoint.lat],
|
||||
{
|
||||
pointFeatures: points.features,
|
||||
units: this.getOption('units'),
|
||||
steps: this.getOption('steps'),
|
||||
id,
|
||||
},
|
||||
);
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
|
||||
protected editFeature(endPoint: ILngLat): void {
|
||||
this.endPoint = endPoint;
|
||||
const newFeature = this.createFeature();
|
||||
const properties = newFeature.properties as { pointFeatures: Feature[] };
|
||||
this.drawLayer.updateData(featureCollection([newFeature]));
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(properties.pointFeatures),
|
||||
);
|
||||
this.emit(DrawEvent.CHANGE, featureCollection([newFeature]).features[0]);
|
||||
}
|
||||
|
||||
protected showOtherLayer() {
|
||||
this.centerLayer.setData([this.currentFeature?.properties?.startPoint]);
|
||||
this.centerLayer.show();
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
if (this.currentFeature) {
|
||||
this.centerLayer.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private initCenterLayer() {
|
||||
const centerStyle = this.getStyle('active').point;
|
||||
const layer = new PointLayer()
|
||||
.source([this.startPoint], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'lng',
|
||||
y: 'lat',
|
||||
},
|
||||
})
|
||||
.shape('circle')
|
||||
.color(centerStyle.color)
|
||||
.size(centerStyle.size)
|
||||
.style(centerStyle.style);
|
||||
this.scene.addLayer(layer);
|
||||
this.centerLayer = layer;
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature } from '@turf/helpers';
|
||||
import { DrawEvent } from '../util/constant';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
import DrawFeature, { IDrawOption } from './draw_mode';
|
||||
export default class DrawDelete extends DrawFeature {
|
||||
// 绘制完成之后显示
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
}
|
||||
|
||||
public enable() {
|
||||
this.emit(DrawEvent.DELETE, '');
|
||||
}
|
||||
public disable() {
|
||||
return null;
|
||||
}
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '删除图形',
|
||||
};
|
||||
}
|
||||
|
||||
protected onDragStart(e: any): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
throw new Error('Method not implemented.');
|
||||
};
|
||||
protected onClick = () => {
|
||||
return null;
|
||||
};
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
import { IInteractionTarget, ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature } from '@turf/helpers';
|
||||
import { DrawEvent } from '../util/constant';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
import DrawFeature, { IDrawOption } from './draw_mode';
|
||||
export default class DrawEdit extends DrawFeature {
|
||||
private endPoint: ILngLat;
|
||||
// 绘制完成之后显示
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
}
|
||||
|
||||
public setEditFeature(feature: Feature) {
|
||||
this.currentFeature = feature;
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
// @ts-ignore
|
||||
};
|
||||
|
||||
protected getDefaultOptions() {
|
||||
return {
|
||||
steps: 64,
|
||||
units: 'kilometres',
|
||||
cursor: 'move',
|
||||
};
|
||||
}
|
||||
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
this.endPoint = e.lngLat;
|
||||
this.emit(DrawEvent.Edit, this.endPoint);
|
||||
return;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
this.emit(DrawEvent.UPDATE, this.currentFeature);
|
||||
this.resetCursor();
|
||||
this.disable();
|
||||
};
|
||||
protected onClick = () => {
|
||||
return null;
|
||||
};
|
||||
}
|
|
@ -1,262 +0,0 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Popup, Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
point,
|
||||
Units,
|
||||
unitsFactors,
|
||||
} from '@turf/helpers';
|
||||
import DrawRender from '../render/draw';
|
||||
import RenderLayer from '../render/draw_result';
|
||||
import DrawVertexLayer from '../render/draw_vertex';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import DrawDelete from './draw_delete';
|
||||
import DrawEdit from './draw_edit';
|
||||
import DrawMode, { IDrawOption } from './draw_mode';
|
||||
import DrawSelected from './draw_selected';
|
||||
export interface IDrawFeatureOption extends IDrawOption {
|
||||
units: Units;
|
||||
steps: number;
|
||||
editEnable: boolean;
|
||||
selectEnable: boolean;
|
||||
cursor: string;
|
||||
}
|
||||
export default abstract class DrawFeature extends DrawMode {
|
||||
// 绘制完成之后显示
|
||||
public selectMode: DrawSelected;
|
||||
public editMode: DrawEdit;
|
||||
public deleteMode: DrawDelete;
|
||||
public editEnable: boolean;
|
||||
public selectEnable: boolean;
|
||||
|
||||
protected normalLayer: RenderLayer;
|
||||
protected drawLayer: DrawRender;
|
||||
protected drawVertexLayer: DrawVertexLayer;
|
||||
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
this.drawLayer = new DrawRender(this);
|
||||
this.drawVertexLayer = new DrawVertexLayer(this);
|
||||
this.normalLayer = new RenderLayer(this);
|
||||
this.selectEnable = this.getOption('selectEnable');
|
||||
this.editEnable = this.getOption('editEnable');
|
||||
|
||||
// this.editLayer = new EditLayer(this);
|
||||
this.selectMode = new DrawSelected(this.scene, {});
|
||||
this.editMode = new DrawEdit(this.scene, {});
|
||||
this.deleteMode = new DrawDelete(this.scene, {});
|
||||
|
||||
this.selectMode.on(DrawEvent.UPDATE, this.onDrawUpdate);
|
||||
this.selectMode.on(DrawEvent.Move, this.onDrawMove);
|
||||
this.editMode.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
this.editMode.on(DrawEvent.UPDATE, this.onDrawUpdate);
|
||||
this.editMode.on(DrawEvent.Edit, this.onDrawEdit);
|
||||
this.selectMode.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
|
||||
this.deleteMode.on(DrawEvent.DELETE, this.onDrawDelete);
|
||||
this.on(DrawEvent.CREATE, this.onDrawCreate);
|
||||
this.on(DrawEvent.MODE_CHANGE, this.onModeChange);
|
||||
document.addEventListener('keydown', this.addKeyDownEvent);
|
||||
if (this.options.data && this.initData()) {
|
||||
this.normalLayer.update(this.source.data);
|
||||
this.normalLayer.enableSelect();
|
||||
}
|
||||
}
|
||||
public abstract drawFinish(): void;
|
||||
public setCurrentFeature(feature: Feature) {
|
||||
this.currentFeature = feature as Feature;
|
||||
// @ts-ignore
|
||||
this.pointFeatures = feature.properties.pointFeatures;
|
||||
|
||||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
public deleteCurrentFeature() {
|
||||
this.deleteMode.enable();
|
||||
}
|
||||
public disableLayer() {
|
||||
// this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
this.drawLayer.disableSelect();
|
||||
}
|
||||
public enableLayer() {
|
||||
this.drawLayer.enableSelect();
|
||||
}
|
||||
|
||||
public getData(): FeatureCollection {
|
||||
return this.source.getData();
|
||||
}
|
||||
|
||||
public removeAllData(): void {
|
||||
this.source.removeAllFeatures();
|
||||
this.currentFeature = null;
|
||||
this.drawLayer.hide();
|
||||
this.drawVertexLayer.hide();
|
||||
this.normalLayer.hide();
|
||||
this.hideOtherLayer();
|
||||
}
|
||||
|
||||
public clear() {
|
||||
this.drawLayer.disableSelect();
|
||||
this.drawLayer.disableEdit();
|
||||
this.drawLayer.hide();
|
||||
this.drawVertexLayer.hide();
|
||||
this.hideOtherLayer();
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
}
|
||||
public reset() {
|
||||
this.drawLayer.show();
|
||||
this.drawVertexLayer.show();
|
||||
this.showOtherLayer();
|
||||
}
|
||||
|
||||
public addVertex(feature: Feature): void {
|
||||
throw new Error('子类未实现该方法');
|
||||
}
|
||||
|
||||
public onRemove() {
|
||||
this.destroy();
|
||||
this.selectMode.destroy();
|
||||
this.editMode.destroy();
|
||||
this.source.destroy();
|
||||
this.drawLayer.destroy();
|
||||
this.drawVertexLayer.destroy();
|
||||
this.normalLayer.destroy();
|
||||
document.removeEventListener('keydown', this.addKeyDownEvent);
|
||||
}
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
steps: 64,
|
||||
units: 'kilometers',
|
||||
cursor: 'crosshair',
|
||||
editEnable: true,
|
||||
selectEnable: true,
|
||||
};
|
||||
}
|
||||
protected abstract onDragStart(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract onDragging(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract onDragEnd(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract createFeature(e?: any): Feature;
|
||||
|
||||
protected abstract moveFeature(e: ILngLat): void;
|
||||
|
||||
protected abstract editFeature(e: any): void;
|
||||
|
||||
protected abstract hideOtherLayer(): void;
|
||||
|
||||
protected abstract showOtherLayer(): void;
|
||||
protected initData(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
private addDrawPopup(lnglat: ILngLat, dis: number) {
|
||||
const popup = new Popup({
|
||||
anchor: 'left',
|
||||
closeButton: false,
|
||||
})
|
||||
.setLnglat(lnglat)
|
||||
.setText(`半径:${dis.toFixed(2)}千米`);
|
||||
this.scene.addPopup(popup);
|
||||
this.popup = popup;
|
||||
}
|
||||
|
||||
private onModeChange = (mode: DrawModes[any]) => {
|
||||
switch (mode) {
|
||||
case DrawModes.DIRECT_SELECT:
|
||||
if (!this.editEnable) {
|
||||
return;
|
||||
}
|
||||
this.editMode.enable();
|
||||
this.editMode.setEditFeature(this.currentFeature as Feature);
|
||||
this.drawLayer.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(this.currentFeature?.properties?.pointFeatures),
|
||||
);
|
||||
this.drawVertexLayer.show();
|
||||
this.drawVertexLayer.enableEdit();
|
||||
this.showOtherLayer();
|
||||
this.drawStatus = 'DrawEdit';
|
||||
break;
|
||||
case DrawModes.SIMPLE_SELECT:
|
||||
if (!this.selectEnable) {
|
||||
this.drawLayer.hide();
|
||||
this.drawVertexLayer.hide();
|
||||
this.hideOtherLayer();
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
return;
|
||||
}
|
||||
this.selectMode.setSelectedFeature(this.currentFeature as Feature);
|
||||
this.selectMode.enable();
|
||||
this.drawLayer.updateData(
|
||||
// TODO:导入数据不能正常使用
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
this.drawLayer.enableSelect();
|
||||
this.drawVertexLayer.updateData(
|
||||
featureCollection(this.currentFeature?.properties?.pointFeatures),
|
||||
);
|
||||
this.drawVertexLayer.disableEdit();
|
||||
this.drawVertexLayer.show();
|
||||
this.drawLayer.show();
|
||||
this.showOtherLayer();
|
||||
this.drawStatus = 'DrawSelected';
|
||||
break;
|
||||
case DrawModes.STATIC:
|
||||
this.source.updateFeature(this.currentFeature as Feature);
|
||||
this.selectMode.disable();
|
||||
this.editMode.disable();
|
||||
this.source.clearFeatureActive();
|
||||
this.drawVertexLayer.hide();
|
||||
this.drawVertexLayer.disableEdit();
|
||||
this.hideOtherLayer();
|
||||
this.normalLayer.update(this.source.data);
|
||||
this.normalLayer.enableSelect();
|
||||
this.drawStatus = 'DrawFinish';
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private onDrawCreate = (feature: Feature) => {
|
||||
this.source.addFeature(feature);
|
||||
};
|
||||
|
||||
private onDrawUpdate = (feature: Feature) => {
|
||||
this.source.updateFeature(this.currentFeature as Feature);
|
||||
this.emit(DrawEvent.UPDATE, this.currentFeature);
|
||||
};
|
||||
|
||||
private onDrawMove = (delta: ILngLat) => {
|
||||
if (this.drawStatus === 'DrawSelected') {
|
||||
this.moveFeature(delta);
|
||||
}
|
||||
};
|
||||
|
||||
private onDrawEdit = (endpoint: ILngLat) => {
|
||||
this.editFeature(endpoint);
|
||||
};
|
||||
|
||||
private onDrawDelete = () => {
|
||||
if (this.drawStatus === 'DrawSelected') {
|
||||
this.clear();
|
||||
this.source.removeFeature(this.currentFeature as Feature);
|
||||
|
||||
this.normalLayer.update(this.source.data);
|
||||
this.drawLayer.disableSelect();
|
||||
this.selectMode.disable();
|
||||
this.currentFeature = null;
|
||||
// this.drawStatus = 'DrawDelete';
|
||||
}
|
||||
};
|
||||
|
||||
private addKeyDownEvent = (event: KeyboardEvent) => {
|
||||
// tslint:disable-next-line:no-arg
|
||||
const e = event || window.event;
|
||||
if (e && e.keyCode === 8) {
|
||||
this.deleteMode.enable();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
import { ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature, featureCollection } from '@turf/helpers';
|
||||
import { unitsType } from '../util/constant';
|
||||
import { createLine, createPoint } from '../util/create_geometry';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
import DrawPolygon from './draw_polygon';
|
||||
export interface IDrawRectOption extends IDrawFeatureOption {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
}
|
||||
export default class DrawLine extends DrawPolygon {
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'line';
|
||||
}
|
||||
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '绘制线',
|
||||
};
|
||||
}
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawLayer.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
this.currentFeature = newFeature[0];
|
||||
this.pointFeatures = newPointFeture;
|
||||
return this.currentFeature;
|
||||
}
|
||||
protected createFeature(
|
||||
points: ILngLat[],
|
||||
id?: string,
|
||||
active: boolean = true,
|
||||
): Feature {
|
||||
const pointfeatures = createPoint(points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
const feature = createLine(points, {
|
||||
id: id || this.getUniqId(),
|
||||
type: 'line',
|
||||
active,
|
||||
pointFeatures: this.pointFeatures,
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
protected initData(): boolean {
|
||||
const features: Feature[] = [];
|
||||
this.source.data.features.forEach((feature) => {
|
||||
if (feature.geometry.type === 'LineString') {
|
||||
// @ts-ignore
|
||||
const points = feature.geometry.coordinates.map((coord) => {
|
||||
return {
|
||||
lng: coord[0],
|
||||
lat: coord[1],
|
||||
};
|
||||
});
|
||||
features.push(
|
||||
this.createFeature(points, feature?.properties?.id, false),
|
||||
);
|
||||
}
|
||||
});
|
||||
this.source.data.features = features;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
import { IInteractionTarget, IPopup, Scene } from '@antv/l7';
|
||||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
import DrawSource from '../source';
|
||||
import LayerStyles from '../util/layerstyle';
|
||||
|
||||
export interface IDrawOption {
|
||||
data: FeatureCollection;
|
||||
title: string;
|
||||
style: any;
|
||||
}
|
||||
|
||||
export type DrawStatus =
|
||||
| 'Drawing'
|
||||
| 'DrawSelected'
|
||||
| 'DrawEdit'
|
||||
| 'DrawFinish'
|
||||
| 'EditFinish'
|
||||
| 'DrawDelete';
|
||||
|
||||
let DrawFeatureId = 0;
|
||||
|
||||
export default abstract class DrawMode extends EventEmitter {
|
||||
public source: DrawSource;
|
||||
public scene: Scene;
|
||||
public type: string;
|
||||
public title: string;
|
||||
public isEnable: boolean = false;
|
||||
|
||||
protected options: {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
style: LayerStyles,
|
||||
};
|
||||
protected drawStatus: DrawStatus = 'Drawing';
|
||||
protected currentFeature: Feature | null;
|
||||
protected currentVertex: Feature | null;
|
||||
protected popup: IPopup;
|
||||
constructor(scene: Scene, options: Partial<IDrawOption> = {}) {
|
||||
super();
|
||||
const { data } = options;
|
||||
this.scene = scene;
|
||||
this.source = new DrawSource(data);
|
||||
this.options = merge(this.options, this.getDefaultOptions(), options);
|
||||
this.title = this.getOption('title');
|
||||
}
|
||||
public enable() {
|
||||
if (this.isEnable) {
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
this.scene.setMapStatus({
|
||||
dragEnable: false,
|
||||
});
|
||||
this.scene.on('dragstart', this.onDragStart);
|
||||
this.scene.on('dragging', this.onDragging);
|
||||
this.scene.on('dragend', this.onDragEnd);
|
||||
this.scene.on('click', this.onClick);
|
||||
this.setCursor(this.getOption('cursor'));
|
||||
this.isEnable = true;
|
||||
}
|
||||
|
||||
public disable() {
|
||||
if (!this.isEnable) {
|
||||
return;
|
||||
}
|
||||
this.scene.off('dragstart', this.onDragStart);
|
||||
this.scene.off('dragging', this.onDragging);
|
||||
this.scene.off('dragend', this.onDragEnd);
|
||||
this.scene.off('click', this.onClick);
|
||||
this.resetCursor();
|
||||
// @ts-ignore
|
||||
this.scene.setMapStatus({
|
||||
dragEnable: true,
|
||||
});
|
||||
this.isEnable = false;
|
||||
}
|
||||
public setCurrentFeature(feature: Feature) {
|
||||
this.currentFeature = feature;
|
||||
this.source.setFeatureActive(feature);
|
||||
}
|
||||
|
||||
public setCurrentVertex(feature: Feature) {
|
||||
this.currentVertex = feature;
|
||||
}
|
||||
public deleteCurrentFeature() {
|
||||
throw new Error('子类未实现该方法');
|
||||
}
|
||||
|
||||
public getCurrentVertex(): Feature {
|
||||
return this.currentVertex as Feature;
|
||||
}
|
||||
public getCurrentFeature(): Feature {
|
||||
return this.currentFeature as Feature;
|
||||
}
|
||||
|
||||
public getOption(key: string) {
|
||||
return this.options[key];
|
||||
}
|
||||
|
||||
public getStyle(id: string) {
|
||||
return this.getOption('style')[id];
|
||||
}
|
||||
|
||||
public getUniqId() {
|
||||
return DrawFeatureId++;
|
||||
}
|
||||
|
||||
public setCursor(cursor: string) {
|
||||
const container = this.scene.getMapCanvasContainer();
|
||||
if (container) {
|
||||
container.style.cursor = cursor;
|
||||
}
|
||||
}
|
||||
public resetCursor() {
|
||||
const container = this.scene.getMapCanvasContainer();
|
||||
if (container) {
|
||||
container.removeAttribute('style');
|
||||
}
|
||||
}
|
||||
public destroy() {
|
||||
DrawFeatureId = 0;
|
||||
this.removeAllListeners();
|
||||
this.disable();
|
||||
}
|
||||
|
||||
protected getDefaultOptions(): any {
|
||||
return {};
|
||||
}
|
||||
|
||||
protected abstract onDragStart(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract onDragging(e: IInteractionTarget): void;
|
||||
|
||||
protected abstract onDragEnd(e: IInteractionTarget): void;
|
||||
|
||||
protected onClick(e: IInteractionTarget): any {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Scene } from '@antv/l7';
|
||||
import { Feature, featureCollection, point } from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
|
||||
export default class DrawPoint extends DrawFeature {
|
||||
protected pointFeatures: Feature[];
|
||||
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'point';
|
||||
}
|
||||
public drawFinish() {
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.disable();
|
||||
}
|
||||
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '绘制点',
|
||||
};
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onClick = (e: any) => {
|
||||
if (this.drawStatus !== 'Drawing') {
|
||||
this.drawLayer.emit('unclick', null);
|
||||
}
|
||||
const lngLat = e.lngLat || e.lnglat;
|
||||
const feature = this.createFeature(lngLat);
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection([feature]));
|
||||
this.drawFinish();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): Feature {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
this.drawLayer.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newFeature));
|
||||
this.currentFeature = newFeature[0];
|
||||
this.pointFeatures = newFeature;
|
||||
this.currentFeature.properties = {
|
||||
...this.currentFeature.properties,
|
||||
pointFeatures: newFeature,
|
||||
};
|
||||
return this.currentFeature;
|
||||
}
|
||||
protected createFeature(
|
||||
p: ILngLat,
|
||||
id?: string,
|
||||
active: boolean = true,
|
||||
): Feature {
|
||||
const feature = point([p.lng, p.lat], {
|
||||
id: id || this.getUniqId(),
|
||||
type: 'point',
|
||||
active,
|
||||
pointFeatures: [point([p.lng, p.lat])],
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
protected initData(): boolean {
|
||||
const features: Feature[] = [];
|
||||
this.source.data.features.forEach((feature) => {
|
||||
if (feature.geometry.type === 'Point') {
|
||||
const p = {
|
||||
lng: feature.geometry.coordinates[0] as number,
|
||||
lat: feature.geometry.coordinates[1] as number,
|
||||
};
|
||||
features.push(this.createFeature(p, feature?.properties?.id, false));
|
||||
}
|
||||
});
|
||||
this.source.data.features = features;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected editFeature(endPoint: ILngLat): void {
|
||||
this.createFeature(endPoint);
|
||||
}
|
||||
|
||||
protected showOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,282 +0,0 @@
|
|||
import { IInteractionTarget, ILayer, ILngLat, Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
Geometries,
|
||||
point,
|
||||
Position,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import DrawMidVertex from '../render/draw_mid_vertex';
|
||||
import { DrawEvent, DrawModes, unitsType } from '../util/constant';
|
||||
import { createPoint, createPolygon } from '../util/create_geometry';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import DrawFeature, { IDrawFeatureOption } from './draw_feature';
|
||||
export interface IDrawRectOption extends IDrawFeatureOption {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
}
|
||||
export default class DrawPolygon extends DrawFeature {
|
||||
protected startPoint: ILngLat;
|
||||
protected endPoint: ILngLat;
|
||||
protected points: ILngLat[] = [];
|
||||
protected pointFeatures: Feature[];
|
||||
protected drawMidVertexLayer: DrawMidVertex;
|
||||
|
||||
constructor(scene: Scene, options: Partial<IDrawRectOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'polygon';
|
||||
this.drawMidVertexLayer = new DrawMidVertex(this);
|
||||
this.on(DrawEvent.MODE_CHANGE, this.addMidLayerEvent);
|
||||
}
|
||||
public enable() {
|
||||
super.enable();
|
||||
this.scene.on('mousemove', this.onMouseMove);
|
||||
this.scene.on('dblclick', this.onDblClick);
|
||||
// 关闭双击放大
|
||||
}
|
||||
|
||||
public disable() {
|
||||
super.disable();
|
||||
this.scene.off('mousemove', this.onMouseMove);
|
||||
this.scene.off('dblclick', this.onDblClick);
|
||||
}
|
||||
|
||||
public drawFinish() {
|
||||
const feature = this.createFeature(this.points);
|
||||
const properties = feature.properties as { pointFeatures: Feature[] };
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(properties.pointFeatures));
|
||||
// @ts-ignore
|
||||
this.emit(DrawEvent.CREATE, this.currentFeature);
|
||||
this.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
this.points = [];
|
||||
this.disable();
|
||||
}
|
||||
|
||||
public addVertex(vertex: Feature<Geometries, Properties>) {
|
||||
// @ts-ignore
|
||||
const id = vertex.properties.id;
|
||||
const coord = vertex?.geometry?.coordinates as Position;
|
||||
const feature = this.currentFeature as Feature<Geometries, Properties>;
|
||||
const type = feature?.geometry?.type;
|
||||
const points = [];
|
||||
if (type === 'Polygon') {
|
||||
const coords = feature?.geometry?.coordinates as Position[][];
|
||||
coords[0].splice(id + 1, 0, coord);
|
||||
for (let i = 0; i < coords[0].length - 1; i++) {
|
||||
points.push({
|
||||
lng: coords[0][i][0],
|
||||
lat: coords[0][i][1],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const coords = feature?.geometry?.coordinates as Position[];
|
||||
coords.splice(id + 1, 0, coord);
|
||||
for (const coor of coords) {
|
||||
points.push({
|
||||
lng: coor[0],
|
||||
lat: coor[1],
|
||||
});
|
||||
}
|
||||
}
|
||||
const pointfeatures = createPoint(points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
this.drawLayer.updateData(featureCollection([feature]));
|
||||
this.drawVertexLayer.updateData(pointfeatures);
|
||||
this.drawMidVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
// @ts-ignore
|
||||
feature.properties.pointFeatures = pointfeatures.features;
|
||||
this.setCurrentFeature(feature);
|
||||
}
|
||||
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '绘制多边形',
|
||||
};
|
||||
}
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
return null;
|
||||
};
|
||||
|
||||
protected onClick = (e: any) => {
|
||||
if (this.drawStatus !== 'Drawing') {
|
||||
this.drawLayer.emit('unclick', null);
|
||||
}
|
||||
const lngLat = e.lngLat || e.lnglat;
|
||||
this.endPoint = lngLat;
|
||||
this.points.push(lngLat);
|
||||
const feature = this.createFeature(this.points);
|
||||
const pointfeatures = createPoint([this.points[0], this.endPoint]);
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
this.drawVertexLayer.update(featureCollection(pointfeatures.features));
|
||||
this.onDraw();
|
||||
};
|
||||
|
||||
protected onMouseMove = (e: any) => {
|
||||
const lngLat = e.lngLat || e.lnglat;
|
||||
if (this.points.length === 0) {
|
||||
return;
|
||||
}
|
||||
const tmpPoints = this.points.slice();
|
||||
tmpPoints.push(lngLat);
|
||||
const feature = this.createFeature(tmpPoints);
|
||||
this.drawLayer.update(featureCollection([feature]));
|
||||
};
|
||||
|
||||
protected onDblClick = (e: any) => {
|
||||
const lngLat = e.lngLat || e.lnglat;
|
||||
if (this.points.length < 2) {
|
||||
return;
|
||||
}
|
||||
this.points.push(lngLat);
|
||||
this.drawFinish();
|
||||
};
|
||||
|
||||
protected moveFeature(delta: ILngLat): void {
|
||||
const newFeature = moveFeatures([this.currentFeature as Feature], delta);
|
||||
const newPointFeture = moveFeatures(this.pointFeatures, delta);
|
||||
this.drawLayer.updateData(featureCollection(newFeature));
|
||||
this.drawVertexLayer.updateData(featureCollection(newPointFeture));
|
||||
newFeature[0].properties = {
|
||||
...newFeature[0].properties,
|
||||
pointFeatures: newPointFeture,
|
||||
};
|
||||
this.setCurrentFeature(newFeature[0]);
|
||||
}
|
||||
protected createFeature(
|
||||
points: ILngLat[],
|
||||
id?: string,
|
||||
active: boolean = true,
|
||||
): Feature {
|
||||
const pointfeatures = createPoint(points);
|
||||
this.pointFeatures = pointfeatures.features;
|
||||
const feature = createPolygon(points, {
|
||||
id: id || this.getUniqId(),
|
||||
type: 'polygon',
|
||||
active,
|
||||
pointFeatures: this.pointFeatures,
|
||||
});
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
|
||||
protected editFeature(vertex: ILngLat): void {
|
||||
const selectVertexed = this.currentVertex as Feature<
|
||||
Geometries,
|
||||
Properties
|
||||
>;
|
||||
if (selectVertexed === null) {
|
||||
return;
|
||||
} else {
|
||||
// @ts-ignore
|
||||
const id = selectVertexed.properties.id * 1;
|
||||
// @ts-ignore
|
||||
selectVertexed.geometry.coordinates = [vertex.lng, vertex.lat];
|
||||
// @ts-ignore
|
||||
this.pointFeatures[id].geometry.coordinates = [vertex.lng, vertex.lat];
|
||||
this.drawVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
this.drawMidVertexLayer.updateData(featureCollection(this.pointFeatures));
|
||||
this.editPolygonVertex(id, vertex);
|
||||
this.drawLayer.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
const feature = this.currentFeature as Feature;
|
||||
feature.properties = {
|
||||
...this.currentFeature?.properties,
|
||||
pointFeatures: this.pointFeatures,
|
||||
};
|
||||
this.setCurrentFeature(feature);
|
||||
}
|
||||
}
|
||||
|
||||
protected onDraw = () => {
|
||||
this.drawVertexLayer.on('mousemove', (e: any) => {
|
||||
this.setCursor('pointer');
|
||||
});
|
||||
this.drawVertexLayer.on('mouseout', () => {
|
||||
this.setCursor('crosshair');
|
||||
});
|
||||
this.drawVertexLayer.on('click', () => {
|
||||
this.resetCursor();
|
||||
this.drawFinish();
|
||||
});
|
||||
};
|
||||
|
||||
protected showOtherLayer() {
|
||||
// if (this.editMode.isEnable) {
|
||||
// this.drawMidVertexLayer.update(featureCollection(this.pointFeatures));
|
||||
// this.drawMidVertexLayer.show();
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
protected hideOtherLayer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected addMidLayerEvent(mode: DrawModes[any]) {
|
||||
switch (mode) {
|
||||
case DrawModes.DIRECT_SELECT:
|
||||
this.drawMidVertexLayer.update(featureCollection(this.pointFeatures));
|
||||
this.drawMidVertexLayer.show();
|
||||
break;
|
||||
case DrawModes.STATIC:
|
||||
this.drawMidVertexLayer.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
protected initData(): boolean {
|
||||
const features: Feature[] = [];
|
||||
this.source.data.features.forEach((feature) => {
|
||||
if (feature.geometry.type === 'Polygon') {
|
||||
const points = (feature.geometry.coordinates[0] as Position[]).map(
|
||||
(coord) => {
|
||||
return {
|
||||
lng: coord[0],
|
||||
lat: coord[1],
|
||||
};
|
||||
},
|
||||
);
|
||||
features.push(
|
||||
this.createFeature(points.slice(1), feature?.properties?.id, false),
|
||||
);
|
||||
}
|
||||
});
|
||||
this.source.data.features = features;
|
||||
return true;
|
||||
}
|
||||
|
||||
private editPolygonVertex(id: number, vertex: ILngLat) {
|
||||
const feature = this.currentFeature as Feature<Geometries, Properties>;
|
||||
const type = feature?.geometry?.type;
|
||||
if (type === 'Polygon') {
|
||||
const coords = feature?.geometry?.coordinates as Position[][];
|
||||
coords[0][id] = [vertex.lng, vertex.lat];
|
||||
if (-id === 0) {
|
||||
coords[0][coords[0].length - 1] = [vertex.lng, vertex.lat];
|
||||
}
|
||||
} else {
|
||||
const coords = feature?.geometry?.coordinates as Position[];
|
||||
coords[id] = [vertex.lng, vertex.lat];
|
||||
}
|
||||
this.setCurrentFeature(feature);
|
||||
this.drawLayer.updateData(
|
||||
featureCollection([this.currentFeature as Feature]),
|
||||
);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* draw 端点响应事件
|
||||
* select Polyon 响应事件
|
||||
* edit 端点 中心点响应事件
|
||||
*/
|
|
@ -1,40 +0,0 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
featureCollection,
|
||||
point,
|
||||
} from '@turf/helpers';
|
||||
import { unitsType } from '../util/constant';
|
||||
import { createPoint, createRect } from '../util/create_geometry';
|
||||
import DrawCircle from './draw_circle';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
export default class DrawRect extends DrawCircle {
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
this.type = 'rect';
|
||||
}
|
||||
public drawFinish() {
|
||||
return null;
|
||||
}
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
...super.getDefaultOptions(),
|
||||
title: '绘制矩形',
|
||||
};
|
||||
}
|
||||
|
||||
protected createFeature(id: string = '0'): Feature {
|
||||
const points = createPoint([this.endPoint]);
|
||||
const feature = createRect(
|
||||
[this.startPoint.lng, this.startPoint.lat],
|
||||
[this.endPoint.lng, this.endPoint.lat],
|
||||
{
|
||||
id,
|
||||
pointFeatures: points.features,
|
||||
},
|
||||
);
|
||||
this.setCurrentFeature(feature as Feature);
|
||||
return feature;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import { Feature, featureCollection, point } from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import moveFeatures from '../util/move_featrues';
|
||||
import { IDrawFeatureOption } from './draw_feature';
|
||||
import DrawFeature, { IDrawOption } from './draw_mode';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
export default class DrawSelect extends DrawFeature {
|
||||
private center: ILngLat;
|
||||
private dragStartPoint: ILngLat;
|
||||
// 绘制完成之后显示
|
||||
constructor(scene: Scene, options: Partial<IDrawFeatureOption> = {}) {
|
||||
super(scene, options);
|
||||
}
|
||||
|
||||
public setSelectedFeature(feature: Feature) {
|
||||
this.currentFeature = feature;
|
||||
}
|
||||
|
||||
protected onDragStart = (e: IInteractionTarget) => {
|
||||
this.scene.setMapStatus({ dragEnable: false });
|
||||
this.dragStartPoint = e.lngLat;
|
||||
};
|
||||
|
||||
protected getDefaultOptions(): Partial<IDrawFeatureOption> {
|
||||
return {
|
||||
steps: 64,
|
||||
units: 'kilometers',
|
||||
cursor: 'move',
|
||||
};
|
||||
}
|
||||
|
||||
protected onDragging = (e: IInteractionTarget) => {
|
||||
const delta = {
|
||||
lng: e.lngLat.lng - this.dragStartPoint.lng,
|
||||
lat: e.lngLat.lat - this.dragStartPoint.lat,
|
||||
};
|
||||
this.emit(DrawEvent.Move, delta);
|
||||
this.dragStartPoint = e.lngLat;
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
protected onDragEnd = () => {
|
||||
this.emit(DrawEvent.UPDATE, this.currentFeature);
|
||||
};
|
||||
protected onClick = () => {
|
||||
return null;
|
||||
};
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import DrawCircle from './draw_circle';
|
||||
import DrawDelete from './draw_delete';
|
||||
import DrawFeature from './draw_feature';
|
||||
import DrawLine from './draw_line';
|
||||
import DrawMode from './draw_mode';
|
||||
import DrawPoint from './draw_point';
|
||||
import DrawPolygon from './draw_polygon';
|
||||
import DrawRect from './draw_rect';
|
||||
export {
|
||||
DrawCircle,
|
||||
DrawFeature,
|
||||
DrawRect,
|
||||
DrawPolygon,
|
||||
DrawPoint,
|
||||
DrawLine,
|
||||
DrawMode,
|
||||
DrawDelete,
|
||||
};
|
|
@ -1,69 +0,0 @@
|
|||
import { IInteractionTarget, ILayer, Scene } from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
type CallBack = (...args: any[]) => any;
|
||||
import { FeatureCollection } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class BaseRenderLayer {
|
||||
public drawLayers: ILayer[] = [];
|
||||
protected draw: Draw;
|
||||
protected isEnableDrag: boolean;
|
||||
protected isEnableEdit: boolean;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
}
|
||||
public update(feature: FeatureCollection) {
|
||||
if (this.drawLayers.length > 0) {
|
||||
this.updateData(feature);
|
||||
}
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('normal');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public on(type: any, handler: CallBack) {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on(type, handler);
|
||||
}
|
||||
public off(type: any, handler: CallBack) {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off(type, handler);
|
||||
}
|
||||
|
||||
public emit(type: string, e: any) {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.emit(type, e);
|
||||
}
|
||||
|
||||
public updateData(data: any) {
|
||||
if (this.drawLayers.length === 0) {
|
||||
this.update(data);
|
||||
}
|
||||
this.drawLayers.forEach((layer) => layer.setData(data));
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.removeLayers();
|
||||
}
|
||||
|
||||
public removeLayers() {
|
||||
if (this.drawLayers.length !== 0) {
|
||||
this.drawLayers.forEach((layer) => this.draw.scene.removeLayer(layer));
|
||||
}
|
||||
}
|
||||
public addLayers() {
|
||||
this.drawLayers.forEach((layer) => this.draw.scene.addLayer(layer));
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.drawLayers.forEach((layer) => layer.show());
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.drawLayers.forEach((layer) => layer.hide());
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
import { IInteractionTarget, ILayer, Scene } from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import Draw from '../modes/draw_feature';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('active');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public enableSelect() {
|
||||
this.show();
|
||||
if (this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseMove);
|
||||
layer.on('mouseout', this.onUnMouseMove);
|
||||
if (this.draw.editEnable) {
|
||||
layer.on('click', this.onClick);
|
||||
}
|
||||
layer.on('unclick', this.onUnClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
public disableSelect() {
|
||||
if (!this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseMove);
|
||||
layer.off('mouseout', this.onUnMouseMove);
|
||||
layer.off('click', this.onClick);
|
||||
layer.off('unclick', this.onUnClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
|
||||
public enableEdit() {
|
||||
if (this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('unclick', this.onUnClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
|
||||
public disableEdit() {
|
||||
if (!this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('unclick', this.onUnClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
|
||||
private onMouseMove = (e: any) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.selectMode.enable();
|
||||
};
|
||||
private onUnMouseMove = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.selectMode.disable();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.selectMode.disable();
|
||||
this.draw.editMode.enable();
|
||||
this.disableSelect();
|
||||
this.draw.resetCursor();
|
||||
this.enableEdit();
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.DIRECT_SELECT);
|
||||
};
|
||||
|
||||
private onUnClick = (e: any) => {
|
||||
this.draw.selectMode.disable();
|
||||
this.draw.editMode.disable();
|
||||
this.draw.source.setFeatureUnActive(
|
||||
this.draw.getCurrentFeature() as Feature,
|
||||
);
|
||||
this.disableSelect();
|
||||
this.disableEdit();
|
||||
this.hide();
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.STATIC);
|
||||
};
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
import {
|
||||
feature,
|
||||
Feature,
|
||||
featureCollection,
|
||||
FeatureCollection,
|
||||
Point,
|
||||
Properties,
|
||||
} from '@turf/helpers';
|
||||
import midPoint from '@turf/midpoint';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawVertexLayer extends BaseRender {
|
||||
public update(pointFeatures: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const midFeatures = this.calcMidPointData(pointFeatures);
|
||||
const style = this.draw.getStyle('mid_point');
|
||||
this.drawLayers = renderFeature(midFeatures, style);
|
||||
this.addLayers();
|
||||
this.enableEdit();
|
||||
}
|
||||
public updateData(data: any) {
|
||||
const midFeatures = this.calcMidPointData(data);
|
||||
this.drawLayers.forEach((layer) => layer.setData(midFeatures));
|
||||
}
|
||||
public enableEdit() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseEnter);
|
||||
layer.on('mouseout', this.onMouseOut);
|
||||
layer.on('click', this.onClick);
|
||||
}
|
||||
|
||||
public disableEdit() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseEnter);
|
||||
layer.off('mouseout', this.onMouseOut);
|
||||
layer.off('click', this.onClick);
|
||||
}
|
||||
|
||||
private onMouseEnter = (e: any) => {
|
||||
this.draw.setCursor('pointer');
|
||||
};
|
||||
private onMouseOut = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.addVertex(e.feature);
|
||||
// 添加一个顶点 1.更新顶点 2.更新重点
|
||||
};
|
||||
|
||||
private calcMidPointData(fe: FeatureCollection) {
|
||||
const midFeatures: Feature[] = [];
|
||||
fe.features.forEach((item, index) => {
|
||||
const preFeature = (item as unknown) as Feature<Point, Properties>;
|
||||
if (this.draw.type === 'line' && index === fe.features.length - 1) {
|
||||
return;
|
||||
}
|
||||
const nextFeature =
|
||||
index !== fe.features.length - 1
|
||||
? ((fe.features[index + 1] as unknown) as Feature<Point, Properties>)
|
||||
: ((fe.features[0] as unknown) as Feature<Point, Properties>);
|
||||
// @ts-ignore
|
||||
const point = midPoint(preFeature, nextFeature) as Feature<
|
||||
Point,
|
||||
Properties
|
||||
>;
|
||||
// @ts-ignore
|
||||
point.properties.id = index;
|
||||
midFeatures.push(point);
|
||||
});
|
||||
return featureCollection(midFeatures);
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawResultLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
if (this.drawLayers.length > 0) {
|
||||
this.updateData(feature);
|
||||
return;
|
||||
}
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('normal');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addFilter();
|
||||
this.addLayers();
|
||||
}
|
||||
public enableSelect() {
|
||||
if (this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
if (!this.draw.selectEnable) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('click', this.onClick);
|
||||
this.isEnableDrag = true;
|
||||
}
|
||||
public disableSelect() {
|
||||
if (!this.isEnableDrag) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('click', this.onClick);
|
||||
this.isEnableDrag = false;
|
||||
}
|
||||
public enableDelete() {
|
||||
this.disableSelect();
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('click', this.onDeleteClick);
|
||||
}
|
||||
|
||||
public disableDelete() {
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('click', this.onDeleteClick);
|
||||
}
|
||||
public addFilter() {
|
||||
this.drawLayers.forEach((layer) =>
|
||||
layer.filter('active', (active) => {
|
||||
return !active;
|
||||
}),
|
||||
);
|
||||
}
|
||||
private onClick = (e: any) => {
|
||||
this.draw.source.setFeatureUnActive(
|
||||
this.draw.getCurrentFeature() as Feature,
|
||||
);
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.source.setFeatureActive(e.feature as Feature);
|
||||
this.updateData(this.draw.source.data);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
};
|
||||
|
||||
private onDeleteClick = (e: any) => {
|
||||
this.draw.source.removeFeature(e.feature);
|
||||
this.updateData(this.draw.source.data);
|
||||
};
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
import { FeatureCollection } from '@turf/helpers';
|
||||
import BaseRender from './base_render';
|
||||
import { renderFeature } from './renderFeature';
|
||||
export default class DrawVertexLayer extends BaseRender {
|
||||
public update(feature: FeatureCollection) {
|
||||
this.removeLayers();
|
||||
const style = this.draw.getStyle('active');
|
||||
this.drawLayers = renderFeature(feature, style);
|
||||
this.addLayers();
|
||||
}
|
||||
public enableSelect() {
|
||||
return;
|
||||
}
|
||||
public disableSelect() {
|
||||
return;
|
||||
}
|
||||
|
||||
public enableEdit() {
|
||||
if (this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.on('mouseenter', this.onMouseEnter);
|
||||
layer.on('mouseout', this.onMouseOut);
|
||||
layer.on('click', this.onClick);
|
||||
this.isEnableEdit = true;
|
||||
}
|
||||
|
||||
public disableEdit() {
|
||||
if (!this.isEnableEdit) {
|
||||
return;
|
||||
}
|
||||
const layer = this.drawLayers[0];
|
||||
layer.off('mouseenter', this.onMouseEnter);
|
||||
layer.off('mouseout', this.onMouseOut);
|
||||
layer.off('click', this.onClick);
|
||||
this.isEnableEdit = false;
|
||||
}
|
||||
|
||||
private onMouseEnter = (e: any) => {
|
||||
this.draw.setCursor('move');
|
||||
this.draw.setCurrentVertex(e.feature);
|
||||
this.draw.editMode.enable();
|
||||
};
|
||||
private onMouseOut = (e: any) => {
|
||||
this.draw.resetCursor();
|
||||
this.draw.editMode.disable();
|
||||
};
|
||||
private onClick = (e: any) => {
|
||||
this.draw.setCurrentVertex(e.feature);
|
||||
this.draw.editMode.enable();
|
||||
};
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
import {
|
||||
IInteractionTarget,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopup,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
const InitFeature = {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
import Draw from '../modes/draw_mode';
|
||||
import { DrawEvent, DrawModes } from '../util/constant';
|
||||
export default class RenderLayer {
|
||||
private polygonLayer: ILayer;
|
||||
private lineLayer: ILayer;
|
||||
private draw: Draw;
|
||||
constructor(draw: Draw) {
|
||||
this.draw = draw;
|
||||
this.init();
|
||||
}
|
||||
public init() {
|
||||
const style = this.draw.getStyle('normal_fill');
|
||||
const linestyle = this.draw.getStyle('normal_line');
|
||||
this.polygonLayer = new PolygonLayer({
|
||||
zIndex: 0,
|
||||
})
|
||||
.source(InitFeature)
|
||||
.filter('active', (active) => {
|
||||
return !active;
|
||||
})
|
||||
.shape('fill')
|
||||
.active(true)
|
||||
.color(style.color)
|
||||
.style(style.style);
|
||||
|
||||
this.lineLayer = new LineLayer({
|
||||
zIndex: 1,
|
||||
})
|
||||
.source(InitFeature)
|
||||
.shape('line')
|
||||
.filter('active', (active) => {
|
||||
return !active;
|
||||
})
|
||||
.size(linestyle.size)
|
||||
.color(linestyle.color)
|
||||
.style(linestyle.style);
|
||||
this.draw.scene.addLayer(this.polygonLayer);
|
||||
this.draw.scene.addLayer(this.lineLayer);
|
||||
this.addLayerEvent();
|
||||
}
|
||||
public updateData() {
|
||||
this.lineLayer.setData(this.draw.source.data);
|
||||
this.polygonLayer.setData(this.draw.source.data);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
this.draw.scene.removeLayer(this.lineLayer);
|
||||
this.draw.scene.removeLayer(this.polygonLayer);
|
||||
}
|
||||
|
||||
public show() {
|
||||
this.lineLayer.show();
|
||||
this.polygonLayer.show();
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.lineLayer.hide();
|
||||
this.polygonLayer.hide();
|
||||
}
|
||||
|
||||
private addLayerEvent() {
|
||||
this.polygonLayer.on('click', (e) => {
|
||||
this.draw.setCurrentFeature(e.feature);
|
||||
this.draw.emit(DrawEvent.MODE_CHANGE, DrawModes.SIMPLE_SELECT);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
import { ILayer, LineLayer, PointLayer, PolygonLayer } from '@antv/l7';
|
||||
import { FeatureCollection } from '@turf/helpers';
|
||||
export function renderFeature(fe: FeatureCollection, style: any): ILayer[] {
|
||||
const type = fe.features[0]?.geometry?.type;
|
||||
let layers;
|
||||
switch (type) {
|
||||
case 'Point':
|
||||
layers = drawPoint(fe, style.point);
|
||||
break;
|
||||
case 'LineString':
|
||||
layers = drawLine(fe, style.line);
|
||||
break;
|
||||
case 'Polygon':
|
||||
layers = drawPolyon(fe, style.polygon);
|
||||
break;
|
||||
}
|
||||
return layers as ILayer[];
|
||||
}
|
||||
|
||||
function drawPoint(fe: FeatureCollection, style: any) {
|
||||
const layer = new PointLayer({
|
||||
zIndex: 2,
|
||||
pickingBuffer: 3,
|
||||
})
|
||||
.source(fe)
|
||||
.shape('circle')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style(style.style);
|
||||
return [layer];
|
||||
}
|
||||
|
||||
function drawLine(fe: FeatureCollection, style: any) {
|
||||
const layer = new LineLayer({
|
||||
pickingBuffer: 3,
|
||||
})
|
||||
.source(fe)
|
||||
.shape('line')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style(style.style);
|
||||
return [layer];
|
||||
}
|
||||
|
||||
function drawPolyon(fe: FeatureCollection, style: any) {
|
||||
const fill = new PolygonLayer()
|
||||
.source(fe)
|
||||
.shape('fill')
|
||||
.color(style.color)
|
||||
.size(style.size)
|
||||
.style({
|
||||
opacity: style.style.opacity,
|
||||
});
|
||||
const line = new PolygonLayer()
|
||||
.source(fe)
|
||||
.shape('line')
|
||||
.color(style.style.stroke)
|
||||
.size(style.style.strokeWidth)
|
||||
.style({
|
||||
opacity: style.style.strokeOpacity,
|
||||
lineType: style.style.lineType,
|
||||
dashArray: style.style.dashArray,
|
||||
});
|
||||
return [fill, line];
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
import { Feature, FeatureCollection } from '@turf/helpers';
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
export default class DrawSource {
|
||||
public data: FeatureCollection;
|
||||
constructor(data?: FeatureCollection) {
|
||||
this.data = data || this.getDefaultData();
|
||||
}
|
||||
|
||||
public addFeature(feature: any) {
|
||||
this.data.features.push(feature);
|
||||
}
|
||||
|
||||
public getData(): FeatureCollection {
|
||||
const features = cloneDeep(this.data.features).map((feature: Feature) => {
|
||||
feature.properties = {
|
||||
id: feature?.properties?.id,
|
||||
type: feature?.properties?.type,
|
||||
};
|
||||
return feature;
|
||||
});
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features,
|
||||
};
|
||||
}
|
||||
|
||||
public getFeature(id: string): Feature | undefined {
|
||||
const result = this.data.features.find((fe: Feature) => {
|
||||
return fe?.properties?.id === id;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
public removeAllFeatures() {
|
||||
this.data = this.getDefaultData();
|
||||
}
|
||||
public removeFeature(feature: Feature) {
|
||||
const index = this.getFeatureIndex(feature);
|
||||
if (index !== undefined) {
|
||||
this.data.features.splice(index, 1);
|
||||
}
|
||||
}
|
||||
public setFeatureActive(feature: Feature) {
|
||||
const fe = this.getFeature(feature?.properties?.id);
|
||||
if (fe && fe.properties) {
|
||||
fe.properties.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
public setFeatureUnActive(feature: Feature) {
|
||||
const fe = this.getFeature(feature?.properties?.id);
|
||||
if (fe && fe.properties) {
|
||||
fe.properties.active = false;
|
||||
}
|
||||
}
|
||||
public clearFeatureActive() {
|
||||
this.data.features.forEach((fe: Feature) => {
|
||||
if (fe && fe.properties) {
|
||||
fe.properties.active = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
public updateFeature(feature: Feature) {
|
||||
this.removeFeature(feature);
|
||||
this.addFeature(feature);
|
||||
}
|
||||
public destroy() {
|
||||
this.data = this.getDefaultData();
|
||||
}
|
||||
private getDefaultData(): FeatureCollection {
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: [],
|
||||
};
|
||||
}
|
||||
|
||||
private getFeatureIndex(feature: Feature): number | undefined {
|
||||
return this.data.features.findIndex((fe) => {
|
||||
return fe?.properties?.id === feature?.properties?.id;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
export enum DrawEvent {
|
||||
CREATE = 'draw.create',
|
||||
DELETE = 'draw.delete',
|
||||
Move = 'draw.move',
|
||||
Edit = 'draw.edit',
|
||||
UPDATE = 'draw.update',
|
||||
CHANGE = 'draw.change',
|
||||
SELECTION_CHANGE = 'draw.selectionchange',
|
||||
MODE_CHANGE = 'draw.modechange',
|
||||
ACTIONABLE = 'draw.actionable',
|
||||
RENDER = 'draw.render',
|
||||
COMBINE_FEATURES = 'draw.combine',
|
||||
UNCOMBINE_FEATURES = 'draw.uncombine',
|
||||
}
|
||||
|
||||
export enum DrawModes {
|
||||
DRAW_Circle = 'draw_circle',
|
||||
DRAW_Rect = 'draw_react',
|
||||
DRAW_LINE_STRING = 'draw_line_string',
|
||||
DRAW_POLYGON = 'draw_polygon',
|
||||
DRAW_POINT = 'draw_point',
|
||||
SIMPLE_SELECT = 'simple_select',
|
||||
DIRECT_SELECT = 'direct_select',
|
||||
STATIC = 'static',
|
||||
}
|
||||
|
||||
export type unitsType = 'degrees' | 'radians' | 'miles' | 'kilometers';
|
||||
|
||||
export enum FeatureType {
|
||||
FEATURE = 'Feature',
|
||||
POLYGON = 'Polygon',
|
||||
LINE_STRING = 'LineString',
|
||||
POINT = 'Point',
|
||||
FEATURE_COLLECTION = 'FeatureCollection',
|
||||
MULTI_PREFIX = 'Multi',
|
||||
MULTI_POINT = 'MultiPoint',
|
||||
MULTI_LINE_STRING = 'MultiLineString',
|
||||
MULTI_POLYGON = 'MultiPolygon',
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
import turfCircle from '@turf/circle';
|
||||
import turfDistance from '@turf/distance';
|
||||
import {
|
||||
Feature,
|
||||
featureCollection,
|
||||
FeatureCollection,
|
||||
lineString,
|
||||
point,
|
||||
polygon,
|
||||
} from '@turf/helpers';
|
||||
import { unitsType } from './constant';
|
||||
|
||||
export function createCircle(
|
||||
center: [number, number],
|
||||
endPoint: [number, number],
|
||||
options: {
|
||||
units: unitsType;
|
||||
steps: number;
|
||||
id: string;
|
||||
pointFeatures: Feature[];
|
||||
},
|
||||
): Feature {
|
||||
const radius = turfDistance(point(center), point(endPoint), options);
|
||||
const feature = turfCircle(center, radius, {
|
||||
units: options.units,
|
||||
steps: options.steps,
|
||||
properties: {
|
||||
...options,
|
||||
active: true,
|
||||
type: 'circle',
|
||||
radius,
|
||||
startPoint: {
|
||||
lng: center[0],
|
||||
lat: center[1],
|
||||
},
|
||||
endPoint: {
|
||||
lng: endPoint[0],
|
||||
lat: endPoint[1],
|
||||
},
|
||||
},
|
||||
});
|
||||
return feature as Feature;
|
||||
}
|
||||
|
||||
export function createRect(
|
||||
startPoint: [number, number],
|
||||
endPoint: [number, number],
|
||||
options: {
|
||||
id: string;
|
||||
pointFeatures: Feature[];
|
||||
[key: string]: any;
|
||||
},
|
||||
): Feature {
|
||||
const minX = Math.min(startPoint[0], endPoint[0]);
|
||||
const minY = Math.min(startPoint[1], endPoint[1]);
|
||||
const maxX = Math.max(startPoint[0], endPoint[0]);
|
||||
const maxY = Math.max(startPoint[1], endPoint[1]);
|
||||
const feature = {
|
||||
type: 'Feature',
|
||||
properties: {
|
||||
type: 'rect',
|
||||
active: true,
|
||||
startPoint: {
|
||||
lng: startPoint[0],
|
||||
lat: startPoint[1],
|
||||
},
|
||||
endPoint: {
|
||||
lng: endPoint[0],
|
||||
lat: endPoint[1],
|
||||
},
|
||||
...options,
|
||||
},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: [
|
||||
[
|
||||
[minX, minY],
|
||||
[minX, maxY],
|
||||
[maxX, maxY],
|
||||
[maxX, minY],
|
||||
[minX, minY],
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
return feature as Feature;
|
||||
}
|
||||
|
||||
export function createPolygon(
|
||||
points: Array<{ lng: number; lat: number }>,
|
||||
options: {
|
||||
id?: string | number;
|
||||
pointFeatures: Feature[];
|
||||
[key: string]: any;
|
||||
},
|
||||
): any {
|
||||
const coords = points.map((p) => [p.lng, p.lat]);
|
||||
if (points.length < 2) {
|
||||
return point(coords[0], options);
|
||||
} else if (points.length < 3) {
|
||||
return lineString(coords, options);
|
||||
} else {
|
||||
coords.push(coords[0]);
|
||||
return polygon([coords], options);
|
||||
}
|
||||
}
|
||||
|
||||
export function createLine(
|
||||
points: Array<{ lng: number; lat: number }>,
|
||||
options: any,
|
||||
): any {
|
||||
const coords = points.map((p) => [p.lng, p.lat]);
|
||||
if (points.length < 2) {
|
||||
return point(coords[0], options);
|
||||
} else {
|
||||
return lineString(coords, options);
|
||||
}
|
||||
}
|
||||
|
||||
export function createPoint(
|
||||
points: Array<{ lng: number; lat: number }>,
|
||||
): FeatureCollection {
|
||||
const features = points.map((p, index) =>
|
||||
point([p.lng, p.lat], {
|
||||
active: true,
|
||||
id: index.toString(),
|
||||
}),
|
||||
);
|
||||
return featureCollection(features);
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
const LayerStyles = {
|
||||
active: {
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 5,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
color: '#fbb03b',
|
||||
size: 1,
|
||||
style: {
|
||||
opacity: 1,
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
polygon: {
|
||||
shape: 'fill',
|
||||
color: '#fbb03b',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
stroke: '#fbb03b',
|
||||
strokeWidth: 1,
|
||||
strokeOpacity: 1,
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
},
|
||||
normal: {
|
||||
polygon: {
|
||||
type: 'PolygonLayer',
|
||||
shape: 'fill',
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 0.1,
|
||||
stroke: '#3bb2d0',
|
||||
strokeWidth: 1,
|
||||
strokeOpacity: 1,
|
||||
lineType: 'solid',
|
||||
dashArray: [2, 2],
|
||||
},
|
||||
},
|
||||
line: {
|
||||
type: 'LineLayer',
|
||||
shape: 'line',
|
||||
size: 1,
|
||||
color: '#3bb2d0',
|
||||
style: {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#3bb2d0',
|
||||
size: 3,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
normal_point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#3bb2d0',
|
||||
size: 3,
|
||||
style: {
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
},
|
||||
},
|
||||
mid_point: {
|
||||
point: {
|
||||
type: 'PointLayer',
|
||||
shape: 'circle',
|
||||
color: '#fbb03b',
|
||||
size: 3,
|
||||
style: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default LayerStyles;
|
|
@ -1,52 +0,0 @@
|
|||
import { Feature, Geometry, Properties } from '@turf/helpers';
|
||||
import { FeatureType } from './constant';
|
||||
interface IDelta {
|
||||
lng: number;
|
||||
lat: number;
|
||||
}
|
||||
type RingType = Array<[number, number]>;
|
||||
export default function(features: Feature[], delta: IDelta) {
|
||||
features.forEach((feature) => {
|
||||
const geometry = feature.geometry as Geometry;
|
||||
let nextCoord;
|
||||
const { type, coordinates } = geometry;
|
||||
switch (type) {
|
||||
case FeatureType.POINT:
|
||||
nextCoord = movePoint(coordinates as [number, number], delta);
|
||||
break;
|
||||
case FeatureType.LINE_STRING:
|
||||
case FeatureType.MULTI_POINT:
|
||||
nextCoord = moveRing(coordinates as RingType, delta);
|
||||
break;
|
||||
case FeatureType.POLYGON:
|
||||
case FeatureType.MULTI_LINE_STRING:
|
||||
nextCoord = moveMultiPolygon(coordinates as RingType[], delta);
|
||||
break;
|
||||
case FeatureType.MULTI_POLYGON:
|
||||
nextCoord = (coordinates as RingType[][]).map((mult) =>
|
||||
moveMultiPolygon(mult as RingType[], delta),
|
||||
);
|
||||
break;
|
||||
}
|
||||
if (nextCoord) {
|
||||
geometry.coordinates = nextCoord;
|
||||
}
|
||||
});
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
export function movePoint(
|
||||
coord: [number, number],
|
||||
delta: IDelta,
|
||||
): [number, number] {
|
||||
return [coord[0] + delta.lng, coord[1] + delta.lat];
|
||||
}
|
||||
|
||||
export function moveRing(coords: RingType, delta: IDelta) {
|
||||
return coords.map((coord) => movePoint(coord, delta));
|
||||
}
|
||||
|
||||
export function moveMultiPolygon(mult: RingType[], delta: IDelta) {
|
||||
return mult.map((ring) => moveRing(ring, delta));
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"declarationDir": "./es",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.1.12](https://github.com/antvis/L7/compare/v2.1.11...v2.1.12) (2020-04-10)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.11](https://github.com/antvis/L7/compare/v2.1.10...v2.1.11) (2020-04-07)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.8](https://github.com/antvis/L7/compare/v2.1.7...v2.1.8) (2020-03-26)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.7](https://github.com/antvis/L7/compare/v2.1.6...v2.1.7) (2020-03-26)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.5](https://github.com/antvis/L7/compare/v2.1.4...v2.1.5) (2020-03-20)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.3](https://github.com/antvis/L7/compare/v2.0.36...v2.1.3) (2020-03-17)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/antvis/L7/compare/v2.0.36...v2.1.2) (2020-03-15)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.1](https://github.com/antvis/L7/compare/v2.0.36...v2.1.1) (2020-03-15)
|
||||
|
||||
**Note:** Version bump only for package @antv/l7-react
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.34](https://github.com/antvis/L7/compare/v2.0.32...v2.0.34) (2020-03-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix map reference ([79e16f5](https://github.com/antvis/L7/commit/79e16f5393c6c31cc088e946dc865cdddfde9b73))
|
|
@ -1,10 +0,0 @@
|
|||
# `react`
|
||||
|
||||
> L7
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
import { Scene } from '@antv/l7-react';
|
||||
|
||||
```
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"name": "@antv/l7-react",
|
||||
"version": "2.2.37",
|
||||
"description": "",
|
||||
"main": "lib/index.js",
|
||||
"module": "es/index.js",
|
||||
"types": "es/index.d.ts",
|
||||
"sideEffects": true,
|
||||
"files": [
|
||||
"lib",
|
||||
"es",
|
||||
"README.md"
|
||||
],
|
||||
"scripts": {
|
||||
"tsc": "tsc --project tsconfig.build.json",
|
||||
"clean": "rimraf dist; rimraf es; rimraf lib;",
|
||||
"build": "run-p build:*",
|
||||
"build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments",
|
||||
"lint:ts": "run-p -c lint:ts-*",
|
||||
"test": "jest",
|
||||
"sync": "tnpm sync"
|
||||
},
|
||||
"author": "lzxue",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@antv/l7": "2.2.37",
|
||||
"@antv/l7-maps": "2.2.37",
|
||||
"@babel/runtime": "^7.7.7",
|
||||
"load-styles": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.10.2"
|
||||
},
|
||||
"gitHead": "20154fe30d512024b03ac5e40f77731bc0580bb0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
import { IMapConfig, ISceneConfig, Scene } from '@antv/l7';
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import { GaodeMap } from '@antv/l7-maps';
|
||||
import React, { createElement, createRef, useEffect, useState } from 'react';
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IMapSceneConig {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
map: Partial<IMapConfig>;
|
||||
option?: Partial<ISceneConfig>;
|
||||
children?: React.ReactNode;
|
||||
onSceneLoaded?: (scene: Scene) => void;
|
||||
}
|
||||
const AMapScene = React.memo((props: IMapSceneConig) => {
|
||||
const { style, className, map, option, onSceneLoaded } = props;
|
||||
const container = createRef();
|
||||
const [scene, setScene] = useState<Scene>();
|
||||
useEffect(() => {
|
||||
const sceneInstance = new Scene({
|
||||
id: container.current as HTMLDivElement,
|
||||
...option,
|
||||
map: new GaodeMap(map),
|
||||
});
|
||||
sceneInstance.on('loaded', () => {
|
||||
setScene(sceneInstance);
|
||||
if (onSceneLoaded) {
|
||||
onSceneLoaded(sceneInstance);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
sceneInstance.destroy();
|
||||
};
|
||||
}, []);
|
||||
// 更新地图样式
|
||||
useEffect(() => {
|
||||
if (scene && map.style) {
|
||||
scene.setMapStyle(map.style);
|
||||
}
|
||||
}, [JSON.stringify(map.style)]);
|
||||
|
||||
useEffect(() => {
|
||||
if (scene && map.zoom) {
|
||||
scene.setZoom(map.zoom);
|
||||
}
|
||||
}, [map.zoom]);
|
||||
|
||||
useEffect(() => {
|
||||
if (scene && map.center) {
|
||||
scene.setCenter(map.center);
|
||||
}
|
||||
}, [JSON.stringify(map.center)]);
|
||||
useEffect(() => {
|
||||
if (scene && map.pitch) {
|
||||
scene.setPitch(map.pitch);
|
||||
}
|
||||
}, [map.pitch]);
|
||||
useEffect(() => {
|
||||
if (scene && map.rotation) {
|
||||
scene.setRotation(map.rotation);
|
||||
}
|
||||
}, [map.rotation]);
|
||||
return (
|
||||
<SceneContext.Provider value={scene}>
|
||||
{createElement(
|
||||
'div',
|
||||
{
|
||||
ref: container,
|
||||
style,
|
||||
className,
|
||||
},
|
||||
scene && props.children,
|
||||
)}
|
||||
</SceneContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
export default AMapScene;
|
|
@ -1,39 +0,0 @@
|
|||
import { IControl, Logo, PositionName, Scale, Scene, Zoom } from '@antv/l7';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
interface IControlProps {
|
||||
type: 'scale' | 'zoom' | 'logo';
|
||||
position: PositionName;
|
||||
[key: string]: any;
|
||||
}
|
||||
export default React.memo(function MapControl(props: IControlProps) {
|
||||
const scene = (useSceneValue() as unknown) as Scene;
|
||||
const [, setControl] = useState();
|
||||
const { type, position } = props;
|
||||
useEffect(() => {
|
||||
let ctr: IControl;
|
||||
switch (type) {
|
||||
case 'scale':
|
||||
ctr = new Scale({
|
||||
position: position || 'bottomright',
|
||||
});
|
||||
break;
|
||||
case 'zoom':
|
||||
ctr = new Zoom({
|
||||
position: position || 'topright',
|
||||
});
|
||||
break;
|
||||
case 'logo':
|
||||
ctr = new Logo({
|
||||
position: position || 'bottomleft',
|
||||
});
|
||||
}
|
||||
setControl(ctr);
|
||||
scene.addControl(ctr);
|
||||
return () => {
|
||||
scene.removeControl(ctr);
|
||||
};
|
||||
}, [type, position]);
|
||||
|
||||
return null;
|
||||
});
|
|
@ -1,44 +0,0 @@
|
|||
import { Control, PositionName, Scene } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
const { useEffect, useState } = React;
|
||||
|
||||
interface IColorLegendProps {
|
||||
position: PositionName;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>;
|
||||
}
|
||||
|
||||
export default function CustoonConrol(props: IColorLegendProps) {
|
||||
const { className, style, children, position } = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
const el = document.createElement('div');
|
||||
useEffect(() => {
|
||||
const custom = new Control({
|
||||
position,
|
||||
});
|
||||
custom.onAdd = () => {
|
||||
if (className) {
|
||||
el.className = className;
|
||||
}
|
||||
if (style) {
|
||||
const cssText = Object.keys(style)
|
||||
.map((key: string) => {
|
||||
// @ts-ignore
|
||||
return `${key}:${style[key]}`;
|
||||
})
|
||||
.join(';');
|
||||
el.style.cssText = cssText;
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
mapScene.addControl(custom);
|
||||
return () => {
|
||||
mapScene.removeControl(custom);
|
||||
};
|
||||
}, []);
|
||||
return createPortal(children, el);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
import * as React from 'react';
|
||||
import { ILayerProps } from './LayerAttribute';
|
||||
import BaseLayer from './LayerAttribute/Layer';
|
||||
|
||||
const PolygonLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('polygonLayer', props);
|
||||
});
|
||||
|
||||
const LineLayer = React.memo(function Layer(props: ILayerProps) {
|
||||
return BaseLayer('lineLayer', props);
|
||||
});
|
||||
|
||||
const PointLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('pointLayer', props);
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
const ImageLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('imagelayer', props);
|
||||
});
|
||||
|
||||
const CityBuildingLayer = React.memo(function Layer(
|
||||
props: ILayerProps & { children?: any },
|
||||
) {
|
||||
return BaseLayer('citybuildinglayer', props);
|
||||
});
|
||||
|
||||
export {
|
||||
PolygonLayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
HeatmapLayer,
|
||||
RasterLayer,
|
||||
ImageLayer,
|
||||
CityBuildingLayer,
|
||||
};
|
|
@ -1,17 +0,0 @@
|
|||
import { IActiveOption, ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
active: {
|
||||
option: IActiveOption | boolean;
|
||||
};
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, active } = props;
|
||||
useEffect(() => {
|
||||
layer.active(active.option);
|
||||
}, [JSON.stringify(active)]);
|
||||
return null;
|
||||
});
|
|
@ -1,16 +0,0 @@
|
|||
import { IAnimateOption, ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IStyleOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
animate: Partial<IAnimateOption>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, animate } = props;
|
||||
useEffect(() => {
|
||||
layer.animate(animate);
|
||||
}, [JSON.stringify(animate)]);
|
||||
return null;
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
import { ILayer, StyleAttrField } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IAttributeOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
color: Partial<IAttributeOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, color } = props;
|
||||
useEffect(() => {
|
||||
color.field
|
||||
? layer.color(color.field as StyleAttrField, color.values)
|
||||
: layer.color(color.values as StyleAttrField);
|
||||
}, [color.field, color.scale, JSON.stringify(color.values), JSON.stringify(color.options)]);
|
||||
|
||||
return null;
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
import { ILayer, StyleAttrField } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IAttributeOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
filter: Partial<IAttributeOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, filter } = props;
|
||||
useEffect(() => {
|
||||
if (filter.field) {
|
||||
layer.filter(filter.field as string, filter.values as StyleAttrField);
|
||||
}
|
||||
}, [filter.field, filter.values, JSON.stringify(filter.values), JSON.stringify(filter.options)]);
|
||||
return null;
|
||||
});
|
|
@ -1,132 +0,0 @@
|
|||
import {
|
||||
CityBuildingLayer,
|
||||
HeatmapLayer,
|
||||
ILayer,
|
||||
ImageLayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
RasterLayer,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { LayerContext } from '../LayerContext';
|
||||
import { useSceneValue } from '../SceneContext';
|
||||
import {
|
||||
Active,
|
||||
Animate,
|
||||
Color,
|
||||
Filter,
|
||||
ILayerProps,
|
||||
Scale,
|
||||
Select,
|
||||
Shape,
|
||||
Size,
|
||||
Source,
|
||||
Style,
|
||||
} from './';
|
||||
|
||||
const { useEffect, useState } = React;
|
||||
|
||||
export default function BaseLayer(type: string, props: ILayerProps) {
|
||||
const {
|
||||
source,
|
||||
color,
|
||||
shape,
|
||||
style,
|
||||
size,
|
||||
scale,
|
||||
active,
|
||||
select,
|
||||
filter,
|
||||
animate,
|
||||
options,
|
||||
onLayerLoaded,
|
||||
} = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
const [layer, setLayer] = useState<ILayer>();
|
||||
if (!layer) {
|
||||
let l: ILayer;
|
||||
switch (type) {
|
||||
case 'polygonLayer':
|
||||
l = new PolygonLayer(options);
|
||||
break;
|
||||
case 'lineLayer':
|
||||
l = new LineLayer(options);
|
||||
break;
|
||||
case 'pointLayer':
|
||||
l = new PointLayer(options);
|
||||
break;
|
||||
case 'heatmapLayer':
|
||||
l = new HeatmapLayer(options);
|
||||
break;
|
||||
case 'rasterLayer':
|
||||
l = new RasterLayer(options);
|
||||
break;
|
||||
case 'imageLayer':
|
||||
l = new ImageLayer(options);
|
||||
break;
|
||||
case 'citybuildingLayer':
|
||||
l = new CityBuildingLayer(options);
|
||||
break;
|
||||
default:
|
||||
l = new PolygonLayer(options);
|
||||
}
|
||||
l.on('inited', () => {
|
||||
if (onLayerLoaded) {
|
||||
onLayerLoaded(l, mapScene);
|
||||
}
|
||||
});
|
||||
setLayer(l);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (layer !== undefined) {
|
||||
mapScene.addLayer(layer as ILayer);
|
||||
return () => {
|
||||
mapScene.removeLayer(layer as ILayer);
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
// 重绘layer
|
||||
if (layer) {
|
||||
mapScene.render();
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited && options) {
|
||||
layer.updateLayerConfig(options);
|
||||
}
|
||||
}, [options?.minZoom, options?.maxZoom, options?.visible]);
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited && options && options.zIndex) {
|
||||
layer.setIndex(options.zIndex);
|
||||
}
|
||||
}, [options?.zIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (layer && layer.inited && options && options.blend) {
|
||||
layer.setBlend(options.blend);
|
||||
}
|
||||
}, [options?.blend]);
|
||||
|
||||
return layer !== null && layer !== undefined ? (
|
||||
<LayerContext.Provider value={layer}>
|
||||
<Source layer={layer} source={source} />
|
||||
{scale && <Scale layer={layer} scale={scale} />}
|
||||
{color && <Color layer={layer} color={color} />}
|
||||
{size && <Size layer={layer} size={size} />}
|
||||
{shape && <Shape layer={layer} shape={shape} />}
|
||||
{style && <Style layer={layer} style={style} />}
|
||||
{active && <Active layer={layer} active={active} />}
|
||||
{select && <Select layer={layer} select={select} />}
|
||||
{filter && <Filter layer={layer} filter={filter} />}
|
||||
{animate && <Animate layer={layer} animate={animate} />}
|
||||
{/* LayerContext主要传入LayerEvent组件 */}
|
||||
{props.children}
|
||||
</LayerContext.Provider>
|
||||
) : null;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
import { ILayer, IScale, IScaleOptions } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IScaleAttributeOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
scale: Partial<IScaleAttributeOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, scale } = props;
|
||||
useEffect(() => {
|
||||
layer.scale(scale.values as IScaleOptions);
|
||||
}, [scale.values]);
|
||||
return null;
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
import { IActiveOption, ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
select: {
|
||||
option: IActiveOption | boolean;
|
||||
};
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, select } = props;
|
||||
useEffect(() => {
|
||||
layer.select(select.option);
|
||||
}, [JSON.stringify(select)]);
|
||||
return null;
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
import { ILayer, StyleAttrField } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IAttributeOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
shape: Partial<IAttributeOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, shape } = props;
|
||||
useEffect(() => {
|
||||
shape.field
|
||||
? layer.shape(shape.field, shape.values)
|
||||
: layer.shape(shape.values as StyleAttrField);
|
||||
}, [shape.field, JSON.stringify(shape.values), JSON.stringify(shape.options)]);
|
||||
return null;
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
import { ILayer, StyleAttrField } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IAttributeOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
size: Partial<IAttributeOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, size } = props;
|
||||
useEffect(() => {
|
||||
size.field
|
||||
? layer.size(size.field, size.values)
|
||||
: layer.size(size.values as StyleAttrField);
|
||||
}, [size.field, size.scale, JSON.stringify(size.values), JSON.stringify(size.options)]);
|
||||
return null;
|
||||
});
|
|
@ -1,25 +0,0 @@
|
|||
import { ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { ISourceOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ISourceProps {
|
||||
layer: ILayer;
|
||||
source: Partial<ISourceOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ISourceProps) {
|
||||
const { layer, source } = props;
|
||||
const { data, ...sourceOption } = source;
|
||||
|
||||
useEffect(() => {
|
||||
if (!layer.inited) {
|
||||
layer.source(data, sourceOption);
|
||||
} else {
|
||||
layer.setData(data, sourceOption);
|
||||
}
|
||||
if (sourceOption.autoFit) {
|
||||
layer.fitBounds(sourceOption && sourceOption.fitBoundsOptions);
|
||||
}
|
||||
}, [data, JSON.stringify(sourceOption)]);
|
||||
return null;
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
import { ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { IStyleOptions } from './';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
layer: ILayer;
|
||||
style: Partial<IStyleOptions>;
|
||||
}
|
||||
export default React.memo(function Chart(props: ILayerProps) {
|
||||
const { layer, style } = props;
|
||||
useEffect(
|
||||
() => {
|
||||
layer.style(style);
|
||||
},
|
||||
Object.keys(style).map((key) => style[key]),
|
||||
);
|
||||
return null;
|
||||
});
|
|
@ -1,97 +0,0 @@
|
|||
import {
|
||||
BlendType,
|
||||
IActiveOption,
|
||||
IAnimateOption,
|
||||
ILayer,
|
||||
IScale,
|
||||
IScaleOptions,
|
||||
ISourceCFG,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import Active from './Active';
|
||||
import Animate from './Animate';
|
||||
import Color from './Color';
|
||||
import Filter from './Filter';
|
||||
import Scale from './Scale';
|
||||
import Select from './Select';
|
||||
import Shape from './Shape';
|
||||
import Size from './Size';
|
||||
import Source from './Source';
|
||||
import Style from './Style';
|
||||
|
||||
type CallBack = (...args: any[]) => any;
|
||||
|
||||
export interface IAttributeOptions {
|
||||
field: string;
|
||||
value: string | number;
|
||||
values: string[] | number[] | string | number | CallBack;
|
||||
scale?: string;
|
||||
blend: keyof typeof BlendType;
|
||||
options?: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IScaleAttributeOptions {
|
||||
field: string | IScaleOptions;
|
||||
value: IScale;
|
||||
values: IScaleOptions | IScale;
|
||||
}
|
||||
export interface ILayerOption {
|
||||
name?: string;
|
||||
visible: boolean;
|
||||
zIndex: number;
|
||||
minZoom: number;
|
||||
maxZoom: number;
|
||||
autoFit: boolean;
|
||||
blend: keyof typeof BlendType;
|
||||
[key: string]: any;
|
||||
}
|
||||
export interface IScaleOption {
|
||||
[key: string]: IScaleAttributeOptions;
|
||||
}
|
||||
export interface IStyleOptions {
|
||||
opacity: number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface ISourceOptions extends ISourceCFG {
|
||||
data: any;
|
||||
// 每次更新数据之后是否自适应缩放
|
||||
autoFit?: boolean;
|
||||
// Mapbox 自适应的参数
|
||||
fitBoundsOptions?: any;
|
||||
}
|
||||
|
||||
export interface IActiveOptions {
|
||||
option: IActiveOption | boolean;
|
||||
}
|
||||
export interface ILayerProps {
|
||||
options?: Partial<ILayerOption>;
|
||||
source: ISourceOptions;
|
||||
color: Partial<IAttributeOptions>;
|
||||
shape: Partial<IAttributeOptions>;
|
||||
scale?: Partial<IScaleAttributeOptions>;
|
||||
size?: Partial<IAttributeOptions>;
|
||||
style?: Partial<IStyleOptions>;
|
||||
active?: IActiveOptions;
|
||||
select?: IActiveOptions;
|
||||
filter?: Partial<IAttributeOptions>;
|
||||
animate?: Partial<IAnimateOption>;
|
||||
onLayerLoaded?: (layer: ILayer, scene: Scene) => void;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export {
|
||||
Active,
|
||||
Color,
|
||||
Filter,
|
||||
Source,
|
||||
Size,
|
||||
Shape,
|
||||
Style,
|
||||
Scale,
|
||||
Select,
|
||||
Animate,
|
||||
};
|
|
@ -1,8 +0,0 @@
|
|||
import { ILayer } from '@antv/l7';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||
export const LayerContext = createContext<ILayer | undefined>({} as ILayer);
|
||||
export function useLayerValue(): ILayer {
|
||||
return (useContext(LayerContext) as unknown) as ILayer;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import { ILayer } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { useLayerValue } from './LayerContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
type: string;
|
||||
handler: (...args: any[]) => void;
|
||||
}
|
||||
export const LayerEvent = React.memo((props: ILayerProps) => {
|
||||
const { type, handler } = props;
|
||||
const layer = (useLayerValue() as unknown) as ILayer;
|
||||
|
||||
useEffect(() => {
|
||||
layer.off(type, handler);
|
||||
layer.on(type, handler);
|
||||
return () => {
|
||||
layer.off(type, handler);
|
||||
};
|
||||
}, [type, handler]);
|
||||
return null;
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
import * as React from 'react';
|
||||
interface IColorLegendProps {
|
||||
items?: any[];
|
||||
title: string;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
import './style.css';
|
||||
export const ColorComponent = React.memo((props: IColorLegendProps) => {
|
||||
const { className, style, title } = props;
|
||||
const items = [
|
||||
{ title: '1', color: 'rgb(239,243,255)' },
|
||||
{ title: '10', color: 'rgb(198,219,239)' },
|
||||
{ title: '30', color: 'rgb(158,202,225)' },
|
||||
{ title: '50', color: 'rgb(107,174,214)' },
|
||||
{ title: '60', color: 'rgb(49,130,189)' },
|
||||
{ title: '100', color: 'rgb(8,81,156)' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
{items.map((c, i) => {
|
||||
return (
|
||||
<div
|
||||
key={i.toString()}
|
||||
style={{
|
||||
background: c.color,
|
||||
height: '100%',
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer',
|
||||
width: '' + (100.0 - items.length) / items.length + '%',
|
||||
marginRight: '1%',
|
||||
padding: 5,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
{items.map((c, i) => {
|
||||
return (
|
||||
<div
|
||||
key={i.toString() + '122'}
|
||||
style={{
|
||||
background: '#fff',
|
||||
height: '100%',
|
||||
display: 'inline-block',
|
||||
textAlign: 'left',
|
||||
cursor: 'pointer',
|
||||
width: '' + (100.0 - items.length) / items.length + '%',
|
||||
marginRight: '1%',
|
||||
}}
|
||||
>
|
||||
{c.title}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
.color {
|
||||
color:'red';
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
import { IActiveOption, IImage, ILayer, Scene } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILoadImageProps {
|
||||
name: string;
|
||||
url: IImage;
|
||||
}
|
||||
export default React.memo(function LoadImage(props: ILoadImageProps) {
|
||||
const { name, url } = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
useEffect(() => {
|
||||
mapScene.addImage(name, url);
|
||||
}, [name, url]);
|
||||
return null;
|
||||
});
|
|
@ -1,82 +0,0 @@
|
|||
import { IMapConfig, ISceneConfig, Scene, Zoom } from '@antv/l7';
|
||||
// @ts-ignore
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import { Mapbox } from '@antv/l7-maps';
|
||||
import React, { createElement, createRef, useEffect, useState } from 'react';
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IMapSceneConig {
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
map: Partial<IMapConfig>;
|
||||
option?: Partial<ISceneConfig>;
|
||||
children?: React.ReactNode;
|
||||
onSceneLoaded?: (scene: Scene) => void;
|
||||
}
|
||||
const MapboxScene = React.memo((props: IMapSceneConig) => {
|
||||
const { style, className, map, option, onSceneLoaded } = props;
|
||||
const container = createRef();
|
||||
const [scene, setScene] = useState<Scene>();
|
||||
|
||||
// 地图初始
|
||||
useEffect(() => {
|
||||
const sceneInstance = new Scene({
|
||||
id: container.current as HTMLDivElement,
|
||||
...option,
|
||||
map: new Mapbox(map),
|
||||
});
|
||||
sceneInstance.on('loaded', () => {
|
||||
setScene(sceneInstance);
|
||||
if (onSceneLoaded) {
|
||||
onSceneLoaded(sceneInstance);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
sceneInstance.destroy();
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 更新地图样式
|
||||
useEffect(() => {
|
||||
if (scene && map.style) {
|
||||
scene.setMapStyle(map.style);
|
||||
}
|
||||
}, [JSON.stringify(map.style)]);
|
||||
|
||||
useEffect(() => {
|
||||
if (scene && map.zoom) {
|
||||
scene.setZoom(map.zoom);
|
||||
}
|
||||
}, [map.zoom]);
|
||||
|
||||
useEffect(() => {
|
||||
if (scene && map.center) {
|
||||
scene.setCenter(map.center);
|
||||
}
|
||||
}, [JSON.stringify(map.center)]);
|
||||
useEffect(() => {
|
||||
if (scene && map.pitch) {
|
||||
scene.setPitch(map.pitch);
|
||||
}
|
||||
}, [map.pitch]);
|
||||
useEffect(() => {
|
||||
if (scene && map.rotation) {
|
||||
scene.setRotation(map.rotation);
|
||||
}
|
||||
}, [map.rotation]);
|
||||
|
||||
return (
|
||||
<SceneContext.Provider value={scene}>
|
||||
{createElement(
|
||||
'div',
|
||||
{
|
||||
ref: container,
|
||||
style,
|
||||
className,
|
||||
},
|
||||
scene && props.children,
|
||||
)}
|
||||
</SceneContext.Provider>
|
||||
);
|
||||
});
|
||||
|
||||
export default MapboxScene;
|
|
@ -1,73 +0,0 @@
|
|||
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[];
|
||||
onMarkerLoaded?: (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, onMarkerLoaded } = 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 (onMarkerLoaded) {
|
||||
onMarkerLoaded(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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
import {
|
||||
IActiveOption,
|
||||
IImage,
|
||||
ILayer,
|
||||
ILngLat,
|
||||
IPopupOption,
|
||||
Popup,
|
||||
Scene,
|
||||
} from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IPopupProps {
|
||||
option?: Partial<IPopupOption>;
|
||||
lnglat: number[] | { lng: number; lat: number };
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
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,
|
||||
stopPropagation: false,
|
||||
});
|
||||
|
||||
if (lnglat) {
|
||||
p.setLnglat(lnglat);
|
||||
}
|
||||
if (children) {
|
||||
p.setDOMContent(this.el);
|
||||
}
|
||||
this.popup = p;
|
||||
this.scene.addPopup(p);
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: IPopupProps) {
|
||||
// @ts-ignore
|
||||
const preLnglat = Array.isArray(prevProps.lnglat)
|
||||
? prevProps.lnglat
|
||||
: [prevProps?.lnglat?.lng, prevProps?.lnglat?.lat];
|
||||
const nowLnglat = Array.isArray(this.props.lnglat)
|
||||
? this.props.lnglat
|
||||
: [this.props?.lnglat?.lng, this.props?.lnglat?.lat];
|
||||
const positionChanged = preLnglat.toString() !== nowLnglat.toString();
|
||||
|
||||
if (positionChanged) {
|
||||
this.popup.remove();
|
||||
this.popup = new Popup({
|
||||
...this.props.option,
|
||||
stopPropagation: false,
|
||||
});
|
||||
this.popup.setLnglat(this.props.lnglat);
|
||||
this.popup.setDOMContent(this.el);
|
||||
this.scene.addPopup(this.popup);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
import { IMapWrapper, Scene } from '@antv/l7';
|
||||
import React, { createElement, createRef, useEffect, useState } from 'react';
|
||||
import { SceneContext } from './SceneContext';
|
||||
interface IMapSceneConig {
|
||||
style?: Partial<React.CSSProperties>;
|
||||
className?: string;
|
||||
map: IMapWrapper;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
export default React.memo((props: IMapSceneConig) => {
|
||||
const { style, className, map } = props;
|
||||
const container = createRef();
|
||||
const [scene, setScene] = useState<Scene>();
|
||||
useEffect(() => {
|
||||
const sceneInstance = new Scene({
|
||||
id: container.current as HTMLDivElement,
|
||||
map,
|
||||
});
|
||||
sceneInstance.on('loaded', () => {
|
||||
setScene(sceneInstance);
|
||||
});
|
||||
return () => {
|
||||
sceneInstance.destroy();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<SceneContext.Provider value={scene}>
|
||||
{createElement(
|
||||
'div',
|
||||
{
|
||||
ref: container,
|
||||
style,
|
||||
className,
|
||||
},
|
||||
scene && props.children,
|
||||
)}
|
||||
</SceneContext.Provider>
|
||||
);
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { createContext, useContext } from 'react';
|
||||
|
||||
// tslint:disable-next-line: no-object-literal-type-assertion
|
||||
export const SceneContext = createContext<Scene | undefined>({} as Scene);
|
||||
export function useSceneValue(): Scene {
|
||||
return (useContext(SceneContext) as unknown) as Scene;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
import { ILayer, Scene } from '@antv/l7';
|
||||
import * as React from 'react';
|
||||
import { useSceneValue } from './SceneContext';
|
||||
|
||||
const { useEffect } = React;
|
||||
interface ILayerProps {
|
||||
type: string;
|
||||
handler: (...args: any[]) => void;
|
||||
}
|
||||
const SceneEvent = React.memo((props: ILayerProps) => {
|
||||
const { type, handler } = props;
|
||||
const mapScene = (useSceneValue() as unknown) as Scene;
|
||||
|
||||
useEffect(() => {
|
||||
mapScene.on(type, handler);
|
||||
return () => {
|
||||
mapScene.off(type, handler);
|
||||
};
|
||||
}, [type]);
|
||||
return null;
|
||||
});
|
||||
|
||||
export default SceneEvent;
|
|
@ -1,15 +0,0 @@
|
|||
export * from './component/SceneContext';
|
||||
export { default as AMapScene } from './component/AMapScene';
|
||||
export { default as MapboxScene } from './component/MapboxScene';
|
||||
export { default as Scene } from './component/Scene';
|
||||
export { default as Control } from './component/Control';
|
||||
export { default as CustomControl } from './component/CustomControl';
|
||||
export * from './component/Layer';
|
||||
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';
|
||||
export { default as SceneEvent } from './component/SceneEvent';
|
||||
export { default as LoadImage } from './component/LoadImage';
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"declarationDir": "./es",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./",
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
Loading…
Reference in New Issue