mirror of https://gitee.com/antv-l7/antv-l7
commit
6120d0904d
|
@ -17,6 +17,17 @@ jobs:
|
|||
# 注意替换为你的 Gitee 目标仓库地址
|
||||
destination-repo: 'git@gitee.com:antv-l7/antv-l7.git'
|
||||
|
||||
- name: 🔁 Sync to Gitee
|
||||
uses: wearerequired/git-mirror-action@master
|
||||
env:
|
||||
# 注意在 Settings->Secrets 配置 GITEE_RSA_PRIVATE_KEY
|
||||
SSH_PRIVATE_KEY: ${{ secrets.GITEE_RSA_PRIVATE_KEY }}
|
||||
with:
|
||||
# 注意替换为你的 GitHub 源仓库地址
|
||||
source-repo: 'git@github.com:antvis/L7.git'
|
||||
# 注意替换为你的 Gitee 目标仓库地址
|
||||
destination-repo: 'git@gitee.com:antv/L7.git'
|
||||
|
||||
- name: ✅ Build Gitee Pages
|
||||
uses: yanglbme/gitee-pages-action@master
|
||||
with:
|
||||
|
|
|
@ -80,3 +80,4 @@ packages/l7/package_bak.json
|
|||
|
||||
stories/Test
|
||||
packages/draw/node_modules/@turf
|
||||
packages/district/src/data
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,4 @@
|
|||
// tslint:disable-next-line:no-submodule-imports
|
||||
// import '!style-loader!css-loader!sass-loader!./iframe.scss';
|
||||
import { addParameters, configure } from '@storybook/react';
|
||||
import { create } from '@storybook/theming';
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const path = require("path");
|
||||
module.exports = ({ config }) => {
|
||||
|
||||
// config.module.rules.push({
|
||||
|
@ -12,24 +13,23 @@ module.exports = ({ config }) => {
|
|||
// options: { inline: true, fallback: false }
|
||||
// }
|
||||
// });
|
||||
config.module.rules =[];
|
||||
|
||||
config.module.rules.push(
|
||||
|
||||
{
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.(ts|tsx)$/,
|
||||
loader: require.resolve('awesome-typescript-loader'),
|
||||
|
||||
});
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.stories\.tsx?$/,
|
||||
// loaders: [
|
||||
// {
|
||||
// loader: require.resolve('@storybook/addon-storysource/loader'),
|
||||
// options: { parser: 'typescript' },
|
||||
// },
|
||||
// ],
|
||||
config.module.rules.push(
|
||||
{
|
||||
test: /.css$/,
|
||||
use: ["style-loader", "css-loader", 'sass-loader'],
|
||||
|
||||
enforce: 'pre',
|
||||
},{
|
||||
test: /\.stories\.css?$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.stories\.svg$/,
|
||||
|
@ -37,7 +37,7 @@ module.exports = ({ config }) => {
|
|||
}
|
||||
);
|
||||
|
||||
config.resolve.extensions.push('.ts', '.tsx', '.js', '.glsl');
|
||||
config.resolve.extensions.push('.ts', '.tsx', 'css', '.js', '.glsl');
|
||||
|
||||
return config;
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = api => {
|
|||
{
|
||||
extensions: [
|
||||
// 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本
|
||||
// '.json',
|
||||
'.pbf',
|
||||
'.glsl'
|
||||
]
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ module.exports = api => {
|
|||
{
|
||||
extensions: [
|
||||
// 由于使用了 TS 的 resolveJsonModule 选项,JSON 可以直接引入,不需要当作纯文本
|
||||
// '.json',
|
||||
'.json',
|
||||
'.glsl'
|
||||
]
|
||||
}
|
||||
|
|
|
@ -379,6 +379,14 @@ scene.removeLayer(layer);
|
|||
scene.exportMap('png');
|
||||
```
|
||||
|
||||
### destroy
|
||||
|
||||
scene 销毁方法,离开页面,或者不需要使用地图可以调用
|
||||
|
||||
```
|
||||
scene.destroy();
|
||||
```
|
||||
|
||||
## 事件
|
||||
|
||||
### on
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
"react-docgen-typescript-loader": "^3.1.0",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-i18next": "^11.0.1",
|
||||
"react-scripts": "^3.4.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup": "^1.27.14",
|
||||
"rollup-plugin-analyzer": "^3.2.2",
|
||||
|
@ -103,7 +104,6 @@
|
|||
"rollup-pluginutils": "^2.8.2",
|
||||
"sass-loader": "^8.0.2",
|
||||
"style-loader": "^1.0.0",
|
||||
"three": "0.115.0",
|
||||
"styled-components": "^3.4.6",
|
||||
"stylelint": "^9.5.0",
|
||||
"stylelint-config-recommended": "^2.1.0",
|
||||
|
@ -111,6 +111,7 @@
|
|||
"stylelint-config-styled-components": "^0.1.1",
|
||||
"stylelint-processor-styled-components": "^1.3.2",
|
||||
"svg-inline-loader": "^0.8.0",
|
||||
"three": "0.115.0",
|
||||
"ts-jest": "^24.0.2",
|
||||
"tslint": "^5.11.0",
|
||||
"tslint-config-prettier": "^1.15.0",
|
||||
|
@ -130,7 +131,7 @@
|
|||
"site:clean": "gatsby clean",
|
||||
"site:deploy": "yarn run site:build && gh-pages -d public",
|
||||
"site:publish": "gh-pages -d public",
|
||||
"lint:fix": "prettier --write docs/api/**/*.md docs/api/*.md packages/**/*.{spec,story}.ts{,x} stories/**/**/*.tsx *.md",
|
||||
"lint:fix": "prettier --write docs/api/**/*.md docs/api/*.md packages/**/*.ts{,x} packages/**/*.{spec,story}.ts{,x} stories/**/**/*.tsx *.md",
|
||||
"lint:examples": "eslint examples/**/**/*.js --fix",
|
||||
"prebuild": "run-p tsc lint",
|
||||
"build": "yarn clean && lerna run build",
|
||||
|
@ -138,8 +139,8 @@
|
|||
"build:declarations": "lerna exec --stream --no-bail 'tsc --project ./tsconfig.build.json'",
|
||||
"fix": "run-p -c 'lint:ts-* --fix'",
|
||||
"lint:css": "stylelint 'packages/**/*.js{,x}'",
|
||||
"lint:ts-prod": "tslint --config tslint.prod.json 'packages/**/*.ts{,x}'",
|
||||
"lint:ts-test": "tslint --config tslint.test.json 'packages/**/*.{spec,story}.ts{,x}'",
|
||||
"lint:ts-prod": "tslint --fix --config tslint.prod.json 'packages/**/*.ts{,x}'",
|
||||
"lint:ts-test": "tslint --fix --config tslint.test.json 'packages/**/*.{spec,story}.ts{,x}'",
|
||||
"lint:ts": "run-p -c lint:ts-*",
|
||||
"lint": "run-p -c lint:*",
|
||||
"commit": "git-cz",
|
||||
|
|
|
@ -457,11 +457,11 @@
|
|||
display: block;
|
||||
padding: 8px;
|
||||
}
|
||||
.l7-control-layers label input[type="radio"], input[type="checkbox"]{
|
||||
.l7-control-layers label input[type="radio"],
|
||||
.l7-control-layers label input[type="checkbox"] {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.l7-control-layers-separator {
|
||||
height: 0;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# `district`
|
||||
|
||||
> TODO: description
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
const district = require('district');
|
||||
|
||||
// TODO: DEMONSTRATE API
|
||||
```
|
|
@ -0,0 +1,9 @@
|
|||
import BaseLayer from '../src/layer/baseLayer';
|
||||
describe('baseLayer', () => {
|
||||
it('set option', () => {
|
||||
const option = {
|
||||
adcode: [],
|
||||
};
|
||||
// const layer = new BaseLayer(null, option);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "@antv/l7-district",
|
||||
"version": "2.2.3",
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/l7": "^2.2.3",
|
||||
"@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",
|
||||
"geobuf": "^3.0.1",
|
||||
"lodash": "^4.6.2",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"pbf": "^3.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@antv/l7": "^2.2.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"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
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.District',
|
||||
file: pkg.unpkg,
|
||||
sourcemap: true,
|
||||
globals: {
|
||||
'@antv/l7': 'L7'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
// tslint:disable-next-line:no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
let DataConfig: { [key: string]: any } = {
|
||||
world: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/21bdf832-1dfc-4cae-92d1-aa8d156df40f.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/76914518-e04c-42c9-8c4b-1ae71aabb024.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/90c51eb3-04d7-402f-bd05-95e4bd27dd62.bin',
|
||||
parser: {
|
||||
type: 'geojson',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
},
|
||||
country: {
|
||||
CHN: {
|
||||
1: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/70ec087e-c48a-4b76-8825-6452f17bae7a.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/70ec087e-c48a-4b76-8825-6452f17bae7a.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
label: {
|
||||
type: 'json',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/36832a45-68f8-4b51-b006-9dec71f92a23.json',
|
||||
},
|
||||
},
|
||||
2: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/561e2cfe-9460-42d1-a2f8-3fd2e1274c52.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
3: {
|
||||
fill: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/516b2703-d692-44e6-80dd-b3f5df0186e7.bin',
|
||||
},
|
||||
line: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
countryLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/bc97875a-90f2-42c0-a62c-43d2efd7460d.bin',
|
||||
},
|
||||
cityLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/8bfbfe7e-bd0e-4bbe-84d8-629f4dc7abc4.bin',
|
||||
},
|
||||
provinceLine: {
|
||||
type: 'pbf',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/778ad7ba-5a3f-4ed6-a94a-b8ab8acae9d6.bin',
|
||||
},
|
||||
},
|
||||
nationalBoundaries: {
|
||||
type: 'json',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/ee493a41-0558-4c0e-bee6-520276c4f1a8.json',
|
||||
},
|
||||
nationalBoundaries2: {
|
||||
type: 'json',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/f2189cc4-662b-4358-8573-36f0f918b7ca.json',
|
||||
},
|
||||
island: {
|
||||
type: 'json',
|
||||
url:
|
||||
'//gw.alipayobjects.com/os/bmw-prod/fe49b393-1147-4769-94ed-70471f4ff15d.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
province: {
|
||||
110000: '',
|
||||
},
|
||||
};
|
||||
|
||||
function setDataConfig(config: any) {
|
||||
DataConfig = merge(DataConfig, config);
|
||||
}
|
||||
|
||||
export { setDataConfig, DataConfig };
|
|
@ -0,0 +1,16 @@
|
|||
import { setDataConfig } from './config';
|
||||
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,
|
||||
setDataConfig,
|
||||
};
|
|
@ -0,0 +1,194 @@
|
|||
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 merge from 'lodash/merge';
|
||||
// @ts-ignore
|
||||
import Pbf from 'pbf';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
export default class BaseLayer extends EventEmitter {
|
||||
public fillLayer: ILayer;
|
||||
public lineLayer: ILayer;
|
||||
public labelLayer: ILayer;
|
||||
protected scene: Scene;
|
||||
protected options: IDistrictLayerOption;
|
||||
protected layers: ILayer[] = [];
|
||||
private popup: IPopup;
|
||||
|
||||
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
|
||||
super();
|
||||
this.scene = scene;
|
||||
this.options = merge({}, this.getDefaultOption(), option);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
protected async fetchData(data: { url: string; type: string }) {
|
||||
if (data.type === 'pbf') {
|
||||
const buffer = await (await fetch(data.url)).arrayBuffer();
|
||||
const geojson = geobuf.decode(new Pbf(buffer));
|
||||
return geojson;
|
||||
} else {
|
||||
return (await fetch(data.url)).json();
|
||||
}
|
||||
}
|
||||
protected getDefaultOption(): IDistrictLayerOption {
|
||||
return {
|
||||
zIndex: 0,
|
||||
depth: 1,
|
||||
adcode: [],
|
||||
label: {
|
||||
enable: true,
|
||||
color: '#000',
|
||||
field: 'name',
|
||||
size: 8,
|
||||
stroke: '#fff',
|
||||
strokeWidth: 2,
|
||||
textAllowOverlap: true,
|
||||
opacity: 1,
|
||||
},
|
||||
fill: {
|
||||
scale: null,
|
||||
field: null,
|
||||
values: '#fff',
|
||||
},
|
||||
autoFit: true,
|
||||
stroke: '#d95f0e',
|
||||
strokeWidth: 0.6,
|
||||
cityStroke: 'rgba(255,255,255,0.6)',
|
||||
cityStrokeWidth: 0.6,
|
||||
countyStrokeWidth: 0.6,
|
||||
provinceStrokeWidth: 0.6,
|
||||
provinceStroke: '#fff',
|
||||
countyStroke: 'rgba(255,255,255,0.6)',
|
||||
coastlineStroke: '#4190da',
|
||||
coastlineWidth: 1,
|
||||
nationalStroke: 'gray',
|
||||
nationalWidth: 1,
|
||||
popup: {
|
||||
enable: true,
|
||||
triggerEvent: 'mousemove',
|
||||
Html: (properties: any) => {
|
||||
return `${properties.name}`;
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected addFillLayer(fillCountry: any) {
|
||||
// 添加省份填充
|
||||
const { popup, data = [], fill, autoFit } = this.options;
|
||||
const fillLayer = new PolygonLayer({
|
||||
autoFit,
|
||||
}).source(fillCountry, {
|
||||
transforms:
|
||||
data.length === 0
|
||||
? []
|
||||
: [
|
||||
{
|
||||
type: 'join',
|
||||
sourceField: 'name', // data1 对应字段名
|
||||
targetField: 'name', // data 对应字段名 绑定到的地理数据
|
||||
data,
|
||||
},
|
||||
],
|
||||
});
|
||||
fill.field
|
||||
? fillLayer.color(fill.field, fill.values)
|
||||
: fillLayer.color(fill.values as string);
|
||||
|
||||
if (fill.scale) {
|
||||
fillLayer.scale('color', {
|
||||
type: 'quantile',
|
||||
field: fill.field as string,
|
||||
});
|
||||
}
|
||||
fillLayer
|
||||
.shape('fill')
|
||||
.active({
|
||||
color: 'rgba(0,0,255,0.3)',
|
||||
})
|
||||
.style({
|
||||
opacity: 1,
|
||||
});
|
||||
this.fillLayer = fillLayer;
|
||||
this.layers.push(fillLayer);
|
||||
this.scene.addLayer(fillLayer);
|
||||
if (popup.enable) {
|
||||
this.addPopup();
|
||||
}
|
||||
this.emit('loaded');
|
||||
}
|
||||
|
||||
protected addFillLine(provinceLine: any) {
|
||||
const { stroke, strokeWidth, zIndex } = this.options;
|
||||
const layer2 = new LineLayer({
|
||||
zIndex: zIndex + 1,
|
||||
})
|
||||
.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 { label, zIndex } = this.options;
|
||||
const labelLayer = new PointLayer({
|
||||
zIndex: zIndex + 2,
|
||||
})
|
||||
.source(labelData, {
|
||||
parser: {
|
||||
type,
|
||||
coordinates: 'center',
|
||||
},
|
||||
})
|
||||
.color(label.color as StyleAttrField)
|
||||
.shape(label.field as StyleAttrField, 'text')
|
||||
.size(10)
|
||||
.style({
|
||||
opacity: label.opacity,
|
||||
stroke: label.stroke,
|
||||
strokeWidth: label.strokeWidth,
|
||||
textAllowOverlap: label.textAllowOverlap,
|
||||
});
|
||||
this.scene.addLayer(labelLayer);
|
||||
this.layers.push(labelLayer);
|
||||
this.labelLayer = labelLayer;
|
||||
}
|
||||
|
||||
protected addPopup() {
|
||||
const { popup } = this.options;
|
||||
this.fillLayer.on('mousemove', (e) => {
|
||||
this.popup = new Popup({
|
||||
closeButton: false,
|
||||
})
|
||||
.setLnglat(e.lngLat)
|
||||
.setHTML(popup.Html ? popup.Html(e.feature.properties) : '');
|
||||
this.scene.addPopup(this.popup);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} 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: ['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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { DataConfig } from '../config';
|
||||
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 } = this.options;
|
||||
this.loadData().then(([fillData, fillLabel]) => {
|
||||
this.addFillLayer(fillData);
|
||||
if (fillLabel && this.options.label?.enable) {
|
||||
this.addLabelLayer(fillLabel);
|
||||
}
|
||||
});
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
|
||||
this.addProvinceLine(countryConfig.provinceLine);
|
||||
|
||||
if (depth === 2 * 1) {
|
||||
this.addCityBorder(countryConfig.cityLine);
|
||||
}
|
||||
if (depth === 3 * 1) {
|
||||
this.addCountryBorder(countryConfig.countryLine);
|
||||
}
|
||||
}
|
||||
// 国界,省界
|
||||
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' || 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);
|
||||
}
|
||||
|
||||
// 国界,省界
|
||||
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 = DataConfig.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) {
|
||||
const {
|
||||
nationalStroke,
|
||||
nationalWidth,
|
||||
coastlineStroke,
|
||||
coastlineWidth,
|
||||
stroke,
|
||||
strokeWidth,
|
||||
zIndex,
|
||||
} = this.options;
|
||||
// 添加国界线
|
||||
const lineLayer = new LineLayer({
|
||||
zIndex: zIndex + 1,
|
||||
})
|
||||
.source(boundaries)
|
||||
.size('type', (v: string) => {
|
||||
if (v === '3') {
|
||||
return strokeWidth;
|
||||
} else if (v === '2') {
|
||||
return coastlineWidth;
|
||||
} else if (v === '0') {
|
||||
return nationalWidth;
|
||||
} else {
|
||||
return '#fff';
|
||||
}
|
||||
})
|
||||
.shape('line')
|
||||
.color('type', (v: string) => {
|
||||
if (v === '3') {
|
||||
return stroke;
|
||||
} else if (v === '2') {
|
||||
return coastlineStroke;
|
||||
} else if (v === '0') {
|
||||
return nationalStroke;
|
||||
} else {
|
||||
return '#fff';
|
||||
}
|
||||
});
|
||||
// 添加未定国界
|
||||
const lineLayer2 = new LineLayer({
|
||||
zIndex: zIndex + 1,
|
||||
})
|
||||
.source(boundaries2)
|
||||
.size(nationalWidth)
|
||||
.shape('line')
|
||||
.color('gray')
|
||||
.style({
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
});
|
||||
|
||||
this.scene.addLayer(lineLayer);
|
||||
this.scene.addLayer(lineLayer2);
|
||||
this.layers.push(lineLayer, lineLayer2);
|
||||
}
|
||||
// 省级边界
|
||||
private async addCityBorder(cfg: any) {
|
||||
const border1 = await this.fetchData(cfg);
|
||||
const { cityStroke, cityStrokeWidth } = this.options;
|
||||
const cityline = new LineLayer({
|
||||
zIndex: 2,
|
||||
})
|
||||
.source(border1)
|
||||
.color(cityStroke)
|
||||
.size(cityStrokeWidth)
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
});
|
||||
this.scene.addLayer(cityline);
|
||||
this.layers.push(cityline);
|
||||
}
|
||||
|
||||
// 县级边界
|
||||
private async addCountryBorder(cfg: any) {
|
||||
// const bordConfig = DataConfig.country.CHN[3];
|
||||
const border1 = await this.fetchData(cfg);
|
||||
const { countyStrokeWidth, countyStroke } = this.options;
|
||||
const cityline = new LineLayer({
|
||||
zIndex: 2,
|
||||
})
|
||||
.source(border1)
|
||||
.color(countyStroke)
|
||||
.size(countyStrokeWidth)
|
||||
.style({
|
||||
opacity: 0.5,
|
||||
});
|
||||
this.scene.addLayer(cityline);
|
||||
this.layers.push(cityline);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import CityLayer from './city';
|
||||
import CountryLayer from './country';
|
||||
import { IDistrictLayerOption } from './interface';
|
||||
import ProvinceLayer from './province';
|
||||
|
||||
export default class DrillDownLayer {
|
||||
private provinceLayer: ProvinceLayer;
|
||||
private cityLayer: CityLayer;
|
||||
private countryLayer: CountryLayer;
|
||||
constructor(scene: Scene, option: Partial<IDistrictLayerOption>) {
|
||||
const cfg = this.getDefaultOption();
|
||||
this.countryLayer = new CountryLayer(scene, option);
|
||||
this.provinceLayer = new ProvinceLayer(scene, cfg.city);
|
||||
// this.cityLayer = new CityLayer(scene);
|
||||
// this.provinceLayer.hide();
|
||||
// this.cityLayer.hide();
|
||||
this.countryLayer.on('loaded', () => {
|
||||
this.addProvinceEvent();
|
||||
});
|
||||
}
|
||||
public getDefaultOption() {
|
||||
return {
|
||||
province: {},
|
||||
city: {
|
||||
adcode: '',
|
||||
},
|
||||
county: {
|
||||
adcode: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
public addProvinceEvent() {
|
||||
// this.countryLayer.fillLayer.on('click', (e: any) => {
|
||||
// });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import { ScaleTypeName, StyleAttributeOption } from '@antv/l7';
|
||||
export interface ILabelOption {
|
||||
enable: boolean;
|
||||
color: string;
|
||||
field: string;
|
||||
size: number;
|
||||
stroke: string;
|
||||
strokeWidth: number;
|
||||
textAllowOverlap: boolean;
|
||||
opacity: number;
|
||||
}
|
||||
export type adcodeType = string[] | string | number | number[];
|
||||
export interface IDistrictLayerOption {
|
||||
zIndex: number;
|
||||
data?: Array<{ [key: string]: any }>;
|
||||
adcode: adcodeType;
|
||||
depth: 0 | 1 | 2 | 3;
|
||||
label: Partial<ILabelOption>;
|
||||
fill: Partial<{
|
||||
scale: ScaleTypeName | null;
|
||||
field: string | null;
|
||||
values: StyleAttributeOption;
|
||||
}>;
|
||||
autoFit: boolean;
|
||||
stroke: string;
|
||||
strokeWidth: number;
|
||||
provinceStroke: string;
|
||||
cityStroke: string;
|
||||
provinceStrokeWidth: number;
|
||||
cityStrokeWidth: number;
|
||||
countyStroke: string;
|
||||
countyStrokeWidth: number;
|
||||
|
||||
coastlineStroke: string;
|
||||
coastlineWidth: number;
|
||||
nationalStroke: string;
|
||||
nationalWidth: number;
|
||||
popup: Partial<{
|
||||
enable: boolean;
|
||||
triggerEvent: 'mousemove' | 'click';
|
||||
Html: (properties: any) => string;
|
||||
}>;
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
// tslint:disable-next-line: no-submodule-imports
|
||||
import merge from 'lodash/merge';
|
||||
import { DataConfig } from '../config';
|
||||
import BaseLayer from './baseLayer';
|
||||
import { adcodeType, IDistrictLayerOption } from './interface';
|
||||
|
||||
export interface IProvinceLayerOption extends IDistrictLayerOption {
|
||||
adcode: adcodeType;
|
||||
}
|
||||
export default class ProvinceLayer extends BaseLayer {
|
||||
private fillData: any;
|
||||
private lineData: any;
|
||||
private labelData: any;
|
||||
constructor(scene: Scene, option: Partial<IProvinceLayerOption> = {}) {
|
||||
super(scene, option);
|
||||
this.addProvinceFillLayer();
|
||||
this.addProvinceLineLayer();
|
||||
}
|
||||
// 通过adcode 更新
|
||||
public updateDistrict(adcode: adcodeType) {
|
||||
if (!adcode && Array.isArray(adcode) && adcode.length === 0) {
|
||||
this.hide();
|
||||
return;
|
||||
}
|
||||
const fillData = this.filterData(this.fillData, adcode);
|
||||
const lineData = this.filterData(this.lineData, adcode);
|
||||
const labelData = this.filterLabelData(this.labelData, adcode);
|
||||
this.fillLayer.setData(fillData);
|
||||
this.lineLayer.setData(lineData);
|
||||
this.labelLayer.setData(labelData);
|
||||
this.show();
|
||||
}
|
||||
|
||||
// 更新渲染数据
|
||||
|
||||
public updateData() {
|
||||
return 'update data';
|
||||
}
|
||||
|
||||
protected getDefaultOption(): IProvinceLayerOption {
|
||||
const config = super.getDefaultOption();
|
||||
return merge({}, config, {
|
||||
adcode: ['110000'],
|
||||
depth: 2,
|
||||
label: {
|
||||
field: 'NAME_CHN',
|
||||
textAllowOverlap: false,
|
||||
},
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
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 } = this.options as IProvinceLayerOption;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
|
||||
this.labelData = fillData.features.map((feature: any) => {
|
||||
return {
|
||||
...feature.properties,
|
||||
center: [feature.properties.x, feature.properties.y],
|
||||
};
|
||||
});
|
||||
const data = this.filterData(fillData, adcode);
|
||||
const labelData = this.filterLabelData(this.labelData, adcode);
|
||||
this.fillData = fillData;
|
||||
this.addFillLayer(data);
|
||||
this.addLabelLayer(labelData);
|
||||
}
|
||||
|
||||
private async addProvinceLineLayer() {
|
||||
const { depth, adcode } = this.options as IProvinceLayerOption;
|
||||
const countryConfig = DataConfig.country.CHN[depth];
|
||||
const fillData = await this.fetchData(countryConfig.line);
|
||||
const data = this.filterData(fillData, adcode);
|
||||
this.lineData = fillData;
|
||||
this.addFillLine(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
import {
|
||||
ILayer,
|
||||
LineLayer,
|
||||
PointLayer,
|
||||
PolygonLayer,
|
||||
Scene,
|
||||
StyleAttrField,
|
||||
} from '@antv/l7';
|
||||
import { DataConfig } from '../config';
|
||||
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.addWorldBorder(border1, border2, island);
|
||||
this.addFillLayer(fillData);
|
||||
this.addFillLine(lineData);
|
||||
if (this.options.label?.enable) {
|
||||
this.addLabelLayer(fillLabel, 'geojson');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public addFillLine(data: any) {
|
||||
// 未定国界
|
||||
const bord1 = data.features.filter((feature: any) => {
|
||||
return (
|
||||
feature.properties.type === '10' ||
|
||||
feature.properties.type === '1' ||
|
||||
feature.properties.type === '11'
|
||||
);
|
||||
});
|
||||
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'
|
||||
);
|
||||
});
|
||||
const nationalFc = {
|
||||
type: 'FeatureCollection',
|
||||
features: nationalBorder,
|
||||
};
|
||||
this.addNationBorder(nationalFc, bordFc);
|
||||
}
|
||||
|
||||
private async loadData() {
|
||||
const countryConfig = DataConfig.world;
|
||||
|
||||
const fillData = await this.fetchData(countryConfig.fill);
|
||||
const lineData = await this.fetchData(countryConfig.line);
|
||||
const fillLabel = await this.fetchData(countryConfig.label);
|
||||
return [fillData, lineData, fillLabel];
|
||||
}
|
||||
private addNationBorder(boundaries: any, boundaries2: any) {
|
||||
const {
|
||||
nationalStroke,
|
||||
nationalWidth,
|
||||
coastlineStroke,
|
||||
coastlineWidth,
|
||||
zIndex,
|
||||
} = this.options;
|
||||
// 添加国界线
|
||||
const lineLayer = new LineLayer({
|
||||
zIndex: zIndex + 1,
|
||||
})
|
||||
.source(boundaries)
|
||||
.size(0.6)
|
||||
.color('type', (v: string) => {
|
||||
if (v === '0') {
|
||||
return 'rgb(99,100, 99)'; // 中国国界线
|
||||
} else if (v === '2') {
|
||||
return 'rgb(0,136, 191)'; // 中国海岸线
|
||||
} else if (v === '9') {
|
||||
return 'rgb(0,136, 191)'; // 国外海岸线
|
||||
} else if (v === '7') {
|
||||
return '#9ecae1'; // 国外国界
|
||||
} else {
|
||||
return '#9ecae1';
|
||||
}
|
||||
});
|
||||
// 添加未定国界
|
||||
const lineLayer2 = new LineLayer({
|
||||
zIndex: zIndex + 1,
|
||||
})
|
||||
.source(boundaries2)
|
||||
.size(nationalWidth)
|
||||
.shape('line')
|
||||
.color('type', (v: string) => {
|
||||
if (v === '1') {
|
||||
return 'rgb(99,100, 99)';
|
||||
} else {
|
||||
return '#9ecae1';
|
||||
}
|
||||
})
|
||||
.style({
|
||||
lineType: 'dash',
|
||||
dashArray: [2, 2],
|
||||
});
|
||||
|
||||
this.scene.addLayer(lineLayer);
|
||||
this.scene.addLayer(lineLayer2);
|
||||
|
||||
this.layers.push(lineLayer, lineLayer2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "../../tsconfig.build.json",
|
||||
"compilerOptions": {
|
||||
"declarationDir": "./es",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["./src"]
|
||||
}
|
|
@ -42,6 +42,7 @@
|
|||
"@turf/helpers": "^6.1.4",
|
||||
"@turf/midpoint": "^5.1.5",
|
||||
"@turf/turf": "^5.1.6",
|
||||
"eventemitter3": "^4.0.0",
|
||||
"lodash": "^4.6.2"
|
||||
},
|
||||
"bugs": {
|
||||
|
|
|
@ -16,10 +16,10 @@ export function computeMiter(
|
|||
export function computeNormal(out: vec2, dir: vec2) {
|
||||
return vec2.set(out, -dir[1], dir[0]);
|
||||
}
|
||||
export function direction(out: vec2, a: vec2, b: vec2) {
|
||||
const a1 = aProjectFlat([a[0], a[1]]) as [number, number];
|
||||
const b1 = aProjectFlat([b[0], b[1]]) as [number, number];
|
||||
vec2.sub(out, a1, b1);
|
||||
export function direction(out: vec2, a: [number, number], b: [number, number]) {
|
||||
// const a1 = aProjectFlat([a[0], a[1]]) as [number, number];
|
||||
// const b1 = aProjectFlat([b[0], b[1]]) as [number, number];
|
||||
vec2.sub(out, a, b);
|
||||
vec2.normalize(out, out);
|
||||
return out;
|
||||
}
|
||||
|
@ -47,9 +47,7 @@ function addNext(
|
|||
miters.push(length);
|
||||
}
|
||||
|
||||
function lineSegmentDistance(end: vec2, start: vec2) {
|
||||
const a1 = aProjectFlat([start[0], start[1]]);
|
||||
const b1 = aProjectFlat([end[0], end[1]]);
|
||||
function lineSegmentDistance(b1: vec2, a1: vec2) {
|
||||
const dx = a1[0] - b1[0];
|
||||
const dy = a1[1] - b1[1];
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
|
@ -110,11 +108,14 @@ export default function(
|
|||
}
|
||||
}
|
||||
let d = 0;
|
||||
const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number];
|
||||
const flatLast = aProjectFlat([last[0], last[1]]) as [number, number];
|
||||
if (isDash) {
|
||||
const lineDistance = lineSegmentDistance(cur, last);
|
||||
const lineDistance = lineSegmentDistance(flatCur, flatLast);
|
||||
d = lineDistance + attrDistance[attrDistance.length - 1];
|
||||
}
|
||||
direction(lineA, cur, last);
|
||||
|
||||
direction(lineA, flatCur, flatLast);
|
||||
if (!lineNormal) {
|
||||
lineNormal = vec2.create();
|
||||
computeNormal(lineNormal, lineA);
|
||||
|
@ -136,8 +137,9 @@ export default function(
|
|||
attrIndex.push(index + 1, index + 2, index + 3);
|
||||
count += 2;
|
||||
} else {
|
||||
const flatNext = aProjectFlat([next[0], next[1]]) as [number, number];
|
||||
// get unit dir of next line
|
||||
direction(lineB, next, cur);
|
||||
direction(lineB, flatNext, flatCur);
|
||||
|
||||
// stores tangent & miter
|
||||
let miterLen = computeMiter(
|
||||
|
|
|
@ -331,7 +331,7 @@ export default class AMapService
|
|||
amapLoaded = true;
|
||||
plugin.push('Map3D');
|
||||
this.loadAMapScript(
|
||||
`https://webapi.amap.com/maps?v=${AMAP_VERSION}&key=${token}&plugin=${plugin.join(
|
||||
`//webapi.amap.com/maps?v=${AMAP_VERSION}&key=${token}&plugin=${plugin.join(
|
||||
',',
|
||||
)}`,
|
||||
).then(() => {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -21,7 +21,6 @@ export default function geoJSON(
|
|||
data: FeatureCollection<Geometries, Properties>,
|
||||
cfg?: IParserCFG,
|
||||
): IParserData {
|
||||
rewind(data, true); // 设置地理多边形方向 If clockwise is true, the outer ring is clockwise, otherwise it is counterclockwise.
|
||||
const resultData: IParseDataItem[] = [];
|
||||
const featureKeys: IFeatureKey = {};
|
||||
data.features = data.features.filter((item: Feature) => {
|
||||
|
@ -34,6 +33,7 @@ export default function geoJSON(
|
|||
geometry.coordinates.length > 0
|
||||
);
|
||||
});
|
||||
rewind(data, true); // 设置地理多边形方向 If clockwise is true, the outer ring is clockwise, otherwise it is counterclockwise.
|
||||
if (data.features.length === 0) {
|
||||
return {
|
||||
dataArray: [],
|
||||
|
|
|
@ -56,7 +56,7 @@ export default class Source extends EventEmitter {
|
|||
|
||||
constructor(data: any, cfg?: ISourceCFG) {
|
||||
super();
|
||||
this.rawData = cloneDeep(data);
|
||||
// this.rawData = cloneDeep(data);
|
||||
this.originData = data;
|
||||
if (cfg) {
|
||||
if (cfg.parser) {
|
||||
|
@ -89,7 +89,7 @@ export default class Source extends EventEmitter {
|
|||
|
||||
public setData(data: any) {
|
||||
this.rawData = data;
|
||||
this.originData = cloneDeep(data);
|
||||
this.originData = data;
|
||||
this.init();
|
||||
this.emit('update');
|
||||
}
|
||||
|
@ -137,11 +137,18 @@ export default class Source extends EventEmitter {
|
|||
}
|
||||
public getFeatureById(id: number): unknown {
|
||||
const { type = 'geojson' } = this.parser;
|
||||
if (type === 'geojson' && !this.cluster && this.transforms.length === 0) {
|
||||
// TODO: 聚合图层返回聚合和后的数据
|
||||
return id < this.originData.features.length
|
||||
if (type === 'geojson' && !this.cluster) {
|
||||
const feature =
|
||||
id < this.originData.features.length
|
||||
? this.originData.features[id]
|
||||
: 'null';
|
||||
if (this.transforms.length !== 0) {
|
||||
const item = this.data.dataArray.find((dataItem: IParseDataItem) => {
|
||||
return dataItem._id === id;
|
||||
});
|
||||
feature.properties = item;
|
||||
}
|
||||
return feature;
|
||||
} else {
|
||||
return id < this.data.dataArray.length ? this.data.dataArray[id] : 'null';
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ export function aProjectFlat(lnglat: number[]) {
|
|||
d = 0.5;
|
||||
x = scale * (a * x + b);
|
||||
y = scale * (c * y + d);
|
||||
return [parseInt(x.toString(), 10), parseInt(y.toString(), 10)];
|
||||
return [Math.floor(x), Math.floor(y)];
|
||||
}
|
||||
export function unProjectFlat(px: number[]): [number, number] {
|
||||
const a = 0.5 / Math.PI;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CountryLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
const Layer = new CountryLayer(scene, {
|
||||
data: [],
|
||||
depth: 1,
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,351 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CountryLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 1,
|
||||
maxZoom: 4,
|
||||
}),
|
||||
});
|
||||
const data = [
|
||||
{
|
||||
name: '湖北',
|
||||
confirm: 16678,
|
||||
suspect: 0,
|
||||
heal: 533,
|
||||
dead: 479,
|
||||
},
|
||||
{
|
||||
name: '广东',
|
||||
confirm: 895,
|
||||
suspect: 0,
|
||||
heal: 37,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '浙江',
|
||||
confirm: 895,
|
||||
suspect: 0,
|
||||
heal: 65,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '河南',
|
||||
confirm: 764,
|
||||
suspect: 0,
|
||||
heal: 41,
|
||||
dead: 2,
|
||||
},
|
||||
{
|
||||
name: '湖南',
|
||||
confirm: 661,
|
||||
suspect: 0,
|
||||
heal: 35,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '江西',
|
||||
confirm: 548,
|
||||
suspect: 0,
|
||||
heal: 27,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '安徽',
|
||||
confirm: 530,
|
||||
suspect: 0,
|
||||
heal: 20,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '重庆',
|
||||
confirm: 376,
|
||||
suspect: 0,
|
||||
heal: 15,
|
||||
dead: 2,
|
||||
},
|
||||
{
|
||||
name: '江苏',
|
||||
confirm: 341,
|
||||
suspect: 0,
|
||||
heal: 13,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '山东',
|
||||
confirm: 307,
|
||||
suspect: 0,
|
||||
heal: 13,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '四川',
|
||||
confirm: 301,
|
||||
suspect: 0,
|
||||
heal: 23,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '北京',
|
||||
confirm: 253,
|
||||
suspect: 0,
|
||||
heal: 24,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '上海',
|
||||
confirm: 243,
|
||||
suspect: 0,
|
||||
heal: 15,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '福建',
|
||||
confirm: 205,
|
||||
suspect: 0,
|
||||
heal: 7,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '黑龙江',
|
||||
confirm: 190,
|
||||
suspect: 0,
|
||||
heal: 7,
|
||||
dead: 2,
|
||||
},
|
||||
{
|
||||
name: '陕西',
|
||||
confirm: 165,
|
||||
suspect: 0,
|
||||
heal: 6,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '广西',
|
||||
confirm: 150,
|
||||
suspect: 0,
|
||||
heal: 10,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '河北',
|
||||
confirm: 135,
|
||||
suspect: 0,
|
||||
heal: 4,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '云南',
|
||||
confirm: 124,
|
||||
suspect: 0,
|
||||
heal: 5,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '海南',
|
||||
confirm: 91,
|
||||
suspect: 0,
|
||||
heal: 4,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '辽宁',
|
||||
confirm: 81,
|
||||
suspect: 0,
|
||||
heal: 3,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '山西',
|
||||
confirm: 81,
|
||||
suspect: 0,
|
||||
heal: 4,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '天津',
|
||||
confirm: 69,
|
||||
suspect: 0,
|
||||
heal: 2,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '贵州',
|
||||
confirm: 64,
|
||||
suspect: 0,
|
||||
heal: 8,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '甘肃',
|
||||
confirm: 57,
|
||||
suspect: 0,
|
||||
heal: 4,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '吉林',
|
||||
confirm: 54,
|
||||
suspect: 0,
|
||||
heal: 1,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '内蒙古',
|
||||
confirm: 42,
|
||||
suspect: 0,
|
||||
heal: 3,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '宁夏',
|
||||
confirm: 34,
|
||||
suspect: 0,
|
||||
heal: 1,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '新疆',
|
||||
confirm: 32,
|
||||
suspect: 0,
|
||||
heal: 0,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '香港',
|
||||
confirm: 18,
|
||||
suspect: 0,
|
||||
heal: 0,
|
||||
dead: 1,
|
||||
},
|
||||
{
|
||||
name: '青海',
|
||||
confirm: 17,
|
||||
suspect: 0,
|
||||
heal: 3,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '台湾',
|
||||
confirm: 11,
|
||||
suspect: 0,
|
||||
heal: 0,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '澳门',
|
||||
confirm: 10,
|
||||
suspect: 0,
|
||||
heal: 0,
|
||||
dead: 0,
|
||||
},
|
||||
{
|
||||
name: '西藏',
|
||||
confirm: 1,
|
||||
suspect: 0,
|
||||
heal: 0,
|
||||
dead: 0,
|
||||
},
|
||||
];
|
||||
scene.on('loaded', () => {
|
||||
const Layer = new CountryLayer(scene, {
|
||||
data,
|
||||
depth: 1,
|
||||
fill: {
|
||||
scale: 'quantile',
|
||||
field: 'confirm',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
const scene2 = new Scene({
|
||||
id: 'map2',
|
||||
logoVisible: false,
|
||||
map: new Mapbox({
|
||||
center: [113.60540108435657, 12.833692637803168],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 1.93,
|
||||
minZoom: 0,
|
||||
maxZoom: 3,
|
||||
interactive: false,
|
||||
}),
|
||||
});
|
||||
scene2.on('loaded', () => {
|
||||
const Layer2 = new CountryLayer(scene2, {
|
||||
data,
|
||||
label: {
|
||||
enable: false,
|
||||
},
|
||||
popup: {
|
||||
enable: false,
|
||||
},
|
||||
autoFit: false,
|
||||
fill: {
|
||||
scale: 'quantile',
|
||||
field: 'confirm',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
id="map2"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
height: '125px',
|
||||
width: '98px',
|
||||
right: '100px',
|
||||
bottom: '20px',
|
||||
border: '1px solid #333',
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CityLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { Cascader } from 'antd';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
public state = {
|
||||
options: [],
|
||||
};
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
private cityLayer: CityLayer;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const res = await fetch(
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/551e3ca6-6dad-421b-a8b4-b225e47f73ca.json',
|
||||
);
|
||||
const options = await res.json();
|
||||
this.setState({
|
||||
options,
|
||||
});
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
this.cityLayer = new CityLayer(scene, {
|
||||
data: [],
|
||||
adcode: ['110100'],
|
||||
depth: 3,
|
||||
label: {
|
||||
field: 'NAME_CHN',
|
||||
textAllowOverlap: false,
|
||||
},
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<Cascader
|
||||
style={{
|
||||
width: 200,
|
||||
zIndex: 2,
|
||||
position: 'absolute',
|
||||
right: '10px',
|
||||
top: '10px',
|
||||
}}
|
||||
options={this.state.options}
|
||||
defaultValue={['110000', '110100']}
|
||||
onChange={this.handleProvinceChange}
|
||||
placeholder="Please select"
|
||||
/>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
private handleProvinceChange = (value: string[]) => {
|
||||
this.cityLayer.updateDistrict([value[1]]);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CountryLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
const Layer = new CountryLayer(scene, {
|
||||
data: [],
|
||||
depth: 2,
|
||||
stroke: '#fff',
|
||||
coastlineWidth: 0.5,
|
||||
nationalWidth: 0.5,
|
||||
fill: {
|
||||
// scale: 'quantile',
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CountryLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
const Layer = new CountryLayer(scene, {
|
||||
data: [],
|
||||
depth: 3,
|
||||
stroke: '#fff',
|
||||
strokeWidth: 1,
|
||||
coastlineWidth: 0.5,
|
||||
nationalWidth: 0.5,
|
||||
fill: {
|
||||
// scale: 'quantile',
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { CountyLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { Cascader } from 'antd';
|
||||
import * as React from 'react';
|
||||
export default class Country extends React.Component {
|
||||
public state = {
|
||||
options: [],
|
||||
};
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
private countyLayer: CountyLayer;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const res = await fetch(
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/04de56cc-5998-4f7e-9ad3-e87e9ac5fd39.json',
|
||||
);
|
||||
const options = await res.json();
|
||||
this.setState({
|
||||
options,
|
||||
});
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
this.countyLayer = new CountyLayer(scene, {
|
||||
data: [],
|
||||
adcode: ['110101'],
|
||||
depth: 3,
|
||||
label: {
|
||||
field: 'NAME_CHN',
|
||||
},
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<Cascader
|
||||
style={{
|
||||
width: 200,
|
||||
zIndex: 2,
|
||||
position: 'absolute',
|
||||
right: '10px',
|
||||
top: '10px',
|
||||
}}
|
||||
options={this.state.options}
|
||||
defaultValue={['110000', '110100', '110101']}
|
||||
onChange={this.handleProvinceChange}
|
||||
placeholder="Please select"
|
||||
/>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private handleProvinceChange = (value: string[]) => {
|
||||
this.countyLayer.updateDistrict([value[2]]);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { DrillDownLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { Cascader } from 'antd';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
public state = {
|
||||
options: [],
|
||||
};
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
private drillDown: DrillDownLayer;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
this.scene = scene;
|
||||
this.drillDown = new DrillDownLayer(scene, {
|
||||
data: [],
|
||||
depth: 1,
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { ProvinceLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
// tslint:disable-next-line:no-submodule-imports
|
||||
import { Select } from 'antd';
|
||||
import * as React from 'react';
|
||||
const { Option } = Select;
|
||||
const ProvinceData = [
|
||||
{
|
||||
NAME_CHN: '云南省',
|
||||
adcode: 530000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '黑龙江省',
|
||||
adcode: 230000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '贵州省',
|
||||
adcode: 520000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '北京市',
|
||||
adcode: 110000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '河北省',
|
||||
adcode: 130000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '山西省',
|
||||
adcode: 140000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '吉林省',
|
||||
adcode: 220000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '宁夏回族自治区',
|
||||
adcode: 640000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '辽宁省',
|
||||
adcode: 210000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '海南省',
|
||||
adcode: 460000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '内蒙古自治区',
|
||||
adcode: 150000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '天津市',
|
||||
adcode: 120000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '新疆维吾尔自治区',
|
||||
adcode: 650000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '上海市',
|
||||
adcode: 310000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '陕西省',
|
||||
adcode: 610000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '甘肃省',
|
||||
adcode: 620000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '安徽省',
|
||||
adcode: 340000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '香港特别行政区',
|
||||
adcode: 810000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '广东省',
|
||||
adcode: 440000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '河南省',
|
||||
adcode: 410000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '湖南省',
|
||||
adcode: 430000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '江西省',
|
||||
adcode: 360000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '四川省',
|
||||
adcode: 510000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '广西壮族自治区',
|
||||
adcode: 450000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '江苏省',
|
||||
adcode: 320000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '澳门特别行政区',
|
||||
adcode: 820000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '浙江省',
|
||||
adcode: 330000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '山东省',
|
||||
adcode: 370000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '青海省',
|
||||
adcode: 630000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '重庆市',
|
||||
adcode: 500000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '福建省',
|
||||
adcode: 350000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '湖北省',
|
||||
adcode: 420000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '西藏自治区',
|
||||
adcode: 540000,
|
||||
},
|
||||
{
|
||||
NAME_CHN: '台湾省',
|
||||
adcode: 710000,
|
||||
},
|
||||
];
|
||||
export default class Country extends React.Component {
|
||||
public state = {
|
||||
province: '110000',
|
||||
};
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
private provinceLayer: ProvinceLayer;
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 3,
|
||||
minZoom: 3,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
|
||||
scene.on('loaded', () => {
|
||||
const { province } = this.state;
|
||||
this.provinceLayer = new ProvinceLayer(scene, {
|
||||
data: [],
|
||||
adcode: [],
|
||||
depth: 3,
|
||||
label: {
|
||||
field: 'NAME_CHN',
|
||||
textAllowOverlap: false,
|
||||
},
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
popup: {
|
||||
enable: true,
|
||||
Html: (props) => {
|
||||
return `<span>${props.NAME_CHN}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<Select
|
||||
defaultValue="北京市"
|
||||
style={{
|
||||
width: 120,
|
||||
zIndex: 2,
|
||||
position: 'absolute',
|
||||
right: '10px',
|
||||
top: '10px',
|
||||
}}
|
||||
onChange={this.handleProvinceChange}
|
||||
>
|
||||
{ProvinceData.map((province, i) => {
|
||||
return (
|
||||
<Option key={i} value={province.adcode}>
|
||||
{province.NAME_CHN}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private handleProvinceChange = (value: string) => {
|
||||
this.setState({
|
||||
province: value,
|
||||
});
|
||||
this.provinceLayer.updateDistrict([value]);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { WorldLayer } from '@antv/l7-district';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import * as React from 'react';
|
||||
|
||||
export default class Country extends React.Component {
|
||||
// @ts-ignore
|
||||
private scene: Scene;
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.scene.destroy();
|
||||
}
|
||||
|
||||
public async componentDidMount() {
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new Mapbox({
|
||||
center: [116.2825, 39.9],
|
||||
pitch: 0,
|
||||
style: 'blank',
|
||||
zoom: 0,
|
||||
minZoom: 0,
|
||||
maxZoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
const Layer = new WorldLayer(scene, {
|
||||
data: [],
|
||||
fill: {
|
||||
field: 'NAME_CHN',
|
||||
values: [
|
||||
'#feedde',
|
||||
'#fdd0a2',
|
||||
'#fdae6b',
|
||||
'#fd8d3c',
|
||||
'#e6550d',
|
||||
'#a63603',
|
||||
],
|
||||
},
|
||||
stroke: '#ccc',
|
||||
label: {
|
||||
enable: false,
|
||||
textAllowOverlap: false,
|
||||
field: 'Short_Name_ZH',
|
||||
},
|
||||
popup: {
|
||||
enable: false,
|
||||
Html: (props) => {
|
||||
return `<span>${props.Short_Name_ZH}</span>`;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
import { storiesOf } from '@storybook/react';
|
||||
require('./../assets/css/antd.css');
|
||||
import * as React from 'react';
|
||||
import City from './Layer/city';
|
||||
import Country from './Layer/Country';
|
||||
import Country2 from './Layer/Country2';
|
||||
import CountryCity from './Layer/country_city';
|
||||
import CountryCounty from './Layer/country_county';
|
||||
import County from './Layer/county';
|
||||
import DrillDown from './Layer/drillDown';
|
||||
import Province from './Layer/province';
|
||||
import World from './Layer/world';
|
||||
|
||||
storiesOf('行政区划', module)
|
||||
.add('世界地图', () => <World />)
|
||||
.add('中国地图', () => <Country />)
|
||||
.add('中国地图市级', () => <CountryCity />)
|
||||
.add('中国地图县级', () => <CountryCounty />)
|
||||
.add('中国地图附图', () => <Country2 />)
|
||||
.add('县级地图', () => <County />)
|
||||
.add('市级地图', () => <City />)
|
||||
.add('上钻下取', () => <DrillDown />)
|
||||
.add('省级地图', () => <Province />);
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue