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安装参见: https://www. runoob.com/nodejs/nodej s-install-setup.html 。
Vue安装参见: https://www. runoob.com/w3cnote/vue2 -start-coding.html 。
安装完之后,查看一下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做一些配图,可以快捷的做很多漂亮的地图应用。说实话,常用的、能想到的地图应用,尤其是展示性的,这一套都能实现。
实践是检验真理的唯一标准,动手实践吧!