fix(district): fix polygon layer setData 样式不生效 & 增加下钻上取地图

This commit is contained in:
thinkinggis 2020-05-11 18:58:46 +08:00
parent 6120d0904d
commit b6a92b1994
9 changed files with 167 additions and 32 deletions

View File

@ -12,10 +12,16 @@ import { EventEmitter } from 'eventemitter3';
// @ts-ignore // @ts-ignore
import geobuf from 'geobuf'; import geobuf from 'geobuf';
// tslint:disable-next-line: no-submodule-imports // tslint:disable-next-line: no-submodule-imports
import merge from 'lodash/merge'; import merge from 'lodash/mergeWith';
// @ts-ignore // @ts-ignore
import Pbf from 'pbf'; import Pbf from 'pbf';
import { IDistrictLayerOption } from './interface'; import { IDistrictLayerOption } from './interface';
function mergeCustomizer(objValue: any, srcValue: any) {
if (Array.isArray(srcValue)) {
return srcValue;
}
}
export default class BaseLayer extends EventEmitter { export default class BaseLayer extends EventEmitter {
public fillLayer: ILayer; public fillLayer: ILayer;
public lineLayer: ILayer; public lineLayer: ILayer;
@ -28,7 +34,7 @@ export default class BaseLayer extends EventEmitter {
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) { constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
super(); super();
this.scene = scene; this.scene = scene;
this.options = merge({}, this.getDefaultOption(), option); this.options = merge(this.getDefaultOption(), option, mergeCustomizer);
} }
public destroy() { public destroy() {
@ -82,8 +88,10 @@ export default class BaseLayer extends EventEmitter {
countyStroke: 'rgba(255,255,255,0.6)', countyStroke: 'rgba(255,255,255,0.6)',
coastlineStroke: '#4190da', coastlineStroke: '#4190da',
coastlineWidth: 1, coastlineWidth: 1,
nationalStroke: 'gray', nationalStroke: '#c994c7',
nationalWidth: 1, nationalWidth: 0.5,
chinaNationalStroke: 'gray',
chinaNationalWidth: 1,
popup: { popup: {
enable: true, enable: true,
triggerEvent: 'mousemove', triggerEvent: 'mousemove',
@ -156,6 +164,13 @@ export default class BaseLayer extends EventEmitter {
} }
protected addLabelLayer(labelData: any, type: string = 'json') { protected addLabelLayer(labelData: any, type: string = 'json') {
const labelLayer = this.addLabel(labelData, type);
this.scene.addLayer(labelLayer);
this.layers.push(labelLayer);
this.labelLayer = labelLayer;
}
protected addLabel(labelData: any, type: string = 'json') {
const { label, zIndex } = this.options; const { label, zIndex } = this.options;
const labelLayer = new PointLayer({ const labelLayer = new PointLayer({
zIndex: zIndex + 2, zIndex: zIndex + 2,
@ -175,9 +190,7 @@ export default class BaseLayer extends EventEmitter {
strokeWidth: label.strokeWidth, strokeWidth: label.strokeWidth,
textAllowOverlap: label.textAllowOverlap, textAllowOverlap: label.textAllowOverlap,
}); });
this.scene.addLayer(labelLayer); return labelLayer;
this.layers.push(labelLayer);
this.labelLayer = labelLayer;
} }
protected addPopup() { protected addPopup() {

View File

@ -17,7 +17,12 @@ export default class CountryLayer extends BaseLayer {
this.loadData().then(([fillData, fillLabel]) => { this.loadData().then(([fillData, fillLabel]) => {
this.addFillLayer(fillData); this.addFillLayer(fillData);
if (fillLabel && this.options.label?.enable) { if (fillLabel && this.options.label?.enable) {
this.addLabelLayer(fillLabel); this.addLabelLayer(
fillLabel.filter((v: any) => {
return v.name !== '澳门';
}),
);
this.addMCLabel();
} }
}); });
const countryConfig = DataConfig.country.CHN[depth]; const countryConfig = DataConfig.country.CHN[depth];
@ -88,6 +93,8 @@ export default class CountryLayer extends BaseLayer {
const { const {
nationalStroke, nationalStroke,
nationalWidth, nationalWidth,
chinaNationalStroke,
chinaNationalWidth,
coastlineStroke, coastlineStroke,
coastlineWidth, coastlineWidth,
stroke, stroke,
@ -105,7 +112,7 @@ export default class CountryLayer extends BaseLayer {
} else if (v === '2') { } else if (v === '2') {
return coastlineWidth; return coastlineWidth;
} else if (v === '0') { } else if (v === '0') {
return nationalWidth; return chinaNationalWidth;
} else { } else {
return '#fff'; return '#fff';
} }
@ -117,7 +124,7 @@ export default class CountryLayer extends BaseLayer {
} else if (v === '2') { } else if (v === '2') {
return coastlineStroke; return coastlineStroke;
} else if (v === '0') { } else if (v === '0') {
return nationalStroke; return chinaNationalStroke;
} else { } else {
return '#fff'; return '#fff';
} }
@ -158,7 +165,6 @@ export default class CountryLayer extends BaseLayer {
// 县级边界 // 县级边界
private async addCountryBorder(cfg: any) { private async addCountryBorder(cfg: any) {
// const bordConfig = DataConfig.country.CHN[3];
const border1 = await this.fetchData(cfg); const border1 = await this.fetchData(cfg);
const { countyStrokeWidth, countyStroke } = this.options; const { countyStrokeWidth, countyStroke } = this.options;
const cityline = new LineLayer({ const cityline = new LineLayer({
@ -173,4 +179,48 @@ export default class CountryLayer extends BaseLayer {
this.scene.addLayer(cityline); this.scene.addLayer(cityline);
this.layers.push(cityline); this.layers.push(cityline);
} }
private addMCLabel() {
const data = [
{
name: '澳门',
center: [113.537747, 22.187009],
},
];
const labelLayer1 = this.addText(data, { maxZoom: 3 }, [-45, -10]);
const labelLayer2 = this.addText(data, { minZoom: 3, maxZoom: 4 }, [
-35,
-10,
]);
const labelLayer = this.addText(data, { minZoom: 4 }, [0, 0]);
this.scene.addLayer(labelLayer);
this.scene.addLayer(labelLayer1);
this.scene.addLayer(labelLayer2);
this.layers.push(labelLayer, labelLayer1);
}
private addText(labelData: any, option: any, offset: [number, number]) {
const { label, zIndex } = this.options;
const labelLayer = new PointLayer({
zIndex: zIndex + 2,
...option,
})
.source(labelData, {
parser: {
type: 'json',
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,
textOffset: offset,
});
return labelLayer;
}
} }

View File

@ -8,30 +8,71 @@ export default class DrillDownLayer {
private provinceLayer: ProvinceLayer; private provinceLayer: ProvinceLayer;
private cityLayer: CityLayer; private cityLayer: CityLayer;
private countryLayer: CountryLayer; private countryLayer: CountryLayer;
private scene: Scene;
constructor(scene: Scene, option: Partial<IDistrictLayerOption>) { constructor(scene: Scene, option: Partial<IDistrictLayerOption>) {
const cfg = this.getDefaultOption(); const cfg = this.getDefaultOption();
this.scene = scene;
this.countryLayer = new CountryLayer(scene, option); this.countryLayer = new CountryLayer(scene, option);
this.provinceLayer = new ProvinceLayer(scene, cfg.city); this.provinceLayer = new ProvinceLayer(scene, cfg.city);
// this.cityLayer = new CityLayer(scene); this.cityLayer = new CityLayer(scene, cfg.county);
// this.provinceLayer.hide(); this.scene.setMapStatus({ doubleClickZoom: false });
// this.cityLayer.hide();
this.countryLayer.on('loaded', () => { this.countryLayer.on('loaded', () => {
this.addCountryEvent();
});
this.provinceLayer.on('loaded', () => {
this.addProvinceEvent(); this.addProvinceEvent();
}); });
this.cityLayer.on('loaded', () => {
this.addCityEvent();
});
} }
public getDefaultOption() { public getDefaultOption() {
return { return {
province: {}, province: {},
city: { city: {
adcode: '', adcode: [],
}, },
county: { county: {
adcode: [], adcode: [],
}, },
}; };
} }
public addCountryEvent() {
this.countryLayer.fillLayer.on('click', (e: any) => {
this.countryLayer.hide();
// 更新市级行政区划
this.provinceLayer.updateDistrict([e.feature.properties.adcode]);
});
}
public addProvinceEvent() { public addProvinceEvent() {
// this.countryLayer.fillLayer.on('click', (e: any) => { this.provinceLayer.fillLayer.on('undblclick', () => {
// }); this.countryLayer.show();
this.countryLayer.fillLayer.fitBounds();
this.provinceLayer.hide();
});
this.provinceLayer.fillLayer.on('click', (e: any) => {
this.provinceLayer.hide();
let adcode = e.feature.properties.adcode.toFixed(0);
if (adcode.substr(2, 2) === '00') {
adcode = adcode.substr(0, 2) + '0100';
}
// 更新县级行政区划
this.cityLayer.updateDistrict([adcode]);
});
}
public addCityEvent() {
this.cityLayer.fillLayer.on('undblclick', () => {
this.provinceLayer.show();
this.provinceLayer.fillLayer.fitBounds();
this.cityLayer.hide();
});
}
public destroy() {
this.countryLayer.destroy();
this.provinceLayer.destroy();
this.cityLayer.destroy();
} }
} }

View File

@ -35,6 +35,8 @@ export interface IDistrictLayerOption {
coastlineWidth: number; coastlineWidth: number;
nationalStroke: string; nationalStroke: string;
nationalWidth: number; nationalWidth: number;
chinaNationalStroke: string;
chinaNationalWidth: number;
popup: Partial<{ popup: Partial<{
enable: boolean; enable: boolean;
triggerEvent: 'mousemove' | 'click'; triggerEvent: 'mousemove' | 'click';

View File

@ -13,7 +13,6 @@ export default class WorldLayer extends BaseLayer {
constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) { constructor(scene: Scene, option: Partial<IDistrictLayerOption> = {}) {
super(scene, option); super(scene, option);
this.loadData().then(([fillData, lineData, fillLabel]) => { this.loadData().then(([fillData, lineData, fillLabel]) => {
// this.addWorldBorder(border1, border2, island);
this.addFillLayer(fillData); this.addFillLayer(fillData);
this.addFillLine(lineData); this.addFillLine(lineData);
if (this.options.label?.enable) { if (this.options.label?.enable) {
@ -28,18 +27,21 @@ export default class WorldLayer extends BaseLayer {
return ( return (
feature.properties.type === '10' || feature.properties.type === '10' ||
feature.properties.type === '1' || feature.properties.type === '1' ||
feature.properties.type === '11' feature.properties.type === '11' ||
feature.properties.type === '8'
); );
}); });
const bordFc = { const bordFc = {
type: 'FeatureCollection', type: 'FeatureCollection',
features: bord1, features: bord1,
}; };
// 已确定国界
const nationalBorder = data.features.filter((feature: any) => { const nationalBorder = data.features.filter((feature: any) => {
return ( return (
feature.properties.type !== '10' && feature.properties.type !== '10' &&
feature.properties.type !== '1' && feature.properties.type !== '1' &&
feature.properties.type !== '11' feature.properties.type !== '11' &&
feature.properties.type !== '8'
); );
}); });
const nationalFc = { const nationalFc = {
@ -62,6 +64,8 @@ export default class WorldLayer extends BaseLayer {
nationalStroke, nationalStroke,
nationalWidth, nationalWidth,
coastlineStroke, coastlineStroke,
chinaNationalStroke,
chinaNationalWidth,
coastlineWidth, coastlineWidth,
zIndex, zIndex,
} = this.options; } = this.options;
@ -73,15 +77,13 @@ export default class WorldLayer extends BaseLayer {
.size(0.6) .size(0.6)
.color('type', (v: string) => { .color('type', (v: string) => {
if (v === '0') { if (v === '0') {
return 'rgb(99,100, 99)'; // 中国国界线 return chinaNationalStroke; // 中国国界线
} else if (v === '2') { } else if (v === '2' || v === '9') {
return 'rgb(0,136, 191)'; // 中国海岸线 return coastlineStroke; // 中国海岸线
} else if (v === '9') {
return 'rgb(0,136, 191)'; // 国外海岸线
} else if (v === '7') { } else if (v === '7') {
return '#9ecae1'; // 国外国界 return nationalStroke; // 国外国界
} else { } else {
return '#9ecae1'; return nationalStroke;
} }
}); });
// 添加未定国界 // 添加未定国界
@ -89,13 +91,19 @@ export default class WorldLayer extends BaseLayer {
zIndex: zIndex + 1, zIndex: zIndex + 1,
}) })
.source(boundaries2) .source(boundaries2)
.size(nationalWidth) .size('type', (v: string) => {
if (v === '1') {
return chinaNationalWidth;
} else {
return nationalWidth;
}
})
.shape('line') .shape('line')
.color('type', (v: string) => { .color('type', (v: string) => {
if (v === '1') { if (v === '1') {
return 'rgb(99,100, 99)'; return chinaNationalStroke;
} else { } else {
return '#9ecae1'; return nationalStroke;
} }
}) })
.style({ .style({

View File

@ -684,6 +684,10 @@ export default class BaseLayer<ChildLayerStyleOptions = {}> extends EventEmitter
} }
const source = this.getSource(); const source = this.getSource();
const extent = source.extent; const extent = source.extent;
const isValid = extent.some((v) => Math.abs(v) === Infinity);
if (isValid) {
return this;
}
this.mapService.fitBounds( this.mapService.fitBounds(
[ [
[extent[0], extent[1]], [extent[0], extent[1]],

View File

@ -61,6 +61,9 @@ export default class FeatureScalePlugin implements ILayerPlugin {
this.scaleOptions = layer.getScaleOptions(); this.scaleOptions = layer.getScaleOptions();
const attributes = styleAttributeService.getLayerStyleAttributes(); const attributes = styleAttributeService.getLayerStyleAttributes();
const { dataArray } = layer.getSource().data; const { dataArray } = layer.getSource().data;
if (dataArray.length === 0) {
return;
}
this.caculateScalesForAttributes(attributes || [], dataArray); this.caculateScalesForAttributes(attributes || [], dataArray);
}); });
@ -69,6 +72,9 @@ export default class FeatureScalePlugin implements ILayerPlugin {
this.scaleOptions = layer.getScaleOptions(); this.scaleOptions = layer.getScaleOptions();
const attributes = styleAttributeService.getLayerStyleAttributes(); const attributes = styleAttributeService.getLayerStyleAttributes();
const { dataArray } = layer.getSource().data; const { dataArray } = layer.getSource().data;
if (dataArray.length === 0) {
return;
}
this.caculateScalesForAttributes(attributes || [], dataArray); this.caculateScalesForAttributes(attributes || [], dataArray);
return true; return true;
}); });
@ -78,6 +84,9 @@ export default class FeatureScalePlugin implements ILayerPlugin {
const attributes = styleAttributeService.getLayerStyleAttributes(); const attributes = styleAttributeService.getLayerStyleAttributes();
if (attributes) { if (attributes) {
const { dataArray } = layer.getSource().data; const { dataArray } = layer.getSource().data;
if (dataArray.length === 0) {
return;
}
const attributesToRescale = attributes.filter( const attributesToRescale = attributes.filter(
(attribute) => attribute.needRescale, (attribute) => attribute.needRescale,
); );

View File

@ -19,7 +19,7 @@ export default class Country extends React.Component {
pitch: 0, pitch: 0,
style: 'blank', style: 'blank',
zoom: 3, zoom: 3,
minZoom: 3, minZoom: 0,
maxZoom: 10, maxZoom: 10,
}), }),
}); });

View File

@ -112,8 +112,12 @@ export default class TextLayerDemo extends React.Component {
}); });
scene.on('loaded', () => { scene.on('loaded', () => {
const layer = new PolygonLayer({}) const layer = new PolygonLayer({})
.source(data) .source({
type: 'FeatureCollection',
features: [],
})
.shape('fill') .shape('fill')
// .color('red')
.color('childrenNum', [ .color('childrenNum', [
'rgb(247,252,240)', 'rgb(247,252,240)',
'rgb(224,243,219)', 'rgb(224,243,219)',
@ -128,6 +132,10 @@ export default class TextLayerDemo extends React.Component {
opacity: 1.0, opacity: 1.0,
}); });
scene.addLayer(layer); scene.addLayer(layer);
setTimeout(() => {
layer.setData(data);
console.log('update');
}, 2000);
layer.on('click', (e) => { layer.on('click', (e) => {
console.log(e); console.log(e);
}); });