D3js:如何设计地形图? [英] D3js: How to design topographic maps?
问题描述
给定具有高程数据的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
(includeogr
,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
(includeogr
,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屋!