Performance Openlayers 6.3.1-渲染瓷砖层

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

在Openlayers 6中,每个层都有一个独立的渲染器(以前,所有层渲染都由一个贴图渲染器管理,并且依赖于一个渲染策略)。在我的项目中,我有超过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);
    }
}
@可注入({
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。但是,如果其中一个服务速度慢,整个磁贴加载将很慢,…,我必须渲染磁贴。