GeoServer工作空间

6 阅读6分钟

借助之前的QGIS的地图工程的概念,我们同步来理解Geoserver的结构

基本概念

GeoServer的工作空间几乎可以简单的理解为QGIS的地图工程

下表格的举例可能不太恰当,主要是为了强行解释尤其是OGC那块,有点牵强。

平台数据源图层符号库字体库
GeoServerPostGIS/MbtilesLayersSLDFonts
桌面-QGIS矢量PostGISLayers样式管理器Fonts
Web-Mapbox[矢量瓦片] SourcesLayersSpriteGlyphs
OGC规范WMTS/WMS/WCS/WFSSLDSESE

Geoser的工作空间包含以下4个部分 namespace和workspace就是个简单的命名和别名,如下所示

<workspace>
  <id>WorkspaceInfoImpl--220010c:1857b55f620:-7fff</id>
  <name>OSM</name>
  <isolated>false</isolated>
  <dateCreated>2023-01-04 05:53:51.146 UTC</dateCreated>
  <dateModified>2023-02-06 03:49:58.307 UTC</dateModified>
</workspace>
<namespace>
  <id>NamespaceInfoImpl--220010c:1857b55f620:-7ffe</id>
  <prefix>OSM</prefix>
  <uri>OSM</uri>
  <isolated>false</isolated>
</namespace>

数据源 datastore

一般为同名的文件夹下,对应上图的OSM,里面的结构如下所示

<dataStore>
  <id>DataStoreInfoImpl--220010c:1857b55f620:-7ffd</id>
  <name>OSM</name>
  <type>MBTiles with vector tiles</type>
  <enabled>true</enabled>
  <workspace>
    <id>WorkspaceInfoImpl--220010c:1857b55f620:-7fff</id>
  </workspace>
  <connectionParameters>
    <entry key="database">file:///home/parndeedlit/Documents/mbtiles/WORLD_0_6.mbtiles</entry>
    <entry key="passwd">crypt1:x2IKsVOwzX2jOXoWioh9PylUVfmEQEcM</entry>
    <entry key="dbtype">mbtiles</entry>
    <entry key="namespace">OSM</entry>
    <entry key="user">admin</entry>
  </connectionParameters>
  <__default>false</__default>
  <dateCreated>2023-01-04 05:55:00.793 UTC</dateCreated>
</dataStore>

上面核心的部分就是记录了数据源的路径uri:mbtile对应的文件,[postgis]对应的服务路径。因此每一个数据源里面存储了众多图层信息,每个图层对应一个自文件夹。

图层 layer

每个图层对应一个文件夹,每个子文件夹里面分为

<layer>
  <name>省级行政区</name>
  <id>LayerInfoImpl--220010c:1857b55f620:-7feb</id>
  <type>VECTOR</type>
  <defaultStyle>
    <id>StyleInfoImpl-37b18cc6:14d5d036d48:-8000</id>
  </defaultStyle>
  <resource class="featureType">
    <id>FeatureTypeInfoImpl--220010c:1857b55f620:-7fec</id>
  </resource>
  <attribution>
    <logoWidth>0</logoWidth>
    <logoHeight>0</logoHeight>
  </attribution>
  <dateCreated>2023-01-04 05:57:40.839 UTC</dateCreated>
</layer>
<featureType>
  <id>FeatureTypeInfoImpl--220010c:1857b55f620:-7fec</id>
  <name>省级行政区</name>
  <nativeName>省级行政区</nativeName>
  <namespace>
    <id>NamespaceInfoImpl--220010c:1857b55f620:-7ffe</id>
  </namespace>
  <title>省级行政区</title>
  <keywords>
    <string>features</string>
    <string>省级行政区</string>
  </keywords>
  <nativeCRS class="projected">PROJCS[&quot;WGS 84 / Pseudo-Mercator&quot;, 
  GEOGCS[&quot;WGS 84&quot;, 
    DATUM[&quot;World Geodetic System 1984&quot;, 
      SPHEROID[&quot;WGS 84&quot;, 6378137.0, 298.257223563, AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]], 
      AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]], 
    PRIMEM[&quot;Greenwich&quot;, 0.0, AUTHORITY[&quot;EPSG&quot;,&quot;8901&quot;]], 
    UNIT[&quot;degree&quot;, 0.017453292519943295], 
    AXIS[&quot;Geodetic longitude&quot;, EAST], 
    AXIS[&quot;Geodetic latitude&quot;, NORTH], 
    AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]], 
  PROJECTION[&quot;Popular Visualisation Pseudo Mercator&quot;, AUTHORITY[&quot;EPSG&quot;,&quot;1024&quot;]], 
  PARAMETER[&quot;semi_minor&quot;, 6378137.0], 
  PARAMETER[&quot;latitude_of_origin&quot;, 0.0], 
  PARAMETER[&quot;central_meridian&quot;, 0.0], 
  PARAMETER[&quot;scale_factor&quot;, 1.0], 
  PARAMETER[&quot;false_easting&quot;, 0.0], 
  PARAMETER[&quot;false_northing&quot;, 0.0], 
  UNIT[&quot;m&quot;, 1.0], 
  AXIS[&quot;Easting&quot;, EAST], 
  AXIS[&quot;Northing&quot;, NORTH], 
  AUTHORITY[&quot;EPSG&quot;,&quot;3857&quot;]]</nativeCRS>
  <srs>EPSG:3857</srs>
  <nativeBoundingBox>
    <minx>-1.971679688981382E7</minx>
    <maxx>1.9861623547335867E7</maxx>
    <miny>-4.4927335427097075E7</miny>
    <maxy>4.492733542709663E7</maxy>
    <crs class="projected">EPSG:3857</crs>
  </nativeBoundingBox>
  <latLonBoundingBox>
    <minx>-177.11900000000003</minx>
    <maxx>178.42</maxx>
    <miny>-89.9</miny>
    <maxy>89.89999999999999</maxy>
    <crs>EPSG:4326</crs>
  </latLonBoundingBox>
  <projectionPolicy>FORCE_DECLARED</projectionPolicy>
  <enabled>true</enabled>
  <store class="dataStore">
    <id>DataStoreInfoImpl--220010c:1857b55f620:-7ffd</id>
  </store>
  <serviceConfiguration>false</serviceConfiguration>
  <simpleConversionEnabled>false</simpleConversionEnabled>
  <internationalTitle/>
  <internationalAbstract/>
  <maxFeatures>0</maxFeatures>
  <numDecimals>0</numDecimals>
  <padWithZeros>false</padWithZeros>
  <forcedDecimal>false</forcedDecimal>
  <overridingServiceSRS>false</overridingServiceSRS>
  <skipNumberMatched>false</skipNumberMatched>
  <circularArcPresent>false</circularArcPresent>
</featureType>

图层组 layergroup

如果说数据源datastore是图层layer的物理上的存储上级,那么图层组LayerGroup就是图层layer的逻辑上的组织上级

上面这一句话怎么理解呢?物理上的存储上级好理解,毕竟一个数据库里面包含若干张表,每张表对应一个图层。但是这样缺少了什么呢?缺少了图层顺序和图层的符号化信息,我们直接把物理存储拖入QGIS中,发现是随机上色的一些点线面(QGIS后面的版本也支持了geopackage中记录了简单的样式),并且这些图层的顺序是按照名称顺序排序的,从人的角度出发几乎是难以阅读的。如果要满足人的阅读,需要按照一定的顺序和一定的符号化显示要求来进行组织,这个进行组织的过程就是图层组 逻辑上的**组织上级 **的含义。

组图层信息记录再layergroups文件夹下

该文件夹下一般存在一个和工作空间同名的xml文件

<layerGroup>
  <id>LayerGroupInfoImpl--220010c:1857b55f620:-7fe9</id>
  <name>OSM</name>
  <mode>SINGLE</mode>
  <workspace>
    <id>WorkspaceInfoImpl--220010c:1857b55f620:-7fff</id>
  </workspace>
  <internationalTitle/>
  <internationalAbstract/>
  <publishables>
    <published type="layer">
      <id>LayerInfoImpl--220010c:1857b55f620:-7fed</id>
    </published>
    <published type="layer">
      <id>LayerInfoImpl--220010c:1857b55f620:-7ff1</id>
    </published>
    <published type="layer">
      <id>LayerInfoImpl--220010c:1857b55f620:-7ff3</id>
    </published>
  </publishables>
  <styles>
    <style>
      <id>StyleInfoImpl-37b18cc6:14d5d036d48:-8000</id>
    </style>
    <style>
      <id>StyleInfoImpl-37b18cc6:14d5d036d48:-8000</id>
    </style>
    <style>
      <id>StyleInfoImpl-37b18cc6:14d5d036d48:-8000</id>
    </style>
  </styles>
  <bounds>
    <minx>-1.971679688981382E7</minx>
    <maxx>1.9861623547335867E7</maxx>
    <miny>-4.4927335427097075E7</miny>
    <maxy>4.492733542709663E7</maxy>
    <crs class="projected">EPSG:3857</crs>
  </bounds>
  <dateCreated>2023-01-04 05:59:50.846 UTC</dateCreated>
  <dateModified>2023-01-04 05:59:57.266 UTC</dateModified>
</layerGroup>

如上所示 图层组核心的逻辑是4个部分

  1. 基本信息:名称 id uuid
  2. 图层信息:一个数组,数组中每一个表示一个图层 implid表示唯一图层,数组中顺序代表了图层的压盖顺序
  3. 样式信息:和上面图层信息数组的长度一一对应,分别表示对应的图层所对应的的样式信息,记录了符号库和字体库2部分
  4. 空间范围:记录了该图层组对应的空间范围,包含坐标系信息

符号库 symbol

符号库在工作空间的下的styles文件夹下

如上图所示,主要分为2部分

符号:由若干的png/svg组成,表示最小的符号单元

SLD:由OGC-SLD语法形成的XML,记录了每个图层的过滤,比例尺,符号化信息,注记等所有信息,可以参考

字体库 font

默认使用操作系统的字体库

OGC服务 service

对应的xml对应了对应的OGC的服务

以wmts为例,这个xml不是标准的OGC-WMTS的xml,而是geoserver本身的元数据的配置xml,因此不做过多的描述

<wmts>
  <id>WMTSInfoImpl-7f9a0455:1859ab22c8f:-7ff4</id>
  <workspace>
    <id>WorkspaceInfoImpl-7f9a0455:1859ab22c8f:-7fff</id>
  </workspace>
  <enabled>true</enabled>
  <name>WMTS</name>
  <title>GeoServer Web Map Tile Service</title>
  <maintainer>http://geoserver.org/com</maintainer>
  <abstrct>A compliant implementation of WMTS service.</abstrct>
  <accessConstraints>NONE</accessConstraints>
  <fees>NONE</fees>
  <versions>
    <org.geotools.util.Version>
      <version>1.0.0</version>
    </org.geotools.util.Version>
  </versions>
  <citeCompliant>false</citeCompliant>
  <onlineResource>http://geoserver.org</onlineResource>
  <schemaBaseURL>http://schemas.opengis.net</schemaBaseURL>
  <verbose>false</verbose>
</wmts>

串联 MapTex

之前的文章 就吐槽过geoserver的人机交互问题,主要是下面2个问题

  1. 图层鼠标人机交互还是挺多挺麻烦的,虽然说是批处理,但是我感觉geoserver的人机交互还是很原始不友好的)
  2. 整个批量处理中,我感觉只是节省了上传大量符号和sld文件的过程,其余的图层发布和融合成一个组图层的工作是一点也不少的。这点感觉需要针对geoserver的代码进行定制开发了。

如果批量处理呢,这些问题同样的我将其集成到了Maptex中了

通过一键命令自动构建所有的层次和关联关系