D3基于OSM绘制高速路网全流程 D3 + OSM +PostGreSQL

路网的数据来源来自OpenStreetMap(OSM)。
下面介绍获取数据,处理,完整绘制的流程:

1.数据获取:

获取:

进入OSM官网点击导出就可以获取数据,你可以通过选定范围获取数据(大小一般不超过一个小型城市),当数据更大时则需要点击Geofabrik下载获取。注意:OSM数据并不百分百可靠,毕竟是开放式的,请谨慎使用。
image.png
这里采用台湾数据集,因此还要点击Asian进入下级目录(大陆和台湾分成了两个数据集,没办法,国外网站)

推荐osm.pbf格式的文件,其本质就是XML文件。

数据格式:

根据OSMWIKI可知,一共有三种类型的数据结构:

点(NODE) 路(WAY) 关系(RELATION)

绘制路网一般只需要线类型的数据。

2.数据处理:

软件安装:

获取到数据后,采用PostgreSQL + PostGIS + QGIS和相关插件处理数据,前两者的
安装和数据导入可以参考我的OSM数据导入PostgreSQL常见问题解决方法,QGIS免费,功能强大,效率高且QGIS通过会话连接PostgreSQL,安装位置自由,基本没有其他注意事项。

将数据全部导入PostgreSQL后,其插件可以在数据库中按照数据类型自动分类建表。

QGIS通过输入PostgreSQL的hostname和密码即可连接:

image.png

QGIS显示:

选择导出roads表格中的数据,全部导出结果如图:
(这里带着大陆地图一起显示了,但其实我工作的电脑里只有湾湾的图,所以最终结果只有湾湾的高速路)
image.png

数据筛选:

OSM已经给各种道路分好了标签,根据其WIKI可知:地区主要高速公路标签为‘motorway’,因此这里过滤器filter选择highway里的‘motorway’,再将其筛选,以GeoJson格式导出即可:

image.png

筛选结果:

image.png

可以看到还是有部分数据有问题,可以后期手动修正(可能会累死吧哈哈),(Vector的Data management tool可以合并图层)

导出:

可以通过postgresql看到,数据库中很多信息都是NULL,导出时可以选择导出我们需要的属性:

image.png

image.png

3.页面路网绘制:

(这部分应该有更好的方案,欢迎各位多提意见)

数据处理:

将导出的路网数据放在web网页下,将文件后缀改为js,这里是为了方便D3读取(偷懒),再将其设置为JS变量,即:

for_test.js

对比原来:

for_test.geojson

(name删不删都无所谓)

导入D3并绘制图形:

下载 D3.js/D3.min.js 并导入网页项目,D3和数据js文件一同导入相关HTML,我这里采用thymeleaf代理:

  <script th:inline="javascript" th:src="@{js/d3.min.js}"></script>
  <script th:inline="javascript" th:src="@{data/for_test.js}"></script>

设置SVG标签,注意,这里最好用SVG标签,D3无法在 div 等常见标签中绘图。

  <svg class = "fortest"></svg>

D3绘制:

    /**
     * 基本配置 
     */
	const svgWidth = 1000;
	const svgHeight = 800;
	const padding = 30;
    /**这里设定容器*/
	const svg = d3.select(".fortest")
	      .attr("height", svgHeight)
	      .attr("width", svgWidth);

这里TW就是你数据js文件中的变量名

     /*
      * 创建一个地理投影
      * .center 设置投影中心位置
      * .scale 设置缩放系数
      */
	const x0 = padding;
	const y0 = padding;
	const x1 = svgWidth - padding * 2;
	const y1 = svgHeight - padding * 2;
	const projection = d3.geoMercator().fitExtent(
		[
                    [x0,y0],
                    [x1,y1],
		],TW
	);
//  创建路径生成器path
	var path = d3.geoPath().projection(projection);
/*
* 渲染地图
*/
	const mapPath = svg.selectAll("path")
	.data(TW.features)
	.join('path')
	.attr('d', path)
	.attr("stroke-width", 2)
    	attr("stroke", "#00cc00")
    	.attr("fill", "#ffffff");

成果:

image.png

成功!

大陆路网数据量更加庞大,后面会进一步介绍处理方法。直接加载会拖慢页面响应速度。

关于D3对地图的进一步优化和丰富功能会在后面的文章介绍到。

希望各位多多指教!

D3绘图部分参考了Jonithan的文章

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值