在Openlayers 6中,每个图层都有一个独立的渲染器(以前,所有图层渲染都是由单个地图渲染器管理的,并且取决于单个渲染策略-https://openlayers.org/workshop/en/webgl/meteorites.html)。在我的项目中,我有20多个TileLayers(TileWMS),并且加载,平移,滚动性能比openlayers 5差。我可以设置渲染策略吗?如何提高性能?
图块加载速度很快,但是(在加载图块之后)在地图上平移很慢。 GPU使用率不是很严格(低于30%)
Angular 9项目,服务类中的逻辑:
@Injectable({
providedIn: 'root'
})
export class EMap {
private eMap: OlMap;
public createMapObject(): void {
this.eMap = new OlMap({
layers: [],
view: new View({
projection,
resolutions: resolutionsArray,
constrainResolution: true,
enableRotation: false
}),
controls: defaultControls({
rotate: false,
attribution: false,
zoom: false
}).extend([
mousePositionControl,
scalelineControl
])
});
}
public initMap(center: Coordinate, zoom: number, target: string): void {
this.eMap.getView().setCenter(center);
this.eMap.getView().setZoom(zoom);
this.eMap.setTarget(target);
}
public addLayer(layer: TileLayer | ImageLayer | VectorLayer): void {
this.eMap.addLayer(layer);
}
}
@Injectable({
providedIn: 'root'
})
export class EMapSupportlayers extends EMapNetworklayers {
constructor(private readonly eMap: EMap) {}
public addTilelayer(networklayerInfo: NetworklayerInfo): void {
const layer: TileLayer = this.createTileLayer(tileLayerInitValues);
this.eMap.addLayer(layer);
}
private createTileLayer(tileLayerInitValues: TileLayerInitValues): TileLayer {
const tileGrid: TileGrid = new TileGrid({
extent: tileLayerInitValues.tileGridExtent,
resolutions: tileLayerInitValues.resolutions,
tileSize: tileLayerInitValues.tileSize
});
const source = new TileWMS({
url: tileLayerInitValues.url,
params: {
LAYERS: tileLayerInitValues.layerName,
FORMAT: tileLayerInitValues.layerFormat
},
tileLoadFunction: (image: any, src: string) => this.customLoader(image, src),
tileGrid
});
return new TileLayer({
visible: tileLayerInitValues.visible,
maxZoom: tileLayerInitValues.maxZoom,
minZoom: ttileLayerInitValues.minZoom,
source,
zIndex: tileLayerInitValues.zindex
});
}
private async customLoader(tile: any, sourceUrl: string): Promise<void> {
const response = await fetch(sourceUrl, {
method: 'POST',
credentials: 'include',
headers: new Headers({
Authorization: `Bearer ${...}`
}),
body: requestBody ? requestBody : null
});
const blob = await response.blob();
tile.getImage().src = URL.createObjectURL(blob);
}
}
--- 07.19。
我创建了一个虚拟轴示例(Angular9,Openlayers 6.3.1): 图层图块正在快速加载。在小屏幕上,平移速度很快,但在大屏幕上,平移速度很慢(在加载和缓存图块之后)。在openlayers 5中,性能更好。
import { AfterViewInit, Component } from '@angular/core';
import TileLayer from 'ol/layer/Tile';
import Map from 'ol/Map';
import { OSM } from 'ol/source';
import View from 'ol/View';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterViewInit {
ngAfterViewInit(): void {
const mapElement = document.createElement('div');
mapElement.style.cssText = 'position:absolute;width:100%;height:100%';
const layers = [];
for (let i = 0; i < 30; ++i) {
const layer = new TileLayer({
source: new OSM(),
// className: 'layer' + i => create own canvas by layers, same performance
});
layer.setOpacity(0.03);
layers.push(layer);
}
const map = new Map({
layers,
view: new View({
center: [0, 0],
zoom: 1
})
});
document.body.appendChild(mapElement);
map.setTarget(mapElement);
}
}
答案 0 :(得分:0)
URL.createObjectURL
可能会导致内存泄漏,请尝试
const blob = await response.blob();
const objectURL = URL.createObjectURL(blob)
tile.getImage().onload = function(){
URL.revokeObjectURL(objectURL);
};
tile.getImage().src = objectURL;
您的任何图层还使用相同的WMS URL和不同的WMS layerName
吗?将它们组合成单个OpenLayers层会更有效,并在LAYERS参数中列出WMS层名称。
答案 1 :(得分:0)
我找到了一个解决方案,虽然不完美,但是性能更好。
map.on('movestart', () => {
layers.forEach(layer => {
layer.setExtent(map.getView().calculateExtent());
});
});
map.on('moveend', () => {
layers.forEach(layer => {
layer.setExtent(undefined);
});
});