Fix 矢量瓦片拾取&线纹理&一些lint fixed (#1598)

* feat: 栅格表示添加 min/max/log10/log2/计算逻辑

* fix: lint format

* fix: 文本避让

* fix: utils some error

* fix: 文本支持 fontFamily,fontweight,padding 更新

* chore: 图片标注图层空数据改为空图标

* chore: fillImange 默认shape 为透明

* fix: 瓦片拾取featureID 兼容

* fix: line 纹理事件

* chore: ts lint fixed
This commit is contained in:
@thinkinggis 2023-02-14 10:25:00 +08:00 committed by GitHub
parent a0b79e89cd
commit 5a96e01ad5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 261 additions and 163 deletions

View File

@ -0,0 +1,77 @@
// @ts-ignore
import { Scene, PolygonLayer, PointLayer } from '@antv/l7';
// @ts-ignore
import { Map } from '@antv/l7-maps';
import React, { useEffect } from 'react';
export default () => {
useEffect(() => {
const scene = new Scene({
id: 'map',
map: new Map({
center: [119.586579, 39.942531],
zoom: 8,
minZoom: 7,
maxZoom: 18,
}),
});
const layer = new PolygonLayer({
featureId: 'id',
sourceLayer: 'qhd_bianhua_jiance',// woods hillshade contour ecoregions ecoregions2 city
});
const url =
'//114.116.251.141:2183/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=ellip:qhd_bianhua_jiance&STYLE=&TILEMATRIX=EPSG:3857:{z}&TILEMATRIXSET=EPSG:3857&FORMAT=application/vnd.mapbox-vector-tile&TILECOL={x}&TILEROW={y}';
layer
.source(
url,
{
parser: {
type: 'mvt',
tileSize: 256,
extent: [-180, -85.051129, 179, 85.051129],
},
},
)
.shape('fill')
.color('red')
// .active(true)
.select(true)
.style({
// opacity: 0.3
});
scene.on('loaded', () => {
scene.addLayer(layer);
console.log(layer)
// layer.on('inited', () => {
// console.log(
// 'layer.getLayerConfig().enableHighlight',
// layer.getLayerConfig().enableHighlight,
// );
// });
layer.on('click', (e) => {
console.log(e);
});
});
}, []);
return (
<div
id="map"
style={{
height: '60vh',
position: 'relative',
}}
/>
);
};

View File

@ -0,0 +1,13 @@
---
group:
path: 'vector'
title: '矢量瓦片'
order: 1
title: 瓦片交互
order: 0
---
### 瓦片交互
<code src="./demos/event.tsx"></code>

View File

@ -44,15 +44,12 @@ export default class PickingService implements IPickingService {
private pickBufferScale: number = 1.0; private pickBufferScale: number = 1.0;
public init(id: string) { public init(id: string) {
const { const { createTexture2D, createFramebuffer, getContainer } =
createTexture2D, this.rendererService;
createFramebuffer,
getContainer,
} = this.rendererService;
let { width, height } = this.getContainerSize( let { width, height } = this.getContainerSize(
getContainer() as HTMLCanvasElement | HTMLElement, getContainer() as HTMLCanvasElement | HTMLElement,
); );
width *= DOM.DPR; width *= DOM.DPR;
height *= DOM.DPR; height *= DOM.DPR;
this.pickBufferScale = this.pickBufferScale =
@ -134,7 +131,8 @@ export default class PickingService implements IPickingService {
const color = pickedColors.slice(i * 4, i * 4 + 4); const color = pickedColors.slice(i * 4, i * 4 + 4);
const pickedFeatureIdx = decodePickingColor(color); const pickedFeatureIdx = decodePickingColor(color);
if (pickedFeatureIdx !== -1 && !featuresIdMap[pickedFeatureIdx]) { if (pickedFeatureIdx !== -1 && !featuresIdMap[pickedFeatureIdx]) {
const rawFeature = layer.layerPickService.getFeatureById(pickedFeatureIdx); const rawFeature =
layer.layerPickService.getFeatureById(pickedFeatureIdx);
features.push({ features.push({
// @ts-ignore // @ts-ignore
...rawFeature, ...rawFeature,
@ -217,9 +215,10 @@ export default class PickingService implements IPickingService {
pickedColors[2] !== 0 pickedColors[2] !== 0
) { ) {
const pickedFeatureIdx = decodePickingColor(pickedColors); const pickedFeatureIdx = decodePickingColor(pickedColors);
// 瓦片数据获取性能问题需要优化 // 瓦片数据获取性能问题需要优化
const rawFeature = layer.layerPickService.getFeatureById(pickedFeatureIdx); const rawFeature =
layer.layerPickService.getFeatureById(pickedFeatureIdx);
if ( if (
pickedFeatureIdx !== layer.getCurrentPickId() && pickedFeatureIdx !== layer.getCurrentPickId() &&
type === 'mousemove' type === 'mousemove'
@ -276,7 +275,6 @@ export default class PickingService implements IPickingService {
type === 'click' && type === 'click' &&
pickedColors?.toString() !== [0, 0, 0, 0].toString() pickedColors?.toString() !== [0, 0, 0, 0].toString()
) { ) {
const selectedId = decodePickingColor(pickedColors); const selectedId = decodePickingColor(pickedColors);
if ( if (
layer.getCurrentSelectedId() === null || layer.getCurrentSelectedId() === null ||
@ -305,7 +303,8 @@ export default class PickingService implements IPickingService {
} }
private async pickingAllLayer(target: IInteractionTarget) { private async pickingAllLayer(target: IInteractionTarget) {
// 判断是否进行拾取操作 // 判断是否进行拾取操作
if (!this.layerService.needPick(target.type) ||!this.isPickingAllLayer()) return; if (!this.layerService.needPick(target.type) || !this.isPickingAllLayer())
return;
this.alreadyInPicking = true; this.alreadyInPicking = true;
await this.pickingLayers(target); await this.pickingLayers(target);
this.layerService.renderLayers(); this.layerService.renderLayers();
@ -314,13 +313,13 @@ export default class PickingService implements IPickingService {
private isPickingAllLayer() { private isPickingAllLayer() {
// this.alreadyInPicking 避免多次重复拾取 // this.alreadyInPicking 避免多次重复拾取
if (this.alreadyInPicking) return false; if (this.alreadyInPicking) { return false; }
// this.layerService.alreadyInRendering 一个渲染序列中只进行一次拾取操作 // this.layerService.alreadyInRendering 一个渲染序列中只进行一次拾取操作
if (this.layerService.alreadyInRendering) return false; if (this.layerService.alreadyInRendering) { return false; }
// this.interactionService.dragging amap2 在点击操作的时候同时会触发 dragging 的情况(避免舍去) // this.interactionService.dragging amap2 在点击操作的时候同时会触发 dragging 的情况(避免舍去)
if (this.interactionService.indragging) return false; if (this.interactionService.indragging) { return false; }
// 判断当前进行 shader pick 拾取判断 // 判断当前进行 shader pick 拾取判断
if (!this.layerService.getShaderPickStat()) return false; if (!this.layerService.getShaderPickStat()) { return false; }
// 进行拾取 // 进行拾取
return true; return true;
@ -349,13 +348,13 @@ export default class PickingService implements IPickingService {
useFramebuffer(this.pickingFBO, () => { useFramebuffer(this.pickingFBO, () => {
const layers = this.layerService.getRenderList(); const layers = this.layerService.getRenderList();
layers layers
.filter((layer) => { .filter((layer) => {
return layer.needPick(target.type)}) return layer.needPick(target.type);
})
.reverse() .reverse()
.some((layer) => { .some((layer) => {
clear({ clear({
framebuffer: this.pickingFBO, framebuffer: this.pickingFBO,
color: [0, 0, 0, 0], color: [0, 0, 0, 0],
@ -389,5 +388,4 @@ export default class PickingService implements IPickingService {
layer.emit(target.type, target); layer.emit(target.type, target);
} }
} }
} }

View File

@ -31,8 +31,9 @@ const lineStyleObj: { [key: string]: number } = {
dash: 1.0, dash: 1.0,
}; };
export default class LineModel extends BaseModel { export default class LineModel extends BaseModel {
private textureEventFlag: boolean = false;
protected texture: ITexture2D = this.createTexture2D({ protected texture: ITexture2D = this.createTexture2D({
data: [0,0,0,0], data: [0, 0, 0, 0],
mag: gl.NEAREST, mag: gl.NEAREST,
min: gl.NEAREST, min: gl.NEAREST,
premultiplyAlpha: false, premultiplyAlpha: false,
@ -68,7 +69,6 @@ export default class LineModel extends BaseModel {
} }
if (this.rendererService.getDirty()) { if (this.rendererService.getDirty()) {
this.texture && this.texture.bind(); this.texture && this.texture.bind();
} }
@ -92,7 +92,7 @@ export default class LineModel extends BaseModel {
); );
this.rowCount = height; // 当前数据纹理有多少行 this.rowCount = height; // 当前数据纹理有多少行
this.dataTexture = this.dataTexture =
this.cellLength > 0 && data.length > 0 this.cellLength > 0 && data.length > 0
? this.createTexture2D({ ? this.createTexture2D({
@ -123,7 +123,7 @@ export default class LineModel extends BaseModel {
u_blur: blur, u_blur: blur,
// 纹理支持参数 // 纹理支持参数
u_texture: this.texture, // 贴图 u_texture: this.texture, // 贴图
u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识 u_line_texture: lineTexture ? 1.0 : 0.0, // 传入线的标识
u_icon_step: iconStep, u_icon_step: iconStep,
u_textSize: [1024, this.iconService.canvasHeight || 128], u_textSize: [1024, this.iconService.canvasHeight || 128],
@ -160,10 +160,15 @@ export default class LineModel extends BaseModel {
}; };
} }
public async initModels():Promise<IModel[]>{ public async initModels(): Promise<IModel[]> {
// this.updateTexture(); // this.updateTexture();
// this.iconService.on('imageUpdate', this.updateTexture); // this.iconService.on('imageUpdate', this.updateTexture);
return await this.buildModels(); if (!this.textureEventFlag) {
this.textureEventFlag = true;
this.updateTexture();
this.iconService.on('imageUpdate', this.updateTexture);
}
return this.buildModels();
} }
public clearModels() { public clearModels() {
@ -206,11 +211,8 @@ export default class LineModel extends BaseModel {
* @returns * @returns
*/ */
public getShaders(): { frag: string; vert: string; type: string } { public getShaders(): { frag: string; vert: string; type: string } {
const { const { sourceColor, targetColor, lineType } =
sourceColor, this.layer.getLayerConfig() as ILineLayerStyleOptions;
targetColor,
lineType,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
if (lineType === 'dash') { if (lineType === 'dash') {
return { return {
@ -374,7 +376,6 @@ export default class LineModel extends BaseModel {
} }
private updateTexture = () => { private updateTexture = () => {
const { createTexture2D } = this.rendererService; const { createTexture2D } = this.rendererService;
if (this.texture) { if (this.texture) {
this.texture.update({ this.texture.update({

View File

@ -1,4 +1,12 @@
import { ILayerService, ITile, ITilePickService, IInteractionTarget, ILayer, IPickingService, TYPES } from '@antv/l7-core'; import {
IInteractionTarget,
ILayer,
ILayerService,
IPickingService,
ITile,
ITilePickService,
TYPES,
} from '@antv/l7-core';
import { decodePickingColor, encodePickingColor } from '@antv/l7-utils'; import { decodePickingColor, encodePickingColor } from '@antv/l7-utils';
import { TileLayerService } from './TileLayerService'; import { TileLayerService } from './TileLayerService';
import { TileSourceService } from './TileSourceService'; import { TileSourceService } from './TileSourceService';
@ -10,26 +18,29 @@ export interface ITilePickServiceOptions {
const SELECT = 'select'; const SELECT = 'select';
const ACTIVE = 'active'; const ACTIVE = 'active';
export class TilePickService implements ITilePickService{ export class TilePickService implements ITilePickService {
private layerService: ILayerService; private layerService: ILayerService;
private tileLayerService: TileLayerService; private tileLayerService: TileLayerService;
private tileSourceService: TileSourceService; private tileSourceService: TileSourceService;
private parent: ILayer; private parent: ILayer;
private tilePickID = new Map(); private tilePickID = new Map();
constructor({ layerService, tileLayerService, parent }: ITilePickServiceOptions) { constructor({
layerService,
tileLayerService,
parent,
}: ITilePickServiceOptions) {
this.layerService = layerService; this.layerService = layerService;
this.tileLayerService = tileLayerService; this.tileLayerService = tileLayerService;
this.parent = parent; this.parent = parent;
this.tileSourceService = new TileSourceService(); this.tileSourceService = new TileSourceService();
} }
pickRender(target: IInteractionTarget) { public pickRender(target: IInteractionTarget) {
// 一个 TileLayer 有多个 Tile但是会同时触发事件的只有一个 Tile // 一个 TileLayer 有多个 Tile但是会同时触发事件的只有一个 Tile
const tile = this.tileLayerService.getVisibleTileBylngLat(target.lngLat); const tile = this.tileLayerService.getVisibleTileBylngLat(target.lngLat);
if (tile) { if (tile) {
// TODO 多图层拾取 // TODO 多图层拾取
const pickLayer = tile.getMainLayer(); const pickLayer = tile.getMainLayer();
pickLayer?.layerPickService.pickRender(target) pickLayer?.layerPickService.pickRender(target);
} }
} }
@ -38,21 +49,24 @@ export class TilePickService implements ITilePickService{
const pickingService = container.get<IPickingService>( const pickingService = container.get<IPickingService>(
TYPES.IPickingService, TYPES.IPickingService,
); );
if(layer.type === 'RasterLayer') { if (layer.type === 'RasterLayer') {
const tile = this.tileLayerService.getVisibleTileBylngLat(target.lngLat); const tile = this.tileLayerService.getVisibleTileBylngLat(target.lngLat);
if (tile && tile.getMainLayer() !== undefined) { if (tile && tile.getMainLayer() !== undefined) {
const pickLayer = tile.getMainLayer() as ILayer; const pickLayer = tile.getMainLayer() as ILayer;
return pickLayer.layerPickService.pickRasterLayer(pickLayer, target, this.parent); return pickLayer.layerPickService.pickRasterLayer(
pickLayer,
target,
this.parent,
);
} }
return false; return false;
} }
this.pickRender(target); this.pickRender(target);
return pickingService.pickFromPickingFBO(layer, target); return pickingService.pickFromPickingFBO(layer, target);
} }
selectFeature(pickedColors: Uint8Array | undefined) { public selectFeature(pickedColors: Uint8Array | undefined) {
// @ts-ignore // @ts-ignore
const [r, g, b] = pickedColors; const [r, g, b] = pickedColors;
const id = this.color2PickId(r, g, b); const id = this.color2PickId(r, g, b);
@ -60,7 +74,7 @@ export class TilePickService implements ITilePickService{
this.updateHighLight(r, g, b, SELECT); this.updateHighLight(r, g, b, SELECT);
} }
highlightPickedFeature(pickedColors: Uint8Array | undefined) { public highlightPickedFeature(pickedColors: Uint8Array | undefined) {
// @ts-ignore // @ts-ignore
const [r, g, b] = pickedColors; const [r, g, b] = pickedColors;
const id = this.color2PickId(r, g, b); const id = this.color2PickId(r, g, b);
@ -68,65 +82,70 @@ export class TilePickService implements ITilePickService{
this.updateHighLight(r, g, b, ACTIVE); this.updateHighLight(r, g, b, ACTIVE);
} }
updateHighLight(r: number, g: number, b: number, type: string){ public updateHighLight(r: number, g: number, b: number, type: string) {
this.tileLayerService.tiles.map((tile: ITile) => { this.tileLayerService.tiles.map((tile: ITile) => {
const layer = tile.getMainLayer(); const layer = tile.getMainLayer();
switch(type) { switch (type) {
case SELECT: case SELECT:
layer?.hooks.beforeSelect.call([r, g, b]); layer?.hooks.beforeSelect.call([r, g, b]);
break; break;
case ACTIVE: case ACTIVE:
layer?.hooks.beforeHighlight.call([r, g, b]); layer?.hooks.beforeHighlight.call([r, g, b]);
break; break;
} }
}); });
} }
setPickState() { public setPickState() {
const selectColor = this.tilePickID.get(SELECT) const selectColor = this.tilePickID.get(SELECT);
const activeColor = this.tilePickID.get(ACTIVE) const activeColor = this.tilePickID.get(ACTIVE);
if(selectColor) { if (selectColor) {
const [r, g, b] = this.pickId2Color(selectColor); const [r, g, b] = this.pickId2Color(selectColor);
this.updateHighLight(r, g, b, SELECT); this.updateHighLight(r, g, b, SELECT);
return; return;
} }
if(activeColor) { if (activeColor) {
const [r, g, b] = this.pickId2Color(activeColor); const [r, g, b] = this.pickId2Color(activeColor);
this.updateHighLight(r, g, b, ACTIVE); this.updateHighLight(r, g, b, ACTIVE);
return; return;
} }
} }
private color2PickId (r: number, g: number, b: number){ private color2PickId(r: number, g: number, b: number) {
return decodePickingColor(new Uint8Array([r,g,b])) return decodePickingColor(new Uint8Array([r, g, b]));
} }
private pickId2Color(str: number){ private pickId2Color(str: number) {
return encodePickingColor(str ) return encodePickingColor(str);
} }
/** 从瓦片中根据数据 */ /** 从瓦片中根据数据 */
getFeatureById(pickedFeatureIdx: number) { public getFeatureById(pickedFeatureIdx: number) {
// 提取当前可见瓦片 // 提取当前可见瓦片
const tiles = this.tileLayerService.getTiles().filter(tile => tile.visible); const tiles = this.tileLayerService
.getTiles()
.filter((tile) => tile.visible);
// 提取当前可见瓦片中匹配 ID 的 feature 列表 // 提取当前可见瓦片中匹配 ID 的 feature 列表
const features: any[] = []; const features: any[] = [];
tiles.forEach(tile => { tiles.forEach((tile) => {
features.push(...tile.getFeatureById(pickedFeatureIdx)); features.push(...tile.getFeatureById(pickedFeatureIdx));
}) });
// 将 feature 列表合并后返回 // 将 feature 列表合并后返回
// 统一返回成 polygon 的格式 点、线、面可以通用 // 统一返回成 polygon 的格式 点、线、面可以通用
// const data = this.tileSourceService.getCombineFeature(features); // const data = this.tileSourceService.getCombineFeature(features);
return features return features;
} }
// Tip: for interface define // Tip: for interface define
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
public pickRasterLayer(layer: ILayer, target: IInteractionTarget, parent?: ILayer) { public pickRasterLayer(
layer: ILayer,
target: IInteractionTarget,
parent?: ILayer,
) {
return false; return false;
} }
} }

View File

@ -6,21 +6,21 @@ import union from '@turf/union';
* Tile * Tile
*/ */
export class TileSourceService { export class TileSourceService {
public getCombineFeature(features: IParseDataItem[]) { public getCombineFeature(features: IParseDataItem[]) {
let p: any = null; let p: any = null;
const properties = features[0]; const properties = features[0];
features.map((feature) => { features.map((feature) => {
const polygon = turf.polygon(feature.coordinates); const polygon = turf.polygon(feature.coordinates);
if (p === null) { if (p === null) {
p = polygon; p = polygon;
} else { } else {
p = union(p, polygon); p = union(p, polygon);
} }
}); });
if (properties) { if (properties) {
p.properties = { ...properties }; p.properties = { ...properties };
}
return p;
} }
} return p;
}
}

View File

@ -1,8 +1,8 @@
import { ILayer, ILayerAttributesOption } from '@antv/l7-core'; import { ILayer, ILayerAttributesOption } from '@antv/l7-core';
import { VectorSource } from '@antv/l7-source'
import MaskLayer from '../../mask';
import Tile from './Tile'; import Tile from './Tile';
import { getTileLayer } from './util'; import { getTileLayer } from './util';
import MaskLayer from '../../mask';
import { VectorSource } from '@antv/l7-source'
export default class VectorTile extends Tile { export default class VectorTile extends Tile {
public async initTileLayer(): Promise<void> { public async initTileLayer(): Promise<void> {
@ -11,15 +11,14 @@ export default class VectorTile extends Tile {
const vectorLayer = getTileLayer(this.parent.type); const vectorLayer = getTileLayer(this.parent.type);
const sourceOptions = this.getSourceOption(); const sourceOptions = this.getSourceOption();
if(!sourceOptions){ if (!sourceOptions) {
this.isLoaded = true; this.isLoaded = true;
return return;
} }
const layer = new vectorLayer({...layerOptions}).source( const layer = new vectorLayer({ ...layerOptions }).source(
sourceOptions.data, sourceOptions.data,
sourceOptions.options, sourceOptions.options,
); );
// 初始化数据映射 // 初始化数据映射
Object.keys(attributes).forEach((type) => { Object.keys(attributes).forEach((type) => {
@ -27,8 +26,8 @@ export default class VectorTile extends Tile {
// @ts-ignore // @ts-ignore
layer[attr](attributes[attr]?.field, attributes[attr]?.values); layer[attr](attributes[attr]?.field, attributes[attr]?.values);
}); });
if(layerOptions.mask ) { if (layerOptions.mask) {
await this.addTileMask(layer) await this.addTileMask(layer);
} }
await this.addLayer(layer); await this.addLayer(layer);
@ -37,29 +36,29 @@ export default class VectorTile extends Tile {
} }
// Todo 校验数据有效性 // Todo 校验数据有效性
protected async addTileMask(layer: ILayer) { protected async addTileMask(layer: ILayer) {
const mask = new MaskLayer({layerType: "MaskLayer"}) const mask = new MaskLayer({ layerType: 'MaskLayer' }).source(
.source({ {
type: 'FeatureCollection', type: 'FeatureCollection',
features: [ features: [this.sourceTile.bboxPolygon],
this.sourceTile.bboxPolygon },
], {
}, { parser: {
parser: { type: 'geojson',
type: 'geojson', featureId: 'id',
featureId: 'id' },
} },
}) );
await this.addMask(layer, mask) await this.addMask(layer, mask);
} }
protected getSourceOption() { protected getSourceOption() {
const rawSource = this.parent.getSource(); const rawSource = this.parent.getSource();
const { sourceLayer = 'defaultLayer', featureId = 'id'} = this.parent.getLayerConfig<{ const { sourceLayer = 'defaultLayer', featureId = 'id' } =
featureId: string; this.parent.getLayerConfig<{
}>(); featureId: string;
const features = this.getFeatures(sourceLayer) }>();
const features = this.getFeatures(sourceLayer);
return { return {
data: { data: {
type: 'FeatureCollection', type: 'FeatureCollection',
@ -77,34 +76,32 @@ export default class VectorTile extends Tile {
protected setLayerMinMaxZoom(layer: ILayer) { protected setLayerMinMaxZoom(layer: ILayer) {
// 文本图层设置,可见范围 // 文本图层设置,可见范围
if(layer.getModelType() === 'text') { if (layer.getModelType() === 'text') {
layer.updateLayerConfig({ layer.updateLayerConfig({
maxZoom: this.z +1, maxZoom: this.z + 1,
minZoom: this.z - 1 minZoom: this.z - 1,
}); });
} }
} }
// 获取瓦片数据 // 获取瓦片数据
public getFeatures(sourceLayer: string){ public getFeatures(sourceLayer: string) {
const source = this.sourceTile.data as VectorSource; const source = this.sourceTile.data as VectorSource;
return source.getTileData(sourceLayer); return source.getTileData(sourceLayer);
} }
/** /**
* Tile ID feature * Tile ID feature
* @param id * @param id
* @returns * @returns
*/ */
public getFeatureById(id: number) { public getFeatureById(id: number) {
const layer = this.getMainLayer(); const layer = this.getMainLayer();
if (!layer) { if (!layer) {
return []; return [];
} }
const res = layer.getSource().data.dataArray.filter(d => d._id === id); console.log(layer.getSource().data.dataArray,id)
return res const res = layer.getSource().data.dataArray.filter((d) => d._id === id);
return res;
} }
} }

View File

@ -5,7 +5,7 @@ order: 1
<embed src="@/docs/common/style.md"></embed> <embed src="@/docs/common/style.md"></embed>
### sourceLayer #### sourceLayer
<description> _string_ **required** </description> <description> _string_ **required** </description>
@ -19,7 +19,7 @@ const layer = new PointLayer({
}); });
``` ```
### featureId #### featureId
<description> _string_ **optional** _default:_ 自动数字编号</description> <description> _string_ **optional** _default:_ 自动数字编号</description>

View File

@ -1,13 +1,13 @@
import { registerParser, registerTransform } from './factory'; import { registerParser, registerTransform } from './factory';
import csv from './parser/csv'; import csv from './parser/csv';
import geojson from './parser/geojson'; import geojson from './parser/geojson';
import geojsonVTTile from './parser/geojsonvt';
import image from './parser/image'; import image from './parser/image';
import json from './parser/json'; import json from './parser/json';
import mapboxVectorTile from './parser/mvt'; import mapboxVectorTile from './parser/mvt';
import geojsonVTTile from './parser/geojsonvt';
import raster from './parser/raster'; import raster from './parser/raster';
import rasterRgb from './parser/rasterRgb';
import rasterTile, { rasterDataTypes } from './parser/raster-tile'; import rasterTile, { rasterDataTypes } from './parser/raster-tile';
import rasterRgb from './parser/rasterRgb';
import testTile from './parser/testTile'; import testTile from './parser/testTile';
import Source from './source'; import Source from './source';
import { cluster } from './transform/cluster'; import { cluster } from './transform/cluster';
@ -16,7 +16,15 @@ import { aggregatorToGrid } from './transform/grid';
import { pointToHexbin } from './transform/hexagon'; import { pointToHexbin } from './transform/hexagon';
import { join } from './transform/join'; import { join } from './transform/join';
import { map } from './transform/map'; import { map } from './transform/map';
export {
getParser,
getTransform,
registerParser,
registerTransform,
} from './factory';
export * from './interface';
export * from './source/index'; export * from './source/index';
export { rasterDataTypes };
registerParser('rasterTile', rasterTile); registerParser('rasterTile', rasterTile);
registerParser('mvt', mapboxVectorTile); registerParser('mvt', mapboxVectorTile);
@ -35,16 +43,4 @@ registerTransform('map', map);
registerTransform('grid', aggregatorToGrid); registerTransform('grid', aggregatorToGrid);
registerTransform('hexagon', pointToHexbin); registerTransform('hexagon', pointToHexbin);
export {
rasterDataTypes,
}
export {
getTransform,
registerTransform,
getParser,
registerParser,
} from './factory';
export * from './interface';
export default Source; export default Source;

View File

@ -36,11 +36,11 @@ function getFeatureID(feature: Feature<Geometries, Properties>, key?: string) {
if (key === undefined) { if (key === undefined) {
return null; return null;
} }
// @ts-ignore // @ts-ignore
if (feature.properties[key]) { if (typeof feature.properties[key] * 1 === 'number') {
// 单独指定要素
// @ts-ignore // @ts-ignore
return feature.properties[key]; return feature.properties[key] * 1;
} }
if (feature.properties && feature.properties[key]) { if (feature.properties && feature.properties[key]) {

View File

@ -4,10 +4,10 @@ import {
IClusterOptions, IClusterOptions,
IParseDataItem, IParseDataItem,
IParserCfg, IParserCfg,
ITileParserCFG,
IParserData, IParserData,
ISource, ISource,
ISourceCFG, ISourceCFG,
ITileParserCFG,
ITransform, ITransform,
} from '@antv/l7-core'; } from '@antv/l7-core';
import { import {
@ -48,7 +48,7 @@ export default class Source extends EventEmitter implements ISource {
public getSourceCfg() { public getSourceCfg() {
return this.cfg; return this.cfg;
} }
public parser: IParserCfg | ITileParserCFG = { type: 'geojson' } ; public parser: IParserCfg | ITileParserCFG = { type: 'geojson' };
public transforms: ITransform[] = []; public transforms: ITransform[] = [];
public cluster: boolean = false; public cluster: boolean = false;
public clusterOptions: Partial<IClusterOptions> = { public clusterOptions: Partial<IClusterOptions> = {
@ -70,7 +70,7 @@ export default class Source extends EventEmitter implements ISource {
protected originData: any; protected originData: any;
protected rawData: any; protected rawData: any;
private cfg: Partial<ISourceCFG> = { private cfg: Partial<ISourceCFG> = {
autoRender: true autoRender: true,
}; };
private clusterIndex: Supercluster; private clusterIndex: Supercluster;
@ -81,11 +81,11 @@ export default class Source extends EventEmitter implements ISource {
this.originData = data; this.originData = data;
this.initCfg(cfg); this.initCfg(cfg);
this.init().then(()=>{ this.init().then(() => {
this.inited = true; this.inited = true;
this.emit('update',{ this.emit('update', {
type: 'inited' type: 'inited',
}) });
}); });
} }
@ -142,7 +142,6 @@ export default class Source extends EventEmitter implements ISource {
} }
public getFeatureById(id: number): unknown { public getFeatureById(id: number): unknown {
const { type = 'geojson', geometry } = this.parser as IParserCfg; const { type = 'geojson', geometry } = this.parser as IParserCfg;
if (type === 'geojson' && !this.cluster) { if (type === 'geojson' && !this.cluster) {
const feature = const feature =
@ -151,7 +150,6 @@ export default class Source extends EventEmitter implements ISource {
: 'null'; : 'null';
const newFeature = cloneDeep(feature); const newFeature = cloneDeep(feature);
if ( if (
newFeature?.properties && newFeature?.properties &&
(this.transforms.length !== 0 || this.dataArrayChanged) (this.transforms.length !== 0 || this.dataArrayChanged)
@ -186,8 +184,8 @@ export default class Source extends EventEmitter implements ISource {
}, },
); );
this.dataArrayChanged = true; this.dataArrayChanged = true;
this.emit('update',{ this.emit('update', {
type: 'update' type: 'update',
}); });
} }
@ -202,13 +200,12 @@ export default class Source extends EventEmitter implements ISource {
this.originData = data; this.originData = data;
this.dataArrayChanged = false; this.dataArrayChanged = false;
this.initCfg(options); this.initCfg(options);
this.init().then(()=>{
this.emit('update',{
type: 'update'
})
});
this.init().then(() => {
this.emit('update', {
type: 'update',
});
});
} }
public destroy() { public destroy() {
@ -221,7 +218,7 @@ export default class Source extends EventEmitter implements ISource {
} }
private async processData() { private async processData() {
return await new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
this.excuteParser(); this.excuteParser();
this.initCluster(); this.initCluster();
@ -280,7 +277,7 @@ export default class Source extends EventEmitter implements ISource {
this.tileset = this.initTileset(); this.tileset = this.initTileset();
// 判断当前 source 是否需要计算范围 // 判断当前 source 是否需要计算范围
if (parser.cancelExtent) return; if (parser.cancelExtent) { return; }
// 计算范围 // 计算范围
this.extent = extent(this.data.dataArray); this.extent = extent(this.data.dataArray);