mirror of https://gitee.com/antv-l7/antv-l7
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:
parent
a0b79e89cd
commit
5a96e01ad5
|
@ -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',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
group:
|
||||||
|
path: 'vector'
|
||||||
|
title: '矢量瓦片'
|
||||||
|
order: 1
|
||||||
|
title: 瓦片交互
|
||||||
|
order: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### 瓦片交互
|
||||||
|
|
||||||
|
<code src="./demos/event.tsx"></code>
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue