D3js:如何设计地形图? [英] D3js: How to design topographic maps?

查看:253
本文介绍了D3js:如何设计地形图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定具有高程数据的GIS栅格,如何在D3js中设计地形图?



有浮雕/






不工作:我探索了 .tif> gdal_contour.py> .shp> topojson> d3js 未成功。



我(< =较旧的代码,在这里比较SO)



0。要求:




  • 地理区域:在两个文件中编辑一行:makefile#boxing和html#Geo-frame_borders使用你自己的十进制坐标fo W,N,E,S边框,像:



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


  • 软件: make curl unzip gdal (include ogr gdal_calc .py gdal_polygonize.py ), nodejs topojson 。有用:触摸。 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
#简化方法进一步探索。欢迎反馈。

#shp2jsoning:
levels.json:levels.shp
ogr2ogr -f GeoJSON -whereelev< 10000levels.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

#多边形切片:
level0001.shp:level0001.tif
gdal_polygonize.py level0001.tif -fESRI Shapefilelevel0001.shp level_0001 elev
level0050.shp:level0050.tif
gdal_polygonize.py level0050.tif -fESRI Shapefilelevel0050.shp level_0050 elev
level0100.shp:level0100.tif
gdal_polygonize.py level0100.tif -fESRI Shapefilelevel0100.shp level_0100 elev
level0200.shp:level0200.tif
gdal_polygonize.py level0200.tif -fESRI Shapefilelevel0200.shp level_0200 elev
level0500.shp:level0500.tif
gdal_polygonize.py level0500.tif - fESRI Shapefilelevel0500.shp level_0500 elev
level1000.shp:level1000.tif
gdal_polygonize.py level1000.tif -fESRI Shapefilelevel1000.shp level_1000 elev
level2000.shp: level2000.tif
gdal_polygonize.py level2000.tif -fESRI Shapefilelevel2000.shp level_2000 elev
level3000.shp:level3000.tif
gdal_polygonize.py level3000.tif -fESRI Shapefile level3000.shp level_3000 elev
level4000.shp:level4000.tif
gdal_polygonize.py level4000.tif -fESRI Shapefilelevel4000.shp level_4000 elev
level5000.shp:level5000.tif
gdal_polygonize.py level5000.tif -fESRI Shapefilelevel5000.shp level_5000 elev

#光栅切片:
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 - 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 // WSEN

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

#下载:
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;中风:#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 ------------- //
//十进制的地理框架边:France
var WNES = {W:-5.3,N:51.6,E:10.2,S:41.0}

//感兴趣的地理值:
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预期框架尺寸
var width = 600,
height = width *(geo_height / geo_width);

//投影:投影,重置缩放和翻译
var projection = d3.geo.equirectangular()
.scale(1)
.translate ,0]);

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

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

//数据(getJSON:TopoJSON)
d3.json(final.json,showData);

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

//焦点区域盒计算导出比例&翻译。
// [[left,bottom],[right,top]] // EWNS
var b = path.bounds(Levels),
s = 1 / Math.max b [1] [0] -b [0] [0])/ width,(b [1] [1] -b [0] [1] *(b [1] [0] + b [0] [0])/ 2,(height-s *(b [1] [1] + b [0] [1]

//投影更新
投影
.scale(s)
.translate(t);

//附加Topo多边形
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){returnTopo_+ d.properties.name;})
.attr(data-elev,function(d){return d.properties.name ;})
.attr(d,path)

}
< / script>
< br />
< div>
< a class =download ac-icon-downloadhref =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>下载< / a> - 适用于Chrome。反馈我为其他浏览器?
< / div>
< br />
< / body>
< / html>

4。结果将正是这样:(应用于您感兴趣的区域)





如果您在网上发布地图,请分享以下链接:)



注意:鼓励+1欢迎。


Given a GIS raster with elevation data, How to design a topographic map in D3js ?

Is there any example of relief / topographic maps of cropped lands made using D3js ?


Not working: I explored the posibility of .tif > gdal_contour.py > .shp > topojson > d3js without success.

I use a makefile which contain all my commands. As my area of interest (France) is a crop of land areas, the gdal_contour.py approach generates broken isolines which does NOT create closed polygons. Also, the SVG end result fails. The only example of D3 topographic map I know is about Iceland, which, as an island, avoid this issue: cropping the country out of the world doesn't result in broken isolines.

nb: This project is part of the #Wikipedia #wikimaps project.

解决方案

Topographic map now on D3js, with full makefile workflow ! See http://bl.ocks.org/hugolpz/6279966 (<= older code, compare to here on SO)

0. Requirements:

  • Geographic area: You may customize your geographic area of interest by editing one line within each of the 2 files : makefile#boxing and html#Geo-frame_borders with your own decimal coordinates fo W,N,E,S borders, something like:

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

  • Software: make, curl, unzip, gdal (include ogr, gdal_calc.py, gdal_polygonize.py), nodejs, topojson. Helpful: touch. The makefile then manage to download the sources, process them, and output a single topojson file that the D3js code provided can use.

1. Save into folder name: /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. Create data by running the makfile :

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

3. D3js & HTML code with auto-focus:

<!-- 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. Result will be precisely such: (applied to your area of interest)

If you publish map(s) online please share up the link :)

Note: encouraging +1 welcome.

这篇关于D3js:如何设计地形图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆