Performance Openlayers 6.3.1-渲染瓷砖层
在Openlayers 6中,每个层都有一个独立的渲染器(以前,所有层渲染都由一个贴图渲染器管理,并且依赖于一个渲染策略)。在我的项目中,我有超过20个TileLayers(TileWMS),加载、平移和滚动的性能比openlayers 5更差。我可以设置渲染策略吗?如何提高性能 瓦片加载速度很快,但(加载瓦片后)在地图上的平移速度很慢。GPU的使用不重要(低于30%) Angular 9项目,服务类中的逻辑:Performance Openlayers 6.3.1-渲染瓷砖层,performance,rendering,openlayers,openlayers-6,Performance,Rendering,Openlayers,Openlayers 6,在Openlayers 6中,每个层都有一个独立的渲染器(以前,所有层渲染都由一个贴图渲染器管理,并且依赖于一个渲染策略)。在我的项目中,我有超过20个TileLayers(TileWMS),加载、平移和滚动的性能比openlayers 5更差。我可以设置渲染策略吗?如何提高性能 瓦片加载速度很快,但(加载瓦片后)在地图上的平移速度很慢。GPU的使用不重要(低于30%) Angular 9项目,服务类中的逻辑: @Injectable({ providedIn: 'root' }) ex
@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);
}
}
@可注入({
providedIn:'根'
})
导出类EMap{
私有eMap:OlMap;
public createMapObject():void{
this.eMap=new OlMap({
图层:[],
视图:新视图({
投影,
决议:决议阵列,
决议:是的,
enableRotation:错误
}),
控件:默认控件({
旋转:假,
归因:假,
缩放:假
}).延伸([
鼠标位置控制,
鳞片控制
])
});
}
public initMap(中心:坐标,缩放:数字,目标:字符串):void{
this.eMap.getView().setCenter(center);
this.eMap.getView().setZoom(缩放);
this.eMap.setTarget(target);
}
公共添加层(层:TileLayer | ImageLayer | VectorLayer):无效{
this.eMap.addLayer(层);
}
}
@注射的({
providedIn:'根'
})
导出类EMapSupportlayers扩展EMapNetworklayers{
构造函数(私有只读eMap:eMap){}
公共addTilelayer(networklayerInfo:networklayerInfo):无效{
const layer:TileLayer=this.createTileLayer(tileLayerInitValues);
this.eMap.addLayer(层);
}
私有createTileLayer(tileLayerInitValues:tileLayerInitValues):TileLayer{
const tileGrid:tileGrid=新tileGrid({
范围:tileLayerInitValues.tileGridExtent,
分辨率:tileLayerInitValues.resolutions,
tileSize:tileLayerInitValues.tileSize
});
const source=新的TileWMS({
url:tileLayerInitValues.url,
参数:{
图层:tileLayerInitValues.layerName,
格式:tileLayerInitValues.layerFormat
},
tileLoadFunction:(image:any,src:string)=>this.customLoader(image,src),
瓦莱格里德
});
返回新TileLayer({
可见:tileLayerInitValues.visible,
maxZoom:tileLayerInitValues.maxZoom,
minZoom:ttileLayerInitValues.minZoom,
来源:,
zIndex:tilleayerinitvalues.zIndex
});
}
私有异步定制加载器(tile:any,sourceUrl:string):承诺{
const response=等待获取(sourceUrl{
方法:“POST”,
凭据:“包括”,
标题:新标题({
授权:`持有人${…}`
}),
正文:requestBody?requestBody:空
});
const blob=wait response.blob();
tile.getImage().src=URL.createObjectURL(blob);
}
}
---07.19
我创建了一个虚拟AxSample(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);
}
}
从'@angular/core'导入{AfterViewInit,Component};
从“ol/layer/Tile”导入TileLayer;
从“ol/Map”导入地图;
从“ol/source”导入{OSM};
从“ol/View”导入视图;
@组成部分({
选择器:'应用程序根',
templateUrl:“./app.component.html”,
样式URL:['./app.component.scss']
})
导出类AppComponent实现AfterViewInit{
ngAfterViewInit():void{
常量mapElement=document.createElement('div');
mapElement.style.cssText='位置:绝对;宽度:100%;高度:100%';
常数层=[];
对于(设i=0;i<30;++i){
const layer=新瓷砖层({
来源:新OSM(),
//className:'layer'+i=>按层创建自己的画布,性能相同
});
层不透明度(0.03);
层。推(层);
}
常量映射=新映射({
层,
视图:新视图({
中间:[0,0],
缩放:1
})
});
document.body.appendChild(mapElement);
setTarget(mapElement);
}
}
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
图层名称
?将它们组合到一个OpenLayers层中,并在LAYERS参数中列出WMS层名称会更有效。我找到了一个解决方案,虽然不完美,但性能更好
map.on('movestart', () => {
layers.forEach(layer => {
layer.setExtent(map.getView().calculateExtent());
});
});
map.on('moveend', () => {
layers.forEach(layer => {
layer.setExtent(undefined);
});
});
你好,安图。欢迎来到StackOverflow。请向我们展示您需要优化的代码。这可能会更容易帮助您。添加了用户在问题中尝试的代码我必须逐层更改层可见性:(如果只是可见性(而不是不透明度),您可以使用
layer.getSource().updateParams({layers:newlayerlist})
很抱歉,但不是相同的URL,我可以尝试在tileLoadFunction中通过larenames分叉URL。但是,如果其中一个服务速度慢,整个磁贴加载将很慢,…,我必须渲染磁贴。