mirror of https://gitee.com/antv-l7/antv-l7
Merge branch 'feat_source_hooks' of https://github.com/antvis/L7 into feat_source_hooks
This commit is contained in:
commit
45d239c3ff
|
@ -21,7 +21,7 @@ const Demo: React.FC = () => {
|
||||||
scene.on('loaded', () => {
|
scene.on('loaded', () => {
|
||||||
const drawer = new DrawPolygon(scene, {
|
const drawer = new DrawPolygon(scene, {
|
||||||
areaOptions: {},
|
areaOptions: {},
|
||||||
liveUpdate: true,
|
// liveUpdate: true,
|
||||||
});
|
});
|
||||||
setPolygonDrawer(drawer);
|
setPolygonDrawer(drawer);
|
||||||
console.log(drawer);
|
console.log(drawer);
|
||||||
|
|
|
@ -24,8 +24,7 @@ export default () => {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'rasterTile',
|
type: 'rasterTile',
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
// zoomOffset: 0
|
|
||||||
// zoomOffset: 1,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: SenTinel 底图
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
<code src="./district/Sentinel-2.tsx"></code>
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: 北京瓦片
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
<code src="./district/citytile.tsx"></code>
|
|
@ -0,0 +1,45 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import { Scene, RasterLayer, TileDebugLayer } 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',
|
||||||
|
stencil: true,
|
||||||
|
map: new Map({
|
||||||
|
center: [113.270854, 23.141717],
|
||||||
|
zoom: 11,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const url1 =
|
||||||
|
'https://tiles.maps.eox.at/wmts/1.0.0/s2cloudless-2020_3857_512/default/GoogleMapsCompatible_512/{z}/{y}/{x}.jpg';
|
||||||
|
const layer1 = new RasterLayer({
|
||||||
|
zIndex: 1,
|
||||||
|
}).source(url1, {
|
||||||
|
parser: {
|
||||||
|
type: 'rasterTile',
|
||||||
|
tileSize: 512,
|
||||||
|
updateStrategy: 'realtime',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
scene.addLayer(layer1);
|
||||||
|
const debugerLayer = new TileDebugLayer();
|
||||||
|
scene.addLayer(debugerLayer);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="map"
|
||||||
|
style={{
|
||||||
|
height: '500px',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
|
@ -123,7 +123,6 @@ export default () => {
|
||||||
scene.addLayer(line);
|
scene.addLayer(line);
|
||||||
scene.addLayer(line2);
|
scene.addLayer(line2);
|
||||||
scene.addLayer(text);
|
scene.addLayer(text);
|
||||||
|
|
||||||
scene.addLayer(debugerLayer);
|
scene.addLayer(debugerLayer);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import { Scene, Source, PolygonLayer, LineLayer } from '@antv/l7';
|
||||||
|
// @ts-ignore
|
||||||
|
import { GaodeMapV2 } from '@antv/l7-maps';
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
useEffect(() => {
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
stencil: true,
|
||||||
|
map: new GaodeMapV2({
|
||||||
|
center: [116.39852, 39.918255],
|
||||||
|
zoom: 9,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const source = new Source(
|
||||||
|
'https://pre-gridwise.alibaba-inc.com/tile/test?z={z}&x={x}&y={y}',
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'mvt',
|
||||||
|
tileSize: 256,
|
||||||
|
// minZoom: 9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const layer = new PolygonLayer({
|
||||||
|
featureId: 'space_id',
|
||||||
|
zIndex: 3,
|
||||||
|
mask: false,
|
||||||
|
sourceLayer: 'default', // woods hillshade contour ecoregions ecoregions2 city
|
||||||
|
})
|
||||||
|
.source(source)
|
||||||
|
.shape('fill')
|
||||||
|
.scale('space_val', {
|
||||||
|
type: 'quantize',
|
||||||
|
domain: [0, 100],
|
||||||
|
})
|
||||||
|
.color('space_val', [
|
||||||
|
'#f2f0f7',
|
||||||
|
'#cbc9e2',
|
||||||
|
'#9e9ac8',
|
||||||
|
'#756bb1',
|
||||||
|
'#54278f',
|
||||||
|
])
|
||||||
|
.style({
|
||||||
|
opacity: 0.8,
|
||||||
|
});
|
||||||
|
|
||||||
|
const layer2 = new LineLayer({
|
||||||
|
featureId: 'space_id',
|
||||||
|
zIndex: 3,
|
||||||
|
mask: false,
|
||||||
|
sourceLayer: 'default', // woods hillshade contour ecoregions ecoregions2 city
|
||||||
|
})
|
||||||
|
.source(source)
|
||||||
|
.shape('simple')
|
||||||
|
.size(0.8)
|
||||||
|
.color('#3E6Eff')
|
||||||
|
.style({
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
scene.addLayer(layer);
|
||||||
|
scene.addLayer(layer2);
|
||||||
|
|
||||||
|
// const debugerLayer = new TileDebugLayer();
|
||||||
|
// scene.addLayer(debugerLayer);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="map"
|
||||||
|
style={{
|
||||||
|
height: '100vh',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
|
@ -0,0 +1,139 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import {
|
||||||
|
Scene,
|
||||||
|
Source,
|
||||||
|
PolygonLayer,
|
||||||
|
TileDebugLayer,
|
||||||
|
RasterLayer,
|
||||||
|
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',
|
||||||
|
stencil: true,
|
||||||
|
map: new Map({
|
||||||
|
center: [-95.7548387434569, 44.82687715672517],
|
||||||
|
zoom: 9,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const url1 =
|
||||||
|
'https://api.mapbox.com/v4/mapbox.satellite/{z}/{x}/{y}.webp?sku=101ifSAcKcVFs&access_token=pk.eyJ1IjoidW5mb2xkZWRpbmMiLCJhIjoiY2s5ZG90MjMzMDV6eDNkbnh2cDJvbHl4NyJ9.BT2LAvHi31vNNEplsgxucQ';
|
||||||
|
const layer1 = new RasterLayer({
|
||||||
|
zIndex: 1,
|
||||||
|
}).source(url1, {
|
||||||
|
parser: {
|
||||||
|
type: 'rasterTile',
|
||||||
|
tileSize: 256,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const source = new Source(
|
||||||
|
'https://cdn.unfolded.ai/indigo/hexify_v5/{z}/{x}/{y}.pbf',
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'mvt',
|
||||||
|
tileSize: 256,
|
||||||
|
// minZoom: 9,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
// const source2 = new Source(
|
||||||
|
// 'https://cdn.unfolded.ai/indigo/hexify_v5/{z}/{x}/{y}.pbf',
|
||||||
|
// {
|
||||||
|
// parser: {
|
||||||
|
// type: 'mvt',
|
||||||
|
// tileSize: 256,
|
||||||
|
// maxZoom: 9,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
const layer = new PolygonLayer({
|
||||||
|
featureId: 'id',
|
||||||
|
zIndex: 3,
|
||||||
|
minZoom: 9,
|
||||||
|
sourceLayer: 'state_s10_27', // woods hillshade contour ecoregions ecoregions2 city
|
||||||
|
})
|
||||||
|
.source(source)
|
||||||
|
.shape('line')
|
||||||
|
.color('#000')
|
||||||
|
.size(0.3)
|
||||||
|
.style({
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const layer2 = new PolygonLayer({
|
||||||
|
featureId: 'id',
|
||||||
|
zIndex: 2,
|
||||||
|
minZoom: 9,
|
||||||
|
sourceLayer: 'state_s10_27', // woods hillshade contour ecoregions ecoregions2 city
|
||||||
|
})
|
||||||
|
.source(source)
|
||||||
|
.shape('fill')
|
||||||
|
.scale('croptype', {
|
||||||
|
type: 'quantize',
|
||||||
|
domain: [0, 4],
|
||||||
|
})
|
||||||
|
.color('croptype', [
|
||||||
|
'#C1C9CC',
|
||||||
|
'#DFB02F',
|
||||||
|
'#7F8120',
|
||||||
|
'#DCD0A4',
|
||||||
|
'#AD5633',
|
||||||
|
])
|
||||||
|
.style({
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const layer3 = new PointLayer({
|
||||||
|
featureId: 'id',
|
||||||
|
zIndex: 2,
|
||||||
|
maxZoom: 9,
|
||||||
|
mask: true,
|
||||||
|
sourceLayer: 'parcel_pointgeojsonl', // woods hillshade contour ecoregions ecoregions2 city
|
||||||
|
})
|
||||||
|
.source(source)
|
||||||
|
.shape('hexagon')
|
||||||
|
.size(2)
|
||||||
|
.scale('croptype', {
|
||||||
|
type: 'quantize',
|
||||||
|
domain: [0, 4],
|
||||||
|
})
|
||||||
|
.color('croptype', [
|
||||||
|
'#C1C9CC',
|
||||||
|
'#DFB02F',
|
||||||
|
'#7F8120',
|
||||||
|
'#DCD0A4',
|
||||||
|
'#AD5633',
|
||||||
|
])
|
||||||
|
.style({
|
||||||
|
opacity: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
scene.addLayer(layer);
|
||||||
|
scene.addLayer(layer1);
|
||||||
|
scene.addLayer(layer2);
|
||||||
|
scene.addLayer(layer3);
|
||||||
|
|
||||||
|
const debugerLayer = new TileDebugLayer();
|
||||||
|
scene.addLayer(debugerLayer);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="map"
|
||||||
|
style={{
|
||||||
|
height: '500px',
|
||||||
|
position: 'relative',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// https://pre-gridwise.alibaba-inc.com/tile/test?z=13&x=6746&y=3104
|
|
@ -22,7 +22,6 @@ export default () => {
|
||||||
)
|
)
|
||||||
.then((d) => d.json())
|
.then((d) => d.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
console.log(data);
|
|
||||||
const source = new Source(data, {
|
const source = new Source(data, {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'geojsonvt',
|
type: 'geojsonvt',
|
||||||
|
|
|
@ -129,18 +129,7 @@ export default () => {
|
||||||
// layer.on('click', (e) => {
|
// layer.on('click', (e) => {
|
||||||
// console.log('layer click');
|
// console.log('layer click');
|
||||||
// console.log(e);
|
// console.log(e);
|
||||||
// });
|
// })
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
layer.style({
|
|
||||||
opacity: 0.6,
|
|
||||||
rampColors: {
|
|
||||||
colors: ['#f00', '#ff0'],
|
|
||||||
positions: [0, 1],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
scene.render();
|
|
||||||
}, 2000);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,26 +3,34 @@ import {
|
||||||
Scene,
|
Scene,
|
||||||
Source,
|
Source,
|
||||||
PolygonLayer,
|
PolygonLayer,
|
||||||
|
LineLayer,
|
||||||
TileDebugLayer,
|
TileDebugLayer,
|
||||||
PointLayer,
|
PointLayer,
|
||||||
} from '@antv/l7';
|
} from '@antv/l7';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Map } from '@antv/l7-maps';
|
import { GaodeMapV2 } from '@antv/l7-maps';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { data } from './data';
|
import { data } from './data';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const counts = [10000, 5000, 1000, 500, 100];
|
const counts = [10000, 5000, 1000, 500, 100];
|
||||||
const color = ['#41ae76', '#99d8c9', '#ccece6', '#e5f5f9', '#f7fcfd'];
|
const color = [
|
||||||
|
'#e41a1c',
|
||||||
|
'#377eb8',
|
||||||
|
'#4daf4a',
|
||||||
|
'#984ea3',
|
||||||
|
'#ff7f00',
|
||||||
|
'#ffff33',
|
||||||
|
];
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
stencil: true,
|
stencil: true,
|
||||||
map: new Map({
|
map: new GaodeMapV2({
|
||||||
center: [120, 30],
|
center: [100, 30],
|
||||||
// zoom: 12,
|
// zoom: 12,
|
||||||
minZoom: 0,
|
minZoom: 0,
|
||||||
zoom: 3,
|
zoom: 2,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,7 +69,7 @@ export default () => {
|
||||||
return c.name == namestr;
|
return c.name == namestr;
|
||||||
});
|
});
|
||||||
if (!country) {
|
if (!country) {
|
||||||
return '#fff';
|
return '#ffff33';
|
||||||
}
|
}
|
||||||
const qz = ((country.qz as unknown) as number) * 1;
|
const qz = ((country.qz as unknown) as number) * 1;
|
||||||
if (qz > counts[0]) {
|
if (qz > counts[0]) {
|
||||||
|
@ -77,30 +85,32 @@ export default () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// const line = new LineLayer({
|
const line = new LineLayer({
|
||||||
// sourceLayer: 'WLD_L',
|
sourceLayer: 'WLD_L',
|
||||||
// zIndex: 2,
|
zIndex: 2,
|
||||||
// })
|
})
|
||||||
// .source(source)
|
.source(source)
|
||||||
// .shape('line')
|
.shape('line')
|
||||||
// .size(0.6)
|
.size(0.6)
|
||||||
// .color('type', (t) => {
|
.color('type', (t) => {
|
||||||
// if (t === '0') {
|
if (t === '0') {
|
||||||
// return 'red';
|
return 'red';
|
||||||
// }
|
}
|
||||||
// if (t === '2') {
|
if (t === '2') {
|
||||||
// return '#09f';
|
return '#09f';
|
||||||
// }
|
}
|
||||||
// return '#fc9272';
|
return '#fc9272';
|
||||||
// });
|
});
|
||||||
|
|
||||||
const text = new PointLayer({
|
const text = new PointLayer({
|
||||||
sourceLayer: 'WLD',
|
sourceLayer: 'WLD',
|
||||||
// blend: 'normal',
|
blend: 'normal',
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
})
|
})
|
||||||
.source(source)
|
.source(source)
|
||||||
.shape('id', 'text')
|
.shape('NAME_CHN', (NAME_CHN) => {
|
||||||
|
return unicode2Char(NAME_CHN);
|
||||||
|
})
|
||||||
.size(12)
|
.size(12)
|
||||||
.color('#000');
|
.color('#000');
|
||||||
|
|
||||||
|
@ -114,8 +124,8 @@ export default () => {
|
||||||
|
|
||||||
scene.addLayer(water_surface);
|
scene.addLayer(water_surface);
|
||||||
scene.addLayer(text);
|
scene.addLayer(text);
|
||||||
// scene.addLayer(line);
|
scene.addLayer(line);
|
||||||
const debugerLayer = new TileDebugLayer({ zIndex: 1 });
|
const debugerLayer = new TileDebugLayer();
|
||||||
scene.addLayer(debugerLayer);
|
scene.addLayer(debugerLayer);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: 矢量 FarmLand
|
||||||
|
order: 2
|
||||||
|
---
|
||||||
|
<code src="./district/farmland.tsx"></code>
|
|
@ -68,7 +68,7 @@ const defaultLayerConfig: Partial<ILayerConfig> = {
|
||||||
active: false,
|
active: false,
|
||||||
activeColor: '#2f54eb',
|
activeColor: '#2f54eb',
|
||||||
enableHighlight: false,
|
enableHighlight: false,
|
||||||
enableSelect: true,
|
enableSelect: false,
|
||||||
highlightColor: '#2f54eb',
|
highlightColor: '#2f54eb',
|
||||||
activeMix: 0,
|
activeMix: 0,
|
||||||
selectColor: 'blue',
|
selectColor: 'blue',
|
||||||
|
|
|
@ -209,14 +209,8 @@ export default class PickingService implements IPickingService {
|
||||||
data: new Uint8Array(1 * 1 * 4),
|
data: new Uint8Array(1 * 1 * 4),
|
||||||
framebuffer: this.pickingFBO,
|
framebuffer: this.pickingFBO,
|
||||||
});
|
});
|
||||||
this.pickedColors = pickedColors;
|
|
||||||
|
|
||||||
// let pickedColors = new Uint8Array(4)
|
this.pickedColors = pickedColors;
|
||||||
// this.rendererService.getGLContext().readPixels(
|
|
||||||
// Math.floor(xInDevicePixel / this.pickBufferScale),
|
|
||||||
// Math.floor((height - (y + 1) * DOM.DPR) / this.pickBufferScale),
|
|
||||||
// 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pickedColors)
|
|
||||||
// console.log(pickedColors[0] == pixels[0] && pickedColors[1] == pixels[1] && pickedColors[2] == pixels[2])
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pickedColors[0] !== 0 ||
|
pickedColors[0] !== 0 ||
|
||||||
|
@ -224,7 +218,7 @@ 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() &&
|
||||||
|
@ -362,6 +356,7 @@ export default class PickingService implements IPickingService {
|
||||||
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],
|
||||||
|
@ -369,34 +364,8 @@ export default class PickingService implements IPickingService {
|
||||||
depth: 1,
|
depth: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Tip: clear last picked tilelayer state
|
|
||||||
// this.pickedTileLayers.map((pickedTileLayer) =>
|
|
||||||
// (pickedTileLayer.tileLayer as ITileLayer)?.clearPick(target.type),
|
|
||||||
// );
|
|
||||||
|
|
||||||
// Tip: 如果当前 layer 是瓦片图层,则走瓦片图层独立的拾取逻辑
|
|
||||||
// if (layer.tileLayer && (layer.tileLayer as ITileLayer).pickLayers) {
|
|
||||||
// return (layer.tileLayer as ITileLayer).pickLayers(target);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// 将当前的 layer 绘制到 pickingFBO
|
|
||||||
// 普通图层和瓦片图层的 layerPickService 拥有不同的 pickRender 方法
|
|
||||||
layer.layerPickService.pickRender(target);
|
layer.layerPickService.pickRender(target);
|
||||||
|
|
||||||
// layer.hooks.beforePickingEncode.call();
|
|
||||||
|
|
||||||
// if (layer.masks.length > 0) {
|
|
||||||
// // 若存在 mask,则在 pick 阶段的绘制也启用
|
|
||||||
// layer.masks.map(async (m: ILayer) => {
|
|
||||||
// m.hooks.beforeRender.call();
|
|
||||||
// m.render();
|
|
||||||
// m.hooks.afterRender.call();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// layer.renderModels(true);
|
|
||||||
// layer.hooks.afterPickingEncode.call();
|
|
||||||
const isPicked = this.pickFromPickingFBO(layer, target);
|
const isPicked = this.pickFromPickingFBO(layer, target);
|
||||||
|
|
||||||
this.layerService.pickedLayerId = isPicked ? +layer.id : -1;
|
this.layerService.pickedLayerId = isPicked ? +layer.id : -1;
|
||||||
return isPicked && !layer.getLayerConfig().enablePropagation;
|
return isPicked && !layer.getLayerConfig().enablePropagation;
|
||||||
});
|
});
|
||||||
|
@ -422,31 +391,4 @@ export default class PickingService implements IPickingService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* highlight 如果直接修改选中 feature 的 buffer,存在两个问题:
|
|
||||||
* 1. 鼠标移走时无法恢复
|
|
||||||
* 2. 无法实现高亮颜色与原始原色的 alpha 混合
|
|
||||||
* 因此高亮还是放在 shader 中做比较好
|
|
||||||
* @example
|
|
||||||
* this.layer.color('name', ['#000000'], {
|
|
||||||
* featureRange: {
|
|
||||||
* startIndex: pickedFeatureIdx,
|
|
||||||
* endIndex: pickedFeatureIdx + 1,
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
private highlightPickedFeature(
|
|
||||||
layer: ILayer,
|
|
||||||
pickedColors: Uint8Array | undefined,
|
|
||||||
) {
|
|
||||||
// @ts-ignore
|
|
||||||
const [r, g, b] = pickedColors;
|
|
||||||
layer.hooks.beforeHighlight.call([r, g, b]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private selectFeature(layer: ILayer, pickedColors: Uint8Array | undefined) {
|
|
||||||
// @ts-ignore
|
|
||||||
const [r, g, b] = pickedColors;
|
|
||||||
layer.hooks.beforeSelect.call([r, g, b]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -870,7 +870,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
||||||
minZoom = -Infinity,
|
minZoom = -Infinity,
|
||||||
maxZoom = Infinity,
|
maxZoom = Infinity,
|
||||||
} = this.getLayerConfig();
|
} = this.getLayerConfig();
|
||||||
return !!visible && zoom >= minZoom && zoom <= maxZoom;
|
return !!visible && zoom >= minZoom && zoom < maxZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setMultiPass(
|
public setMultiPass(
|
||||||
|
|
|
@ -25,6 +25,7 @@ export default class FillModel extends BaseModel {
|
||||||
dir: 'in',
|
dir: 'in',
|
||||||
},
|
},
|
||||||
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
||||||
|
|
||||||
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
|
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
|
||||||
this.judgeStyleAttributes({ opacity });
|
this.judgeStyleAttributes({ opacity });
|
||||||
const encodeData = this.layer.getEncodedData();
|
const encodeData = this.layer.getEncodedData();
|
||||||
|
@ -52,7 +53,9 @@ export default class FillModel extends BaseModel {
|
||||||
width: 1,
|
width: 1,
|
||||||
height: 1,
|
height: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
|
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
|
||||||
u_cellTypeLayout: this.getCellTypeLayout(),
|
u_cellTypeLayout: this.getCellTypeLayout(),
|
||||||
|
|
|
@ -53,14 +53,52 @@ export class TileLayerService {
|
||||||
}
|
}
|
||||||
updateTileVisible(sourceTile: SourceTile) {
|
updateTileVisible(sourceTile: SourceTile) {
|
||||||
const tile = this.getTile(sourceTile.key);
|
const tile = this.getTile(sourceTile.key);
|
||||||
|
// if(sourceTile.isVisible) {
|
||||||
|
// // 不可见 => 可见 兄弟节点加载完成
|
||||||
|
// if(sourceTile.parent) {
|
||||||
|
// const flag = this.isChildrenLoaded(sourceTile.parent)
|
||||||
|
// tile?.updateVisible(flag);
|
||||||
|
// } else {
|
||||||
|
// tile?.updateVisible(true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// // 可见 => 不可见 兄弟节点加载完成
|
||||||
|
// if(sourceTile.parent) {
|
||||||
|
// const flag = this.isChildrenLoaded(sourceTile.parent)
|
||||||
|
// tile?.updateVisible(!flag);
|
||||||
|
// } else {
|
||||||
|
// tile?.updateVisible(false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
tile?.updateVisible(sourceTile.isVisible);
|
tile?.updateVisible(sourceTile.isVisible);
|
||||||
|
|
||||||
}
|
}
|
||||||
beforeRender() {
|
public isParentLoaded(sourceTile: SourceTile): boolean {
|
||||||
// TODO 统一处理状态更新 attribute style
|
const parentTile = sourceTile.parent;
|
||||||
|
if(!parentTile) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const tile = this.getTile(parentTile?.key)
|
||||||
|
if(tile?.isLoaded) { // 递归父级
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isChildrenLoaded(sourceTile: SourceTile):boolean {
|
||||||
|
const childrenTile = sourceTile?.children;
|
||||||
|
if(childrenTile.length === 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return childrenTile.some((tile:SourceTile)=>{
|
||||||
|
const tileLayer = this.getTile(tile?.key)
|
||||||
|
return tileLayer?.isLoaded === false
|
||||||
|
})
|
||||||
|
}
|
||||||
async render() {
|
async render() {
|
||||||
const layers = this.getRenderLayers();
|
const layers = this.getRenderLayers();
|
||||||
layers.map(async layer => {
|
layers.map(async layer => {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ILayerService, ITile, ITilePickService, IInteractionTarget } from '@antv/l7-core';
|
import { ILayerService, ITile, ITilePickService, IInteractionTarget } from '@antv/l7-core';
|
||||||
|
import { decodePickingColor, encodePickingColor } from '@antv/l7-utils';
|
||||||
import { TileLayerService } from './TileLayerService';
|
import { TileLayerService } from './TileLayerService';
|
||||||
import { TileSourceService } from './TileSourceService';
|
import { TileSourceService } from './TileSourceService';
|
||||||
export interface ITilePickServiceOptions {
|
export interface ITilePickServiceOptions {
|
||||||
|
@ -24,15 +25,14 @@ export class TilePickService implements ITilePickService{
|
||||||
if (tile) {
|
if (tile) {
|
||||||
// TODO 多图层拾取
|
// TODO 多图层拾取
|
||||||
const pickLayer = tile.getMainLayer();
|
const pickLayer = tile.getMainLayer();
|
||||||
if (pickLayer) {
|
pickLayer?.layerPickService.pickRender(target)
|
||||||
pickLayer.layerPickService.pickRender(target)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectFeature(pickedColors: Uint8Array | undefined) {
|
selectFeature(pickedColors: Uint8Array | undefined) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const [r, g, b] = pickedColors;
|
const [r, g, b] = pickedColors;
|
||||||
const id = this.clor2PickId(r, g, b);
|
const id = this.color2PickId(r, g, b);
|
||||||
this.tilePickID.set(SELECT, id);
|
this.tilePickID.set(SELECT, id);
|
||||||
this.updateHighLight(r, g, b, SELECT);
|
this.updateHighLight(r, g, b, SELECT);
|
||||||
}
|
}
|
||||||
|
@ -40,24 +40,23 @@ export class TilePickService implements ITilePickService{
|
||||||
highlightPickedFeature(pickedColors: Uint8Array | undefined) {
|
highlightPickedFeature(pickedColors: Uint8Array | undefined) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const [r, g, b] = pickedColors;
|
const [r, g, b] = pickedColors;
|
||||||
const id = this.clor2PickId(r, g, b);
|
const id = this.color2PickId(r, g, b);
|
||||||
this.tilePickID.set(ACTIVE, id);
|
this.tilePickID.set(ACTIVE, id);
|
||||||
this.updateHighLight(r, g, b, ACTIVE);
|
this.updateHighLight(r, g, b, ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHighLight(r: number, g: number, b: number, type: string){
|
updateHighLight(r: number, g: number, b: number, type: string){
|
||||||
this.tileLayerService.tiles.map((tile: ITile) => {
|
this.tileLayerService.tiles.map((tile: ITile) => {
|
||||||
const layers = tile.getLayers();
|
const layer = tile.getMainLayer();
|
||||||
layers.forEach((layer) => {
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +75,12 @@ export class TilePickService implements ITilePickService{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private clor2PickId (r: number, g: number, b: number){
|
private color2PickId (r: number, g: number, b: number){
|
||||||
return r + '-' + g + '-' + b;
|
return decodePickingColor(new Uint8Array([r,g,b]))
|
||||||
}
|
}
|
||||||
|
|
||||||
private pickId2Color(str: string){
|
private pickId2Color(str: number){
|
||||||
return str.split('-').map(n => +n)
|
return encodePickingColor(str )
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 从瓦片中根据数据 */
|
/** 从瓦片中根据数据 */
|
||||||
|
@ -99,6 +98,9 @@ export class TilePickService implements ITilePickService{
|
||||||
}
|
}
|
||||||
// 将 feature 列表合并后返回
|
// 将 feature 列表合并后返回
|
||||||
// 统一返回成 polygon 的格式 点、线、面可以通用
|
// 统一返回成 polygon 的格式 点、线、面可以通用
|
||||||
return this.tileSourceService.getCombineFeature(features);
|
|
||||||
|
// const data = this.tileSourceService.getCombineFeature(features);
|
||||||
|
|
||||||
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ILayer, createLayerContainer, ILngLat, ITile } from '@antv/l7-core';
|
import { ILayer, createLayerContainer, ILngLat, ITile } from '@antv/l7-core';
|
||||||
import { SourceTile } from '@antv/l7-utils';
|
import { SourceTile } from '@antv/l7-utils';
|
||||||
import { Container } from 'inversify';
|
import { Container } from 'inversify';
|
||||||
import { Feature, Properties } from '@turf/helpers';
|
|
||||||
export default abstract class Tile implements ITile{
|
export default abstract class Tile implements ITile{
|
||||||
public x: number;
|
public x: number;
|
||||||
public y: number;
|
public y: number;
|
||||||
|
@ -35,6 +35,7 @@ export default abstract class Tile implements ITile{
|
||||||
return lng >= minLng && lng <= maxLng && lat >= minLat && lat <= maxLat;
|
return lng >= minLng && lng <= maxLng && lat >= minLat && lat <= maxLat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected async addMask(layer: ILayer, mask: ILayer) {
|
protected async addMask(layer: ILayer, mask: ILayer) {
|
||||||
const container = createLayerContainer(
|
const container = createLayerContainer(
|
||||||
this.parent.sceneContainer as Container,
|
this.parent.sceneContainer as Container,
|
||||||
|
@ -75,45 +76,17 @@ export default abstract class Tile implements ITile{
|
||||||
return this.layers[0];
|
return this.layers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFeatures(sourceLayer: string | undefined){
|
public getFeatures(sourceLayer: string | undefined):any[] {
|
||||||
if(!sourceLayer || !this.sourceTile.data?.layers[sourceLayer]) {
|
return []
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const vectorTile = this.sourceTile.data?.layers[sourceLayer];
|
|
||||||
|
|
||||||
if(Array.isArray(vectorTile.features)) {
|
|
||||||
// 数据不需要被解析 geojson-vt 类型
|
|
||||||
return vectorTile.features;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { x, y, z } = this.sourceTile;
|
|
||||||
const features: Feature<GeoJSON.Geometry, Properties>[] = [];
|
|
||||||
for( let i = 0; i < vectorTile.length; i++ ) {
|
|
||||||
const vectorTileFeature = vectorTile.feature(i);
|
|
||||||
const feature = vectorTileFeature.toGeoJSON(x, y, z);
|
|
||||||
features.push({
|
|
||||||
...feature,
|
|
||||||
properties: {
|
|
||||||
id: feature.id,
|
|
||||||
...feature.properties,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return features;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在一个 Tile 中可能存在一个相同 ID 的 feature
|
* 在一个 Tile 中可能存在一个相同 ID 的 feature
|
||||||
* @param id
|
* @param id
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public getFeatureById(id: number) {
|
public getFeatureById(id: number):any[] {
|
||||||
const layer = this.getMainLayer();
|
return []
|
||||||
if (!layer) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
return layer.getSource().data.dataArray.filter(d => d._id === id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public destroy() {
|
public destroy() {
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import { ILayer, ILayerAttributesOption } from '@antv/l7-core';
|
import { ILayer, ILayerAttributesOption } from '@antv/l7-core';
|
||||||
import Tile from './Tile';
|
import Tile from './Tile';
|
||||||
import { getTileLayer, getMaskLayer } from './util';
|
import { getTileLayer, isNeedMask } 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> {
|
||||||
const attributes = this.parent.getLayerAttributeConfig();
|
const attributes = this.parent.getLayerAttributeConfig();
|
||||||
const layerOptions = this.parent.getLayerConfig()
|
const layerOptions = this.parent.getLayerConfig()
|
||||||
|
layerOptions.mask = isNeedMask(this.parent.type) ||layerOptions.mask;
|
||||||
const vectorLayer = getTileLayer(this.parent.type);
|
const vectorLayer = getTileLayer(this.parent.type);
|
||||||
const maskLayer = getMaskLayer(this.parent.type);
|
|
||||||
layerOptions.mask = !!maskLayer;
|
|
||||||
|
|
||||||
|
|
||||||
const sourceOptions = this.getSourceOption();
|
const sourceOptions = this.getSourceOption();
|
||||||
if(!sourceOptions){
|
if(!sourceOptions){
|
||||||
this.isLoaded = true;
|
this.isLoaded = true;
|
||||||
|
@ -21,7 +20,7 @@ export default class VectorTile extends Tile {
|
||||||
sourceOptions.data,
|
sourceOptions.data,
|
||||||
sourceOptions.options,
|
sourceOptions.options,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// 初始化数据映射
|
// 初始化数据映射
|
||||||
Object.keys(attributes).forEach((type) => {
|
Object.keys(attributes).forEach((type) => {
|
||||||
|
@ -29,8 +28,17 @@ 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 (maskLayer) {
|
if(layerOptions.mask ) {
|
||||||
const mask = new maskLayer({layerType: "MaskLayer"})
|
await this.addTileMask(layer)
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.addLayer(layer);
|
||||||
|
this.setLayerMinMaxZoom(layer);
|
||||||
|
this.isLoaded = true;
|
||||||
|
}
|
||||||
|
// Todo 校验数据有效性
|
||||||
|
protected async addTileMask(layer: ILayer) {
|
||||||
|
const mask = new MaskLayer({layerType: "MaskLayer"})
|
||||||
.source({
|
.source({
|
||||||
type: 'FeatureCollection',
|
type: 'FeatureCollection',
|
||||||
features: [
|
features: [
|
||||||
|
@ -39,19 +47,10 @@ export default class VectorTile extends Tile {
|
||||||
}, {
|
}, {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'geojson',
|
type: 'geojson',
|
||||||
|
featureId: 'id'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// .style({
|
|
||||||
// opacity: 1
|
|
||||||
// });
|
|
||||||
await this.addMask(layer, mask)
|
await this.addMask(layer, mask)
|
||||||
}
|
|
||||||
await this.addLayer(layer);
|
|
||||||
this.setLayerMinMaxZoom(layer);
|
|
||||||
this.isLoaded = true;
|
|
||||||
}
|
|
||||||
// Todo 校验数据有效性
|
|
||||||
protected beforeInit() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
protected getSourceOption() {
|
protected getSourceOption() {
|
||||||
|
@ -86,4 +85,22 @@ export default class VectorTile extends Tile {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public getFeatures(sourceLayer: string){
|
||||||
|
const source = this.sourceTile.data as VectorSource;
|
||||||
|
return source.getTileData(sourceLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在一个 Tile 中可能存在一个相同 ID 的 feature
|
||||||
|
* @param id
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getFeatureById(id: number) {
|
||||||
|
const layer = this.getMainLayer();
|
||||||
|
if (!layer) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return layer.getSource().data.dataArray.filter(d => d._id === id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import PointLayer from '../../point/index';
|
import PointLayer from '../../point/index';
|
||||||
import LineLayer from '../../line';
|
import LineLayer from '../../line';
|
||||||
import PolygonLayer from '../../polygon';
|
import PolygonLayer from '../../polygon';
|
||||||
import MaskLayer from '../../mask';
|
|
||||||
|
|
||||||
export function getTileLayer(type: string) {
|
export function getTileLayer(type: string) {
|
||||||
if(type === 'PolygonLayer') {
|
if(type === 'PolygonLayer') {
|
||||||
|
@ -18,15 +18,6 @@ export function getTileLayer(type: string) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMaskLayer(type: string){
|
export function isNeedMask(type: string) {
|
||||||
switch(type) {
|
return ['PolygonLayer','LineLayer'].indexOf(type) !== -1
|
||||||
case 'PolygonLayer':
|
|
||||||
case 'LineLayer':
|
|
||||||
return MaskLayer;
|
|
||||||
case 'PointLayer':
|
|
||||||
case 'RasterLayer':
|
|
||||||
return undefined;
|
|
||||||
default:
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -181,10 +181,12 @@ export default class BaseTileLayer {
|
||||||
if (!this.tilesetManager) {
|
if (!this.tilesetManager) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const minZoom = this.parent.getMinZoom();
|
||||||
|
const maxZoom = this.parent.getMaxZoom()
|
||||||
await Promise.all(this.tilesetManager.tiles
|
await Promise.all(this.tilesetManager.tiles
|
||||||
.filter((tile: SourceTile) => tile.isLoaded) // 过滤未加载完成的
|
.filter((tile: SourceTile) => tile.isLoaded) // 过滤未加载完成的
|
||||||
.filter((tile: SourceTile) => tile.isVisibleChange) // 过滤未发生变化的
|
.filter((tile: SourceTile) => tile.isVisibleChange) // 过滤未发生变化的
|
||||||
.filter((tile: SourceTile) => this.isTileReady(tile)) // 过滤未发生变化的
|
.filter((tile: SourceTile) => tile.z>= minZoom && tile.z < maxZoom)
|
||||||
.map(async (tile: SourceTile) => {
|
.map(async (tile: SourceTile) => {
|
||||||
if (!this.tileLayerService.hasTile(tile.key)) {
|
if (!this.tileLayerService.hasTile(tile.key)) {
|
||||||
const tileInstance = getTileFactory(this.parent);
|
const tileInstance = getTileFactory(this.parent);
|
||||||
|
@ -193,11 +195,11 @@ export default class BaseTileLayer {
|
||||||
this.tilePickService.setPickState();
|
this.tilePickService.setPickState();
|
||||||
if(tileLayer.getLayers().length!==0) {
|
if(tileLayer.getLayers().length!==0) {
|
||||||
this.tileLayerService.addTile(tileLayer);
|
this.tileLayerService.addTile(tileLayer);
|
||||||
|
this.tileLayerService.updateTileVisible(tile);
|
||||||
this.layerService.reRender()
|
this.layerService.reRender()
|
||||||
}
|
}
|
||||||
this.tileLayerService.addTile(tileLayer);
|
} else {// 已加载瓦片
|
||||||
this.layerService.reRender()
|
|
||||||
} else {
|
|
||||||
this.tileLayerService.updateTileVisible(tile);
|
this.tileLayerService.updateTileVisible(tile);
|
||||||
this.tilePickService.setPickState();
|
this.tilePickService.setPickState();
|
||||||
this.layerService.reRender()
|
this.layerService.reRender()
|
||||||
|
@ -210,21 +212,6 @@ export default class BaseTileLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
public isTileReady(tile: SourceTile) {
|
|
||||||
|
|
||||||
// if (tile.data?.layers && this.sourceLayer) {
|
|
||||||
// // vector
|
|
||||||
// const vectorTileLayer = tile.data.layers[this.sourceLayer];
|
|
||||||
// const features = vectorTileLayer?.features;
|
|
||||||
// if (!(Array.isArray(features) && features.length > 0)) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
public setPickState(layers: ILayer[]) {}
|
public setPickState(layers: ILayer[]) {}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ 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 * from './source/index';
|
||||||
|
|
||||||
registerParser('rasterTile', rasterTile);
|
registerParser('rasterTile', rasterTile);
|
||||||
registerParser('mvt', mapboxVectorTile);
|
registerParser('mvt', mapboxVectorTile);
|
||||||
|
|
|
@ -36,16 +36,13 @@ function getFeatureID(feature: Feature<Geometries, Properties>, key?: string) {
|
||||||
if (key === undefined) {
|
if (key === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (key === 'id' && feature.id) {
|
|
||||||
// 标准 mapbox vector feature
|
|
||||||
return feature.id;
|
|
||||||
}
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (feature[key]) {
|
if (feature.properties[key]) {
|
||||||
// 单独指定要素
|
// 单独指定要素
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return feature[key];
|
return feature.properties[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (feature.properties && feature.properties[key]) {
|
if (feature.properties && feature.properties[key]) {
|
||||||
// 根据 properties 要素的属性进行编码
|
// 根据 properties 要素的属性进行编码
|
||||||
return djb2hash(feature.properties[key] + '') % 1000019;
|
return djb2hash(feature.properties[key] + '') % 1000019;
|
||||||
|
@ -59,7 +56,6 @@ export default function geoJSON(
|
||||||
): IParserData {
|
): IParserData {
|
||||||
const resultData: IParseDataItem[] = [];
|
const resultData: IParseDataItem[] = [];
|
||||||
const featureKeys: IFeatureKey = {};
|
const featureKeys: IFeatureKey = {};
|
||||||
|
|
||||||
if (!data.features) {
|
if (!data.features) {
|
||||||
data.features = [];
|
data.features = [];
|
||||||
return {
|
return {
|
||||||
|
@ -95,6 +91,7 @@ export default function geoJSON(
|
||||||
if (featureId === null) {
|
if (featureId === null) {
|
||||||
featureId = featureIndex;
|
featureId = featureIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedID = featureId;
|
const sortedID = featureId;
|
||||||
|
|
||||||
const coord = getCoords(currentFeature);
|
const coord = getCoords(currentFeature);
|
||||||
|
|
|
@ -7,10 +7,10 @@ import {
|
||||||
TileLoadParams,
|
TileLoadParams,
|
||||||
TilesetManagerOptions,
|
TilesetManagerOptions,
|
||||||
} from '@antv/l7-utils';
|
} from '@antv/l7-utils';
|
||||||
import { VectorTile, VectorTileLayer } from '@mapbox/vector-tile';
|
import { VectorTileLayer } from '@mapbox/vector-tile';
|
||||||
import { Feature } from '@turf/helpers';
|
import { Feature } from '@turf/helpers';
|
||||||
import Protobuf from 'pbf';
|
|
||||||
import { IParserData } from '../interface';
|
import { IParserData } from '../interface';
|
||||||
|
import VectorSource from '../source/vector';
|
||||||
|
|
||||||
const DEFAULT_CONFIG: Partial<TilesetManagerOptions> = {
|
const DEFAULT_CONFIG: Partial<TilesetManagerOptions> = {
|
||||||
tileSize: 256,
|
tileSize: 256,
|
||||||
|
@ -29,7 +29,7 @@ const getVectorTile = async (
|
||||||
tileParams: TileLoadParams,
|
tileParams: TileLoadParams,
|
||||||
tile: SourceTile,
|
tile: SourceTile,
|
||||||
requestParameters?: Partial<RequestParameters>,
|
requestParameters?: Partial<RequestParameters>,
|
||||||
): Promise<MapboxVectorTile> => {
|
): Promise<VectorSource | undefined> => {
|
||||||
const tileUrl = getURLFromTemplate(url, tileParams);
|
const tileUrl = getURLFromTemplate(url, tileParams);
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const xhr = getArrayBuffer(
|
const xhr = getArrayBuffer(
|
||||||
|
@ -39,12 +39,13 @@ const getVectorTile = async (
|
||||||
},
|
},
|
||||||
(err, data) => {
|
(err, data) => {
|
||||||
if (err || !data) {
|
if (err || !data) {
|
||||||
resolve({ layers: {} });
|
resolve(undefined);
|
||||||
} else {
|
} else {
|
||||||
const vectorTile = new VectorTile(
|
const vectorSource = new VectorSource(data, tile.x, tile.y, tile.z);
|
||||||
new Protobuf(data),
|
// const vectorTile = new VectorTile(
|
||||||
) as MapboxVectorTile;
|
// new Protobuf(data),
|
||||||
resolve(vectorTile);
|
// ) as MapboxVectorTile;
|
||||||
|
resolve(vectorSource);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { ITileSource } from './interface';
|
||||||
|
export default abstract class BaseSource implements ITileSource {
|
||||||
|
protected x: number;
|
||||||
|
protected y: number;
|
||||||
|
protected z: number;
|
||||||
|
constructor(data: any, x: number, y: number, z: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
}
|
||||||
|
public abstract getTileData(layer: string): any;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './interface';
|
||||||
|
export { default as VectorSource } from './vector';
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { VectorTileLayer } from '@mapbox/vector-tile';
|
||||||
|
import { Feature } from '@turf/helpers';
|
||||||
|
export interface ITileSource {
|
||||||
|
getTileData(layer: string): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MapboxVectorTile = {
|
||||||
|
layers: { [_: string]: VectorTileLayer & { features: Feature[] } };
|
||||||
|
};
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { VectorTile } from '@mapbox/vector-tile';
|
||||||
|
import { Feature, Properties } from '@turf/helpers';
|
||||||
|
import Protobuf from 'pbf';
|
||||||
|
import { ITileSource, MapboxVectorTile } from './interface';
|
||||||
|
export default class VectorSource implements ITileSource {
|
||||||
|
private vectorTile: VectorTile;
|
||||||
|
private vectorLayerCache: {
|
||||||
|
[key: string]: Array<Feature<GeoJSON.Geometry, Properties>>;
|
||||||
|
} = {};
|
||||||
|
private x: number;
|
||||||
|
private y: number;
|
||||||
|
private z: number;
|
||||||
|
|
||||||
|
constructor(data: ArrayBuffer, x: number, y: number, z: number) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.vectorTile = new VectorTile(new Protobuf(data)) as MapboxVectorTile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTileData(sourceLayer: string) {
|
||||||
|
if (!sourceLayer || !this.vectorTile.layers[sourceLayer]) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
// 优先走缓存
|
||||||
|
if (this.vectorLayerCache[sourceLayer]) {
|
||||||
|
return this.vectorLayerCache[sourceLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
const vectorTile = this.vectorTile.layers[sourceLayer];
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
if (Array.isArray(vectorTile.features)) {
|
||||||
|
// 数据不需要被解析 geojson-vt 类型
|
||||||
|
// @ts-ignore
|
||||||
|
this.vectorLayerCache[sourceLayer] = vectorTile.features;
|
||||||
|
// @ts-ignore
|
||||||
|
return vectorTile.features;
|
||||||
|
}
|
||||||
|
|
||||||
|
const features: Array<Feature<GeoJSON.Geometry, Properties>> = [];
|
||||||
|
for (let i = 0; i < vectorTile.length; i++) {
|
||||||
|
const vectorTileFeature = vectorTile.feature(i);
|
||||||
|
const feature = vectorTileFeature.toGeoJSON(this.x, this.y, this.z);
|
||||||
|
|
||||||
|
features.push({
|
||||||
|
...feature,
|
||||||
|
properties: {
|
||||||
|
id: feature.id,
|
||||||
|
...feature.properties,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.vectorLayerCache[sourceLayer] = features;
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
public getFeatureById() {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -105,6 +105,7 @@ export class SourceTile extends EventEmitter {
|
||||||
const polygon = bboxPolygon(this.bounds as TileBounds, {
|
const polygon = bboxPolygon(this.bounds as TileBounds, {
|
||||||
properties: {
|
properties: {
|
||||||
key: this.key,
|
key: this.key,
|
||||||
|
id: this.key,
|
||||||
bbox: this.bounds,
|
bbox: this.bounds,
|
||||||
center,
|
center,
|
||||||
meta: `
|
meta: `
|
||||||
|
|
|
@ -109,10 +109,11 @@ export class TilesetManager extends EventEmitter {
|
||||||
verifyZoom,
|
verifyZoom,
|
||||||
latLonBoundsBuffer,
|
latLonBoundsBuffer,
|
||||||
).filter((tile) => {
|
).filter((tile) => {
|
||||||
|
// 处理数据 warp
|
||||||
return (
|
return (
|
||||||
this.options.warp || (tile.x >= 0 && tile.x <= Math.pow(verifyZoom, 2))
|
this.options.warp || (tile.x >= 0 && tile.x < Math.pow(2, verifyZoom))
|
||||||
);
|
);
|
||||||
}); // TODO 数据循环
|
});
|
||||||
this.currentTiles = tileIndices.map(({ x, y, z }) => {
|
this.currentTiles = tileIndices.map(({ x, y, z }) => {
|
||||||
let tile = this.getTile(x, y, z);
|
let tile = this.getTile(x, y, z);
|
||||||
if (tile) {
|
if (tile) {
|
||||||
|
|
Loading…
Reference in New Issue