首发于 GIS实践

GeoServer+vue2+leaflet构建地图服务

因为geoserver就是后端服务,所以如果没有太强烈的数据安全需求,其实没有必要再加一个python django或者java springboot来做服务中转,转发请求。

现在其实有一个大前端的概念,前端开发模式下,能模拟服务端请求,也能解决get和post请求的跨域问题,而且前端也可以直接部署到服务器上,所以,我们只要有一个前端平台就可以了。

我这里选用的前端框架是vue2,主要出于三点考虑,其一是简单易用上手快;其二是leaflet对它的集成比较好;其三是用的人比较多,有点问题上网搜,容易找到回答。

(这里着重提示一下,尽量用比较大众的东西,否则的话,排查问题、查找资料都很难,做得好赖也不好评价。会油然而生孤立无援之感,这是经验之谈。)

我的IDE选择的是sublime,轻量,而且插件多。

Git代码见(别忘了给点个star):

前端工程能实现,地图加载WMTS服务,点击渲染geojson,根据属性筛选要素,矢量要素绘制等功能,最常用的功能都涵盖了,怎么实现,往下看,写得很详细。

本例配套的Geoserver发布地图服务见:

视频教程见:

一、构建工程

1-1.构建vue-cli工程

首先要确保本机已经安装了nodejs和vue。

如果没有安装,nodejs安装参见: runoob.com/nodejs/nodej

Vue安装参见: runoob.com/w3cnote/vue2

安装完之后,查看一下node和vue的版本。




Vue已经有3版本了,但为了稳定性,我们还是用2版本。记住vue的版本号,后续安装依赖,要考虑版本。


好,我们默认已经安装好nodejs和vue了,接下来我们要开始构建工程了。

打开cmd窗口,切换到指定路径下。

首先,我们切换一下vue的下载源。

因为vue的资源服务器在国外,下载起来特别慢,我们切换到淘宝镜像:

npm config set registry https://registry.npm.taobao.org

然后运行:

mkdir geoserver_vue2_leaflet

新建一个geoserver_vue2_leaflet文件夹。

cd geoserver_vue2_leaflet

切换到文件夹下。

运行:

vue init webpack geoserver_vue_leaflet

新建工程geoserver_vue_leaflet。

根据提示回车,或者输入内容,保持默认设置就行,这些后续都可以修改。

注意install vue-router项,要选择yes。




工程安装完之后,运行:

cd geoserver_vue_leaflet
npm run dev

访问:http://localhost:8080/#/

能看到vue页面,就说明vue-cli工程创建成功了。






1-2.安装依赖

我们要安装leaflet、axios、css-loader等依赖。

在cmd窗口,Ctrl+c,可以退出正在运行的开发状态。

安装leaflet,构建地图服务用:

npm install leaflet --save-dev

安装axios,构建网络请求用:

npm install axios --save-dev

安装css-loader等,为了在vue中解析css文件。为了以防万一,我们把相关的包全部装一遍。

因为vue2对css-loader等包的版本有要求,所以我们安装的时候,要指定包版本,通常不指定的时候,默认安装最高版本。

查看包版本的命令行:

npm view css-loader versions

安装css-loader等包的命令行:

npm install stylus-loader css-loader style-loader --save-dev
npm install sass-loader --save-dev
npm install less-loader@7.3.0 --save-dev

其中less-loader指定了版本。

用sublime等IDE打开geoserver_vue_leaflet文件夹。

打开geoserver_vue_leaflet\package.json文件,就能看到工程信息和工程依赖等内容,可以看看各依赖的版本号。




1-3.修改端口号

因为我们要请求geoserver发布的服务,geoserver的端口号是8080,vue和geoserver的端口号不能冲突,所以在启动geoserver前,我们应该先将vue的端口修改为8090。

打开geoserver_vue_leaflet\config\index.js,将port由8080,修改为8090。





1-4.关闭eslint

Eslint是用来规范代码的,但对于新手来说,不太友好,多个空格,少个空格都会报错,所以我们要把它关掉。

geoserver_vue_leaflet\build\webpack.base.conf.js中,注释掉...(config.dev.useEslint ? [createLintingRule()] : [])即可。



再次运行npm run dev,访问http://localhost:8090/#/。


二、新建地图页面

注意先把geoserver启动。

我们用的地图服务,就是《GeoServer速成:安装启动,发布地图,加载QGIS》中发布的服务:

2-1.MapStart页面

在geoserver_vue_leaflet\src路径下,新建一个views文件夹,新建一个MapStart.vue文件。

代码截图如下,代码内容可以去git上下载。



在geoserver_vue_leaflet\src\router\index.js中,新增一个路由。




访问,http://localhost:8090/#/mapstart,效果如下。



加载一个高德地图,就是这么简单。


2-2.MapWMTS页面

这个页面,我们把GeoServer发布的瓦片地图加载进来。

在views文件夹下新建MapWMTS.vue文件。



在router/index.js中新增路由。




访问,http://localhost:8090/#/mapwmts,效果如下:





2-3.FeatureClick页面

点击地图,获取并渲染矢量要素。

在views中新建ClickFeature.vue文件。

在router\index.js中新增clickfeature路由。

访问http://localhost:8090/#/clickfeature,点击地图,效果如下,会渲染黑色边线,白色透明底色的矢量要素:





2-4.FeatureCQL页面

根据查询条件,获取并渲染矢量要素。

在views中新建FeatureCQL.vue页面。

其中按钮绑定了cql方法,cql方法在methods中定义。

在router\index.js中新增featurecql路由。

访问访问http://localhost:8090/#/featurecql,输入查询条件,点击查询按钮,效果如下:




以上,就是在vue中使用leaflet简单的渲染地图要素。

接下来看看怎么在地图上绘制矢量要素,这个会稍微难一点点。


三、绘制要素页面

3-1.安装依赖

在cmd窗口,Ctrl+c,先退出dev状态。

运行:

npm install leaflet-draw --save-dev

安装leaflet-draw依赖。

这里注意一下,leaflet-draw也有版本区分,针对于不同的leaflet版本。因为我leaflet默认安装的最高版本,所以对应的,leaflet-draw也可以默认安装最高版本。


3-2.设置代理

因为post请求会涉及到跨域问题,所以我们先在开发环境,设置个代理,解决跨域问题。

Geoserver_vue_leaflet\config\index.js中,添加代理设置:




加上一个logLevel,可以在cmd中看代理日志,以便于排查错误。




设置代理,还可以区分开发环境和线上环境,方便部署。通常一个工程的后端和前端,都是分别开发的,设置代理,最重要是方便联调。

ProxyTable这段代码说明,所有带有/apis/的URL连接,都会被指向http://localhost:8080/,就是我们部署geoserver的端口上。

changOrigin=true,说明允许跨域。

pathRewrite,是路径重写,'^/apis': '/',说明http://localhost:8090/apis/geoserver/wfs会被重写为http://localhost:8080/geoserver/wfs。

这点要特别注意,如果写成了'^/apis': '/apis',则http://localhost:8090/apis/geoserver/wfs会被重写为http://localhost:8080/apis/geoserver/wfs。但我们知道这个链接是不存在的,会报404错误。 这是个坑,要注意。



3-3.POST页面

因为绘制页面需要向geoserver提交数据,的确复杂一些,所以我们先写一个post页面,来过渡熟悉一下。

在geoserver_vue_leaflet\views文件夹下,新建一个PostGML.vue页面。

代码截图如下,这个可以在git上下载源代码看。



注意upload方法中headers的Content-type是text/xml;charset=UTF-8。




在router/index.js中添加个路由。

访问:http://localhost:8090/#/postgml,注意gml文本中,encoding要指定为UTF8,与upload方法中指定的content-type编码一致,点击确定,即可将gml上传至geoserver,gml文本可以是增删改查任意内容。



GML文本的构造方式,可查阅:

3-4.绘制页面

在geoserver_vue_leaflet/views下新建一个MapDraw.vue页面,代码比较长,可以看git上的源码。

要注意的是,构建gml文本的时候,encoding要注明是UTF8。




在geoserver_vue_leaflet/router/index.js中新建一个路由。

访问:http://localhost:8090/#/mapdraw,效果如下:



地图上绘制面,属性边栏添加属性,点击添加按钮,即可上传数据。



四、marker不显示问题

因为leaflet和webpack有点冲突,所以vue下用leaflet绘制marker,marker的图标不显示。



解决起来,也很简单,我们重新定义一下marker的icon就行。


在geoserver_vue-leaflet\views中新建个页面,PointDraw.vue,在geoserver_vue-leaflet\router\index.js中新建路由。

在PointDraw.vue中引入图标文件:



定义图标,并用这个图标在地图中心添加一个点:




在绘制工具中,重新指定marker的icon为DefaultIcon。




访问:http://localhost:8090/#/pointdraw,随便画几个点,效果如下。




这种重新定义icon的方式,通用性更强,同样适用于自定义图标,而且不影响代码移植和后续打包部署。Prefect。


五、总结

Vue的确上手快,而且网上资料多,有不会的查一查,很快就能找到答案。

Leaflet也是使用最多的地图框架,因为我用过所有的地图框架,它是最轻量、最简单的,虽然我至今仍然无法忍受它把纬度放在前面。

Geoserver我觉得它发布地图,比ArcServer要简单,最主要的是它开源,低版本的geoserver还有跟qgis不兼容的问题,现在也都优化好了。

Vue、leaflet、geoserver结合起来,再加上qgis做一些配图,可以快捷的做很多漂亮的地图应用。说实话,常用的、能想到的地图应用,尤其是展示性的,这一套都能实现。

实践是检验真理的唯一标准,动手实践吧!

编辑于 2021-06-28 16:46

文章被以下专栏收录