2013-08-18 43 views
8

給定具有高程數據的GIS柵格,如何在D3js中設計地形圖?D3js:如何設計地形圖?

是否有使用D3js製作的裁剪土地的地形圖/地形圖的任何示例?


不工作:我探索的.tif > gdal_contour.py > .shp > topojson > d3js的posibility沒有成功。

use a makefile其中包含我所有的命令。由於我感興趣的領域(法國)是一片陸地區域,因此gdal_contour.py方法會生成破碎的等值線,而不會生成封閉的多邊形。另外,SVG最終結果失敗。 D3地形圖的唯一例子就是我知道的is about Iceland,它作爲一個島嶼避免了這個問題:將這個國家從世界中剪出來不會導致等值線破裂。

enter image description here

注:此項目是#Wikipedia #wikimaps項​​目的一部分。

回答

20

D3js上的地形圖,帶有完整的makefile工作流程!見http://bl.ocks.org/hugolpz/6279966(< =舊的代碼,比較這裏SO)

0要求:

  • 地理區域:您可以通過編輯內的每一行定義您感興趣的地理區域的2個文件:makefile#boxing和html#用你自己的小數座標fo W,N,E,S邊框,像這樣的地理框架邊界:

    var WNES = {「target」:「France」,「W 「:-5.3,」N「:51.6,」E「:10.2,」S「:41.0};

  • 軟件:makecurlunzipgdal(包括ogrgdal_calc.pygdal_polygonize.py),nodejstopojson。有用:touch。然後,makefile管理下載源代碼,處理它們,並輸出D3js代碼提供的單個topojson文件可以使用的文件。

1.保存到文件夾名稱:/topo_map/topo.mk

# topojsoning: 
final.json: levels.json 
    topojson --id-property none --simplify=0.5 -p name=elev -o final.json -- levels.json 
    # simplification approach to explore further. Feedbacks welcome. 

# shp2jsoning: 
levels.json: levels.shp 
    ogr2ogr -f GeoJSON -where "elev < 10000" levels.json levels.shp 

# merge 
levels.shp: level0001.shp level0050.shp level0100.shp level0200.shp level0500.shp level1000.shp level2000.shp level3000.shp level4000.shp level5000.shp 
    ogr2ogr levels.shp level0001.shp 
    ogr2ogr -update -append levels.shp level0050.shp 
    ogr2ogr -update -append levels.shp level0100.shp 
    ogr2ogr -update -append levels.shp level0200.shp 
    ogr2ogr -update -append levels.shp level0500.shp 
    ogr2ogr -update -append levels.shp level1000.shp 
    ogr2ogr -update -append levels.shp level2000.shp 
    ogr2ogr -update -append levels.shp level3000.shp 
    ogr2ogr -update -append levels.shp level4000.shp 
    ogr2ogr -update -append levels.shp level5000.shp 

# Polygonize slices: 
level0001.shp: level0001.tif 
    gdal_polygonize.py level0001.tif -f "ESRI Shapefile" level0001.shp level_0001 elev 
level0050.shp: level0050.tif 
    gdal_polygonize.py level0050.tif -f "ESRI Shapefile" level0050.shp level_0050 elev 
level0100.shp: level0100.tif 
    gdal_polygonize.py level0100.tif -f "ESRI Shapefile" level0100.shp level_0100 elev 
level0200.shp: level0200.tif 
    gdal_polygonize.py level0200.tif -f "ESRI Shapefile" level0200.shp level_0200 elev 
level0500.shp: level0500.tif 
    gdal_polygonize.py level0500.tif -f "ESRI Shapefile" level0500.shp level_0500 elev 
level1000.shp: level1000.tif 
    gdal_polygonize.py level1000.tif -f "ESRI Shapefile" level1000.shp level_1000 elev 
level2000.shp: level2000.tif 
    gdal_polygonize.py level2000.tif -f "ESRI Shapefile" level2000.shp level_2000 elev 
level3000.shp: level3000.tif 
    gdal_polygonize.py level3000.tif -f "ESRI Shapefile" level3000.shp level_3000 elev 
level4000.shp: level4000.tif 
    gdal_polygonize.py level4000.tif -f "ESRI Shapefile" level4000.shp level_4000 elev 
level5000.shp: level5000.tif 
    gdal_polygonize.py level5000.tif -f "ESRI Shapefile" level5000.shp level_5000 elev 

# Raster slicing: 
level0001.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0001.tif --calc="1*(A>0)"  --NoDataValue=0 
level0050.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0050.tif --calc="50*(A>50)"  --NoDataValue=0 
level0100.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0100.tif --calc="100*(A>100)"  --NoDataValue=0 
level0200.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0200.tif --calc="200*(A>200)"  --NoDataValue=0 
level0500.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0500.tif --calc="500*(A>500)"  --NoDataValue=0 
level1000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level1000.tif --calc="1000*(A>1000)"  --NoDataValue=0 
level2000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level2000.tif --calc="2000*(A>2000)"  --NoDataValue=0 
level3000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level3000.tif --calc="3000*(A>3000)"  --NoDataValue=0 
level4000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level4000.tif --calc="4000*(A>4000)"  --NoDataValue=0 
level5000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level5000.tif --calc="5000*(A>5000)"  --NoDataValue=0 

# boxing: 
crop.tif: ETOPO1_Ice_g_geotiff.tif 
    gdal_translate -projwin -5.3 41.0 10.2 51.6 ETOPO1_Ice_g_geotiff.tif crop.tif 
    # ulx uly lrx lry // W S E N 

# unzip: 
ETOPO1_Ice_g_geotiff.tif: ETOPO1.zip 
    unzip ETOPO1.zip 
    touch ETOPO1_Ice_g_geotiff.tif 

# download: 
ETOPO1.zip: 
    curl -o ETOPO1.zip 'http://www.ngdc.noaa.gov/mgg/global/relief/ETOPO1/data/ice_surface/grid_registered/georeferenced_tiff/ETOPO1_Ice_g_geotiff.zip' 

clean: 
    rm `ls | grep -v 'zip' | grep -v 'Makefile'` 
# Makefile v4b (@Lopez_lz) 

2.運行makfile創建數據

cd ./topo_map 
make -f ./topo.mk 

3。 D3js &帶自動對焦的HTML代碼:

<!-- language: html --> 
<style> 
svg { border: 5px solid #333; background-color: #C6ECFF;} 

/* TOPO */ 
path.Topo_1 { fill:#ACD0A5; stroke: #0978AB; stroke-width: 1px; } 
path.Topo_50 {fill: #94BF8B; } 
path.Topo_100 {fill: #BDCC96; } 
path.Topo_200 {fill: #E1E4B5; } 
path.Topo_500 {fill: #DED6A3; } 
path.Topo_1000 {fill:#CAB982 ; } 
path.Topo_2000 {fill: #AA8753; } 
path.Topo_3000 {fill: #BAAE9A; } 
path.Topo_4000 {fill: #E0DED8 ; } 
path.Topo_5000 {fill: #FFFFFF ; } 
.download { 
    background: #333; 
    color: #FFF; 
    font-weight: 900; 
    border: 2px solid #B10000; 
    padding: 4px; 
    margin:4px; 
} 
</style> 
<body> 
<script src="http://code.jquery.com/jquery-2.0.2.min.js"></script> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<script src="http://d3js.org/topojson.v1.min.js"></script> 
<script> 
// 1. -------------- SETTINGS ------------- // 
// Geo-frame_borders in decimal ⁰: France 
var WNES = { "W": -5.3, "N":51.6, "E": 10.2, "S": 41.0 }; 

// Geo values of interest : 
var latCenter = (WNES.S + WNES.N)/2, 
    lonCenter = (WNES.W + WNES.E)/2, 
    geo_width = (WNES.E - WNES.W), 
    geo_height= (WNES.N - WNES.S); 
// HTML expected frame dimensions 
var width = 600, 
    height = width * (geo_height/geo_width); 

// Projection: projection, reset scale and translate 
var projection = d3.geo.equirectangular() 
     .scale(1) 
     .translate([0, 0]); 

// SVG injection: 
var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

// Path 
var path = d3.geo.path() 
    .projection(projection) 
    .pointRadius(4); 

// Data (getJSON: TopoJSON) 
d3.json("final.json", showData); 

// 2. ---------- FUNCTION ------------- // 
function showData(error, fra) { 
    var Levels = topojson.feature(fra, fra.objects.levels); 

// Focus area box compute for derive scale & translate. 
// [​[left, bottom], [right, top]​] // E W N S 
var b = path.bounds(Levels), 
    s = 1/Math.max((b[1][0] - b[0][0])/width, (b[1][1] - b[0][1])/height), 
    t = [(width - s * (b[1][0] + b[0][0]))/2, (height - s * (b[1][1] + b[0][1]))/2]; 

// Projection update 
projection 
    .scale(s) 
    .translate(t); 

//Append Topo polygons 
    svg.append("path") 
     .datum(Levels) 
     .attr("d", path) 
    svg.selectAll(".levels") 
     .data(topojson.feature(fra, fra.objects.levels).features) 
     .enter().append("path") 
     .attr("class", function(d) { return "Topo_" + d.properties.name; }) 
     .attr("data-elev", function(d) { return d.properties.name; }) 
     .attr("d", path) 

} 
</script> 
<br /> 
<div> 
    <a class="download ac-icon-download" href="javascript:javascript: (function() { var e = document.createElement('script'); if (window.location.protocol === 'https:') { e.setAttribute('src', 'https://raw.github.com/NYTimes/svg-crowbar/gh-pages/svg-crowbar.js'); } else { e.setAttribute('src', 'http://nytimes.github.com/svg-crowbar/svg-crowbar.js'); } e.setAttribute('class', 'svg-crowbar'); document.body.appendChild(e); })();"><!--⤋--><big>⇩</big> Download</a> -- Works on Chrome. Feedback me for others web browsers ? 
</div> 
<br /> 
</body> 
</html> 

4。結果將是正是這樣:(適用於您感興趣的區域)

enter image description here

如果你出版的地圖(縣)在線請您分享了鏈接:)

注:鼓勵+1歡迎。

+0

要求#軟件:我前一陣子安裝這些軟件,在不同的時間。如果某人得到她/他的手部分或所有'sudo apt-get install'命令來運行,感謝這裏的共享或在線:) – Hugolpz

+0

當我嘗試上面的Makefile時,看到以下錯誤: 'Input文件大小爲21601,10801, 從計算窗口計算的-srcwin 10482 2940 930-635。 錯誤:Computed -srcwin 10482 2940 930 -635具有負寬度和/或高度。 *** [crop.tif]錯誤代碼1' –

+0

'crop.tif:'任務正在失敗。看起來你的寬度和/或高度是負值。此外,請檢查您的'-projwin'值及其在'gdal_translate -projwin -5.3 41.0 10.2 51.6 ETOPO1_Ice_g_geotiff.tif crop.tif'行中的位置。順序是西部,北部,東部,南部邊界,但如果您映射太平洋並穿過[第180子午線](https://en.wikipedia.org/wiki/180th_meridian),則可能需要更改。 – Hugolpz

1

如果有人正在尋找更新,這裏是我今天運行的構建代碼。要求我手動下載.zip文件,並將其移動到topo_map目錄,然後進行一些更改(以粗體顯示):

# topojsoning (USE GEO2TOPO not TOPOJSON): 
final.json: levels.json 
    geo2topo --id-property none --simplify=0.5 -p name=elev -o final.json -- levels.json 
    # simplification approach to explore further. Feedbacks welcome. 

# shp2jsoning: 
levels.json: levels.shp 
    ogr2ogr -f GeoJSON -where "elev < 10000" levels.json levels.shp 

# merge 
levels.shp: level0001.shp level0050.shp level0100.shp level0200.shp level0500.shp level1000.shp level2000.shp level3000.shp level4000.shp level5000.shp 
    ogr2ogr levels.shp level0001.shp 
    ogr2ogr -update -append levels.shp level0050.shp 
    ogr2ogr -update -append levels.shp level0100.shp 
    ogr2ogr -update -append levels.shp level0200.shp 
    ogr2ogr -update -append levels.shp level0500.shp 
    ogr2ogr -update -append levels.shp level1000.shp 
    ogr2ogr -update -append levels.shp level2000.shp 
    ogr2ogr -update -append levels.shp level3000.shp 
    ogr2ogr -update -append levels.shp level4000.shp 
    ogr2ogr -update -append levels.shp level5000.shp 

# Polygonize slices: 
level0001.shp: level0001.tif 
    gdal_polygonize.py level0001.tif -f "ESRI Shapefile" level0001.shp level_0001 elev 
level0050.shp: level0050.tif 
    gdal_polygonize.py level0050.tif -f "ESRI Shapefile" level0050.shp level_0050 elev 
level0100.shp: level0100.tif 
    gdal_polygonize.py level0100.tif -f "ESRI Shapefile" level0100.shp level_0100 elev 
level0200.shp: level0200.tif 
    gdal_polygonize.py level0200.tif -f "ESRI Shapefile" level0200.shp level_0200 elev 
level0500.shp: level0500.tif 
    gdal_polygonize.py level0500.tif -f "ESRI Shapefile" level0500.shp level_0500 elev 
level1000.shp: level1000.tif 
    gdal_polygonize.py level1000.tif -f "ESRI Shapefile" level1000.shp level_1000 elev 
level2000.shp: level2000.tif 
    gdal_polygonize.py level2000.tif -f "ESRI Shapefile" level2000.shp level_2000 elev 
level3000.shp: level3000.tif 
    gdal_polygonize.py level3000.tif -f "ESRI Shapefile" level3000.shp level_3000 elev 
level4000.shp: level4000.tif 
    gdal_polygonize.py level4000.tif -f "ESRI Shapefile" level4000.shp level_4000 elev 
level5000.shp: level5000.tif 
    gdal_polygonize.py level5000.tif -f "ESRI Shapefile" level5000.shp level_5000 elev 

# Raster slicing: 
level0001.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0001.tif --calc="1*(A>0)"  --NoDataValue=0 
level0050.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0050.tif --calc="50*(A>50)"  --NoDataValue=0 
level0100.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0100.tif --calc="100*(A>100)"  --NoDataValue=0 
level0200.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0200.tif --calc="200*(A>200)"  --NoDataValue=0 
level0500.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level0500.tif --calc="500*(A>500)"  --NoDataValue=0 
level1000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level1000.tif --calc="1000*(A>1000)"  --NoDataValue=0 
level2000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level2000.tif --calc="2000*(A>2000)"  --NoDataValue=0 
level3000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level3000.tif --calc="3000*(A>3000)"  --NoDataValue=0 
level4000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level4000.tif --calc="4000*(A>4000)"  --NoDataValue=0 
level5000.tif: crop.tif 
    gdal_calc.py -A crop.tif --outfile=level5000.tif --calc="5000*(A>5000)"  --NoDataValue=0 

# boxing: 
crop.tif: ETOPO1_Ice_g_geotiff.tif 
    gdal_translate -projwin -84.9 47.0 -69.9 33.7 ETOPO1_Ice_g_geotiff.tif crop.tif 
    # ulx uly lrx lry // W N E S <- Coordinate order 
# unzip: 
ETOPO1_Ice_g_geotiff.tif: ETOPO1.zip 
    unzip ETOPO1.zip 
    touch ETOPO1_Ice_g_geotiff.tif 

# download: 
#ETOPO1.zip: 
# curl -o ETOPO1.zip 'http://www.ngdc.noaa.gov/mgg/global/relief/ETOPO1/data/ice_surface/grid_registered/georeferenced_tiff/ETOPO1_Ice_g_geotiff.zip' 

clean: 
    rm `ls | grep -v 'zip' | grep -v 'Makefile'` 
# Makefile v4b (@Lopez_lz) 
+0

謝謝尼克。這些差異在https://www.diffchecker.com/lFTXbr1A中可見。你能否澄清爲什麼你的答案是這些編輯? 至於** CLI命令**'''topojson''' =>''''geo2json''',是否有CLI更改? 對於**下載網址**,理想情況下,只要網址提供失敗,您只需在makefile中找到並更新網址即可。 對於'WSEN''''''WNES''',[gdal_translate手冊](http://gdal.org/gdal_translate.html)似乎證實了我的初始配置。你的工作也可以,因爲gdal很聰明:) – Hugolpz

+0

是的,我會編輯我的迴應以反映變化。有兩個主要的變化是topojson => geo2json和裁剪的座標順序。 –