天天看點

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

路網的資料來源來自OpenStreetMap(OSM)。

下面介紹擷取資料,處理,完整繪制的流程:

1.資料擷取:

擷取:

進入OSM官網點選導出就可以擷取資料,你可以通過標明範圍擷取資料(大小一般不超過一個小型城市),當資料更大時則需要點選Geofabrik下載下傳擷取。注意:OSM資料并不百分百可靠,畢竟是開放式的,請謹慎使用。

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

這裡采用台灣資料集,是以還要點選Asian進入下級目錄(大陸和台灣分成了兩個資料集,沒辦法,國外網站)

推薦osm.pbf格式的檔案,其本質就是XML檔案。

資料格式:

根據OSMWIKI可知,一共有三種類型的資料結構:

點(NODE) 路(WAY) 關系(RELATION)

繪制路網一般隻需要線類型的資料。

2.資料處理:

軟體安裝:

擷取到資料後,采用PostgreSQL + PostGIS + QGIS和相關插件處理資料,前兩者的

安裝和資料導入可以參考我的OSM資料導入PostgreSQL常見問題解決方法,QGIS免費,功能強大,效率高且QGIS通過會話連接配接PostgreSQL,安裝位置自由,基本沒有其他注意事項。

将資料全部導入PostgreSQL後,其插件可以在資料庫中按照資料類型自動分類建表。

QGIS通過輸入PostgreSQL的hostname和密碼即可連接配接:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

QGIS顯示:

選擇導出roads表格中的資料,全部導出結果如圖:

(這裡帶着大陸地圖一起顯示了,但其實我工作的電腦裡隻有灣灣的圖,是以最終結果隻有灣灣的高速路)

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

資料篩選:

OSM已經給各種道路分好了标簽,根據其WIKI可知:地區主要高速公路标簽為‘motorway’,是以這裡過濾器filter選擇highway裡的‘motorway’,再将其篩選,以GeoJson格式導出即可:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

篩選結果:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

可以看到還是有部分資料有問題,可以後期手動修正(可能會累死吧哈哈),(Vector的Data management tool可以合并圖層)

導出:

可以通過postgresql看到,資料庫中很多資訊都是NULL,導出時可以選擇導出我們需要的屬性:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:
D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

3.頁面路網繪制:

(這部分應該有更好的方案,歡迎各位多提意見)

資料處理:

将導出的路網資料放在web網頁下,将檔案字尾改為js,這裡是為了友善D3讀取(偷懶),再将其設定為JS變量,即:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

對比原來:

D3基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

(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基于OSM繪制高速路網全流程 D3 + OSM +PostGreSQL1.資料擷取:2.資料處理:3.頁面路網繪制:

成功!

大陸路網資料量更加龐大,後面會進一步介紹處理方法。直接加載會拖慢頁面響應速度。

關于D3對地圖的進一步優化和豐富功能會在後面的文章介紹到。

希望各位多多指教!

D3繪圖部分參考了Jonithan的文章