路網的資料來源來自OpenStreetMap(OSM)。
下面介紹擷取資料,處理,完整繪制的流程:
1.資料擷取:
擷取:
進入OSM官網點選導出就可以擷取資料,你可以通過標明範圍擷取資料(大小一般不超過一個小型城市),當資料更大時則需要點選Geofabrik下載下傳擷取。注意:OSM資料并不百分百可靠,畢竟是開放式的,請謹慎使用。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yN0IjZyYmY2MWNmFjNiJWNyYGMzMGMkFjYyM2MyEGNw8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
這裡采用台灣資料集,是以還要點選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 等常見标簽中繪圖。
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的文章