路网的数据来源来自OpenStreetMap(OSM)。
下面介绍获取数据,处理,完整绘制的流程:
1.数据获取:
获取:
进入OSM官网点击导出就可以获取数据,你可以通过选定范围获取数据(大小一般不超过一个小型城市),当数据更大时则需要点击Geofabrik下载获取。注意:OSM数据并不百分百可靠,毕竟是开放式的,请谨慎使用。
这里采用台湾数据集,因此还要点击Asian进入下级目录(大陆和台湾分成了两个数据集,没办法,国外网站)
推荐osm.pbf格式的文件,其本质就是XML文件。
数据格式:
根据OSMWIKI可知,一共有三种类型的数据结构:
点(NODE) 路(WAY) 关系(RELATION)
绘制路网一般只需要线类型的数据。
2.数据处理:
软件安装:
获取到数据后,采用PostgreSQL + PostGIS + QGIS和相关插件处理数据,前两者的
安装和数据导入可以参考我的OSM数据导入PostgreSQL常见问题解决方法,QGIS免费,功能强大,效率高且QGIS通过会话连接PostgreSQL,安装位置自由,基本没有其他注意事项。
将数据全部导入PostgreSQL后,其插件可以在数据库中按照数据类型自动分类建表。
QGIS通过输入PostgreSQL的hostname和密码即可连接:
QGIS显示:
选择导出roads表格中的数据,全部导出结果如图:
(这里带着大陆地图一起显示了,但其实我工作的电脑里只有湾湾的图,所以最终结果只有湾湾的高速路)
数据筛选:
OSM已经给各种道路分好了标签,根据其WIKI可知:地区主要高速公路标签为‘motorway’,因此这里过滤器filter选择highway里的‘motorway’,再将其筛选,以GeoJson格式导出即可:
筛选结果:
可以看到还是有部分数据有问题,可以后期手动修正(可能会累死吧哈哈),(Vector的Data management tool可以合并图层)
导出:
可以通过postgresql看到,数据库中很多信息都是NULL,导出时可以选择导出我们需要的属性:
3.页面路网绘制:
(这部分应该有更好的方案,欢迎各位多提意见)
数据处理:
将导出的路网数据放在web网页下,将文件后缀改为js,这里是为了方便D3读取(偷懒),再将其设置为JS变量,即:
对比原来:
(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");
成果:
成功!
大陆路网数据量更加庞大,后面会进一步介绍处理方法。直接加载会拖慢页面响应速度。
关于D3对地图的进一步优化和丰富功能会在后面的文章介绍到。
希望各位多多指教!
D3绘图部分参考了Jonithan的文章