题外话
时光任然,一年一度的五一劳动节已然来到。作为疫情之后迎来的第一个五一,不知道各位小伙伴们怎么度过这个劳动节呢?是决定去另一个城市,观察体验一下不一样的风景,或者去旅游,给自己放假。昨天被12306的一则关于上海虹桥站4月28日火车票全部售罄的帖子刷爆了。这充分说明了大家在五一出行的热情。
此时此刻,肯定还有一些因为各种各样的原因要工作值班的小伙伴。在此,向各行各业的辛苦劳动的劳动者致敬。奋斗的人最美, 奋斗的你,就是五一最美的风景,努力耕耘的你,就是五月最灿烂的存在!致敬我们每一位辛勤的劳动者。
一、前言
在前面的博客中使用LeafLet叠加Geoserver wms图层到已有底图的方法,简单的讲解了Geoserver进行Wms等服务的发布,对于GeoServer的服务发布没有具体介绍。之前项目组的同学在使用GeoServer进行服务发布时,遇到了一些问题。比如创建数据源时失败,还有带中文的WMS服务在预览时没有正确展示,而是提示下载的问题。本文将重点讲解如何使用GeoServer进行WMS服务的发布,以及在创建数据源时会遇到的问题,服务图层遇到中文图层提示下载的问题。如果您在生产过程中也遇到这些问题,希望可以帮你抛砖引玉。
二、GeoServer
1、GeoServer简介
本文不是重点介绍GeoServer的文章,哦。关于GeoServer的介绍,有很多的文章。这里只做简单的介绍。下面是在GitHub上的官方介绍geoserver github,描述这个项目的主要功能。
简单来讲就是,GeoServer项目是一个完整的Java(J2EE)系统,现实了OpenGIS联盟的网络功能服务器规范和网络覆盖服务器规范(完整的OGC标准实现),并且集成了Web地图服务器,所有标准的OGC服务,比如WMS,WMTS,WCS,WFS,矢量切片等都是可以直接支持的。
2、GeoServer主界面
本文采用的GeoServer版本如下图所示,采用war包的形式进行部署,jdk1.8,tomcat采用8.5
将Tomcat启动后即可访问到GeoServer应用,并进行服务的发布。
三、GeoServer服务发布
1、登录GeoServer
GeoServer是需要登录之后才能使用的。默认的账号是:admin/geoserver。
2、新建工作区
点击左边的工作区菜单,再右边的列表按钮,点击新增按钮,进行工作区的管理。工作区主要用于管理不同的数据,比如道路的数据、水系的数据、POI的数据,分类进行管理。
通常来说,工作区的命名空间URI只需要填一个不重名的就可以。最好采用官网的地址加上一个可以表示工作项目类型的字符串即可。一般在这里不容易出错,正常操作即可。
3、新建数据源异常
点击新建数据源按钮,进行数据源的新增管理。数据源包括矢量、栅格和其他数据。如下图所示。
这里我们以矢量数据源为例,点击Shapefile - ESRI(tm) Shapefiles (*.shp),进入下面页面:
这里请注意数据源的名称,名称当中包含了一个冒号,请特别注意。这里就是引起问题的数据。点击保存后,系统会报下面这个错。
同时在Geoserver的运行控制台也发现报错了,详情如下图所示:
后台无法创建相应的目录,到这里,我们到后台看一下相应的目录。
我们发现每个数据源都会有一个相应的目录进行数据绑定。打开hnxjxqarea目录下的datastore.xml文件,可以发现如下的定义。
<dataStore>
<id>DataStoreInfoImpl--3834fa5a:187c815698e:-7ffc</id>
<name>hnxjxqarea</name>
<description>湖南湘江新区</description>
<type>Shapefile</type>
<enabled>true</enabled>
<workspace>
<id>WorkspaceInfoImpl--3834fa5a:187c815698e:-7fff</id>
</workspace>
<connectionParameters>
<entry key="charset">ISO-8859-1</entry>
<entry key="filetype">shapefile</entry>
<entry key="create spatial index">true</entry>
<entry key="memory mapped buffer">false</entry>
<entry key="timezone">Asia/Shanghai</entry>
<entry key="enable spatial index">true</entry>
<entry key="namespace">http://www.yelangking.com/gisdev</entry>
<entry key="cache and reuse memory maps">true</entry>
<entry key="skipScan">true</entry>
<entry key="url">file://F:\vector_data\湘江新区\湘江新区-融合.shp</entry>
<entry key="fstype">shape</entry>
</connectionParameters>
<__default>false</__default>
<dateCreated>2023-04-28 13:44:33.890 UTC</dateCreated>
</dataStore>
4、异常定位
在控制台中,可以看到,org.geoserver.platform.resource.FileSystemResourceStore.java这个类的324行出了问题。我们到其源码中看一下324行到底执行了什么业务逻辑。
由于源代码较多,不全部列出,将上图中涉及的代码复制出来,看一下。这里已经写得非常清楚,上级目录没有正确创建导致了异常的抛出。这里我们验证一下带冒号的文件格式能否创建目录。
public File file() {
if (!file.exists()) {
try {
File parent = file.getParentFile();
if (!parent.exists()) {
boolean created = parent.mkdirs();
if (!created) {
throw new IllegalStateException("Unable to create " + parent.getAbsolutePath());
}
}
if (parent.isDirectory()) {
Lock lock = lock();
boolean created;
try {
created = file.createNewFile();
} finally {
lock.release();
}
if (!created) {
throw new FileNotFoundException("Unable to create " + file.getAbsolutePath());
}
} else {
throw new FileNotFoundException(
"Unable to create" + file.getName() + " - not a directory " + parent.getAbsolutePath());
}
} catch (IOException e) {
throw new IllegalStateException("Cannot create " + path, e);
}
}
if (file.isDirectory()) {
throw new IllegalStateException("Directory (not a file) at " + path);
} else {
return file;
}
}
在Windows中,随便新建一个文件夹,然后带上冒号,通常系统会报如下警告:
由此,彻底找到了问题的根源,而且千万要记住,在GeoServer中,目录的名字一定不能特殊字符。在Java的世界中,很多是约定大于配置,预定俗成的规则很多。找到了问题的根源就好解决问题了,只需要将冒号去掉后,保存即可。
5、wms中文问题
是不是到了这一步,地图的发布就一切顺利,万事大吉呢。那可不一定,在未正常进行数据展示之前,一切都是有待验证的。
有的同学是不是遇到问题了。尤其是图层中名字是包含中文,并没有看到数据展示界面,而是有下载提示。这真的是黎明前的黑暗,令人崩溃。如果对Web开发有经验的同学大概已经猜到了问题的所在,就是图层中包含中文的原因。修改的方式也很简单,在tomcat中,设置一下容器的请求编码。在tomcat的安装目录下,在server.xml中找到以下代码:
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
在文件的最后加上编码设置,如下所示:
<Connector port="8083" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
记得保存后,重启tomcat服务。至此,数的据的服务发布全部完成,在路上遇到的数据源创建问题以及中文图层访问问题,均全部解决。来看一下实际预览效果。
6、使用Leaflet加载Wms
<!DOCTYPE html>
<html>
<head>
<title>geoserver全国地铁展示</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="/2d/leaflet/leaflet.css" />
<script src="/2d/leaflet/leaflet.js?v=1.0.0"></script>
</head>
<body>
<div id="mapid" style="width: 100%; height: 600px;"></div>
<script>
var mymap = L.map('mapid').setView([29.052934, 104.0625], 5);
//加载wms服务的图层
var dtLineLayer = L.tileLayer.wms(
'http://localhost:8083/geoserver/testwzh/wms', {
layers: 'testwzh:2022年全国地铁线数据',
format: 'image/png',
transparent: true
}
);
dtLineLayer.addTo(mymap);
</script>
</body>
</html>
总结
以上就是本文的主要内容,本文将重点讲解如何使用GeoServer进行WMS服务的发布,以及在创建数据源时会遇到的问题,服务图层遇到中文图层提示下载的问题。如果您在生产过程中也遇到这些问题,希望可以帮你抛砖引玉,行文仓促,不足之处还望海涵,同时也欢迎各位朋友在评论区留言批评指正。
行文最后,再次祝愿所有的朋友们节日快乐,出门有风景,在家也舒心,致敬劳动者。