Step 2: Topographic map. final_topo_France.json (topojson) created using makefile.
Attempt to programmatically generate geolocalized France_location_map.svg (focus: France, type: location map, geolocalised yet light, printable) following existing Wikipedia’s guidelines.
Meta: v13.08.22. Makefile: Make4b. Focus: France. Type: topographic_map.
With: countries (L0), subdivisions (L1), places (major cities). Labels for L1 & places.
This code is part of the Wikimaps team push for better wikipedia maps. An efforts for both GIS data collection and map generation for the purpose of encyclopedic cartography and free knowledge.
Sources:
1a. Base idea and tutorial: Let’s Make a Map by Mike Bostock
1b. In practice (shorter) : Making a map of germany with topojson
2a. Base introduction to Makefile Why Use Make by Mike Bostock
2b. In practice (shorter): Austria D3 TopoJSON
3a. wikimaps’ stylesheets: Wikipedia:WikiProject_Maps/Conventions
Interesting: Creating and Publishing Maps with D3, Dymo, and PhantomJS, ISO_3166-2
TODO: Conditional borders and coastlines : http://bost.ocks.org/mike/map/#displaying-boundaries
<!DOCTYPE html>
<!-- //bost.ocks.org/mike/map/-->
<meta charset="utf-8">
v. 08/13:12:30am. Last version on codio.com
<style>
svg { border: 5px solid #646464; background-color: #C6ECFF;}
path.L0 { fill:#E0E0E0;}
path.L1 { fill:#FEFEE9;}
path.L1:hover { fill: #B10000 ;}
.red { border: 5px solid red;} /* Class for tests */
.subunit-boundary {
fill: none;
stroke-width:1px;
stroke: #646464;
/* stroke-dasharray: 2,2; */
stroke-linejoin: round;
}
.place,
.place-label {
fill: #444;
font-size:4px;
}
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 6px;
pointer-events: none;
}
.subunit-label {
fill: #777;
fill-opacity: .5;
font-size: 11px;
font-weight: 200;
text-anchor: middle;
}
</style>
<body>
<script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v0.min.js"></script>
<script>
// -------------- SETTINGS ------------- //
// HTML frame: dimensions & colors
var width = 525,
height = 525,
color = d3.scale.category10(); // d3.scale.ordinal().domain(["000000", "FFFFFF", "baz"]).range(colorbrewer.RdBu[9]);
// Projection: New projection, center coord, scale(?):
var projection = d3.geo.mercator()
.center([2.2, 46.4]) // jap: [139, 35.4]
.scale(2000) // behavioral definition welcome
.translate([width / 2, height / 2]); //??
// 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("fra.json", showData);
// ---------- FUNCTION ------------- //
function showData(error, fra) {
// var #Coord: projection formerly here
// var #Path: formerly here
var countries = topojson.object(fra, fra.objects.countries)
subunits = topojson.object(fra, fra.objects.subunits),
neighbors = topojson.neighbors(fra.objects.subunits.geometries); // coloring: full line
//Append L0 polygons
svg.append("path")
.datum(countries)
.attr("d", path)
svg.selectAll(".countries")
.data(topojson.object(fra, fra.objects.countries).geometries)
.enter().append("path")
.attr("class", function(d) { return "L0 " + d.properties.name; })
.attr("d", path)
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: full line
.on("click", click);
//Append L1 polygons
svg.append("path")
.datum(subunits)
.attr("d", path)
svg.selectAll(".subunit")
.data(topojson.object(fra, fra.objects.subunits).geometries)
.enter().append("path")
.attr("class", function(d) { return "L1 " + d.properties.name; })
.attr("d", path)
//.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return subunits[n].color; }) + 1 | 0); }) // coloring: full line
.on("click", click);
// Function Click > Console
function click(a){
console.log(a.properties.name);}
//Append [what that !!!?]
svg.append("path")
.datum(topojson.mesh(fra, fra.objects.subunits, function(a,b) { if (a!==b || a.properties.name === "Berlin"|| a.properties.name === "Bremen"){var ret = a;}return ret;}))
.attr("d", path)
.attr("class", "subunit-boundary");
// Append [??]
svg.append("path")
.datum(topojson.object(fra, fra.objects.places))
.attr("d", path)
.attr("class", "place");
// Positioning: place-label
svg.selectAll(".place-label")
.data(topojson.object(fra, fra.objects.places).geometries)
.enter().append("text")
.attr("class", "place-label")
.attr("transform", function(d) { return "translate(" + projection(d.coordinates) + ")"; })
.attr("dy", ".35em")
.text(function(d) { if (d.properties.name!=="Paris"&&d.properties.name!=="Bremen"){return d.properties.name;} })
.attr("x", function(d) { return d.coordinates[0] > -1 ? 6 : -6; })
.style("text-anchor", function(d) { return d.coordinates[0] > -1 ? "start" : "end"; });
// Positioning: subunit-label
svg.selectAll(".subunit-label")
.data(topojson.object(fra, fra.objects.subunits).geometries)
.enter().append("text")
.attr("class", function(d) { return "subunit-label " + d.properties.name; })
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
// Vertical adjustment: Champagne-Ardenne-- Languedoc-Roussillon-- Haute-Normandie- Loraine++ Île-de-france 0.5em franche-Comté-1.0em Limousin -1.0
.attr("dy", function(d){
if(d.properties.name==="Champagne-Arfranne"||d.properties.name==="Languedoc-Roussillon" || d.properties.name==="Limousin" )
{return "1.5em"}
else if(d.properties.name==="Haute-Normandie" )
{return ".5em"}
else if(d.properties.name==="Loraine"|| d.properties.name==="france-Comté")
{return "-1.5em"}
else if(d.properties.name==="Île-de-france" )
{return "-.5em"}
else{return ".2em"}}) // frafault
.text(function(d) { return d.properties.name; });
}
</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', '//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>
fra.json: countries.json subunits.json places.json
topojson --id-property none -p name=name -p name=NAME -o fra0813b.json -- countries.json subunits.json places.json
### FILES FILTERS & 2JSON
countries.json: ne_10m_admin_0_sovereignty.shp
ogr2ogr -f GeoJSON -where "admin IN ('Spain', 'Italy', 'Andorra', 'Switzerland', 'Belgium', 'Netherlands', 'Luxembourg', 'Germany', 'United Kingdom')" countries.json ne_10m_admin_0_sovereignty.shp
subunits.json: ne_10m_admin_1_states_provinces_shp
ogr2ogr -f GeoJSON -where "admin IN ('France')" subunits.json ne_10m_admin_1_states_provinces_shp.shp
places.json: ne_10m_populated_places.shp
ogr2ogr -f GeoJSON -where "ADM0NAME = 'France' OR SOV0NAME = 'French Republic' OR ISO_A2 = 'FR' AND FEATURECLA = 'Admin-1 region capital'" places.json ne_10m_populated_places.shp
#or "iso_a2 = 'AT' AND SCALERANK < 20" , see also sr_adm0_a3
### FILES UNZIP:
ne_10m_admin_0_sovereignty.shp: countries.zip
unzip countries.zip
touch ne_10m_admin_0_sovereignty.shp
ne_10m_admin_1_states_provinces_shp: subunits.zip
unzip subunits.zip
touch ne_10m_admin_1_states_provinces_shp.shp
ne_10m_populated_places.shp: places.zip
unzip places.zip
touch ne_10m_populated_places.shp
### FILES DOWNLOAD:
countries.zip:
curl -L -o countries.zip 'http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_0_sovereignty.zip'
# http://www.nacis.org/naturalearth/10m/cultural/ne_10m_admin_0_map_subunits.zip
subunits.zip:
curl -L -o subunits.zip 'http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/10m/cultural/ne_10m_admin_1_states_provinces_shp.zip'
places.zip:
curl -o places.zip 'http://www.nacis.org/naturalearth/10m/cultural/ne_10m_populated_places.zip'
clean:
rm `ls | grep -v 'zip' | grep -v 'Makefile' `