1.写在前
最近学习了点空间数据库的知识,算是知道了点皮毛,趁热打铁——所以打算利用所学知识制作一张交通线路专题图,主要包括数据下载、数据洗涤、清洗、专题图制作、专题图发布等内容,同时也希望下面的内容对你有帮助。
2. 运行环境与适读对象
2.1运行环境
硬件:笔记本电脑win11
软件:
名字 | 版本 | 备注 |
postgreSQL | 15.7.1 | jdk8u411 postgis-v3.3.2 |
QGIS | 3.28.3 | |
Apache | 2.4.59 | |
GeoServer | 2.22.0 |
安装包图片如下,仅供参考。
注意:在本次使用过程中使用高版本的GeoServer发布的地图不显示,网上说是版本过高,所以我当时又换成了低版本的,
其次,使用安装版的GeoServer安装,默认服务端口是8080,有些笔记本电脑用这个端口安装后无法打开GeoServer,建议把端口换成别,比如8083,8084等端口,如果你用的是免安装的,那当我没说,免安装的问题从理论上讲,改一下配置里的端口应该可以,但是我试过没有用。
2.2 适合人群
学过空间数据库,会使用QGIS,postgreSQL,Apache,GeoServer等工具。(当然即使你没学过,单纯是对专题图制作兴趣,这也是适合)
3.1 数据收集导入和清洗
3.1.1地图数据收集
登录网址https://www.webmap.cn/commres.do?method=dataDownload,如下图,
![](https://img-blog.csdnimg.cn/direct/4325635aab254875aed553c776ec5c57.png)
需要说明的是这个网站可能注册和登录时会显示账户已被注册,或说存在和账户不存在,反正就是注册注册不了,注册了又登录不了。
针对注册建议更换浏览器,用谷歌或者火狐的浏览器试试,多点击几次注册可能就会成功。
针对登录建议更换浏览器,同时使用邮箱登录,使用邮箱登录,使用邮箱登录!不要用昵称。
点击1:100万全国基础地理数据库进入数据地图下载。
![](https://img-blog.csdnimg.cn/direct/12b29e53c0be45a9b5bee8256b8df73a.png)
点击查询进入下图界面,选择要下载的地图区域,然后选择黄色购物车添加下载的地图数据:
![](https://img-blog.csdnimg.cn/direct/a90a4ff722d345fcbe028e3cacbd6a8d.png)
接着填写相关信息,点击提交订单进入下面的页面,点击数据下载如下图:
![](https://img-blog.csdnimg.cn/direct/443cd3fe71124f8cbed94ca4973ca57d.png)
然后按照页面的提示完善信息,如下图三个步骤:
值得注意的是下载地图时可能会出现如下情况,填写的信息不显示,刷新网站或者更换浏览器也一样的情况,这里给连个建议:
1.等一段时间再进去试试;
2.使用我给的资料包,当然这个建议只适合练习的小伙伴。(后面会附上链接)
![](https://img-blog.csdnimg.cn/direct/1faffb962411419b8e312917acc37459.png)
下面是正常显示的效果:
![](https://img-blog.csdnimg.cn/direct/0c1b3416f7dc48d9b75216a782cabbe9.png)
完善信息后最后一步就可以下载选中的地图数据了,点击页面上的“矢量地图数据”,在下拉选项中点击下载,如下如:
![](https://img-blog.csdnimg.cn/direct/e46525d50c554a33a200eadbdc38cf1f.png)
至此地图数据下载就完成了。
3.1.2数据导入
将下载的地图进行解压,如下图:
![](https://img-blog.csdnimg.cn/direct/d94ac360a1ef402ca99ee60f3ab7025e.png)
运行QGIS,连接postgres后点击菜单栏的数据库,找到刚才解压的数据,选择.gdbtable结尾的文件,根据本次设计需要选择名字以c、b、e结尾的.gdbtable文件(你可以选择其他的),他们分别表示交通线路、桥梁、县市地图,在此我们将使用traffic、bridge、city 表示这些数据,下面是具体操作步骤:
导入数据库:
![](https://img-blog.csdnimg.cn/direct/0f41f374f24245059154b4984da836fa.png)
这里需要注意的是如果在导入数据库时没有勾选创建空间索引,那么可以在创建后再右下角,如下图:
![](https://img-blog.csdnimg.cn/direct/a644befba89d41fba36de485edfbc358.png)
在弹出页面使用过滤所搜自己需要的索引,测出为4326,如下图:
![](https://img-blog.csdnimg.cn/direct/2e8e3c31c9b7480ca084c79b3609b893.png)
设置导入的数据表的坐标投影,如下图:
![](https://img-blog.csdnimg.cn/direct/e95a1af1d5d24805815d4894a9b37aa1.png)
对于city与bridge也需要同样的操作。
在操作之前,右键图层,让地图上的标注显示:
接着继续右键图层点击过滤,如下图:
使用like命令过滤掉不必要信息,在traffic空间数据中使用"name" LIKE '%铁路%'保留包含铁路字样的信息,如下图:
图3-13 铁路数据过滤图
点击平移地图,拖动地图查看效果,其实也就是类似于刷新。
图3-14 点击平移地图
同样的操作:
对bridge使用"name" LIKE '%桥%'保留包含桥字样的数据;
对city使用"name" LIKE '%市%'保留包含市字样的数据;
当数据都使用like命令过滤后,找到要制作的地图位置,本次制作的是长葛市交通地图,在地图上放大找到长葛市,如下图:
![](https://img-blog.csdnimg.cn/direct/896af95f96dd4c8f96087063b1346f74.png)
可以发现周围还有很多不需要的数据,此时就需要使用delete命令删除选中你ID以外的数据,先打开SQLshell,输入口令,进入命令行操作;
![](https://img-blog.csdnimg.cn/direct/370c23900e8449b187e08101367258bb.png)
在使命令前,我们需要添加如下命令,
create extension if not exists postgis;
目的是创建PostGIS 扩展到当前数据库,如下图是已添加拓展后执行的结果:
![](https://img-blog.csdnimg.cn/direct/485fa78eeb9343e3961c698d4ed879f5.png)
在使用delete命令前,需要知道要保留数据的ID,在QGIS右上角找到识别要素功能,接着在点击要操作的图层:
然后框选要保留的区域,如下图红色点则为选中点,是要保留的数据。
![](https://img-blog.csdnimg.cn/direct/7aa288b61467458282a7eaf1c5e508db.png)
在右侧找到对应数据的ID,保留的ID为1269,1668
![](https://img-blog.csdnimg.cn/direct/216a88b0de644057bfc86499e49f31f3.png)
随后在SQL shell中使用delete命令,
delete from bridge where id not in(1269,1668);
如下图:
![](https://img-blog.csdnimg.cn/direct/22f3f053c8394585905272f64bc7c469.png)
回到QGIS点击平移地图,也就是白色手套,拖动地图查看结果,此时可以发现除了要保留的数据其他数据都已经被过滤掉了,如下图:
![](https://img-blog.csdnimg.cn/direct/3fd7cdd5810846bd9e7f2c9888a3b785.png)
使用同样的方式对city和traffic表进行操作,traffic表中所需要保留的数据ID为49,254,464,465,466,482;city表中要保留的市ID为123;这里就不依依展示了。
最终结果如下:
至此数据收集过滤洗涤就完成了,下一步是专题图的制作。
3.2 地图样式详细制作
对点数据样式选择红色,点击属性——符号化——分类——值为name。
![](https://img-blog.csdnimg.cn/direct/24526e4c8a5d4dd8bafefd9ac381c3e7.png)
而交通线路数据使用灰色,点击属性——符号化——分类——值name,调浅颜色。
![](https://img-blog.csdnimg.cn/direct/d25b854adbd945339e41a64eb0ec9aea.png)
市地图使用浅蓝色,点击属性——符号化——分类——值name,颜色选择浅蓝色。
![](https://img-blog.csdnimg.cn/direct/ad4eb7a6e0b549129b5412e7464944c6.png)
接着长葛市字样的大小,具体如下图:
![](https://img-blog.csdnimg.cn/direct/52f18b648cb2469a99aa449cbe3ca6a6.png)
最终结果如下:
![](https://img-blog.csdnimg.cn/direct/a2d4b70e559d4eb799d49c3177a939f9.png)
3.3 数据操作与分析
数据分析这一步只是这次专题图制作的延伸,你可以跳过,做数据分析时依据自己的地图情况而定,下面具几个函数作为数据操作,需要声明的是这些命令一部分是询问AI的,所以——你遇到不懂的,想实现的也可以询问AI,像文心一言,通义千问,kimi等;
3.3.1 ST_buffer数据分析
先创建一个表,此处为citybuffer1,
create table citybuffer1(id int primary key,geom geometry( ' polygon' ,4326));
在往表里添加数据,数据需要结合bridge的数据,
insert into citybuffer1(id ,geom) values(3,(select st_buffer(geom,9.815) from bridge where id=1668));
如下图:
回到QGIS查看结果:
![](https://img-blog.csdnimg.cn/direct/864731ffaf3144e98db309042512bb83.png)
由图可知增福庙立交桥0.015单位内有铁路,而京广立交桥0.015单位内没有铁路经过。
3.3.2 st_astext和st_intersection数据分析
执行如下代码:
select st_intersects(geom,(select geom from traffic where id=482))from traffic where id=49;
执行结果如下:
结果返回t,这表明京广高速铁路和郑许市域铁路有交点。
执行st_intersection函数目的是为了找到京广高速铁路和郑许市域铁路交点坐标:
select st_astext(st_intersection((select geom from traffic where id=482),(select geom from traffic where id=49))) as intersection point from traffic where id in(482,29);
结果如下,从图中可以看到交点坐标是(113.81276238076573 34.2411422886219)。
3.3.3 ST_Distance、ST_SetSRID、ST_AsText和ST_GeomFromText数据分析
执行如下代码,目的是为了找到图上两个桥的坐标,第一个坐标(113.76838476000012 34.26305228000007)是增福庙立交桥,第二个坐标(113.7766645050001 34.18909505500005)是京广立交桥。
接着使用如下代码计算出两座桥的距离.
SELECT ST_Distance( ST_GeomFromText('POINT(113.76838476000012 34.26305228000007)', 4326), ST_GeomFromText('POINT(113.7766645050001 34.18909505500005)', 4326) ) AS distance;
从结果可以看出二者的距离大约是0.07个单位。
下面我们结合上面的分析计算出下图Q到P和G的距离,从之前的分析可知Q点就是京广高速铁路和郑许市域铁路交点坐标为(113.81276238076573,34.2411422886219),P(113.76838476000012,34.26305228000007),G(113.7766645050001,34.18909505500005)。
![](https://img-blog.csdnimg.cn/direct/ebb0c4fff2c041b8b6c021a9269f097a.png)
执行下面的代码:
SELECT ST_Distance( ST_GeomFromText('POINT(113.76838476000012 34.26305228000007)', 4326), ST_GeomFromText('POINT(113.81276238076573 34.2411422886219)', 4326) ) AS distance1,ST_Distance( ST_GeomFromText('POINT(113.81276238076573 34.2411422886219)', 4326), ST_GeomFromText('POINT(113.7766645050001 34.18909505500005)', 4326) ) AS distance1;
从结果可以看到QP长大约为0.0495,QG长大约为0.0633,说明交点到增福庙立交桥更近一些。
3.3.4 st_relate和ST_SetSRID数据分析
![](https://img-blog.csdnimg.cn/direct/4802e0b089104cdeb32e41dbd317b7fb.png)
执行如下代码:
select st_relate(ST_SetSRID(geom,4326),ST_SetSRID((select geom from city where id=123),4326)) from citybuffer1 where id=3;
对这个结果的解释是:
2:增福立交桥0.015个单位范围内与长葛市内部相交(存在面与面相交);
F:增福立交桥0.015个单位范围内与长葛市边界不相交;
F:增福立交桥0.015个单位范围内与长葛市外部不相交;
1:增福立交桥0.015个单位的边界与长葛市内部相交(存在线与线相交);
F:增福立交桥0.015个单位的边界与长葛市边界不相交;
F:增福立交桥0.015个单位的边界与长葛市外部不相交;
2:增福立交桥0.015个单位的外部与长葛市内部相交(存在面与面相交);
1:增福立交桥0.015个单位的外部与长葛市的边界相交(存在线与线相交);
2:增福立交桥0.015个单位的外部与长葛市的外部相交(存在面与面相交);
3.3.5 st_union数据分析
更具id联合显示京广高速铁路和郑许市域铁路,先创建一个表
create table traffic_union_line(id int primary key,geom geometry(MultiLineString,4326));
注意这里使用的类型是MultiLineString,而不是LINESTRING,前者用于表示多条线段的集合,每条线段都是一个单独的 LINESTRING 对象,后者用于表示由两个或多个点组成的线段,这些点在空间上是连续的,如果显示的是点或面则不能用这一类型;
接着往表里插入京广高速铁路和郑许市域铁路数据,执行命令:
insert into traffic_union_line(id,geom) select 1,st_union(geom) from traffic where id in(482,49);
执行结果如下图:
![](https://img-blog.csdnimg.cn/direct/4e92f092455140d58bc764737819a73c.png)
3.4 专题图制作
点击打印布局,如下图:
![](https://img-blog.csdnimg.cn/direct/3bfb00e395e54281b2fc96c97359d705.png)
在弹出的页面填写布局名称,在左侧栏有以下功能,主要用到框出来的部分:
![](https://img-blog.csdnimg.cn/direct/f49edfc8aab740c1a15525fd0c1ccab2.png)
添加地图
![](https://img-blog.csdnimg.cn/direct/06fe185a4ed14dea9c73ac2af9bf8e44.png)
添加方向、比例尺和图例
![](https://img-blog.csdnimg.cn/direct/2d429b36909d418587abdc2d2d23786c.png)
添加标题
![](https://img-blog.csdnimg.cn/direct/fce91bab6c1e4a40bab946d776f2a54b.png)
导出为JPG格式图片
![](https://img-blog.csdnimg.cn/direct/1f50bcf3f9c24f4fa6e5c8cbc9e9baea.png)
![](https://img-blog.csdnimg.cn/direct/e8b7e5f961744f6a81398e5695e99cf1.png)
![](https://img-blog.csdnimg.cn/direct/a68e398bf2e74d6789b8ba610c96e4c3.png)
3.5 地图发布
3.5.1Apache发布专题图
在Apache24文件目录bin下打开下图程序
![](https://img-blog.csdnimg.cn/direct/1171662bc1374e109b632c16da3e6310.png)
查看电脑右下角Apache是否打开,亮绿灯表示打开
![](https://img-blog.csdnimg.cn/direct/965774144bff42709eced0dc90517cf2.png)
在.html中插入图片
![](https://img-blog.csdnimg.cn/direct/60ff882385e0409794d16ff92bf91c31.png)
打开电脑终端cmd,输入ipconfig查看本地IP地址
![](https://img-blog.csdnimg.cn/direct/05e260898ec441ccb06666389b32533a.png)
查看运行端口
![](https://img-blog.csdnimg.cn/direct/839940036db546aeaba0be0b53215eed.png)
打开httpd.conf找到Listen,查看开放端口,此处为8090.
![](https://img-blog.csdnimg.cn/direct/b97a618432a642aca5e3d72b4e61bc5c.png)
在浏览器上数据IP地址+开放端口如下图:
电脑端:
![](https://img-blog.csdnimg.cn/direct/05bd290de5f04e0eac6233dc77f06863.png)
手机端:
![](https://img-blog.csdnimg.cn/direct/6a48793cc9174fff83229f8836a9b00c.png)
手机端查看请确保网络在局域网内,否则无法访问。
3.5.2geoserver发布专题图
创建工作空间如下图:
![](https://img-blog.csdnimg.cn/direct/f904d8fe68954fbdb9e6bae151a6fedd.png)
创建存储空间如下图
![](https://img-blog.csdnimg.cn/direct/e30e270d73824c4fb8ff594b9d726c48.png)
创建样式此处需要创建三个样式,即city、bridge和traffic的样式,在这之前我们需要将QGIS的样式导出为.sdl文件,此处我们以city的为例。对city的样式修改如下图:
![](https://img-blog.csdnimg.cn/direct/2f04d70aa17741efbe04fa9a7d3d232d.png)
需要说明的是使用name字段也是可以的,但也会出现GeoServer无法识别的情况,所以你嫌麻烦可以先不更改字段为id,而是用原来的name。
右键图层点击导出,如下图:
![](https://img-blog.csdnimg.cn/direct/5bd33d5760704add8cc3def4cf132259.png)
选择保存样式和保存路径如下图:
![](https://img-blog.csdnimg.cn/direct/ba8aec2a05054fd0b202fc847e1a0e6c.png)
回到GeoServer创建图层,发布要显示的图层,如下图:
![](https://img-blog.csdnimg.cn/direct/e37bd553e49d453eaf3eee82441e252d.png)
在发布的图层中的数据一栏往下滑,看到边框字样,点击computer fromnative bounds,接着点击保存。
![](https://img-blog.csdnimg.cn/direct/b628a9a565ed45afb4d7cbaa486f6da0.png)
接着创建样式,如下图:
![](https://img-blog.csdnimg.cn/direct/3f8eae0eb5174ef0819565c486e7d121.png)
将id修改为objectid这是因为导入的样式GeoServer无法识别id,但可以识别objectid,这一点的依据可以点击Layer Attributes查看,在下图中可以发现确实没有id字段,而有objectid,
![](https://img-blog.csdnimg.cn/direct/3a0f2539767a4da1adc572c1fc06b499.png)
从上面这张图可以看到数据里面是有name字段的,而没有id,所以理论上创建样式的时候可以使用name字段(但是我自己用name和id都不行,都报错说无法识别,所以这里用了id,而且还要把.sld文件里面的部分代码改掉,属实是走了很多弯路了)
知道这一点后修改下面的代码,把id改为objectid如下图:
![](https://img-blog.csdnimg.cn/direct/697edd12c2534c848e38dbbec70810ef.png)
点击采用并验证是否有报错,接着点击publishing选择默认,如下图:
![](https://img-blog.csdnimg.cn/direct/956c802c31d44ac3900890fbba385615.png)
点击预览如果可以正常预览则说明创建没有问题,如下图:
![](https://img-blog.csdnimg.cn/direct/3a9046d11c4a473bb5c688fe5f3ee8c1.png)
最后保存即可。
然后回到图层编辑对应图层,选择发布一栏往下滑,看到WMS设置,将要显示的图层添加到右边,并点击保存,如下图:
![](https://img-blog.csdnimg.cn/direct/a37f9eb58d5c44c88668ae36f2580dfb.png)
接着就可以预览发布的图层了,如下图:
![](https://img-blog.csdnimg.cn/direct/9b8021da61a54d12abc8b53901102a16.png)
上面是city图层的发布,对bridge和traffic也是一样的操作。他们的发布预览如下图:
![](https://img-blog.csdnimg.cn/direct/ae95017361ec4633a24392a758c421f6.png)
![](https://img-blog.csdnimg.cn/direct/d73c71d5691643eb976e18c4573356eb.png)
3.5.3 GeoServer中图层组的发布
显示三个图层则需要创建图层组,创建图层组名称并添加要显示的图层,如下图:
![](https://img-blog.csdnimg.cn/direct/844cc7e5cd4b447890ce7c2a501d9139.png)
![](https://img-blog.csdnimg.cn/direct/ae81886d9e7046dfb29f21c7e1e51d75.png)
值得注意的是排在最后的是在最上层的图层,点击保存后可以查看发布的图层组,如下图所示:
![](https://img-blog.csdnimg.cn/direct/af4f68c1829e402997a03d554af8e1eb.png)
![](https://img-blog.csdnimg.cn/direct/8409505b727d42338f119e16943aac8a.png)
至此GeoServer的发布就结束了。
4. 结束语
希望本次的专题图制作与发布教程对你有帮助,我也是第一次完整的制作专题图,这一过程中一些论述可能会有问题,一些方法可能欠缺,希望你在实际操作中结合自己实际情况,多多搜集资料,祝你成功!感谢你看到这里。