diff --git a/docs/api/district/baselayer.en.md b/docs/api/district/baselayer.en.md index 77720a351e..f01fce2d13 100644 --- a/docs/api/district/baselayer.en.md +++ b/docs/api/district/baselayer.en.md @@ -24,6 +24,7 @@ order: 2 - joinBy 数据关联,属性数据如何内部空间数据关联绑定 目前支持 NAME_CHN,adcode 字段连接 对照表 `Array [string, string]` 第一个值为空间数据字段,第二个为传入数据字段名 - depth 数据显示层级 0:国家级,1:省级,2: 市级,3:线级 + - showBorder `boolean` 是否显示国界线,默认显示,不建议不显示 - label 标注配置项 支持常量,不支持数据映射 - enable `boolean` 是否显示标注 @@ -102,6 +103,10 @@ District 提供 polygon 数据需要跟用户的属性数据,通过关系字 - data 需要更新的数据 - joinBy 关联字段 可选,如果不设置保持和初始化一致。 +### getFillData + +获取填充数据,可用于绘制独立的边界线 + #### show 显示图层 diff --git a/docs/api/district/baselayer.zh.md b/docs/api/district/baselayer.zh.md index 77720a351e..924025bc0f 100644 --- a/docs/api/district/baselayer.zh.md +++ b/docs/api/district/baselayer.zh.md @@ -49,6 +49,7 @@ order: 2 - size 气泡大小 支持常量、数据映射 - shape 气泡形状 支持常量、数据映射 - style 气泡图样式 同 PointLayer + - showBorder `boolean` 是否显示国界线,默认显示,不建议不显示 - stroke 填充描边颜色 `ProvinceLayer, CityLayer, CountyLayer` - strokeWidth 填充描边宽度 `ProvinceLayer, CityLayer, CountyLayer` - autoFit 是否自动缩放到图层范围 `boolean` @@ -102,6 +103,10 @@ District 提供 polygon 数据需要跟用户的属性数据,通过关系字 - data 需要更新的数据 - joinBy 关联字段 可选,如果不设置保持和初始化一致。 +### getFillData + +获取填充数据,可用于绘制独立的边界线 + #### show 显示图层 diff --git a/examples/district/basic/API.en.md b/examples/district/basic/API.en.md index 0203ff7e41..1838bfce9e 100644 --- a/examples/district/basic/API.en.md +++ b/examples/district/basic/API.en.md @@ -43,6 +43,7 @@ District 支持下面几种图 - joinBy 数据关联,属性数据如何内部空间数据关联绑定 目前支持 NAME_CHN,adcode 字段连接 对照表 `Array [string, string]` 第一个值为空间数据字段,第二个为传入数据字段名 - depth 数据显示层级 0:国家级,1:省级,2: 市级,3:线级 + - showBorder `boolean` 是否显示国界线,默认显示,不建议不显示 - label 标注配置项 支持常量,不支持数据映射 - enable `boolean` 是否显示标注 - color 标注字体颜色 常量 @@ -111,6 +112,10 @@ District 提供polygon数据需要跟用户的属性数据,通过关系字段 - data 需要更新的数据 - joinBy 关联字段 可选,如果不设置保持和初始化一致。 +### getFillData + +获取填充数据,可用于绘制独立的边界线 + #### show 显示图层 diff --git a/examples/district/basic/API.zh.md b/examples/district/basic/API.zh.md index 96cc79f16d..0877c4adfa 100644 --- a/examples/district/basic/API.zh.md +++ b/examples/district/basic/API.zh.md @@ -41,6 +41,7 @@ District 支持下面几种图 - visible 地图是否可见 - joinBy 数据关联,属性数据如何内部空间数据关联绑定 目前支持 NAME_CHN,adcode 字段连接 对照表 `Array [string, string]` 第一个值为空间数据字段,第二个为传入数据字段名 + - showBorder `boolean` 是否显示国界线,默认显示,不建议不显示 - depth 数据显示层级 0:国家级,1:省级,2: 市级,3:线级 - label 标注配置项 支持常量,不支持数据映射 - enable `boolean` 是否显示标注 @@ -112,6 +113,10 @@ District 提供polygon数据需要跟用户的属性数据,通过关系字段 - data 需要更新的数据 - joinBy 关联字段 可选,如果不设置保持和初始化一致。 +### getFillData + +获取填充数据,可用于绘制独立的边界线 + #### show 显示图层 diff --git a/examples/tutorial/layer/demo/layer_highlight.js b/examples/tutorial/layer/demo/layer_highlight.js new file mode 100644 index 0000000000..72106ec454 --- /dev/null +++ b/examples/tutorial/layer/demo/layer_highlight.js @@ -0,0 +1,63 @@ +import { PolygonLayer, LineLayer, Scene } from '@antv/l7'; +import { GaodeMap } from '@antv/l7-maps'; +const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + style: 'light', + pitch: 0, + center: [ 118.7368, 32.0560 ], + zoom: 9 + }) +}); +scene.on('loaded', () => { + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/91247d10-585b-4406-b1e2-93b001e3a0e4.json' + ) + .then(res => res.json()) + .then(data => { + const filllayer = new PolygonLayer({ + name: 'fill' + }) + .source(data) + .shape('fill') + .color('unit_price', [ '#f0f9e8', '#ccebc5', '#a8ddb5', '#7bccc4', '#43a2ca', '#0868ac' ]) + .style({ + opacity: 1 + }); + const linelayer = new LineLayer({ + zIndex: 1, + name: 'line' + }) + .source(data) + .shape('line') + .size(0.5) + .color('#fff') + .style({ + opacity: 0.5 + }); + const hightLayer = new LineLayer({ + zIndex: 4, // 设置显示层级 + name: 'hightlight' + }) + .source({ + type: 'FeatureCollection', + features: [ ] + }) + .shape('line') + .size(2) + .color('red') + .style({ + opacity: 1 + }); + scene.addLayer(filllayer); + scene.addLayer(linelayer); + scene.addLayer(hightLayer); + filllayer.on('click', feature => { + console.log(feature); + hightLayer.setData({ + type: 'FeatureCollection', + features: [ feature.feature ] + }); + }); + }); +}); diff --git a/examples/tutorial/layer/demo/mapbox.js b/examples/tutorial/layer/demo/mapbox.js new file mode 100644 index 0000000000..63daeb5080 --- /dev/null +++ b/examples/tutorial/layer/demo/mapbox.js @@ -0,0 +1,17 @@ +import { Scale, Zoom, Scene } from '@antv/l7'; +import { Mapbox } from '@antv/l7-maps'; +const scene = new Scene({ + id: 'map', + map: new Mapbox({ + style: 'light', + pitch: 0, + center: [ 107.054293, 35.246265 ], + zoom: 4.056 + }) +}); +scene.on('loaded', () => { + const zoomControl = new Zoom(); + const scaleControl = new Scale(); + scene.addControl(zoomControl); + scene.addControl(scaleControl); +}); diff --git a/examples/tutorial/layer/demo/meta.json b/examples/tutorial/layer/demo/meta.json new file mode 100644 index 0000000000..7e0fad15f0 --- /dev/null +++ b/examples/tutorial/layer/demo/meta.json @@ -0,0 +1,18 @@ +{ + "title": { + "zh": "地图", + "en": "Category" + }, + "demos": [ + { + "filename": "amap.js", + "title": "高德底图组件", + "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*yXzQRYcGTyoAAAAAAAAAAABkARQnAQ" + }, + { + "filename": "mapbox.js", + "title": "MapBox底图组件", + "screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*_SIYR50bbcoAAAAAAAAAAABkARQnAQ" + } + ] +} diff --git a/examples/tutorial/layer/index.en.md b/examples/tutorial/layer/index.en.md new file mode 100644 index 0000000000..cc6bcc0f49 --- /dev/null +++ b/examples/tutorial/layer/index.en.md @@ -0,0 +1,5 @@ +--- +title: Layer +order: 2 +--- +How to use the map control diff --git a/examples/tutorial/layer/index.zh.md b/examples/tutorial/layer/index.zh.md new file mode 100644 index 0000000000..25e6d6ac4a --- /dev/null +++ b/examples/tutorial/layer/index.zh.md @@ -0,0 +1,5 @@ +--- +title: 图层 +order: 2 +--- +图层初始化与交互 diff --git a/packages/boundry/src/layer/baseLayer.ts b/packages/boundry/src/layer/baseLayer.ts index 4d969b886d..0fbff8d6dc 100644 --- a/packages/boundry/src/layer/baseLayer.ts +++ b/packages/boundry/src/layer/baseLayer.ts @@ -59,6 +59,10 @@ export default class BaseLayer extends EventEmitter { this.options = mergeWith(this.options, newOption, mergeCustomizer); } + public getFillData() { + return this.fillData; + } + public updateData( newData: Array<{ [key: string]: any }>, joinByField?: [string, string], @@ -129,13 +133,16 @@ export default class BaseLayer extends EventEmitter { 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, diff --git a/packages/boundry/src/layer/country.ts b/packages/boundry/src/layer/country.ts index 190f54f805..30bfd50d9f 100644 --- a/packages/boundry/src/layer/country.ts +++ b/packages/boundry/src/layer/country.ts @@ -6,14 +6,15 @@ import { IDistrictLayerOption } from './interface'; export default class CountryLayer extends BaseLayer { constructor(scene: Scene, option: Partial = {}) { super(scene, option); - const { depth } = this.options; + const { depth, showBorder } = this.options; this.addProvinceFill(); this.addProvinceLabel(); const countryConfig = getDataConfig(this.options.geoDataLevel).country.CHN[ depth ]; - - this.addProvinceLine(countryConfig.provinceLine); + if (showBorder) { + this.addProvinceLine(countryConfig.provinceLine); + } if (depth === 2 * 1) { this.addCityBorder(countryConfig.fill); @@ -127,6 +128,7 @@ export default class CountryLayer extends BaseLayer { chinaNationalWidth, coastlineStroke, coastlineWidth, + showBorder, stroke, strokeWidth, visible, @@ -135,7 +137,7 @@ export default class CountryLayer extends BaseLayer { // 添加国界线 const lineLayer = new LineLayer({ zIndex: zIndex + 0.1, - visible, + visible: visible && showBorder, }) .source(boundaries) .size('type', (v: string) => { @@ -152,11 +154,11 @@ export default class CountryLayer extends BaseLayer { .shape('line') .color('type', (v: string) => { if (v === '3') { - return provinceStroke; + return provinceStroke; // 省界 } else if (v === '2') { - return coastlineStroke; + return coastlineStroke; // 海岸线 } else if (v === '0') { - return chinaNationalStroke; + return chinaNationalStroke; // 中国国界线 } else { return '#fff'; } @@ -164,7 +166,7 @@ export default class CountryLayer extends BaseLayer { // 添加未定国界 const lineLayer2 = new LineLayer({ zIndex: zIndex + 0.1, - visible, + visible: visible && showBorder, }) .source(boundaries2) .size(chinaNationalWidth) @@ -178,7 +180,7 @@ export default class CountryLayer extends BaseLayer { // 添加澳门香港界限 const lineLayer3 = new LineLayer({ zIndex: zIndex + 0.1, - visible, + visible: visible && showBorder, }) .source(boundaries3) .size(provinceStrokeWidth) diff --git a/packages/boundry/src/layer/interface.ts b/packages/boundry/src/layer/interface.ts index 212877611e..4ebce747b8 100644 --- a/packages/boundry/src/layer/interface.ts +++ b/packages/boundry/src/layer/interface.ts @@ -85,10 +85,13 @@ export interface IDistrictLayerOption { label: Partial; bubble: Partial; fill: Partial; + showBorder: boolean; autoFit: boolean; stroke: string; + strokeVisible: boolean; strokeWidth: number; provinceStroke: string; + provinceStrokeVisible: boolean; cityStroke: string; provinceStrokeWidth: number; cityStrokeWidth: number; diff --git a/packages/boundry/src/layer/province.ts b/packages/boundry/src/layer/province.ts index c8aa866dcb..3376d56136 100644 --- a/packages/boundry/src/layer/province.ts +++ b/packages/boundry/src/layer/province.ts @@ -34,6 +34,7 @@ export default class ProvinceLayer extends BaseLayer { this.hide(); return; } + const { label } = this.options; this.setOption({ adcode }); const fillData = this.filterData(this.fillRawData, adcode); const lineData = this.filterData(this.lineRawData, adcode); @@ -50,7 +51,10 @@ export default class ProvinceLayer extends BaseLayer { this.fillData = fillData; this.updateData(newData, joinByField); this.lineLayer.setData(lineData); - this.labelLayer.setData(labelData); + if (label.enable) { + this.labelLayer.setData(labelData); + } + this.show(); } diff --git a/packages/core/src/services/layer/LayerService.ts b/packages/core/src/services/layer/LayerService.ts index 1cd1c04e77..e5792471c6 100644 --- a/packages/core/src/services/layer/LayerService.ts +++ b/packages/core/src/services/layer/LayerService.ts @@ -92,7 +92,6 @@ export default class LayerService implements ILayerService { this.layers.sort((pre: ILayer, next: ILayer) => { return pre.zIndex - next.zIndex; }); - this.renderLayers(); } public destroy() { diff --git a/packages/layers/src/core/BaseLayer.ts b/packages/layers/src/core/BaseLayer.ts index 3134472e24..cddd4d346c 100644 --- a/packages/layers/src/core/BaseLayer.ts +++ b/packages/layers/src/core/BaseLayer.ts @@ -495,7 +495,6 @@ export default class BaseLayer extends EventEmitter // } else { // this.renderModels(); // } - this.renderModels(); // this.multiPassRenderer.render(); // this.renderModels(); diff --git a/packages/layers/src/line/models/line.ts b/packages/layers/src/line/models/line.ts index 366a4c1429..ffd208638d 100644 --- a/packages/layers/src/line/models/line.ts +++ b/packages/layers/src/line/models/line.ts @@ -123,7 +123,9 @@ export default class LineModel extends BaseModel { attributeIdx: number, ) => { const { size = 1 } = feature; - return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0]; + return Array.isArray(size) + ? [size[0], size[1] + this.layer.zIndex] + : [size as number, this.layer.zIndex]; }, }, }); diff --git a/stories/District/Layer/Country.tsx b/stories/District/Layer/Country.tsx index e13876eca3..d5e538fd82 100644 --- a/stories/District/Layer/Country.tsx +++ b/stories/District/Layer/Country.tsx @@ -1,4 +1,4 @@ -import { Scene } from '@antv/l7'; +import { LineLayer, Scene } from '@antv/l7'; import { CountryLayer } from '@antv/l7-district'; import { GaodeMap, Mapbox } from '@antv/l7-maps'; import * as React from 'react'; @@ -200,6 +200,7 @@ export default class Country extends React.Component { visible: true, data: ProvinceData, joinBy: ['NAME_CHN', 'name'], + showBorder: false, // label: { // field: 'NAME_CHN', // textAllowOverlap: true, @@ -207,7 +208,7 @@ export default class Country extends React.Component { depth: 1, fill: { color: { - field: 'value', + field: 'NAME_CHN', values: [ '#feedde', '#fdd0a2', @@ -225,6 +226,60 @@ export default class Country extends React.Component { }, }, }); + Layer.on('loaded', () => { + const filldata = Layer.getFillData(); + const border = new LineLayer({ + zIndex: 3, // 设置显示层级 + }) + .source(filldata) + .shape('line') + .size(0.6) + .color('#a00') + .style({ + opacity: 1, + }); + const hightLayer = new LineLayer({ + zIndex: 7, // 设置显示层级 + name: 'line3', + }) + .source({ + type: 'FeatureCollection', + features: [], + }) + .shape('line') + .size(0.6) + .color('#000') + .style({ + opacity: 1, + }); + const hightLayer2 = new LineLayer({ + zIndex: 6, // 设置显示层级 + name: 'line3', + }) + .source({ + type: 'FeatureCollection', + features: [], + }) + .shape('line') + .size(2) + .color('#fff') + .style({ + opacity: 1, + }); + scene.addLayer(border); + scene.addLayer(hightLayer); + scene.addLayer(hightLayer2); + Layer.fillLayer.on('click', (feature) => { + hightLayer.setData({ + type: 'FeatureCollection', + features: [feature.feature], + }); + hightLayer2.setData({ + type: 'FeatureCollection', + features: [feature.feature], + }); + }); + }); }); this.scene = scene; } diff --git a/stories/District/Layer/province.tsx b/stories/District/Layer/province.tsx index 3525159fab..41eefa091f 100644 --- a/stories/District/Layer/province.tsx +++ b/stories/District/Layer/province.tsx @@ -220,22 +220,13 @@ export default class Country extends React.Component { geoDataLevel: 1, joinBy: ['adcode', 'code'], adcode: ['330000'], + stroke: '#7096B3', depth: 2, label: { enable: false, }, fill: { - color: { - field: 'NAME_CHN', - values: [ - '#feedde', - '#fdd0a2', - '#fdae6b', - '#fd8d3c', - '#e6550d', - '#a63603', - ], - }, + color: '#A3D7FF', }, popup: { enable: false, diff --git a/stories/Layers/Layers.stories.tsx b/stories/Layers/Layers.stories.tsx index 69c5ab2e8b..9401d9450e 100644 --- a/stories/Layers/Layers.stories.tsx +++ b/stories/Layers/Layers.stories.tsx @@ -13,6 +13,7 @@ import HeatMapDemo from './components/HeatMap'; import HeatMap3D_2 from './components/heatmap2'; import HeatMapDemo3D from './components/heatmap3d'; import HexagonLayerDemo from './components/hexagon'; +import HighLight from './components/highlight'; import LineLayer from './components/Line'; import LineAnimate from './components/lineAnimate'; import PointDemo from './components/Point'; @@ -50,4 +51,5 @@ storiesOf('图层', module) .add('栅格', () => ) .add('图片', () => ) .add('网格测试', () => ) + .add('图层高亮', () => ) .add('世界地图', () => ); diff --git a/stories/Layers/components/highlight.tsx b/stories/Layers/components/highlight.tsx new file mode 100644 index 0000000000..003f674750 --- /dev/null +++ b/stories/Layers/components/highlight.tsx @@ -0,0 +1,126 @@ +import { LineLayer, PolygonLayer, Scene } from '@antv/l7'; +import { Mapbox } from '@antv/l7-maps'; +import * as React from 'react'; + +export default class LineDemo 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({ + style: 'light', + pitch: 0, + center: [118.7368, 32.056], + zoom: 9, + }), + }); + scene.on('loaded', () => { + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/91247d10-585b-4406-b1e2-93b001e3a0e4.json', + ) + .then((res) => res.json()) + .then((data) => { + const filllayer = new PolygonLayer({ + name: 'fill', + zIndex: 3, + }) + .source(data) + .shape('fill') + .color('unit_price', [ + '#f0f9e8', + '#ccebc5', + '#a8ddb5', + '#7bccc4', + '#43a2ca', + '#0868ac', + ]) + .style({ + opacity: 1, + }); + + const filllayer2 = new PolygonLayer({ + name: 'fill', + zIndex: 1, + }) + .source(data) + .shape('fill') + .color('red') + .style({ + opacity: 1, + }); + const linelayer = new LineLayer({ + zIndex: 5, + name: 'line2', + }) + .source(data) + .shape('line') + .size(2) + .color('#fff') + .style({ + opacity: 1, + }); + const hightLayer = new LineLayer({ + zIndex: 4, // 设置显示层级 + name: 'line1', + }) + .source(data) + .shape('line') + .size(3) + .color('#f00') + .style({ + opacity: 1, + }); + const hightLayer2 = new LineLayer({ + zIndex: 6, // 设置显示层级 + name: 'line3', + }) + .source(data) + .shape('line') + .size(0.6) + .color('#000') + .style({ + opacity: 1, + }); + scene.addLayer(filllayer); + scene.addLayer(filllayer2); + scene.addLayer(linelayer); + scene.addLayer(hightLayer); + scene.addLayer(hightLayer2); + this.scene = scene; + + // filllayer.on('click', (feature) => { + // hightLayer.setData({ + // type: 'FeatureCollection', + // features: [feature.feature], + // }); + // hightLayer2.setData({ + // type: 'FeatureCollection', + // features: [feature.feature], + // }); + // }); + // scene.render(); + }); + }); + } + + public render() { + return ( +
+ ); + } +}