docs(distrcit): add district demo

This commit is contained in:
thinkinggis 2020-05-03 19:58:17 +08:00
parent 61e75d5479
commit 4f106d9e24
18 changed files with 56748 additions and 244 deletions

27500
.storybook/antd.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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';

View File

@ -13,27 +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: /.css?$/,
include: [
path.resolve(__dirname, "../src"),
],
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.stories\.svg$/,
@ -41,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;
};

View File

@ -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": "^2.6.2",
"rollup": "^1.27.14",
"rollup-plugin-analyzer": "^3.2.2",

View File

@ -17,6 +17,8 @@ import Pbf from 'pbf';
import { IDistrictLayerOption } from './interface';
export default class BaseLayer {
public fillLayer: ILayer;
public lineLayer: ILayer;
public labelLayer: ILayer;
protected scene: Scene;
protected options: IDistrictLayerOption;
protected layers: ILayer[] = [];
@ -134,9 +136,9 @@ export default class BaseLayer {
}
protected addFillLine(provinceLine: any) {
const { stroke, strokeWidth } = this.options;
const { stroke, strokeWidth, zIndex } = this.options;
const layer2 = new LineLayer({
zIndex: 2,
zIndex: zIndex + 1,
})
.source(provinceLine)
.color(stroke)
@ -146,9 +148,10 @@ export default class BaseLayer {
});
this.scene.addLayer(layer2);
this.layers.push(layer2);
this.lineLayer = layer2;
}
protected addLableLayer(labelData: any, type: string = 'json') {
protected addLabelLayer(labelData: any, type: string = 'json') {
const { label, zIndex } = this.options;
const labelLayer = new PointLayer({
zIndex: zIndex + 2,
@ -170,6 +173,7 @@ export default class BaseLayer {
});
this.scene.addLayer(labelLayer);
this.layers.push(labelLayer);
this.labelLayer = labelLayer;
}
protected addPopup() {

View File

@ -8,19 +8,14 @@ import {
} from '@antv/l7';
// tslint:disable-next-line: no-submodule-imports
import merge from 'lodash/merge';
import { DataConfig } from '../config';
import BaseLayer from './baseLayer';
import { IDistrictLayerOption } from './interface';
import { adcodeType, IDistrictLayerOption } from './interface';
import ProvinceLayer from './province';
export interface IProvinceLayerOption extends IDistrictLayerOption {
adcode: string[];
}
export default class CityLayer extends BaseLayer {
constructor(scene: Scene, option: Partial<IProvinceLayerOption> = {}) {
super(scene, option);
this.addCityFillLayer();
this.addCityLineLayer();
}
export default class CityLayer extends ProvinceLayer {
protected getdefaultOption(): IProvinceLayerOption {
const config = super.getdefaultOption();
return merge({}, config, {
@ -28,25 +23,27 @@ export default class CityLayer extends BaseLayer {
depth: 3,
});
}
private async addCityFillLayer() {
const { depth, adcode } = this.options as IProvinceLayerOption;
const countryConfig = DataConfig.country.CHN[depth];
const fillData = await this.fetchData(countryConfig.fill);
const data = fillData.features.filter((fe: any) => {
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 adcode.indexOf('' + code) !== -1;
return (
adcodeArray.indexOf(code) !== -1 ||
adcodeArray.indexOf('' + code) !== -1
);
});
this.addFillLayer({ type: 'FeatureCollection', features: data });
return { type: 'FeatureCollection', features };
}
private async addCityLineLayer() {
const { depth, adcode } = this.options as IProvinceLayerOption;
const countryConfig = DataConfig.country.CHN[depth];
const fillData = await this.fetchData(countryConfig.line);
const data = fillData.features.filter((fe: any) => {
const code = fe.properties.adcode_cit;
return adcode.indexOf(code) !== -1 || adcode.indexOf('' + code) !== -1;
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
);
});
this.addFillLine({ type: 'FeatureCollection', features: data });
return features;
}
}

View File

@ -17,7 +17,7 @@ export default class CountryLayer extends BaseLayer {
this.loadData().then(([fillData, fillLabel]) => {
this.addFillLayer(fillData);
if (fillLabel && this.options.label?.enable) {
this.addLableLayer(fillLabel);
this.addLabelLayer(fillLabel);
}
});
const countryConfig = DataConfig.country.CHN[depth];

View File

@ -1,19 +1,13 @@
import { Scene } from '@antv/l7';
// tslint:disable-next-line: no-submodule-imports
import merge from 'lodash/merge';
import { DataConfig } from '../config';
import BaseLayer from './baseLayer';
import { IDistrictLayerOption } from './interface';
import { adcodeType, IDistrictLayerOption } from './interface';
import ProvinceLayer from './province';
export interface IProvinceLayerOption extends IDistrictLayerOption {
adcode: string[];
}
export default class CityLayer extends BaseLayer {
constructor(scene: Scene, option: Partial<IProvinceLayerOption> = {}) {
super(scene, option);
this.addCountyFillLayer();
this.addCountyLineLayer();
}
export default class CityLayer extends ProvinceLayer {
protected getdefaultOption(): IProvinceLayerOption {
const config = super.getdefaultOption();
return merge({}, config, {
@ -21,25 +15,27 @@ export default class CityLayer extends BaseLayer {
depth: 3,
});
}
private async addCountyFillLayer() {
const { depth, adcode } = this.options as IProvinceLayerOption;
const countryConfig = DataConfig.country.CHN[depth];
const fillData = await this.fetchData(countryConfig.fill);
const data = fillData.features.filter((fe: any) => {
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 adcode.indexOf('' + code) !== -1;
return (
adcodeArray.indexOf(code) !== -1 ||
adcodeArray.indexOf('' + code) !== -1
);
});
this.addFillLayer({ type: 'FeatureCollection', features: data });
return { type: 'FeatureCollection', features };
}
private async addCountyLineLayer() {
const { depth, adcode } = this.options as IProvinceLayerOption;
const countryConfig = DataConfig.country.CHN[depth];
const fillData = await this.fetchData(countryConfig.line);
const data = fillData.features.filter((fe: any) => {
const code = fe.properties.adcode;
return adcode.indexOf(code) !== -1 || adcode.indexOf('' + code) !== -1;
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
);
});
this.addFillLine({ type: 'FeatureCollection', features: data });
return features;
}
}

View File

@ -9,6 +9,7 @@ export interface ILabelOption {
textAllowOverlap: boolean;
opacity: number;
}
export type adcodeType = string[] | string | number | number[];
export interface IDistrictLayerOption {
zIndex: number;
data?: Array<{ [key: string]: any }>;

View File

@ -10,43 +10,91 @@ import {
import merge from 'lodash/merge';
import { DataConfig } from '../config';
import BaseLayer from './baseLayer';
import { IDistrictLayerOption } from './interface';
import { adcodeType, IDistrictLayerOption } from './interface';
export interface IProvinceLayerOption extends IDistrictLayerOption {
adcode: string[];
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) {
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);
}
// 更新渲染数据
public updateData() {
return 'update data';
}
protected getdefaultOption(): IProvinceLayerOption {
const config = super.getdefaultOption();
return merge({}, config, {
adcode: ['440000'],
adcode: ['110000'],
depth: 2,
});
}
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);
const data = fillData.features.filter((fe: any) => {
const code = fe.properties.adcode_pro;
return adcode.indexOf('' + code) !== -1;
this.labelData = fillData.features.map((feature: any) => {
return {
...feature.properties,
center: [feature.properties.x, feature.properties.y],
};
});
this.addFillLayer({ type: 'FeatureCollection', features: data });
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 = fillData.features.filter((fe: any) => {
const code = fe.properties.adcode_pro;
return adcode.indexOf(code) !== -1 || adcode.indexOf('' + code) !== -1;
});
this.addFillLine({ type: 'FeatureCollection', features: data });
const data = this.filterData(fillData, adcode);
this.lineData = fillData;
this.addFillLine(data);
}
}

View File

@ -17,7 +17,7 @@ export default class WorldLayer extends BaseLayer {
this.addFillLayer(fillData);
this.addFillLine(lineData);
if (this.options.label?.enable) {
this.addLableLayer(fillLabel, 'geojson');
this.addLabelLayer(fillLabel, 'geojson');
}
});
}

View File

@ -21,7 +21,7 @@ void main() {
// float blur = smoothstep(1.0, u_blur, length(v_normal.xy));
gl_FragColor.a *= u_opacity;
if(u_line_type == LineTypeDash) {
gl_FragColor.a *= blur * (1.0- step(v_dash_array.x, mod(v_distance_ratio, v_dash_array.x +v_dash_array.y)));
gl_FragColor.a *= (1.0- step(v_dash_array.x, mod(v_distance_ratio, v_dash_array.x +v_dash_array.y)));
}
if(u_aimate.x == Animate) {

View File

@ -1,17 +1,29 @@
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({
@ -24,10 +36,14 @@ export default class Country extends React.Component {
}),
});
scene.on('loaded', () => {
const Layer = new CityLayer(scene, {
this.cityLayer = new CityLayer(scene, {
data: [],
adcode: ['540200', '110100'],
adcode: ['110100'],
depth: 3,
label: {
field: 'NAME_CHN',
textAllowOverlap: false,
},
fill: {
field: 'NAME_CHN',
values: [
@ -52,16 +68,34 @@ export default class Country extends React.Component {
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
<>
<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]]);
};
}

View File

@ -1,17 +1,28 @@
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({
@ -24,10 +35,13 @@ export default class Country extends React.Component {
}),
});
scene.on('loaded', () => {
const Layer = new CountyLayer(scene, {
this.countyLayer = new CountyLayer(scene, {
data: [],
adcode: ['110101', '110102'],
adcode: ['110101'],
depth: 3,
label: {
field: 'NAME_CHN',
},
fill: {
field: 'NAME_CHN',
values: [
@ -52,16 +66,35 @@ export default class Country extends React.Component {
public render() {
return (
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
<>
<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]]);
};
}

View File

@ -1,14 +1,155 @@
import { Scene } from '@antv/l7';
import { ProvinceLayer } from '@antv/l7-district';
import { GaodeMap, Mapbox } from '@antv/l7-maps';
import 'antd/dist/antd.css';
// 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();
}
@ -25,11 +166,17 @@ export default class Country extends React.Component {
maxZoom: 10,
}),
});
scene.on('loaded', () => {
const Layer = new ProvinceLayer(scene, {
const { province } = this.state;
this.provinceLayer = new ProvinceLayer(scene, {
data: [],
adcode: ['440000', '110000'],
depth: 1,
adcode: [province],
depth: 3,
label: {
field: 'NAME_CHN',
textAllowOverlap: false,
},
fill: {
field: 'NAME_CHN',
values: [
@ -55,10 +202,24 @@ export default class Country extends React.Component {
public render() {
return (
<>
<Select defaultValue="lucy" style={{ width: 120 }}>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="Yiminghe">yiminghe</Option>
<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"
@ -73,4 +234,11 @@ export default class Country extends React.Component {
</>
);
}
private handleProvinceChange = (value: string) => {
this.setState({
province: value,
});
this.provinceLayer.updateDistrict([value]);
};
}

View File

@ -1,4 +1,5 @@
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';

27500
stories/assets/css/antd.css Normal file

File diff suppressed because it is too large Load Diff

1480
yarn.lock

File diff suppressed because it is too large Load Diff