GeoServer 图层组发布与应用

概要

项目开发中经常遇到需要对专题图服务的图层进行控制,在使用 ArcGIS/GeoScene Server 的时候这点很好实现。
通过 ArcGIS/GeoScene Server 发布的 MapServer 能够很好的构建带有子分组的图层组,也能对图层设置中文别名。服务地址加上 f=pjson 访问参数能直接获取图层树 json 信息,ArcGIS /GeoScene API for JS v4.x 还提供了 MapImageLayer 类来加载并控制子图层。
MapServer 示例
GeoServer 相对 ArcGIS/GeoScene Server 来说并不能直接发布对应的专题图层,但仍能通过自身的【图层组】功能实现类似的专题图服务发布与应用。

发布图层组

GeoServer 具备发布【图层组】的能力,但不能像 ArcGIS/GeoScene Server 一样一步到位,因为 GeoServer 图层组不支持直接对内部图层进行再次分组,需要将各个分组先发布成图层组,再将分组加入目标图层组,具体可参考下述操作:

  1. 创建子分组的图层组

    💡 为方便后续查询,需做以下设置:

    • 【命名】可设置为英文图层名,【标题】可设置为中文别名
    • 指定【工作区】,方便数据筛查
    • 【模式】设置为 named tree

    image.png

  2. 重复以上操作,创建所有子分组;

  3. 创建目标图层组,加入之前创建的图层组,作为子图层组;

    image.png

  4. 获取图层信息

    • 方式一:通过 GeoServer REST API 获取信息 ,但需要进行身份验证

      GET /geoserver/rest/layergroups/{layerGroupName}.json  
      
    • 方式二:通过 GetCapabilities 获取指定工作区的 XML 能力文档,从 WMS_Capabilities.Capability.Layer 中过滤出目标图层组,Name 节点对应【命名】,Title 节点对应【标题】。

      💡 需要注意以下几点:

      1. 能力文档会获取指定工作空间下的所有图层和图层组,需要根据需求进行过滤筛查
      2. 图层组和子图层组的【模式】都需设置为 named tree,否则能力文档无法展示子图层信息
      3. 图层组不支持 WFS 操作,WFS 仅针对单个图层设计。GeoServer 的图层组主要用于将多个图层组合在一起以实现样式或渲染的共享,而不是用于跨多个图层执行数据查询。此外,每个图层可能有自己的特性和属性,这使得使用单个 WFS 查询处理图层组数据变得复杂。因此,如果需要对属于同一图层组的多个图层进行数据查询,需要对每个图层单独执行 WFS 查询。

    image.png

服务加载与查询

ArcGIS /GeoScene API for JS v4.x

图层加载

使用 WMSLayer 加载图层组(为方便图层控制,不采用 WMTS 格式)

// 添加管线图层
const layerGroupName = 'pipeLine';
const layer = new WMSLayer({
  url: 'http://yourGeoserverInstance/geoserver/{workspace}/wms',
  sublayers: [{
    name: layerGroupName 
  }],
  spatialReference:{wkid:number} //! important
});

图层树信息获取

通过能力文档获取图层组图层列表信息

const url = 'http://yourGeoserverInstance/geoserver/{workspace}/wms?service=wms&version=1.3.0&request=GetCapabilities';
let groups;
axios.get(url).then(
  function (response) {
    // 需要借助第三方库将 xml 解析成 json
    const wmsCapabilities = xmltojson(response.data);
    // 需要将专题图筛选出来
    groups = wmsCapabilities.WMS_Capabilities.Capability.Layer.Layer.find((layer) => layer.Name === layerGroupName).Layer;
  },
  function (error) {
    console.error(error);
  }
);

图层显隐控制

通过变更WMSLayersublayers 属性控制当前展示的图层

layer.sublayers = [
    {
      name: 'sublayer1'
    },
    {
      name: 'sublayer2'
    }
  ];

要素信息拾取

通过 WMS 的 GetFeatureInfo 拾取要素信息

view.on('click', function (event) {
  // 获取可见图层
  const layers = layer.sublayers
    .filter(({ visible, queryable, name }) => visible && queryable && name)
    .map(({ name }) => name)
    .join();
  
  const x = event.mapPoint.x;
  const y = event.mapPoint.y;

  // 拾取容差处理
  const toleranceInMeters = 10;
  const xmin = x - toleranceInMeters;
  const xmax = x + toleranceInMeters;
  const ymin = y - toleranceInMeters;
  const ymax = y + toleranceInMeters;

  const { spatialReference: { latestWkid, wkid} } = view.extent;
  const bbox = `${xmin},${ymin},${xmax},${ymax}`;
  const crs = `EPSG:${latestWkid ?? wkid}`;

  request(layer.featureInfoUrl, {
    query: {
      SERVICE: "WMS",
      LAYERS: layers,
      QUERY_LAYERS: layers,
      REQUEST: "GetFeatureInfo",
      INFO_FORMAT: "application/json",
      FEATURE_COUNT: 5,
      BBOX: bbox,
      CRS: crs,
      WIDTH: view.width,
      HEIGHT: view.height,
      I: Math.round(event.x),
      J: Math.round(event.y)
    }
  }).then(({data}) => { // to do something });
});

OpenLayers 3

图层加载

使用 ImageWMS 加载图层组

// 添加管线图层
const layerGroupName = 'pipeLine';
const layer = new ol.layer.Image({
  source: new ol.source.ImageWMS({
    ratio: 1,
    url: 'http://yourGeoserverInstance/geoserver/{workspace}/wms',
    params: {
      'FORMAT': 'image/png',
      'VERSION': '1.1.1',  
      "LAYERS": layerGroupName,
    }
  })
});

图层树信息获取

同上

图层显隐控制

通过变更ImageWMSupdateParams 属性来更新当前展示的图层

layer.getSource().updateParams = ({'LAYERS': 'sublayer1,sublayer2'});

要素信息拾取

通过 WMS 的 GetFeatureInfo 拾取要素信息

map.on('singleclick', function(evt) {
  const view = map.getView();
  const viewResolution = view.getResolution();
  const source = layer.getSource();
  const url = source.getGetFeatureInfoUrl(
    evt.coordinate, 
    viewResolution, 
    view.getProjection(),
    {
      'INFO_FORMAT': 'application/json', 
      'FEATURE_COUNT': 5
    });
  request(url).then(({data}) => { // to do something });
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值