2013-08-18 11 views
8

標高データを持つGISラスタを指定すると、D3jsで地形図をデザインする方法は?D3js:地形図のデザイン方法は?

D3jsを使用して切り取った土地の救済/地形図の例はありますか?


に動作していない:私は成功せず.tif > gdal_contour.py > .shp > topojson > d3jsの働かを検討しました。

I use a makefileすべてのmyコマンドが含まれています。関心領域(フランス)が土地の一部であるため、gdal_contour.pyアプローチでは、閉じたポリゴンを作成しない壊れた等値線が生成されます。また、SVGの最終結果は失敗します。 D3の地形図の唯一の例は私が島として、この問題を避けるis about Icelandを知っています。国を世界から切り取っても、孤立線が壊れることはありません。

enter image description here

NB:このプロジェクトは、#Wikipedia #wikimapsプロジェクトの一部です。

答えて

20

メイクファイルのフルワークフローを備えたD3jsの地形図! (SO上でここに比較し、< =古いコード)http://bl.ocks.org/hugolpz/6279966を参照してください

0要件:

  • 地理的エリア:あなたはそれぞれの中で1行を編集することで、興味のある地理的エリアをカスタマイズすることあなたの小数点座標をW、N、E、Sのボーダーのような、makefile#boxingとhtml#Geo-frame_bordersのようなものがあります:

    var WNES = {"target": "France"、 "W" ":-5.3、" N ":51.6、" E ":10.2、" S ":41.0}

  • ソフトウェア:makecurlunzipgdalnodejstopojsonogrgdal_calc.pygdal_polygonize.pyが含まれます)。役に立つ:touch。メークファイルは、ソースをダウンロードして処理し、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

要件:手動で、その後(太字で記載)いくつかの変更を.zipファイルをダウンロードし、topo_mapディレクトリに移動し、ために私を必要と私は別の回で、しばらく前にこれらのソフトウェアをインストールしました。誰かが 'sudo apt-get install'コマンドの一部または全部を手に入れて、ここやオンラインで共有してくれてありがとうございました:) – Hugolpz

+0

上記のMakefileを試してみると、次のエラーが表示されます: ' Inputファイルサイズは21601,10801 です。投影されたウィンドウから計算された-rcwin 10482 2940 930 -635です。 エラー:計算された-rcwin 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

誰かがアップデートをお探しの場合は、ここから今日実行しているビルドコードをご覧ください。 #ソフト

# 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の変更はありましたか? ** download url **の場合、提供されたURLが失敗したときはいつでも、makefile内のurlを見つけて更新するだけです。 '' 'WSEN''' =>' '' WNES'''については、[gdal_translate manual](http://gdal.org/gdal_translate.html)が私の初期設定を確認しているようです。 gdalはスマートなので、あなたもうまくいくかもしれません:) – Hugolpz

+0

変更を反映するように私の回答を編集します。 topojson => geo2jsonとクロッピングの座標順序の2つの主な変更点があります。 –

関連する問題