首页 文章

WMS图层在所有缩放级别上都无法正确呈现

提问于
浏览
2

我已经使用PostGIS v2.4.2扩展配置了PostgreSQL v9.5.12数据库 . 我使用GeoServer v2.13.1将数据库的表格呈现为WMS图层,并使用Openlayers(v4.6.5)在webapp中将其可视化 . 使用的投影是EPSG:31255 .

但是,WMS图层在所有缩放级别上都无法正确显示 . 有时瓷砖会被切断(见截图1),或者不会渲染图层中的每个点(参见屏幕截图2) . 在某些级别,特别是在放大时,图层根本不显示 . 在GeoServer本身以及将它们添加到qGIS时,图层会正确显示 .

我也使用这个设置和代码用于其他图层并且它工作顺利,但是这些图层使用不同的投影(ESPG:4326) .

我怎样才能解决这个问题?

WMS Example 1
截屏1(右侧轮廓的一部分被切掉)

WMS Example 2
截屏2(缺少中间的绿点)

编辑:这是一个代码片段,其中包含EPSG:31255的定义,而实际上并未将其用于wmsSource .

// proj4js custom projection        
    proj4.defs("EPSG:31255","+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs");
    var proj31255 = ol.proj.get('EPSG:31255');
    proj31255.setExtent([-115771.3204, 130037.7189, 115359.4571, 408002.5351]);

    var wmsSource = new ol.source.TileWMS({
        url: geoserver_getcapabilities_url + geoserver_workspace + '/wms?',
        params: {
            'LAYERS': wms_layer_name
        },
        serverType: 'geoserver',
        //projection: 'EPSG:31255'
    });

    var wmsLayer = new ol.layer.Tile({
        source: wmsSource,
        name: 'selected_wms_layer',
        visible: true
    }); 

    var osmLayer = new ol.layer.Tile({
        source: new ol.source.OSM()
    });

    var view = new ol.View({
        center: map_centre,
        zoom: initial_zoom_level,
        projection: 'EPSG:3857'
    });

    /** Set-up the map */
    var map = new ol.Map({
        target: 'map',
        layers: [osmLayer, wmsLayer, point_layer],
        overlays: [overlay],
        view: view,
        loadTilesWhileAnimating: true,
        loadTilesWhileInteracting: true,
        controls: ol.control.defaults().extend([
            new ol.control.OverviewMap()
        ])
    });

2 回答

  • 2

    像这样的问题的常见原因是使用标准WMS作为 TileWMS 层的基础 . 这可能会导致客户端和服务器中出现各种问题 .

    利用提供的WMTS或TMS endpoints 从GeoServer / GeoWebCache请求切片 . 例如,page显示了如何正确执行 .

  • 3

    TL; DR:An excellent working example is available on the OpenLayers WebSite

    (在下面的例子中,我使用的位置应该在奥地利的某个地方)

    首先,让我们确保正确设置EPSG:31255 . 如评论中所述,我建议您使用proj4js,如果您必须处理预测,它将使您的生活更轻松 .

    将proj4js库导入应用程序后,请按以下方式声明EPSG:31255投影:

    proj4.defs("EPSG:31255","+proj=tmerc +lat_0=0 +lon_0=13.33333333333333 +k=1 +x_0=0 +y_0=-5000000 +ellps=bessel +towgs84=577.326,90.129,463.919,5.137,1.474,5.297,2.4232 +units=m +no_defs");
    

    (您可以使用epsg.io作为源导入proj4js中的大量投影:https://epsg.io/31255.js

    提示:在OpenLayers之前导入proj4js,它将在OpenLayers中使用而无需额外的工作 .

    第一种情况:处理所有图层的一个投影

    现在,我们需要创建或更新OpenLayers Map ,其中包含考虑此新投影的视图 .

    let myMap = new ol.Map({
            target: myDOMElement,
            layers: [...],
            view: new ol.View({
                center: ol.proj.fromLonLat([50163.181015, 255280.097217]),
                zoom: 5,
                projection: 'EPSG:31255'
            })
        });
    

    现在,您可能会在设置正确的中心时遇到困难,因为您必须在EPSG:31255投影中设置其坐标 .

    为了更容易,我建议使用基于EPSG的变换:4326 .

    view: new ol.View({
        // Converts from coordinates known in EPSG:4326 to coordinates in EPSG:31255
        center: ol.proj.transform([13.7548828125, 47.43896484375], 'EPSG:4326', 'EPSG:31255'),
        zoom: 5,
        projection: 'EPSG:31255' // Projection you want the map to use
    })
    

    第二种情况:处理不同的预测

    那么,如果您对不同的图层有不同的投影怎么办?

    只需在TileWMS中指定它们(确保它们都已声明) .

    let myWMSSource = new ol.source.TileWMS({
        url: myURL,
        params: {
            'LAYERS': 'myCustomLayer'
        },
        serverType: 'geoserver',
        projection: 'EPSG:31255' // Declare the projection the source is in.
    });
    

    OpenLayers应该在 Map 投影中自动重新投影它们 .

    具体示例:在OSM Map 上使用您的图层

    /** Set a source */
    let myWMSSource = new ol.source.TileWMS({
        url: myURL,
        params: {
            'LAYERS': 'myCustomLayer'
        },
        serverType: 'geoserver',
        projection: 'EPSG:31255'
    });
    
    /** Create a custom tile layer */
    let myLayerTile = new ol.layer.Tile({
        source: myWMSSource,
        name: 'MyTile',
        visible: true
    });
    
    /**
     * Create a layer using OSM.
     * Note that ol.source.OSM uses EPSG:3857
     */
    let OSMLayer = new ol.layer.Tile({
        source: new ol.source.OSM()
    });
    
    /** Set-up the map */
    let myMap = new ol.Map({
        target: DOMElement,
        layers: [OSMLayer, myLayerTile],
        view: new ol.View({
            center: ol.proj.fromLonLat([1549123.872774, 6044640.196792]),
            zoom: 1,
            projection: 'EPSG:3857'
        }),
        loadTilesWhileAnimating: true,
        loadTilesWhileInteracting: true,
        controls: ol.control.defaults().extend([
            new ol.control.OverviewMap()
        ])
    });
    

相关问题