D3 & TopoJSON sample for Austria.
see Let's Make a Map and Why Use Make by Mike Bostock
D3 & TopoJSON sample for Austria.
see Let's Make a Map and Why Use Make by Mike Bostock
| #import datetime | |
| #from mx import DateTime | |
| from dbfpy import dbf | |
| def dbfview(fname,n=1): | |
| try: | |
| db = dbf.Dbf(fname) | |
| print '#'*70 | |
| print 'Sample record(s) read from {0}'.format(fname) | |
| print '#'*70 | |
| for idx,rec in enumerate(db): | |
| if idx<(n): | |
| print '='*55 | |
| print 'Record #{0}'.format(idx) | |
| print '='*55 | |
| print rec | |
| print "Dataset contains {0} entries.".format(idx+1) | |
| except Exception as e: | |
| print "{0} failed on {1} with Exception {2}".format(__file__,fname,e) | |
| class nOptionError(Exception): | |
| def __str__(): | |
| return "-n requires an integer argument greater zero" | |
| if __name__=="__main__": | |
| from sys import argv | |
| n = 1 | |
| foundn = False | |
| if len(argv)<2: | |
| print 'No files given.' | |
| else: | |
| args = [] | |
| for idx,arg in enumerate(argv[1:]): | |
| if arg == "-n": | |
| try: | |
| n = int(argv[idx+2]) | |
| foundn = True | |
| except IndexError: | |
| raise nOptionError() | |
| except ValueError: | |
| raise nOptionError() | |
| elif foundn: | |
| foundn = False | |
| else: | |
| args.append(arg) | |
| for f in args: | |
| dbfview(f,n) | |
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| .subunit.AUT { fill: #dcd; } | |
| .place, | |
| .place-label { | |
| fill: #444; | |
| } | |
| text { | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| font-size: 10px; | |
| pointer-events: none; | |
| } | |
| .subunit-boundary { | |
| fill: none; | |
| stroke: #777; | |
| stroke-dasharray: 2,2; | |
| stroke-linejoin: round; | |
| } | |
| .subunit-label { | |
| fill: #777; | |
| fill-opacity: .5; | |
| font-size: 20px; | |
| font-weight: 300; | |
| text-anchor: middle; | |
| } | |
| </style> | |
| <body> | |
| <h4>Passau lies in Austria</h4> | |
| well, actually <a href=http://www.naturalearthdata.com/corrections/ticket.php?track=PHYUJ1VZWW>it doesn't</a>. | |
| <p> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script src="http://d3js.org/topojson.v1.min.js"></script> | |
| <script> | |
| var width = 960, | |
| height = 1160; | |
| var projection = d3.geo.albers() | |
| .center([0, 45.5]) | |
| .rotate([-13.8, 0]) | |
| .parallels([40, 50]) | |
| .scale(9000) | |
| .translate([width / 2, height / 2]); | |
| var path = d3.geo.path() | |
| .projection(projection) | |
| .pointRadius(2); | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| d3.json("aut.json", function(error, aut) { | |
| //console.log(aut); | |
| svg.selectAll(".subunit") | |
| .data(topojson.feature(aut, aut.objects.subunits).features) | |
| .enter().append("path") | |
| .attr("class", function(d) { | |
| return "subunit " + d.id; | |
| }) | |
| .attr("d", path); | |
| svg.append("path") | |
| .datum(topojson.feature(aut, aut.objects.places)) | |
| .attr("d", path) | |
| .attr("class", "place"); | |
| svg.selectAll(".place-label") | |
| .data(topojson.feature(aut, aut.objects.places).features) | |
| .enter().append("text") | |
| .attr("class", "place-label") | |
| .attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; }) | |
| .attr("dy", ".35em") | |
| .text(function(d) { return d.properties.name; }); | |
| svg.selectAll(".place-label") | |
| .attr("x", function(d) { return d.geometry.coordinates[0] > 16.3 ? 6 : -6; }) | |
| .style("text-anchor", function(d) { return d.geometry.coordinates[0] > 16.3 ? "start" : "end"; }); | |
| svg.selectAll(".subunit-label") | |
| .data(topojson.feature(aut, aut.objects.subunits).features) | |
| .enter().append("text") | |
| .attr("class", function(d) { return "subunit-label " + d.id; }) | |
| .attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; }) | |
| .attr("dy", ".35em") | |
| .text(function(d) { return d.properties.name; }); | |
| }); | |
| </script> | |
| </body> |
| aut.json: subunits.json places.json | |
| topojson --id-property SU_A3 -p name=NAME -o aut.json subunits.json places.json | |
| underscore -i aut.json print > aut.pp.json | |
| subunits.json: ne_10m_admin_0_map_subunits.shp | |
| rm subunits.json | |
| ogr2ogr -f GeoJSON -where "adm0_a3 IN ('AUT')" -s_srs ne_10m_admin_0_map_subunits.prj -t_srs EPSG:4326 subunits.json ne_10m_admin_0_map_subunits.shp | |
| touch samples.dbf | |
| places.json: ne_10m_populated_places.shp | |
| rm places.json | |
| ogr2ogr -f GeoJSON -where "iso_a2 = 'AT'" -s_srs ne_10m_populated_places.prj -t_srs EPSG:4326 places.json ne_10m_populated_places.shp | |
| touch samples.dbf | |
| samples.txt: samples.dbf | |
| python /Users/georg/work/d3js//d3_samples/d/dbfview.py -n 100000 ne_10m_populated_places.dbf > samples.places.dbf.txt | |
| python /Users/georg/work/d3js//d3_samples/d/dbfview.py -n 100000 ne_10m_admin_0_map_subunits.dbf > samples.sub.dbf.txt | |
| ne_10m_admin_0_map_subunits.shp: subunits.zip | |
| unzip subunits.zip | |
| touch ne_10m_admin_0_map_subunits.shp | |
| ne_10m_populated_places.shp: places.zip | |
| unzip places.zip | |
| touch ne_10m_populated_places.shp | |
| subunits.zip: | |
| curl -o subunits.zip 'http://www.nacis.org/naturalearth/10m/cultural/ne_10m_admin_0_map_subunits.zip' | |
| places.zip: | |
| curl -o places.zip 'http://www.nacis.org/naturalearth/10m/cultural/ne_10m_populated_places.zip' | |
| clean: | |
| rm *.json |