mirror of https://gitee.com/antv-l7/antv-l7
parent
b0a88c40a9
commit
2f8749064b
|
@ -0,0 +1,102 @@
|
|||
// @ts-ignore
|
||||
import { PointLayer, Scene } 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',
|
||||
map: new GaodeMapV2({
|
||||
center: [ 110, 36 ],
|
||||
style: 'light',
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const pointLayer = new PointLayer({})
|
||||
.source({
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"name": "A"
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
135.52734375,
|
||||
46.31658418182218
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"name": "B"
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
120.9375,
|
||||
27.059125784374068
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {
|
||||
"name": "C"
|
||||
},
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
107.22656249999999,
|
||||
37.020098201368114
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
.shape('circle')
|
||||
.size(12)
|
||||
.color('red')
|
||||
.style({
|
||||
stroke: ['name', (name)=>{
|
||||
switch (name) {
|
||||
case 'A' :
|
||||
return '#fc8d59';
|
||||
|
||||
case 'B' :
|
||||
return '#91cf60';
|
||||
default:
|
||||
return '#ffffbf';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
], // 描边颜色
|
||||
strokeWidth: 5, // 描边宽度
|
||||
|
||||
});
|
||||
|
||||
scene.addLayer(pointLayer);
|
||||
|
||||
|
||||
});
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
// @ts-ignore
|
||||
import { PointLayer,LineLayer, Scene } from '@antv/l7';
|
||||
// @ts-ignore
|
||||
import {GaodeMapV2 } from '@antv/l7-maps';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
export default () => {
|
||||
useEffect( () => {
|
||||
let startPoint =[110.23,32];
|
||||
const scene = new Scene({
|
||||
id: 'map',
|
||||
map: new GaodeMapV2({
|
||||
center: [ 110, 36 ],
|
||||
style: 'light',
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const line = new LineLayer({})
|
||||
.source({
|
||||
"type": "FeatureCollection",
|
||||
"features": []
|
||||
})
|
||||
.shape('line')
|
||||
.size(1)
|
||||
.color('red')
|
||||
.style({ // 描边颜色
|
||||
lineType: 'dash',
|
||||
dashArray: [5, 5],
|
||||
});
|
||||
const pointLayer = new PointLayer({})
|
||||
.source([])
|
||||
.shape('name','text')
|
||||
.size(12)
|
||||
.color('red')
|
||||
.style({
|
||||
strokeWidth: 0.3, // 描边宽度
|
||||
strokeOpacity: 1.0,
|
||||
textAllowOverlap: false,
|
||||
});
|
||||
|
||||
const circleLayer = new PointLayer({})
|
||||
.source({
|
||||
"type": "FeatureCollection",
|
||||
"features": []
|
||||
})
|
||||
.shape('circle')
|
||||
.size(12)
|
||||
.color('red')
|
||||
.style({
|
||||
stroke:'#fff',
|
||||
strokeWidth: 2, // 描边宽度
|
||||
strokeOpacity: 1.0,
|
||||
});
|
||||
|
||||
scene.addLayer(pointLayer);
|
||||
scene.addLayer(line);
|
||||
scene.addLayer(circleLayer);
|
||||
|
||||
scene.on('mousemove',(e)=>{
|
||||
const {lng,lat} = e.lnglat;
|
||||
pointLayer.setData([])
|
||||
circleLayer.setData({
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
77.34374999999999,
|
||||
34.88593094075317
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
lng,lat
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
line.setData({
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": [
|
||||
[
|
||||
77.34374999999999,
|
||||
34.88593094075317
|
||||
],
|
||||
[
|
||||
lng,lat
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// @ts-ignore
|
||||
import { PointLayer, Scene } 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',
|
||||
map: new GaodeMapV2({
|
||||
center: [ 110, 36 ],
|
||||
style: 'light',
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
fetch('https://gw.alipayobjects.com/os/rmsportal/oVTMqfzuuRFKiDwhPSFL.json')
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
const pointLayer = new PointLayer({})
|
||||
.source([], {
|
||||
parser: {
|
||||
type: 'json',
|
||||
x: 'j',
|
||||
y: 'w'
|
||||
}
|
||||
})
|
||||
.shape('m', 'text')
|
||||
.size(12)
|
||||
.color('w', [ '#0e0030', '#0e0030', '#0e0030' ])
|
||||
.style({
|
||||
// textAllowOverlap: true,
|
||||
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
||||
textOffset: [ 0, 0 ], // 文本相对锚点的偏移量 [水平, 垂直]
|
||||
spacing: 2, // 字符间距
|
||||
padding: [ 1, 1 ], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
||||
stroke: '#ffffff', // 描边颜色
|
||||
strokeWidth: 0.3, // 描边宽度
|
||||
strokeOpacity: 1.0
|
||||
});
|
||||
pointLayer.style({
|
||||
stroke: '#f00', // 描边颜色
|
||||
strokeWidth: 0.3, // 描边宽度
|
||||
strokeOpacity: 1.0,
|
||||
textAllowOverlap: false,
|
||||
})
|
||||
scene.addLayer(pointLayer);
|
||||
setTimeout(()=>{
|
||||
pointLayer.setData(data.list)
|
||||
},2000)
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
### Point - stroke
|
||||
#### style 映射
|
||||
<code src="./demos/pointstroke.tsx"></code>
|
|
@ -0,0 +1,3 @@
|
|||
### Point - text
|
||||
#### 文本更新
|
||||
<code src="./demos/text.tsx"></code>
|
|
@ -0,0 +1,3 @@
|
|||
### Point - update
|
||||
#### style 映射
|
||||
<code src="./demos/pointupdate.tsx"></code>
|
|
@ -0,0 +1,84 @@
|
|||
// @ts-ignore
|
||||
import { PolygonLayer, Scene } 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',
|
||||
map: new GaodeMapV2({
|
||||
center: [ 110, 36 ],
|
||||
style: 'light',
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
|
||||
const fill = new PolygonLayer({})
|
||||
.source({
|
||||
type: 'FeatureCollection',
|
||||
features:[]
|
||||
})
|
||||
.shape('line')
|
||||
.color('red')
|
||||
.style({
|
||||
opacity:1,
|
||||
|
||||
});
|
||||
|
||||
scene.addLayer(fill);
|
||||
setTimeout(()=>{
|
||||
fill.setData({
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"properties": {},
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[
|
||||
97.734375,
|
||||
29.6880527498568
|
||||
],
|
||||
[
|
||||
119.88281249999999,
|
||||
29.6880527498568
|
||||
],
|
||||
[
|
||||
119.88281249999999,
|
||||
42.8115217450979
|
||||
],
|
||||
[
|
||||
97.734375,
|
||||
42.8115217450979
|
||||
],
|
||||
[
|
||||
97.734375,
|
||||
29.6880527498568
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
},2000)
|
||||
});
|
||||
|
||||
|
||||
}, []);
|
||||
return (
|
||||
<div
|
||||
id="map"
|
||||
style={{
|
||||
height: '500px',
|
||||
position: 'relative',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
### polygon
|
||||
<code src="./demos/polygon.tsx"></code>
|
|
@ -0,0 +1,39 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { DrawPolygon } from '@antv/l7-draw';
|
||||
import { GaodeMapV2 } from '@antv/l7-maps';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
const id = String(Math.random());
|
||||
|
||||
const Demo: React.FC = () => {
|
||||
const [, setPolygonDrawer] = useState<DrawPolygon | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const scene = new Scene({
|
||||
id,
|
||||
map: new GaodeMapV2({
|
||||
center: [120.151634, 30.244831],
|
||||
pitch: 0,
|
||||
style: 'dark',
|
||||
zoom: 10,
|
||||
}),
|
||||
});
|
||||
scene.on('loaded', () => {
|
||||
const drawer = new DrawPolygon(scene, {
|
||||
areaOptions: {},
|
||||
liveUpdate: true,
|
||||
});
|
||||
setPolygonDrawer(drawer);
|
||||
console.log(drawer);
|
||||
drawer.enable();
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div id={id} style={{ height: 400, position: 'relative' }} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Demo;
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
title: 展示距离和面积
|
||||
order: 3
|
||||
group:
|
||||
path: /polygon
|
||||
title: 绘制面
|
||||
order: 3
|
||||
---
|
||||
|
||||
<code src="./demo/draw.tsx" compact="true" defaultShowCode="true"></code>
|
|
@ -32,6 +32,15 @@ export default () => {
|
|||
dashArray: [5, 5],
|
||||
});
|
||||
scene.addLayer(layer);
|
||||
|
||||
// setTimeout(()=>{
|
||||
// console.log('setdata')
|
||||
// layer.setData({
|
||||
// type: 'featureCollection',
|
||||
// features:[],
|
||||
// })
|
||||
|
||||
// },3000)
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"@antv/g2plot": "^2.3.40",
|
||||
"@antv/gatsby-theme-antv": "^1.1.15",
|
||||
"@antv/l7-district": "^2.3.9",
|
||||
"@antv/l7-draw": "2.4.18",
|
||||
"@antv/l7-draw": "^3.0.8",
|
||||
"@antv/l7-react": "^2.3.3",
|
||||
"@antv/l7plot": "^0.1.0",
|
||||
"@babel/cli": "^7.6.4",
|
||||
|
|
|
@ -687,9 +687,6 @@ export interface ILayerService {
|
|||
renderLayers(): void;
|
||||
setEnableRender(flag: boolean): void;
|
||||
getOESTextureFloat(): boolean;
|
||||
pickRender(layer: ILayer,target?: IInteractionTarget):void
|
||||
selectFeature(layer: ILayer, pickedColors: Uint8Array | undefined):void;
|
||||
highlightPickedFeature(layer: ILayer, pickedColors: Uint8Array | undefined):void;
|
||||
|
||||
destroy(): void;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,6 @@ import { TYPES } from '../../types';
|
|||
import Clock from '../../utils/clock';
|
||||
import { IMapService } from '../map/IMapService';
|
||||
import { IRendererService } from '../renderer/IRendererService';
|
||||
import {
|
||||
IInteractionTarget,
|
||||
} from '../interaction/IInteractionService';
|
||||
import { ILayer, ILayerService, LayerServiceEvent } from './ILayerService';
|
||||
|
||||
@injectable()
|
||||
|
@ -145,7 +142,6 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
}
|
||||
this.alreadyInRendering = true;
|
||||
this.clear();
|
||||
|
||||
for (const layer of this.layerList) {
|
||||
if (layer.masks.filter((m)=>m.inited).length > 0) {
|
||||
// 清除上一次的模版缓存
|
||||
|
@ -178,12 +174,15 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
}
|
||||
|
||||
public async beforeRenderData(layer: ILayer) {
|
||||
const res = await layer.hooks.beforeRenderData.promise()
|
||||
res && this.renderLayers();
|
||||
const flag = await layer.hooks.beforeRenderData.promise();
|
||||
if(flag) {
|
||||
this.renderLayers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async renderLayer(layer: ILayer){
|
||||
|
||||
|
||||
if (layer.masks.filter((m)=>m.inited).length > 0) {
|
||||
layer.masks.map(mask =>{
|
||||
this.renderService.clear({
|
||||
|
@ -261,44 +260,6 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
return this.shaderPicking;
|
||||
}
|
||||
|
||||
// For Pick
|
||||
|
||||
// 拾取绘制
|
||||
public pickRender(layer: ILayer,target: IInteractionTarget) {
|
||||
if(layer.tileLayer) {
|
||||
// 瓦片图层(layerGroup)走独立的拾取渲染
|
||||
return layer.tileLayer.pickRender(target)
|
||||
}
|
||||
|
||||
// 普通瓦片(单个图层的拾取渲染)
|
||||
layer.hooks.beforePickingEncode.call();
|
||||
|
||||
if (layer.masks.length > 0) {
|
||||
// 若存在 mask,则在 pick 阶段的绘制也启用
|
||||
layer.masks.map(async (m: ILayer) => {
|
||||
m.render();
|
||||
});
|
||||
}
|
||||
layer.renderModels(true);
|
||||
layer.hooks.afterPickingEncode.call();
|
||||
|
||||
}
|
||||
|
||||
public selectFeature(layer: ILayer, pickedColors: Uint8Array | undefined) {
|
||||
|
||||
if(layer.tileLayer) {
|
||||
return layer.tileLayer.selectFeature(pickedColors)
|
||||
}
|
||||
// @ts-ignore
|
||||
const [r, g, b] = pickedColors;
|
||||
layer.hooks.beforeSelect.call([r, g, b]);
|
||||
}
|
||||
|
||||
public highlightPickedFeature(layer: ILayer,pickedColors: Uint8Array | undefined): void {
|
||||
if(layer.tileLayer) {
|
||||
return layer.tileLayer.highlightPickedFeature(pickedColors)
|
||||
}
|
||||
}
|
||||
|
||||
public clear() {
|
||||
const color = rgb2arr(this.mapService.bgColor) as [
|
||||
|
|
|
@ -75,6 +75,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
|||
options: Partial<IStyleAttributeInitializationOptions>,
|
||||
updateOptions?: Partial<IStyleAttributeUpdateOptions>,
|
||||
) {
|
||||
|
||||
let attributeToUpdate = this.getLayerStyleAttribute(attributeName);
|
||||
if (!attributeToUpdate) {
|
||||
attributeToUpdate = this.registerStyleAttribute({
|
||||
|
@ -82,8 +83,6 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
|||
name: attributeName,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const { scale } = options;
|
||||
if (scale && attributeToUpdate) {
|
||||
// TODO: 需要比较新旧值确定是否需要 rescale
|
||||
|
|
|
@ -369,7 +369,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
);
|
||||
this.multiPassRenderer.setLayer(this);
|
||||
}
|
||||
|
||||
// 完成样式服务注册完成前添加的属性
|
||||
this.pendingStyleAttributes.forEach(
|
||||
({ attributeName, attributeField, attributeValues, updateOptions }) => {
|
||||
|
@ -673,7 +672,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
*/
|
||||
public renderLayers(): void {
|
||||
this.rendering = true;
|
||||
|
||||
this.layerService.renderLayers();
|
||||
|
||||
this.rendering = false;
|
||||
|
@ -685,7 +683,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
this.tileLayer.render();
|
||||
return this;
|
||||
}
|
||||
|
||||
this.layerService.beforeRenderData(this);
|
||||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return this;
|
||||
}
|
||||
|
@ -698,9 +696,9 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
* renderMultiPass 专门用于渲染支持 multipass 的 layer
|
||||
*/
|
||||
public async renderMultiPass() {
|
||||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return;
|
||||
}
|
||||
// if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
// return;
|
||||
// }
|
||||
if (this.multiPassRenderer && this.multiPassRenderer.getRenderFlag()) {
|
||||
// multi render 开始执行 multiPassRender 的渲染流程
|
||||
await this.multiPassRenderer.render();
|
||||
|
@ -1043,7 +1041,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
if (this.layerSource) {
|
||||
this.layerSource.off('update', this.sourceEvent);
|
||||
}
|
||||
|
||||
this.layerSource = source;
|
||||
this.clusterZoom = 0;
|
||||
|
||||
|
@ -1056,7 +1053,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
this.sourceEvent();
|
||||
}
|
||||
// this.layerSource.inited 为 true update 事件不会再触发
|
||||
this.layerSource.on('update', () => {
|
||||
this.layerSource.on('update', ({ type }) => {
|
||||
if (this.coordCenter === undefined) {
|
||||
const layerCenter = this.layerSource.center;
|
||||
this.coordCenter = layerCenter;
|
||||
|
@ -1064,7 +1061,11 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
this.mapService.setCoordCenter(layerCenter);
|
||||
}
|
||||
}
|
||||
this.sourceEvent();
|
||||
|
||||
if (type === 'update') {
|
||||
// source 初始化不需要处理
|
||||
this.sourceEvent();
|
||||
}
|
||||
});
|
||||
}
|
||||
// layer 初始化source
|
||||
|
@ -1325,18 +1326,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return this;
|
||||
}
|
||||
// TODO 待评估
|
||||
// if (this.layerModelNeedUpdate && this.layerModel) {
|
||||
|
||||
// this.layerModel.buildModels((models: IModel[]) => {
|
||||
// this.models = models;
|
||||
// this.hooks.beforeRender.call();
|
||||
// this.layerModelNeedUpdate = false;
|
||||
// });
|
||||
// }
|
||||
this.layerService.beforeRenderData(this);
|
||||
this.hooks.beforeRender.call();
|
||||
|
||||
this.models.forEach((model) => {
|
||||
model.draw(
|
||||
{
|
||||
|
@ -1345,7 +1335,6 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
isPicking,
|
||||
);
|
||||
});
|
||||
|
||||
this.hooks.afterRender.call();
|
||||
return this;
|
||||
}
|
||||
|
@ -1375,8 +1364,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.inited) {
|
||||
if (!this.startInit) {
|
||||
// 开始初始化执行
|
||||
this.pendingStyleAttributes.push({
|
||||
attributeName: type,
|
||||
attributeField: field,
|
||||
|
|
|
@ -51,10 +51,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
|
||||
// remapping before render
|
||||
layer.hooks.beforeRender.tap('DataMappingPlugin', () => {
|
||||
const { usage } = layer.getLayerConfig();
|
||||
if (usage === 'basemap') {
|
||||
return;
|
||||
}
|
||||
const source = layer.getSource();
|
||||
if (layer.layerModelNeedUpdate || !source || !source.inited) {
|
||||
return;
|
||||
|
@ -62,12 +58,15 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||
const { dataArray } = source.data;
|
||||
// TODO 数据为空的情况
|
||||
if (Array.isArray(dataArray) && dataArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attributesToRemapping = attributes.filter(
|
||||
(attribute) => attribute.needRemapping, // 如果filter变化
|
||||
);
|
||||
let filterData = dataArray;
|
||||
|
||||
// 数据过滤完 再执行数据映射
|
||||
if (filter?.needRemapping && filter?.scale) {
|
||||
filterData = dataArray.filter((record: IParseDataItem) => {
|
||||
|
@ -95,8 +94,8 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
);
|
||||
layer.setEncodedData(encodeData);
|
||||
}
|
||||
// 处理文本更新
|
||||
layer.emit('remapping', null);
|
||||
// 处理文本更新,更新文字形状
|
||||
// layer.emit('remapping', null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -198,61 +197,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
return mappedData;
|
||||
}
|
||||
|
||||
private mapLayerMapping(
|
||||
layer: ILayer,
|
||||
attributes: IStyleAttribute[],
|
||||
data: IParseDataItem[],
|
||||
predata?: IEncodeFeature[],
|
||||
): IEncodeFeature[] {
|
||||
const usedAttributes = attributes.filter(
|
||||
(attribute) => attribute.scale !== undefined,
|
||||
);
|
||||
const mappedData = data.map((record: IParseDataItem, i) => {
|
||||
const preRecord = predata ? predata[i] : {};
|
||||
const encodeRecord: IEncodeFeature = {
|
||||
id: record._id,
|
||||
coordinates: record.coordinates,
|
||||
...preRecord,
|
||||
};
|
||||
usedAttributes.forEach((attribute: IStyleAttribute) => {
|
||||
if (
|
||||
attribute.name === 'shape' &&
|
||||
// @ts-ignore
|
||||
layer.shapeOption?.field === 'simple'
|
||||
) {
|
||||
encodeRecord[attribute.name] = 'simple';
|
||||
attribute.needRemapping = false;
|
||||
} else {
|
||||
const values = this.applyMapLayerAttributeMapping(attribute, record);
|
||||
|
||||
attribute.needRemapping = false;
|
||||
|
||||
// @ts-ignore
|
||||
encodeRecord[attribute.name] =
|
||||
Array.isArray(values) && values.length === 1 ? values[0] : values;
|
||||
|
||||
// 增加对 layer/text/iconfont unicode 映射的解析
|
||||
if (attribute.name === 'shape') {
|
||||
encodeRecord.shape = this.fontService.getIconFontKey(
|
||||
encodeRecord[attribute.name] as string,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (encodeRecord.size === undefined) {
|
||||
// in case not set size
|
||||
encodeRecord.size = 1;
|
||||
}
|
||||
return encodeRecord;
|
||||
}) as IEncodeFeature[];
|
||||
|
||||
// 调整数据兼容 Amap2.0
|
||||
this.adjustData2Amap2Coordinates(mappedData, layer);
|
||||
|
||||
return mappedData;
|
||||
}
|
||||
|
||||
private adjustData2Amap2Coordinates(
|
||||
mappedData: IEncodeFeature[],
|
||||
layer: ILayer,
|
||||
|
@ -374,29 +318,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
// return attribute.mapping ? attribute.mapping(params) : [];
|
||||
}
|
||||
|
||||
private applyMapLayerAttributeMapping(
|
||||
attribute: IStyleAttribute,
|
||||
record: { [key: string]: unknown },
|
||||
) {
|
||||
if (!attribute.scale) {
|
||||
return [];
|
||||
}
|
||||
const scalers = attribute?.scale?.scalers || [];
|
||||
const params: unknown[] = [];
|
||||
|
||||
scalers.forEach(({ field }) => {
|
||||
if (
|
||||
record.hasOwnProperty(field) ||
|
||||
attribute.scale?.type === 'variable'
|
||||
) {
|
||||
params.push(record[field]);
|
||||
}
|
||||
});
|
||||
|
||||
const mappingResult = attribute.mapping ? attribute.mapping(params) : [];
|
||||
return mappingResult;
|
||||
}
|
||||
|
||||
private getArrowPoints(p1: Position, p2: Position) {
|
||||
const dir = [p2[0] - p1[0], p2[1] - p1[1]];
|
||||
const normalizeDir = normalize(dir);
|
||||
|
|
|
@ -10,25 +10,32 @@ export default class DataSourcePlugin implements ILayerPlugin {
|
|||
this.mapService = layer.getContainer().get<IMapService>(TYPES.IMapService);
|
||||
layer.hooks.init.tapPromise('DataSourcePlugin', async () => {
|
||||
let source = layer.getSource();
|
||||
|
||||
if (!source) {
|
||||
// Tip: 用户没有传入 source 的时候使用图层的默认数据
|
||||
const { data, options } =
|
||||
layer.sourceOption || layer.defaultSourceConfig;
|
||||
source = new Source(data, options);
|
||||
await new Promise((resolve) => {
|
||||
source.on('update', (e) => {
|
||||
if (e.type === 'inited') {
|
||||
layer.initSource(source);
|
||||
}
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
layer.setSource(source);
|
||||
// await new Promise((resolve) => {
|
||||
// source.on('update', (e) => {
|
||||
// if (e.type === 'inited') {
|
||||
// layer.initSource(source);
|
||||
// }
|
||||
// resolve(null);
|
||||
// });
|
||||
// });
|
||||
}
|
||||
if (source.inited) {
|
||||
this.updateClusterData(layer);
|
||||
} else {
|
||||
source.once('update', () => {
|
||||
this.updateClusterData(layer);
|
||||
await new Promise((resolve) => {
|
||||
source.on('update', (e) => {
|
||||
if (e.type === 'inited') {
|
||||
this.updateClusterData(layer);
|
||||
}
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -36,6 +43,7 @@ export default class DataSourcePlugin implements ILayerPlugin {
|
|||
// 检测数据是否需要更新
|
||||
layer.hooks.beforeRenderData.tapPromise('DataSourcePlugin', async () => {
|
||||
const neeUpdateCluster = this.updateClusterData(layer);
|
||||
|
||||
const dataSourceNeedUpdate = layer.dataState.dataSourceNeedUpdate;
|
||||
layer.dataState.dataSourceNeedUpdate = false;
|
||||
return neeUpdateCluster || dataSourceNeedUpdate;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {
|
||||
ILayer,
|
||||
ILayerPlugin,
|
||||
IParserData,
|
||||
IScale,
|
||||
IScaleOptions,
|
||||
IStyleAttribute,
|
||||
|
@ -42,17 +41,6 @@ const scaleMap = {
|
|||
export default class FeatureScalePlugin implements ILayerPlugin {
|
||||
private scaleOptions: IScaleOptions = {};
|
||||
|
||||
private getSourceData(layer: ILayer, callback: (data: IParserData) => void) {
|
||||
const source = layer.getSource();
|
||||
if (source.inited) {
|
||||
callback(source.data);
|
||||
} else {
|
||||
source.once('update', () => {
|
||||
callback(source.data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public apply(
|
||||
layer: ILayer,
|
||||
{
|
||||
|
@ -82,18 +70,16 @@ export default class FeatureScalePlugin implements ILayerPlugin {
|
|||
const dataArray = layer.getSource().data.dataArray;
|
||||
|
||||
if (Array.isArray(dataArray) && dataArray.length === 0) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
this.caculateScalesForAttributes(attributes || [], dataArray);
|
||||
layer.layerModelNeedUpdate = true;
|
||||
|
||||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
layer.hooks.beforeRender.tap('FeatureScalePlugin', () => {
|
||||
const { usage } = layer.getLayerConfig();
|
||||
if (layer.layerModelNeedUpdate || usage === 'basemap') {
|
||||
if (layer.layerModelNeedUpdate) {
|
||||
return;
|
||||
}
|
||||
this.scaleOptions = layer.getScaleOptions();
|
||||
|
|
|
@ -21,7 +21,7 @@ export default class LayerModelPlugin implements ILayerPlugin {
|
|||
// clear layerModel resource
|
||||
// 初始化 Model
|
||||
await layer.buildModels();
|
||||
layer.layerModelNeedUpdate = false;
|
||||
// layer.layerModelNeedUpdate = false;
|
||||
}
|
||||
|
||||
public apply(layer: ILayer) {
|
||||
|
@ -43,7 +43,7 @@ export default class LayerModelPlugin implements ILayerPlugin {
|
|||
}
|
||||
if (layer.getSource().isTile) {
|
||||
layer.tileLayer = new TileLayer(layer);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
await this.prepareLayerModel(layer);
|
||||
return true;
|
||||
|
|
|
@ -13,5 +13,8 @@ export default class UpdateModelPlugin implements ILayerPlugin {
|
|||
layer.layerModel.needUpdate();
|
||||
}
|
||||
});
|
||||
layer.hooks.afterRender.tap('UpdateModelPlugin', () => {
|
||||
layer.layerModelNeedUpdate = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ export default class FillModel extends BaseModel {
|
|||
unit = 'l7size',
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.updateUnit(unit);
|
||||
|
||||
if (
|
||||
this.dataTextureTest &&
|
||||
this.dataTextureNeedUpdate({
|
||||
|
@ -68,7 +67,6 @@ export default class FillModel extends BaseModel {
|
|||
this.cellProperties,
|
||||
);
|
||||
this.rowCount = height; // 当前数据纹理有多少行
|
||||
|
||||
this.dataTexture =
|
||||
this.cellLength > 0 && data.length > 0
|
||||
? this.createTexture2D({
|
||||
|
|
|
@ -177,8 +177,12 @@ export default class TextModel extends BaseModel {
|
|||
}
|
||||
|
||||
public async initModels():Promise<IModel[]> {
|
||||
|
||||
// 绑定事件
|
||||
this.bindEvent();
|
||||
if(!this.layer.inited) {
|
||||
this.bindEvent();
|
||||
}
|
||||
|
||||
this.extent = this.textExtent();
|
||||
const {
|
||||
textAnchor = 'center',
|
||||
|
@ -195,8 +199,15 @@ export default class TextModel extends BaseModel {
|
|||
const {
|
||||
mask = false,
|
||||
maskInside = true,
|
||||
textAllowOverlap = false
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.mapping();
|
||||
|
||||
// this.mapping(); 重复调用
|
||||
this.initGlyph(); //
|
||||
this.updateTexture();
|
||||
if(!textAllowOverlap) {
|
||||
this.filterGlyphs();
|
||||
}
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
|
@ -215,16 +226,21 @@ export default class TextModel extends BaseModel {
|
|||
const {
|
||||
textAllowOverlap = false,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
const data = this.layer.getEncodedData();
|
||||
if(data.length < 5 || textAllowOverlap) { // 小于不做避让
|
||||
return false;
|
||||
}
|
||||
|
||||
// textAllowOverlap 发生改变
|
||||
const zoom = this.mapService.getZoom();
|
||||
const extent = this.mapService.getBounds();
|
||||
const flag = boundsContains(this.extent, extent);
|
||||
// 文本不能压盖则进行过滤
|
||||
if (
|
||||
(!textAllowOverlap && (Math.abs(this.currentZoom - zoom) > 1 || !flag)) ||
|
||||
((Math.abs(this.currentZoom - zoom) > 1 || !flag)) ||
|
||||
textAllowOverlap !== this.preTextStyle.textAllowOverlap
|
||||
) {
|
||||
// TODO this.mapping
|
||||
// TODO this.mapping 数据未变化,避让
|
||||
this.reBuildModel();
|
||||
return true;
|
||||
}
|
||||
|
@ -327,15 +343,14 @@ export default class TextModel extends BaseModel {
|
|||
|
||||
private bindEvent() {
|
||||
if(!this.layer.isTileLayer) {
|
||||
// console.log('mapping')
|
||||
// 重新绑定
|
||||
this.layer.on('remapping', this.mapping);
|
||||
}
|
||||
}
|
||||
|
||||
private mapping = async(): Promise<void> =>{
|
||||
this.initGlyph();
|
||||
this.initGlyph(); //
|
||||
this.updateTexture();
|
||||
this.filterGlyphs();
|
||||
await this.reBuildModel();
|
||||
}
|
||||
|
||||
|
@ -470,7 +485,7 @@ export default class TextModel extends BaseModel {
|
|||
? feature.originCentroid
|
||||
: feature.centroid) as [number, number];
|
||||
const size = feature.size as number;
|
||||
const fontScale: number = size / 24;
|
||||
const fontScale: number = size / 16;
|
||||
const pixels = this.mapService.lngLatToContainer(centroid);
|
||||
const { box } = collisionIndex.placeCollisionBox({
|
||||
x1: shaping.left * fontScale - padding[0],
|
||||
|
@ -515,7 +530,6 @@ export default class TextModel extends BaseModel {
|
|||
if (this.texture) {
|
||||
this.texture.destroy();
|
||||
}
|
||||
|
||||
this.texture = createTexture2D({
|
||||
data: canvas,
|
||||
mag: gl.LINEAR,
|
||||
|
@ -530,7 +544,7 @@ export default class TextModel extends BaseModel {
|
|||
mask = false,
|
||||
maskInside = true,
|
||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||
this.filterGlyphs();
|
||||
this.filterGlyphs();
|
||||
const model = await this.layer
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointText',
|
||||
|
@ -543,6 +557,6 @@ export default class TextModel extends BaseModel {
|
|||
});
|
||||
// TODO 渲染流程待修改
|
||||
this.layer.models = [model];
|
||||
this.layerService.throttleRenderLayers();
|
||||
// this.layerService.throttleRenderLayers();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ export default class FillModel extends BaseModel {
|
|||
this.cellProperties,
|
||||
);
|
||||
this.rowCount = height; // 当前数据纹理有多少行
|
||||
|
||||
this.dataTexture =
|
||||
this.cellLength > 0 && data.length > 0
|
||||
? this.createTexture2D({
|
||||
|
|
|
@ -202,6 +202,7 @@ export default class Source extends EventEmitter implements ISource {
|
|||
this.originData = data;
|
||||
this.dataArrayChanged = false;
|
||||
this.initCfg(options);
|
||||
|
||||
this.init().then(()=>{
|
||||
this.emit('update',{
|
||||
type: 'update'
|
||||
|
|
|
@ -76,7 +76,6 @@ export const getTileImage = async (
|
|||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(imageUrl);
|
||||
const xhr = getImage({ url: imageUrl }, (err, img) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
|
|
Loading…
Reference in New Issue