0%

地图服务发布

地图服务发布

教程参考:https://www.cnblogs.com/kkyyhh96/p/6379515.html

视频参考:https://www.bilibili.com/video/BV1vk4y127P8

PostgreSQL

MySQL 是最流行的关系型数据库管理系统(RDBMS)。

PostgreSQL 是一个免费的对象-关系数据库系统(ORDBMS)。ORDBMS是面向对象技术与传统的关系数据库相结合的产物,在原来关系数据库的基础上,增加了一些新的特性。

EnterpriseDB 是全球唯一一家提供基于 PostgreSQL 企业级产品与服务的厂商,在这里可以下载pg数据库。

下载地址:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads

image-20210804152642254

下载进来是个exe可执行文件,双击运行。

安装过程参考:https://www.runoob.com/postgresql/windows-install-postgresql.html

(注意:安装时可以选择中文,但是我的报错了The database cluster initialization failed

image-20210804212205842

汉化:

image-20210805095604949

安装完成后Navicat连接,密码为安装时设置的密码(xiaoshi)。

image-20210804154704044

默认是开机启动服务,如果需要设置成手动,按如下步骤执行:开始->运行->(然后键入:) services.msc。当您看到PostgresSQL服务时,将它们设置为手动而不是自动。

之后开启关闭服务可以通过如下命令:

1
2
3
net start postgresql-x64-10

net stop postgresql-x64-10

PostGIS

PostGIS 是一个开源程序,它为对象-关系型数据库PostgreSQL提供了存储空间地理数据的支持,使PostgreSQL成为了一个空间数据库,能够进行空间数据管理、数量测量与几何拓扑分析。PostGIS 实现了开放地理空间协会所提出的基本要素类(点、线、面、多点、多线、多面等)的SQL实现参考。

PostgreSQL安装完成后自带了Application Stack Builder,但速度比较慢,而且可能会卡死无响应(我就卡死了,下载不进来)。

推荐直接下载exe可执行文件安装。

下载地址:http://download.osgeo.org/postgis/windows/pg10/

image-20210804155233170

下载完成后安装,注意在设置安装组件时,最好选择”Create spatial database“,以便在创建数据库时可以以此作为模板。对于其他步骤的设置都选择默认值即可。

image-20210804155357258

输入密码:2

image-20210804155541958

安装成功后就可以在Navicat里面看到新增了一个数据库。

image-20210804160203816

创建空间数据库

新建一个数据库postgis_test,里面新建查询,输入以下查询语句以加载PostGIS空间扩展

1
CREATE EXTENSION postgis;

成功后,刷新,数据表中会出现spatial_ref_sys表,说明可以导入空间数据了。

也可以通过运行PostGIS函数来确认是否在数据库中安装了PostGIS扩展插件:

1
SELECT postgis_full_version();

加载空间数据

参考教程:https://zhuanlan.zhihu.com/p/62160223

数据下载地址

使用的数据介绍:https://zhuanlan.zhihu.com/p/62337014

  1. 一个shapfile必须有的文件:
  • .shp —— 存储地理要素的几何信息

  • .shx —— 存储要素几何图形的索引信息

  • .dbf —— 存储地理要素的属性信息(非几何信息)

可选文件包括:

  • .prj —— 存储空间参考信息,即地理坐标系统信息和投影坐标系统信息。使用well-known文本格式进行描述。

PostGIS shapefile工具将shapefile数据从二进制转换为一系列的SQL命令,然后在数据库中运行以加载数据,从而使shapefile数据在PostGIS中可用。

  1. “SRID”表示“Spatial Reference IDentifier(空间参考标识符)”。它定义了我们数据的地理坐标系统投影的所有参数。

SRID很方便,因为它将有关地图投影的所有信息(可能非常复杂)打包(更具体的说应该是映射)到一个数字中。

直接在PostGIS内部对spatial_ref_sys表进行查询:

1
SELECT srtext FROM spatial_ref_sys WHERE srid = 26918;

PostGIS的spatial_ref_sys表是一个OGC标准表,用于定义数据库已知的所有空间参考系统。PostGIS附带的数据列出了3000多个已知的空间参考系统以及在它们之间进行转换/重新投影所需的详细信息。

26918对应的空间参考系统的文本表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
PROJCS[
"NAD83 / UTM zone 18N",
GEOGCS[
"NAD83",
DATUM[
"North_American_Datum_1983",
SPHEROID[
"GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]
],
AUTHORITY["EPSG","6269"]
],
PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],
UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],
AUTHORITY["EPSG","4269"]
],
UNIT["metre",1,AUTHORITY["EPSG","9001"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",0],
PARAMETER["central_meridian",-75],
PARAMETER["scale_factor",0.9996],
PARAMETER["false_easting",500000],
PARAMETER["false_northing",0],
AUTHORITY["EPSG","26918"],
AXIS["Easting",EAST],
AXIS["Northing",NORTH]
]

如果从数据的data目录打开xxx.prj文件,将看到相同的投影信息。

使用PostGIS的一个常见问题是弄清楚要使用哪个SRID号来使用他们的数据。他们只有一个.prj文件,但是应该如何将.prj文件转换成正确的SRID号呢?

最简单的方法就是去GIS软件里面查看shapfile的属性。

加载过程:

使用PostGIS 2.0 Shapefile and DBF Loader Exporter进行加载。

  1. 设置连接
image-20210805144708038
  1. 导入数据,设置SRID号

在QGIS里面查看SRID为image-20210805145010252

image-20210805150251816

可以看到,导入失败,报错:Unable to convert data value to UTF-8 (iconv reports "Illegal byte sequence"). Current encoding is "UTF-8". Try "LATIN1" (Western European), or one of the values described at http://www.postgresql.org/docs/current/static/multibyte.html.

原因是编码格式不对,打开Options 将编码改为 GBK (中文),如果改成GBK还不行,试试gb18030编码。

数据详解

数据是有关纽约市的四个shapefile文件和一个包含社会人口经济数据的数据表。

  1. nyc_census_blocks

QGIS

QGIS教程:https://www.osgeo.cn/qgis-tutorial/index.html

QGIS,是一个桌面端GIS查看器/编辑器,用于快速查看数据。

QGIS可以查看许多数据格式,包括shapefile和PostGIS数据库。

QGIS,是一个桌面端GIS查看器/编辑器,用于快速查看数据。

QGIS可以查看许多数据格式,包括shapefile和PostGIS数据库。

它的图形界面允许我们轻松探索我们的数据,以及快速的对地理要素样式进行设置。

下载地址:https://qgis.org/en/site/forusers/download.html

对于新用户,推荐独立安装程序。

image-20210804230604759

汉化:

image-20210805095200735

安装完成之后可以连接postgreSQL数据直接查看数据:

image-20210804232220609 image-20210804232313533

在这张图右下角可以看到使用的坐标系统SRID号为26918。

GeoServer

GeoServer教程:https://ethanblog.com/tech/installation-of-geoserver.html

GeoServer的是一个基于Java的软件,它允许用户查看和编辑地理空间数据,使用开放地理空间联盟(OGC)提出的开放标准,为地图创建和数据分享提供了强大的便利性。

GeoServer是OpenGIS Web 服务器规范的 J2EE 实现,利用 GeoServer 可以方便的发布地图数据,允许用户对特征数据进行更新、删除、插入操作,通过 GeoServer 可以比较容易的在用户之间迅速共享空间地理信息。

主要特性:

兼容 WMS 和 WFS 特性;支持 PostGIS 、 Shapefile 、 ArcSDE 、 Oracle 、 VPF 、 MySQL 、 MapInfo ;支持上百种投影;能够将网络地图输出为 jpeg 、 gif 、 png 、 SVG 、 KML 等格式;能够运行在任何基于 J2EE/Servlet 容器之上;嵌入 MapBuilder 支持 AJAX 的地图客户端OpenLayers;除此之外还包括许多其他的特性。

下载地址:http://geoserver.org/release/2.19.0/

下载进来是一个war包,放到Tomcat里面即可启动服务。

image-20210804145336531

启动后,访问地址http://localhost:8080/geoserver/。

这时可以设置GeoServer的管理员帐号。帐号admin,密码geoserver。当出现下图时,说明服务器配置成功。

image-20210804233112513

该图即为GeoServer在服务器上的首页。可以在本页进行数据的连接和发布。

首先,数据区域集中展示了GeoServer服务器上的所有数据和工作区划分,提供数据存储、图层预览、样式编辑等功能。数据区域是我们在实际开发中需要重点关注的地方。

  • 图层预览提供了GeoServer的所图层配置列表,并提供以各种格式预览。在以后我们继续深入学习后,发布了某一个图层可以来到这里选择进行预览。
  • 工作区类似我们工作空间,概念可以类比我们进行其他开发时所配置的项目根目录,用于对某一项具体的工作进行统一的管理。对应于GeoServer所用于的web服务,也可以理解为是一个web网站的根目录。
  • 数据存储用于管理GeoServer的数据存储,我们可以将其理解为为Web服务提供数据支持的“数据库”。
  • 图层和图层组都是用来发布和管理新图层,并使用组的形式来进行组织和管理。
  • styles是用于管理GeoServer发布的样式。

服务部分主要是面向高级用户的,他们可以在此修改GeoServer提供的请求协议的配置。

  • Web Coverage Service (WCS)用于管理元数据信息和WCS、WFS、WMS通用的配置信息,如数据请求读写最大值等。
  • Web Feature Service (WFS)用于配置和管理Feature Data、服务级别以及GML输出等。
  • Web Map Service (WMS)用于管理和配置栅格数据和SVG选项以及切片地图压缩和分级情况。

数据发布

在GeoServer上部署地图数据非常简单,GeoServer支持的数据格式和数据源也很多,发布和部署地图数据涉及到GeoServer的几个重要知识点:工作区数据存储图层等概念。

  1. 进入GeoServer首页,点击左侧的工作区(Workspaces),再点击添加新的工作区(Add new workspaces)可以创建工作空间。工作空间的作用是在于将不同数据来源的数据保存在一起。在设置URI时,须设置为http://localhost:8080/china,china代表的是工作空间的名字,这样所有与之相关的网页均在这个URI之后。
image-20210805150914247
  1. 接下来点击数据存储(Stores),再点击添加新的数据存储(Add new store),可以添加一个新的数据源。GeoServer支持多种数据类型。在这里我们以PostGIS为例进行服务的发布。

    image-20210806131553756

    首先点击PostGIS选项,进入数据源信息的页面。先点击工作区(Workspace)下拉选项,可以选择具体的工作空间,例如本文中选择china。

    接下来输入数据源名称,这是标识不同数据的依据,例如本文中输入gdp。

    在连接参数中,输入host为localhost,端口5432,再输入数据源在PostgreSQL中的数据库名称,之后输入连接PostgreSQL的帐号和密码即可完成数据库的连接。

    在最下面点击保存即可。

image-20210805151308547
  1. 接下来就要发布具体的图层了。点击图层(Layers),即可进入图层选择界面;再点击添加一个新图层(Add a new resource),即可发布具体的图层。点击后,先选择具体的数据源,会出现该数据源下的各种表,选择需要发布为图层的数据表,点击发布(publish),即可进行发布。
image-20210805151504094

可以根据需要输入图层名称,也可以直接使用默认的图层名称。需要注意的是地图投影的定义:

在这里可以输入地图投影。如果原图没有投影,将不会进行显示,在这里可以点击Find,输入投影的代码(如WGS84为4326)进行查找。接下来在下方的范围中,点击从数据中计算(Compute from data),即可算出范围。

其他的文本框可以不填。保存之后即为图层的发布。

image-20210805151806217
  1. 为了查看发布后的效果,可以点击左侧的Layer Preview,找到刚刚发布的内容。GeoServer提供了多种数据格式可以调用。点击OpenLayers可以直接看到使用OpenLayers调用的图层。
image-20210805153625854

服务发布

OGC(Open Geospatial Consortium,开放地理信息协会)是一个非赢利的国际化标准制定组织,领导进行对地理数据相关的操作和服务标准的制定。

Web Services 即 Web 服务,它是自包含的、模块化的应用程序,它可以在网络中被描述、发布、查找以及调用。Web 服务的一个主要思想,就是未来的应用将由一组应用了网络的服务组合而成。在 Web Services 体系中,所有东西都是服务,这些服务发布一个 API 供网络中的其他服务或者应用使用,并且封装了实现细节。Web Services 是 OGC 规范以及建立面向服务的空间共享体系的基础技术体系。空间信息 Web 服务是在 Web 服务技术和标准基础之上实现的地理空间信息网上在线服务。它利用 Web 服务技术提供的公共接口、交换协议和服务规范,提供应用客户管理、注册服务、编码、处理服务、描述服务和数据服务等。主要的应用客户包括发现客户、地图浏览客户、影像利用客户等。空间信息 Web 服务除了采用基本的 Web 服务技术协议外,还需要相关地理空间信息及处理的技术协议,目前主要有 OGC、ISO/TC211 和 W3C 等组织在进行相关协议标准的制定。 OGC Web 服务(OWS)即是典型的空间信息 Web 服务标准体系。

OGC Web 服务公共执行规范详细描述了 OWS 接口执行规范包含的公共方面:

  • 操作请求和响应的内容
  • 操作请求和响应包含的参数和数据结构
  • 操作请求和响应的 XML 和 KVP 编码

OGC 服务类型:

  • Web 地图服务 (WMS,Web Map Service),用于以地图图像的形式提供图层集合

    Web 地图服务(WMS)利用具有地理空间位置信息的数据制作地图。在 WMS 规范中将地图定义为地理数据可视的表现,WMS 返回的不是地图数据,而是地图图像。

  • TMS 切片地图服务 (Tile map Servcie)定义了一些操作,这些操作允许用户按需访问切片地图,访问速度更快,还支持修改坐标系。

    切片地图服务又叫缓存服务区,地图缓存是使地图和图像服务更快运行的一种非常有效的方法。创建地图缓存时,服务器会在若干个不同的比例级别上绘制整个地图并存储地图图像的副本。然后,服务器可在用户请求使用地图时分发这些图像。对于服务器来说,每次请求使用地图时,返回缓存的图像要比绘制地图快得多。

    切片地图服务的优点:

    1. 由于切片地图服务中的瓦片不需要服务器实时生成,本身存在服务器的硬盘上,所以大大提高了服务器的性能。
    2. 瓦片图片的详细程度不会对服务器分发副本的速度造成显著影响。

    切片服务的缺点:

    1. 切片地图服务由于瓦片图片已经存在,所以该服务实现的功能有限,无法对图层进行一系列操作。
    2. 当缓存级别较高时,占用的硬盘存储量较大。
  • Web 地图切片服务 (WMTS,Web Map Tile Service),用于以缓存地图切片的形式提供地图图层

    WMTS的目的是,更高效快速的加载渲染地图数据。如果海量的地图数据以矢量的形式传输到客户端,在客户端渲染,首先需要消耗大量的网络流量,其次对客户端的CPU也是很大的负荷。考虑到这些情况,WMTS提出预渲染图块的模式,在服务端将地图渲染好,并根据比例尺分割不同的栅格图块,根据客户端的请求,传输这些图块,提供给客户端显示。

    目前,大部分PC端、手机端的地图底图使用的都是这种栅格瓦片

    TMS和WMTS差异主要在于协议、瓦片组织方式,WMTS理论模型更好,TMS来自于OSGeo,WMTS来自于OGC。

  • Web 要素服务 (WFS,Web Feature Service),用于以矢量要素的形式提供数据

    WFS 是基于地理要素级别的数据共享和数据操作,WFS 规范定义了若干基于地理要素(Feature)级别的数据操作接口,并以 HTTP 作为分布式计算平台。通过 WFS 服务,客户端可以得到矢量数据格式描述的单个地理要素的空间数据或要素集的空间数据,并可以对单个地理要素进行编辑、 删除、 添加等数据操作。WFS 采用 GML 描述地理要素特征, 根据用户请求的内容返回 GML 描述的空间数据。

  • Web 覆盖服务 (WCS,Web Coverage Service),网络覆盖服务是面向空间影像数据,它将包含地理位置的地理空间数据作为”覆盖(Coverage)”在网上相互交换,如卫星影像、数字高程数据等栅格数据。

    WCS 面向空间影像数据,它将包含地理位置值的地理空间数据作为 “覆盖物(COverage)“在网上相互交换。

  • Web 处理服务 (WPS,Web Processing Server),用于提供地理空间处理功能

可提供 OGC 功能:

服务类型 WCS WFS WMS WMTS WPS
地图服务 支持 支持 支持 支持
地理数据服务 支持 支持
影像服务 支持 支持 支持
地理处理服务 支持

三种服务参数详解

WMS服务

GeoServer中以OpenLayers方式预览WMS服务发布的地图:

  1. 请求

    1
    http://localhost:8088/geoserver/china/wms?service=WMS&version=1.1.0&request=GetMap&layers=china:china_2014gdp&bbox=73.441276550293,18.1598281860352,135.086944580078,53.5617713928223&width=768&height=441&srs=EPSG:4326&styles=&format=application/openlayers

    响应:(一个html文件,地图外部边框)

  2. 请求:(发起者ol.js)

    1
    http://localhost:8088/geoserver/china/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&STYLES&LAYERS=china%3Achina_2014gdp&exceptions=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4326&WIDTH=769&HEIGHT=442&BBOX=70.470703125%2C16.4619140625%2C138.005859375%2C55.2568359375

    响应:

    image-20210806125217252
  3. 点击地图对象的某个省份,返回属性信息。

    请求:

    1
    http://localhost:8088/geoserver/china/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=china%3Achina_2014gdp&STYLES&LAYERS=china%3Achina_2014gdp&exceptions=application%2Fvnd.ogc.se_inimage&INFO_FORMAT=text%2Fhtml&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG%3A4326&WIDTH=101&HEIGHT=101&BBOX=110.3466794192791%2C38.5839846432209%2C119.2236325442791%2C47.4609377682209

    响应:(一个html文件)

    image-20210806125914280

WMS 规范定义了三个操作:

参考:WMS的三大操作

  1. GetCapabilities 操作返回服务级元数据,它是对服务信息内容和请求参数的一种描述,元数据使用 XML 形式文件表示;

    请求参数:

    image-20210806130133895
  2. GetMap 操作根据客户端发出的请求参数在服务端进行检索,服务器返回一个地图图象,其地理空间参数和大小是已经明确定义的,返回的地图图象可以是 GIF,JPEG,PNG 或 SVG 格式的;

    请求参数:

    image-20210806130203534
  3. GetFeatureInfo 操作根据用户请求的 X,Y 坐标或感兴趣的图层,返回这些特殊要素的信息,信息以 HTML,GML 或者 ASCII 格式表示。

    请求参数:

    image-20210806130247319

WFS服务

参考:https://www.cnblogs.com/naaoveGIS/p/5508882.html

WFS,即Web要素服务,支持对地理要素的插入,更新,删除,检索和发现服务。不同于WMS(Web地图服务)的是,该服务专注于要素的地理信息,而忽略其渲染信息,简化了返回信息。

一个图层的WFS服务查看方法是在Layer Preview页面,选择WFS下的GeoJSON(以JSON数据形式展现要素信息,方便解析),查看该图层的要素信息。

一个WFS请求如下:

1
http://localhost:8088/geoserver/china/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=china%3Achina_2014gdp&maxFeatures=50&outputFormat=application%2Fjson

GetFeature(获取图层要素)

参数名称 是否必须 默认值 举例
VERSION 1.1.0 version=1.1.0或version=1.0.0
SERVICE WFS WFS
REQUEST=GetFeature
TYPENAME text/xml; subtype=gml/3.1.1
OUTPUTFORMAT outputFormat=GML2

WMTS服务

Web Map Tile Service(网络地图瓦片服务),简称WMTS,由开放地理信息联盟(Open GeoSpatial Consortium,OGC)制定,是和WMS并列的重要OGC规范之一。WMTS不同于WMS,它最重要的特征是采用缓存技术能够缓解WebGIS服务器端数据处理的压力,提高交互响应速度,大幅改善在线地图应用客户端的用户体验。WMTS是OGC主推的缓存技术规范,是目前各种缓存技术相互兼容的一种方法。

WMTS接口支持的三类资源如下表所示:

操作 是否必选 描述
GetCapabilities 获取服务的元信息
GetTile 获取切片
GetFeatureInfo 获取点选的要素信息

一个WMTS请求如下:

1
http://localhost:8088/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=china:china_2014gdp&STYLE=&TILEMATRIX=EPSG:4326:5&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL=48&TILEROW=6
image-20210808221539428

矢量切图

矢量切片的优点是:

  • 数据在客户端渲染,而不是在服务器端。这允许不同的地图应用程序使用不同的样式去渲染一个地图,而不需要事先在服务器端(比如GeoServer)进行预先的样式配置。
  • 矢量切片的大小通常比图片瓦片小,这可以使得数据传输得更快以及使用更低的带宽。
  • GeoServer内嵌的GeoWebCache可以有效地存储矢量切片数据。由于样式由客户端配置,而不是在服务器配置,因此GeoWebCache只需要存储一个矢量切片就能在客户端配置不同的样式
  • 由于在客户端上可以获取到矢量数据,所以不需要相应地增加带宽,就可以绘制分辨率很高的地图
  • 客户端可以本地访问实际的要素信息(属性信息和几何信息),所以可以进行非常复杂和精细的要素渲染。

矢量切片的主要缺点是需要对地理数据进行预处理,以便客户端能够完成所需的绘图(类似于图像瓦片地图的预处理数据)。考虑到这一点,矢量切片只能用于渲染。(虽然是矢量格式,但是它们不可编辑,矢量切片是为了读取和渲染优化的格式,如果想在客户端编辑要素,最适合的是使用OGC的WFS服务

GeoServer可以生成三种格式的矢量切片:GeoJSON,TopoJSON,MapBox Vector(MVT)。这些矢量切片格式也得到OpenLayers和其他客户端地图引擎的支持。

MVT是生产环境中首选的矢量切片格式。

v2-993218ce2e75170788779296d67ba9ba_r

GeoServer的矢量切片插件是官方的插件,下载地址:http://geoserver.org/release/2.19.0/。

image-20210806124018279

将下载的内容解压(jar包)并复制到GeoServer的WEB-INF/lib文件夹下。重新启动GeoServer。

  1. 验证矢量切片扩展是否已安装成功:打开GeoServer的Web管理界面。单击”图层“并随意选择一个矢量图层。

    图层类型(图层可以分为两种类型的数据:栅格和矢量)

领域 描述
../../_images/raster_icon.png 光栅(栅格)
../../_images/polygon_icon.png 多边形
../../_images/line_string_icon.png 线
../../_images/point_icon.png
  1. 点击”TileCaching“面板,滚动页面到”Tile Image Formats“部分,除了标准的GIF/PNG/JPEG格式之外,看到以下内容就表示矢量切片的插件已经安装成功了。
image-20210806150858530

勾选上面红框中的格式点击保存即可发布矢量切图服务。

  1. 进入Tile Layers,选择pbf预览即可预览效果:

image-20210808190237522

效果如下:

image-20210808190459394

服务地址需要到点击左上角geoserver图标退回首页,点击右侧的tms:

image-20210808233025537

找到发布的服务:

image-20210808232955563

GeoWebCache

参考:https://www.cnblogs.com/hao-zhang/p/10051159.html

在geoserver1.7版本之后,geoserver本身集成了GeoWebCache这个模块。GeoWebCache(GWC)是一个采用Java实现用于缓存WMS(Web Map Service)Tile的开源项目。当地图客户端请求一张新地图和Tile时,GeoWebCache将拦截这些调用然后返回缓存过的Tiles。如果找不到缓存再调用服务器上的Tiles,从而提高地图展示的速度。实现更好的用户体验。

  1. GWC支持多种来源的瓦片,比如ArcGIS的瓦片。
  2. GWC支持多种请求,比如WMS、WMS-C、WMTS、TMS、Googl Maps KML和Virtual Earth。
  3. GWC支持在第一次请求地图某范围时,将此范围内的地图按照配置的信息进行切图缓存。第二次同样请求此范围的地图时,直接读取缓存瓦片进行加速显示。此功能类似于AGS的动态出图。
  4. GWC同时也支持预先将瓦片按照配置信息切完,地图加载时直接读取瓦片。此功能类似于AGS的瓦片缓存出图。

对比两个服务的url:
http://localhost:8680/geoserver/wms
http://localhost:8680/geoserver/gwc/service/wms

可以看见两者的区别仅仅在于,当请求的URL中加上gwc/service后,便可以开启瓦片缓存服务了。

跨域配置

要想外部程序能够调用地图服务,首先需要对GeoServer进行跨域配置。

开启CORS跨域请求访问的方法,即在webapps/geoserver/WEB-INF/web.xml中添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<web-app>
<!--...-->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--...-->
</web-app>

添加完成后重启Tomcat使配置生效。

前端开源JS库

Web的地图API分类

  • Charts:以D3.js,Echarts等为代表。
  • LBS:以高德/谷歌/百度地图等为代表。
  • WebGIS商业API:ESRI的ArcGIS API For JS,超图的IClient。
  • WebGIS开源API: Leaflet,OpenLayers,Cesium,MapboxGL等。

应用场景

  • Charts类型在各种业务页面或后台管理页面很常见,适用业务场景是地图非页面表达的主体,且几乎没有交互,页面中同时还有其他各类主题。

  • LBS(基于位置的服务)广泛应用于互联网类应用,在这个时代人们的衣食住行与这些地图网站、地图APP及其背后的地理信息服务日益紧密。LBS必须要在连接互联网场景中使用,只能使用地图服务商提供的数据和服务,最多支持自定义用户标记若干兴趣点的简单操作,复杂企业级地理数据展示分析等几乎无能为力。

WebGIS发展历程

Html5标准确立前,Flex,JS,Silverlight作为前端开发的主要技术,这个时代JS还没有取得优势,产品都以Flex为首推。WebGIS以ArcGIS的Flex API(也有JS版)和开源的OpenScale(openlayer2 是其JS版)为代表。随着时代发展,移动互联网的崛起,H5标准发布,H5技术及其主力语言JS获得一统前端的地位,很多基于H5标准的WebGIS引擎纷纷入场,WebGIS H5时代开启。

  • 2011年3月,WebGL1.0标准发布。(浏览器渲染技术(如WebGL),让浏览器可以借助系统显卡展示2D和3D地图,还能创建复杂的导航和数据视觉化效果)
  • 2011年5月,Leaflet发布v0.1版本,基于H5草案,只来得及支持Canvas,与WebGL擦肩而过,以后也再没实现WebGL。
  • 2012年底,H5标准发布。
  • 2013年中,OpenLayer3测试版发布,与OpenLayer2不同,3是基于H5标准完全重写的,并不是迭代升级,而是一个全新的产品,只是继承了Openlayer这个已获得认可的名称与产品定位,应该说产品定位继承的相当彻底且发扬光大,只是过于保守,从而没能设想进入三维,满足于自己的二维领域。
  • 2013年制定WebGL2.0标准。
  • 2014年秋,Cesium发布1.0版本,开源WebGIS引擎进入三维时代。
  • 2016年春,ArcGIS API for JS 4.0发布,商业WebGIS引擎进入三维时代。
  • 2017年2月,WebGL2.0标准发布。
  • 2019年中,MapboxGL发布1.0版本,地图可视化从功能迈向了性能,颜值等方向,更多人发现原来地图还可以这样展示,更多的客户需要更加个性化的地图更加舒服的用户体验。
  • 2020年12月,MapboxGL发布2.0版本,支持三维相机参数,地形,地图最大倾角从60°到85°等,终于摆脱2.5D的产品印象。

WebGIS引擎各自特点与适用业务场景

  • LeafLet,Canvas渲染机制,仅支持二维表达,地图坐标系墨卡托投影,不支持球,特点是入手简单,缺陷是不支持webgl渲染性能有瓶颈,适用于轻量级简单地理信息主题可视化。
  • OL6,WebGL渲染机制,仅支持二维表达,不限制坐标系,不支持球,特点是二维GIS功能最丰富全面,缺陷地图样式简单,难以定制高颜值的可视化效果,不支持三维,适用于传统地理信息强GIS的二维数据Web维护和展示,面向公网地图颜值上有些上不了台面。
  • Cesium,WebGL渲染机制,二三维一体化,经纬度坐标系,支持球,明星数据格式是3DTiles,特点是唯一开源的WebGIS三维引擎,缺陷是卡,体验差,地图丑,原因应该是为了支持球,所有的平面瓦片都要进行纹理转换贴球,计算量偏大,最新的矢量切片也是变成图片再纹理转换到球上,栅格化严重一点都不精美,可以说为了球,牺牲了太多性能和地图美观度,适用于Web强三维应用场景。
  • ArcGIS API JS 4,对标Cesium,明星数据格式是I3S,也有类似Cesium的问题,但由于有ArcGIS平台的体系支持,应该功能最强大,但是如果不采购这个平台体系,纯API很鸡肋,适合采购了商业平台的用户,如政府采购再定制应用方式。
  • MapboxGL,WebGL渲染机制,二三维一体化,墨卡托坐标系,不支持球,明星数据格式是矢量切片,特点是最具美感的专题地图,缺点是没有球,最新2.0必须联网验证token,适用于互联网场景复杂地理信息表达,内网追求地图可视化效果的也适用,Mapbox很多优化都是基于互联网场景的。

在WebGIS 3D领域,比较有争议性的是cesium与mapboxgl。

对于Cesium的API用户来说,加载倾斜摄影,点云数据,地形数据都是直接调用引擎API就可以了,即使不懂WebGL也很快能做个三维的地图样子,当然高级开发者还会基于WebGL开发自定义高级显示效果。

对于Mapbox的API用户来说,2.0版本之前三维不足,主打的二维的矢量切片技术,并且切片加载机制导致倾角太大性能很差,因此引擎限制了最大倾角为60°,看起来就很像2.5D的东西。类似Cesium的三维功能只能依靠Deck.gl等库去集成,万幸的是引擎开放了自定义WebGL图层功能,高级开发者可以定制自己的三维图层,但坑爹的是没有三维相机参数需要自己源码扩展。2.0版本之后新增的地形3D展示,三维开发需要的相机参数,地图倾角限制从60°改成85°,比较有三维感觉了,效果辅助和性能优化方向考虑的Sky API等,显示了MapboxGL开始在三维方向发力,但仍然没有在官方API层面支持倾斜摄影的3Dtiles,点云等,不熟悉WebGL的开发者使用仍然很困难。除此以外,值得警惕的地方是2.0的开源协议从商业友好的BSD-3改成了Mapbox自己的使用协议,无论是否使用Mapbox资源强制进行在线token计数,等于完全放弃了内网用户(不联网没法计数等于没法用),因此从安全和商业应用开发角度,请不要升级到2.0,保持在1.13版本进行企业定制化开发。

虽然mapbox更改了使用协议,但不否认它仍是家伟大的公司,在现有的技术体系下,开创性的提出数据用矢量切片技术,图标用sprite(互联网应用场景的同学很熟悉,减少网络请求的优化,合并的图标纹理减少webgl渲染的调用命令次数),字体用字体pbf切片,就是怎么极致优化怎么做,强大的技术流风格。

后H5时代的WebGIS

把时间线后移4,5年,在后H5时代的WebGIS会形成“云渲染”、“WebAssemble”、“WebGPU”新的三足鼎立。

  • 云渲染

​ 原理:C端使用游戏引擎做数据可视化,可视化的结果通过视频流传到客户端显示。

​ 优点:游戏引擎比较成熟,效果好,三维大量数据,美术资源等不用传到客户端。

​ 缺点:完全放弃日益先进强大的客户端计算资源(摩尔定律),完全依靠服务器资源,导致服务器资源投入很大,如果有高并发,起码得有分布式GPU计算引擎吧?所以不可能广泛应用,业务场景很小,只适合大屏可视化目前。

  • WebAssemble

​ 原理:能让c++,rust等高性能语言写的功能以wasm形式在Web端应用,弥补JS性能的缺陷,(经过谷歌V8引擎优化,JS的性能也是直逼后台,缺陷有点牵强,而且前端计算可以使用GPGPU,WebWork等技术在gpu,在多线程非阻塞计算)当然更主要的用处是有利于原先C端图形软件如CAD,GoogleEarth搬到BS上,例如GoogleEarth的BS版已经实现了。

​ 优点:可以用高性能语言写的算法应用到前端改进JS的算法(牵强,实际投入产出比不大对绝大部分公司),大量的后端程序员开始进入前端搞事情,前端不再是JS程序员的前端(从性能方向考虑甚至产生是否WebAssemble会取代JS的疑问)。

​ 缺点:WebAssemble不能操作dom,因此它只是一个补充,给前端留个“后路”而已,并没有取代JS的能力也没有这样的定位。另外业务应用场景非常狭窄,只适合有成熟C端图形产品搬到BS,对一般业务产品冲击不大。从公司角度如果没有C端成熟图形产品就不值得投入,从程序员个人角度,如果是JS程序员可以直接无视,这种技术不会对你产生任何影响,如果是后端程序员,可以兴奋起来,你可以去前端玩玩了。。。

  • WebGPU

​ 原理:下一代Web图形引擎,WebGL的替代者,业务场景就是现在用WebGL的地方,将来也都是WebGPU应用的场景。

​ 优点:BS端的图形引擎与C端几乎一致(差半代),可以设想很多原先只有C端能做的酷炫效果B端也能做。(WebGL与C端差了好多代了,所以没法做出能追上C端效果的东西)

​ 缺点:目前正式标准还没发布,那么基于WebGPU的图形,GIS引擎当然也没有了,就算有了,酷炫效果也不是GIS API这种,更多是图形学领域,大部分目前的业务API开发者会失去竞争力。

总结

如果不懂图形学原理,就算使用了WebGL的GIS引擎是做不出符合业务发展的东西来的,顶多加加地形加个建筑做做项目而已,稍微个性化的展示都做不了。从后H5时代来看,一方面可能C++,Rust等技术会更加如鱼得水,那么依靠JS的程序员和依靠JS实现可视化的公司只能抱紧WebGPU的大腿,要在图形学领域持续进行技术投入,纯调用API实现效果的时代一去不复返了,更加先进的图形引擎与更加灵活的渲染管线,再与更加个性化的业务展示要求结合与促进,会产生新的思想碰撞和化学反应,如果个人和公司跟不上,那么在下个时代,才真的是遇到”降维打击”了。

地理可视化(尤其3D)的未来并不属于GIS,而是属于图形学,所谓万变不离其宗。

OpenLayers

OpenLayers(http://openlayers.org)是一个专为 Web GIS 客户端开发提供的二维GIS JavaScript 类库包,用于实现标准格式发布的地图数据访问。由于自身较为重的原因,难于扩展,社区生态插件比较少,主要还是依赖官方的库实现绘制编辑功能。

OpenLayers 支持的地图来源包括 Google Maps、Yahoo、 Map、微软 Virtual Earth 等,用户还可以用简单的图片地图作为背景图,与其他的图层在 OpenLayers 中进行叠加。除此之外,OpenLayers 实现访问地理空间数据的方法都符合行业标准。OpenLayers 支持 Open GIS 协会制定的 WMS(Web Mapping Service)和 WFS(Web Feature Service)等网络服务规范,可以通过远程服务的方式,将以 OGC 服务形式发布的地图数据加载到基于浏览器的 OpenLayers 客户端中进行显示。

使用开源的 GeoServer 和 OpenLayers 发布地图服务在 Web GIS 部署中比较常用。

Leaflet

leaflet(https://leafletjs.com/)是一个轻量的**二维GIS**的JS库。实现绘制编辑可以依靠社区的插件,主要有 Leaflet.draw 、Leaflet.geoman(前身为Leaflet.pm)、Leaflet.Editable等绘制插件。

MapboxGL

MapboxGL不同于Mapbox,MapboxGL底层采用webGL实现,性能和体验显著的提升,Mapbox则是采用leaflet。MapboxGL在用户体验和性能上个人觉得都是最优的,gl版本起步较晚。社区生态插件也不是很多,但是官方也提供了相应的绘制插件。

官方提供了插件 mapbox-gl-draw ,总体来看,该库封装得较为成熟,最重要的是它在大数据量下的编辑一点都不卡(仅编辑点击的时候添加控制点)。

Mapbox地图使用矢量切片技术和地图渲染技术(Mapbox GL)实现。前端通过Mapbox GL JS进行渲染,Mapbox GL JS是一个Java Script库,使用WebGL渲染交互式矢量瓦片地图和栅格瓦片地图,渲染性能高。它能够解析各种来源的矢量数据,然后在客户端实时渲染生成带有几何图形、文字标注、图示符号3D场景地图。Mapbox GL JS不仅能够渲染大数据量的地图要素,拥有流畅的交互以及动画效果,而且还可以显示立体地图。

mapbox.js 和 mapbox-gl.js有什么区别?

相同点:

1、两者都是Mapbox公司推出的免费(每月有使用次数的限制)开源的JavaScript库

2、都可以作为前端渲染矢量瓦片交互地图的工具(WMS、普通瓦片等地图也都支持)

3、它们的样式设置都是支持Mapbox Style的

主要的不同点:

1、Mapbox.js是Leaflet的一个插件,使用方式是通过结合leaflet使用。

2、mapbox-gl.js 则是使用WebGL技术独立渲染前端库,不需要结合其它渲染引擎(比如Leaflet、OpenLayer)来使用。

3、使用mapbox-gl.js的浏览器必须支持WebGL渲染,在老旧的浏览器中是不支持mapbox-gl.js的。而mapbox.js则没有此限制。

MapboxGL基础

MapboxGL的地图对象Map有参数实例成员事件

  1. 参数:

    container(进行地图渲染的 dom元素id)、style(地图样式)、zoom(地图初始化时的层级)、center(地图初始化时的地理中心点)等;

  2. 实例成员:

    addSource(id,source)添加数据源、addLayer(layer)添加图层、loadImage(url,callback)、addImage(id,image)等

  3. 事件:

    比如on(type,listener),可以为特定类型的事件添加监听器,其中type(string)添加监听器的事件类型,(包括’mousedown’ , ‘mouseup’ ,’mousemove’、’click’、’load’),listener(Function)事件被触发时调用的函数;

数据源Source表明地图应显示哪些数据。使用“type”属性指定源的类型,该属性必须是 vector, raster, raster-dem, geojson, image, video(矢量,栅格,栅格dem,geojson,图像,视频)之一。

GeoJSON源数据必须通过data属性提供,其属性可以是URL或内联GeoJSON。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"geojson-marker": {
"type": "geojson",
"data": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-77.0323, 38.9131]
},
"properties": {
"title": "Mapbox DC",
"marker-symbol": "monument"
}
}
}

添加一个Source不足以使数据显示在地图上,因为source不包含颜色或宽度等样式细节。图层Layersource提供可视化表示。这样就可以以不同的方式对同一source进行样式设置。

id是唯一的图层名称。

图层的类型由'type'属性指定,并且必须是background, fill, line, symbol, raster, circle, fill-extrusion, heatmap, hillshade(背景(颜色或者图案),填充(具有可选描边边框的填充多边形),线,符号(图标或文字标签),栅格,实心圆,拉伸的(3D)多边形,热图,山体阴影)。

除了背景类型的图层外,每个图层都需要引用源source。图层将从源中获取数据。

图层具有两个子属性,这些子属性确定如何渲染该图层中的数据:布局layout和绘画paint属性。

布局属性显示在图层的layout对象中。它们将在渲染过程的早期应用,绘画属性将在稍后的渲染过程中应用。绘画属性显示在图层的paint对象中。

1
2
3
4
5
6
7
8
9
10
"layers": [
{
"id": "water",
"type": "fill",
"source": "mapbox-streets",
"paint": {
"fill-color": "#00ffff"
}
}
]

简单demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title>Display a map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<-- 引入相关的库 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>

<body>
<div id="map"></div>
<script>
// 访问令牌accessToken
mapboxgl.accessToken = 'pk.eyJ1IjoieGlhb3NoaWhkIiwiYSI6ImNrNngzYnRhdzBqNm0zZnJ4eWZjdndrYzkifQ.qQjf8zANr9PsMpwq2NsRWQ';
// 地图对象Map
var map = new mapboxgl.Map({
container: 'map', // Mapbox GL JS 进行地图渲染的 HTML 元素
style: 'mapbox://styles/mapbox/streets-v11', // 地图的 Mapbox 配置样式
center: [-74.5, 40], // 地图初始化时的地理中心点 [lng, lat]
zoom: 9 // 地图初始化时的层级
});
</script>
</body>

</html>

可以看出最核心的代码就是 style: 'mapbox://styles/mapbox/streets-v11',他包含了所有的地图样式。

将style分解,为后面离线部署提供解决方案,具体可以查看一下style api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title>Display a map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<-- 引入相关的库 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>

<body>
<div id="map"></div>
<script>
// 访问令牌accessToken
mapboxgl.accessToken = 'pk.eyJ1IjoieGlhb3NoaWhkIiwiYSI6ImNrNngzYnRhdzBqNm0zZnJ4eWZjdndrYzkifQ.qQjf8zANr9PsMpwq2NsRWQ';
// 地图对象Map
var map = new mapboxgl.Map({
container: 'map', // Mapbox GL JS 进行地图渲染的 HTML 元素
style: {
"version": 8, // 这个JS SDK对应版本必须为8。
"name": "Mapbox Streets", // 样式的命名
"sprite": "mapbox://sprites/mapbox/streets-v8", // 将一个地图涉及到的所有零星图标图片都包含到一张大图中去
"glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf", // .pbf格式的字体样式,例如微软雅黑等字体库
"sources": { // 图层的资源文件,可以支持矢量切片、栅格、dem栅格、图片、geojson、视频等格式。
"mapbox-streets": {
"type": "vector",
"url": "mapbox://mapbox.mapbox-streets-v6"
}
},
"layers": [ // 对每个图层样式的描述,这里就是对地图样式渲染的关键,可以做很多精美的设计。
{
"id": "water",
"source": "mapbox-streets",
"source-layer": "water",
"type": "fill",
"paint": {
"fill-color": "#00ffff"
}
}
]
}, // 地图的 Mapbox 配置样式
center: [-74.5, 40], // 地图初始化时的地理中心点 [lng, lat]
zoom: 9 // 地图初始化时的层级
});
</script>
</body>

</html>

接入WMS服务

官方教程:https://docs.mapbox.com/mapbox-gl-js/example/wms/

参考:https://blog.csdn.net/hequhecong10857/article/details/113881004

  1. 确保成功发布WMS服务并且配置好跨域。
  2. 在点击Openlayers预览图层时,打开调试工具,点击NetWork可获取tiles的url,需要将bbox参数用{bbox-epsg-3857}替换,之后修改坐标系为&SRS=EPSG:3857(Mapbox GL支持的是EPSG:3857(Web墨卡托)坐标)。加载的时候,Mapbox GL会自动替换成对应的参数,这样地图就可以加载了。
image-20210808195750909
  1. 在点击Openlayers预览图层时,打开调试工具,点击查询图层要素,NetWork中会出现一个请求url,而axios请求的url只需将INFO_FORMAT参数由text/html替换成application/json即可,获取到json数据后,可根据实际进行下一步操作。
image-20210808201040795
  1. BBOX是以SRS单位表示的边界框边角 (左下角,右上角),但是点击返回的是点击点的坐标。需要进行换算,需要注意的是点击返回的坐标是经纬度,还需要转换成墨卡托坐标,之后请求的SRS也需要变成EPSG:3857

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>
Add a WMS source and query
</title>
<meta content="initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"/>
<-- 引入相关的库 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js">
</script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet"/>
<!--Axios网络请求库 -->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js">
</script>
<!--地理空间分析库 https://turfjs.fenxianglu.cn/ -->
<script src="https://unpkg.com/@turf/turf@6.3.0/turf.min.js">
</script>
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map">
</div>
<script>
// 访问令牌accessToken
mapboxgl.accessToken = 'pk.eyJ1IjoieGlhb3NoaWhkIiwiYSI6ImNrNngzYnRhdzBqNm0zZnJ4eWZjdndrYzkifQ.qQjf8zANr9PsMpwq2NsRWQ';
// 地图对象Map
var map = new mapboxgl.Map({
container: 'map', // Mapbox GL JS 进行地图渲染的 HTML 元素
style: 'mapbox://styles/mapbox/streets-v11', // 地图的 Mapbox 配置样式
zoom: 4,
center: [112, 28]
});

// 地图加载的时候调用WMS服务
map.on('load', function () {
map.addSource('wms-source', {
'type': 'raster', // 栅格数据
'tiles': [
'http://localhost:8088/geoserver/china/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&STYLES&LAYERS=china%3Achina_2014gdp&exceptions=application%2Fvnd.ogc.se_inimage&WIDTH=769&HEIGHT=442&BBOX={bbox-epsg-3857}&SRS=EPSG:3857'
],
'tileSize': 256
});
map.addLayer({
'id': 'wms-layer',
'type': 'raster',
'source': 'wms-source',
'paint': {
'raster-opacity': 0.5 // 设置透明度
}
},
'aeroway-line'
);
});

// 地图点击的时候进行属性查询
map.on("click", function (e) {
const {
lng,
lat
} = e.lngLat; // 点击返回的是点击位置的经纬度
const radius = Math.pow(2, 22 - map.getZoom());
// 以下为墨卡托坐标下的换算过程
const pointM = turf.toMercator(turf.point([lng, lat])); // 转换成EPSG:3857坐标系(墨卡托)
const pointC = pointM.geometry.coordinates;
const bbox = [pointC[0] - radius, pointC[1] - radius, pointC[0] + radius, pointC[1] + radius];
const url =
'http://localhost:8088/geoserver/china/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=china%3Achina_2014gdp&STYLES&LAYERS=china%3Achina_2014gdp&exceptions=application%2Fvnd.ogc.se_inimage&INFO_FORMAT=application%2Fjson&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG:3857&WIDTH=101&HEIGHT=101&BBOX=' +
bbox.join();
axios.get(url) // Axios进行网络请求
.then(function (res) {
console.log(res);
alert(res.data.features[0].properties.name);
})
});
</script>
</body>
</html>

实现效果

image-20210808211120574

接入矢量瓦片服务

参考这两篇:

https://blog.csdn.net/qq_34870529/article/details/92768540

Mapbox GL 加载GeoServer发布的矢量切片

Mapbox GL只支持坐标为EPSG:3857的矢量切片,而GeoServer(version 2.13.3)默认没有该坐标系的Gridsets,需要自己手动创建。

创建名为EPSG:3857的Gridsets(缩放层级可自行控制,我在此处共设置了22层):

image-20210809153919417

之后添加新的图层、添加新的数据存储。

之后添加新的图层并发布图层:

image-20210809154405831

切换到Tile Caching(添加刚才定义好的Gridsets 3857):

image-20210809154328641

在Tile Layers页面可以看到发布的服务:

image-20210809161938035

3857我预览总是出不来数据。

4326和900913都可以。

在矢量切图教程中获取到了服务的URL。

1
http://localhost:8088/geoserver/gwc/service/tms/1.0.0/china%3Achina_2014gdp@EPSG%3A900913@pbf

拼接服务地址供mapbox调用:

1
http://localhost:8088/geoserver/gwc/service/tms/1.0.0/china%3Achina_2014gdp@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf

4326Mapbox调用后不显示,但是900913和3857都成功显示。这也证明3857其实没必要建立。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>
Display a map
</title>
<meta content="initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport"/>
<-- 引入相关的库 -->
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js">
</script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet"/>
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map">
</div>
<script>
// 访问令牌accessToken
mapboxgl.accessToken = 'pk.eyJ1IjoieGlhb3NoaWhkIiwiYSI6ImNrNngzYnRhdzBqNm0zZnJ4eWZjdndrYzkifQ.qQjf8zANr9PsMpwq2NsRWQ';
// 地图对象Map
var map = new mapboxgl.Map({
container: 'map', // Mapbox GL JS 进行地图渲染的 HTML 元素
// style: 'mapbox://styles/mapbox/light-v10', // 地图的 Mapbox 配置样式
style: 'mapbox://styles/mapbox/satellite-v9', //卫星图
zoom: 4, // 地图初始化时的层级
center: [112, 28] // 地图初始化时的地理中心点 [lng, lat]
});

map.on('load', function() {
map.addSource('tms-source', {
'type': 'vector', // 矢量数据
"scheme":"tms",
'tiles': [
// 'http://localhost:8088/geoserver/gwc/service/tms/1.0.0/china%3Achina_2014gdp@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf'
'http://localhost:8088/geoserver/gwc/service/tms/1.0.0/northLaker%3Alakemaxextent_north@EPSG%3A3857@pbf/{z}/{x}/{y}.pbf'
],
});
map.addLayer({
'id': 'tms-layer',
'type': 'fill',
'source': 'tms-source',
// "source-layer": "china_2014gdp", // 图层名称
"source-layer": "lakemaxextent_north", // 图层名称
'paint': {
"fill-color":"#ff0000",
"fill-opacity":0.3
}
});
});

// 添加mapbox自带菜单
map.addControl(new mapboxgl.NavigationControl());
</script>
</body>
</html>

Mapbox样式

1
2
3
4
5
6
let mapboxStyle = [
'http://61.161.150.90:5081/api/v1/styles/aolutong/Bkl7eaQNyU',
'http://61.161.150.90:5081/api/v1/styles/aolutong/HJeN6h7VyL',
'http://61.161.150.90:5081/api/v1/styles/aolutong/ByetWaXVJL',
'mapbox://styles/mapbox/satellite-v9',
]

自定义样式其实就是返回配置的json文件,在json文件里面调用矢量瓦片的接口请求数据源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
"updatedAt": "2020-12-23T07:04:03.832Z",
"owner": "aolutong",
"format": "pbf",
"description": "ln_peak",
"name": "ln_peak",
"createdAt": "2020-12-23T06:56:35.787Z",
"vector_layers": [
{
"fieldalias": {
"dists_code": "区划代码",
"town_code": "乡镇行政区代码",
"town_name": "所属乡镇",
"city_code": "市级行政代码",
"city_name": "所属市级",
"province_code": "省份行政代码",
"province_name": "所属省份",
"type": "类型",
"name": "名称"
},
"fields": {
"dists_code": "String",
"town_code": "String",
"town_name": "String",
"city_code": "String",
"city_name": "String",
"province_code": "String",
"province_name": "String",
"type": "String",
"name": "String"
},
"description": "山峰",
"id": "ln_peak",
"_id": null
}
],
"center": [
125.530673,
40.784181,
18
],
"bounds": [
73.49735,
6.318649,
134.773613,
53.561648
],
"maxzoom": 18,
"minzoom": 10,
"data": [],
"grids": [],
"tiles": [
"http://124.70.71.54:8080/api/v1/tilesets/aolutong/ln_peak/{z}/{x}/{y}.pbf"
],
"scheme": "xyz",
"version": "2",
"tilejson": "2.1.0",
"tags": [],
"scope": "public",
"tileset_id": "ln_peak"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title>Add Markers</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<style>
body {
margin: 0;
padding: 0;
}

#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}

#menu {
position: absolute;
background: #fff;
padding: 10px;
font-family: 'Open Sans', sans-serif;
}

#menu2 {
position: absolute;
background: #fff;
padding: 10px;
font-family: 'Open Sans', sans-serif;
right: 0px;
bottom: 0px;
}
</style>
</head>

<body>
<div id="map"></div>
<div id="menu">
<button onclick="changeSize(true);" style="width:40px;height:40px"><img src="icons/Zoomin.png" width="25" height="25" alt="放大" /></button>
<button onclick="changeSize(false);" style="width:40px;height:40px"><img src="icons/Zoomout.png" width="25" height="25" alt="缩小" /></button>
</div>
<div id="menu2">
<input name="style" type="radio" checked="true" onclick="changeStyle(0);" style="width:20px;height:20px" value="阳光白">阳光白
<input name="style" type="radio" onclick="changeStyle(1);" style="width:20px;height:20px" value="暗夜蓝">暗夜蓝
<input name="style" type="radio" onclick="changeStyle(2);" style="width:20px;height:20px" value="清淡蓝">清淡蓝
<input name="style" type="radio" onclick="changeStyle(3);" style="width:20px;height:20px" value="遥感">遥感
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoieGlhb3NoaWhkIiwiYSI6ImNrNngzYnRhdzBqNm0zZnJ4eWZjdndrYzkifQ.qQjf8zANr9PsMpwq2NsRWQ';

let mapboxStyle = [
'http://61.161.150.90:5081/api/v1/styles/aolutong/Bkl7eaQNyU',
'http://61.161.150.90:5081/api/v1/styles/aolutong/HJeN6h7VyL',
'http://61.161.150.90:5081/api/v1/styles/aolutong/ByetWaXVJL',
'mapbox://styles/mapbox/satellite-v9',
]

var map = new mapboxgl.Map({
container: 'map',
style: mapboxStyle[0],
center: [123.38, 41.8],
zoom: 5
});

function changeSize(bool) {
if (bool) {
map.setZoom(map.getZoom() + 1);
} else {
map.setZoom(map.getZoom() - 1);
}
}

function changeStyle(num) {
map.setStyle(mapboxStyle[num]);
}
</script>
</body>

</html>

开源方案搭建可离线的精美矢量切片地图服务-1.开篇(附成果演示地址)

Mapbox官方提供的在线样式编辑器:

https://studio.mapbox.com/styles/

空间分析库

Turf.js 是一个开源的空间分析库,由 Mapbox 提供。源码地址,在其(官网)[]中都有 Mapbox 作为底图的示例。

并且在 Mapbox 官网也推荐使用 Turf.js 作为空间分析库。

缓冲分析这些功能可以用的postgis自带的空间分析函数。