【问题标题】:WMS Layer not rendered properly on all zoom levelsWMS 图层未在所有缩放级别上正确渲染
【发布时间】:2018-11-25 01:35:46
【问题描述】:

我已经配置了一个带有 PostGIS v2.4.2 扩展的 PostgreSQL v9.5.12 数据库。我使用 GeoServer v2.13.1 将数据库表呈现为 WMS 图层,并使用 Openlayers (v4.6.5) 在 web 应用程序中将它们可视化。使用的投影是EPSG:31255

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

我也将此设置和代码用于其他层,并且运行顺畅,但是这些层使用不同的投影 (ESPG:4326)。

我该如何解决这个问题?

截图1(右侧部分轮廓被剪掉)

截图 2(中间的绿点不见了)

编辑: 这是一个包含 EPSG:31255 定义的代码 sn-p,但实际上并未将其用于 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()
        ])
    });

【问题讨论】:

  • EPSG:4326 是内置在 OpenLayers 中的,我认为 31255 不是这种情况。您可以仔细检查投影的定义(顺便说一句,您使用的是 proj4js 吗?)另外,使用网络调试选项卡,您能否确认 WMS 切片请求中没有失败?是否有可能使用最少的代码来进一步挖掘您的问题?
  • 确实,我没有使用 proj4s 声明 EPSG:31255。我现在添加了该部分,但该图层根本不可见。我需要更改地图的视图吗?我按照这里的答案,只改变了 WMS 的投影,而不是地图本身的投影:gis.stackexchange.com/questions/143883/…
  • 显然图层仍然在地图上渲染,只是不在它应该在的位置。

标签: javascript openlayers postgis geoserver wms


【解决方案1】:

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

提示:before OpenLayers 导入 proj4js,不用 OpenLayers 中的额外工作。

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

现在,我们需要使用将这个新投影考虑在内的视图来创建或更新 OpenLayers 地图。

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 应该自动将它们重新投影到您的地图投影中。

具体示例:在 OSM 地图上使用图层

/** 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()
    ])
});

【讨论】:

  • GeoServer 将比 OpenLayers 更好更快地重新投影矢量数据,因此始终在地图投影中请求您的切片。
  • 提供的示例表明我也需要设置投影的范围。这是必需的还是可选的?目前这两种方式都不起作用。
  • @IanTurton :如果您在加载完所有内容后不需要切换投影,那确实是这样。否则,OL 重投影足以避免通过网络重新请求切片。 stopopol:我认为不需要指定范围。您能否为我们提供更多见解,例如代码?没有更多信息,很难找到问题的根源。
  • 这个问题真的超出了我的想象。如果我仔细按照您的指示,问题实际上会变得更糟。这些图层仅在很少的缩放级别上可见。我一放大,它们就完全消失了。如果我省略投影定义,它们会显示得更好,但仍然很糟糕。投影声明本身有效。我使用 console.log(ol.proj.fromLonLat([5.2, 52.25], 'EPSG:31255')); 进行了测试
【解决方案2】:

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

利用提供的 WMTS 或 TMS 端点从 GeoServer/GeoWebCache 请求切片。例如,这个page 展示了如何正确操作。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-27
  • 2013-10-18
  • 1970-01-01
  • 2012-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多