block by hugolpz 6364683

India_location_map-en (Wikipedia style + provinces names)

Full Screen

Step 3: Location maps. India’s topojson created using makefile.

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.

Meta: v13.08.28. Makefile: Make2/data. Focus: India. Type: location_map.

With: Auto-focus. Wikipedia styles : polygons and conditional boundaries. Download button. Provinces name for fun.

Sources & thanks:

  1. Mike Bostock: Why Use Make

  2. Eidmanna: Austria D3 TopoJSON (makefile in action)

  3. Wikipedia maps’ guidelines: Wikipedia:WikiProject_Maps/Conventions

To do: add water bodies.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg { border: 5px solid #646464; background-color: #C6ECFF;}
path.L0 { fill:#E0E0E0;}
path.L1 { fill:#FEFEE9;}
path.invisible,text.invisible { fill:none;stroke:none; visibility:none;}

path.L1:hover { fill: #B10000 ;}
.red { border: 5px solid red;} /* Class for tests */
.Topo_50 { border: green; fill:purple; }
.subunit-boundary {
  fill: none;
  stroke-width:1px;
  stroke: #646464;
  /* stroke-dasharray: 10,3,3,3; */
  stroke-linejoin: round;
}
.international-boundary {
  fill: none;
  stroke-width:2px;
  stroke: #646464;
  stroke-dasharray: 16,4,3,4;
  stroke-linejoin: round;  
}
.place,
.place-label {
  fill: #444;
  font-size:12px;
}
.coastline {fill: none; stroke:#0978AB;}
text {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  pointer-events: none;
}
.subunit-label {
  fill: #777;
  fill-opacity: .5;
  font-weight: 900;
  text-anchor: middle;
  font-size: 14px;
}
.download { background: #333; color: #FFF; font-weight: 900; border: 2px solid #B10000; padding: 4px; margin:4px;}

</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.v1.min.js"></script>
<script>
// 1. -------------- SETTINGS ------------- //
// India geo-frame borders in decimal ⁰
var WNES = { "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0, "vert_%": 106, "item":"India" },
	target =WNES.item;
// Function Click > Console
    function click(a){ var name = a.properties.name || a.id ; console.log(name);}
// var WNES = { "W": -5.8, "N":51.5, "E": 10, "S": 41.0, "vert_%": 140, "stone":"France" };

// 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 Stoneme dimensions
var width  = 600,
    height = width * (geo_height / geo_width); 

// var color = d3.scale.category10(); // d3.scale.ordinal().domain(["000000", "FFFFFF", "baz"]).range(colorbrewer.RdBu[9]);


// 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);

//Pattern injection : disputed-in, disputed-out
var pattern = svg.append("defs")
	.append("pattern")
		.attr({ id:"hash2_4", width:"6", height:"6", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
	.append("rect")
		.attr({ width:"2", height:"6", transform:"translate(0,0)", fill:"#E0E0E0" });
 var pattern = svg.append("defs")
	.append("pattern")
		.attr({ id:"hash4_2", width:"6", height:"6", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
	.append("rect")
		.attr({ width:"2", height:"6", transform:"translate(0,0)", fill:"#FEFEE9" });
 
// Path
var path = d3.geo.path()
    .projection(projection)
    .pointRadius(4);
    
 
// Data (getJSON: TopoJSON)
d3.json("./administrative.topo.json", showData);
 
// ---------- FUNCTION ------------- //
function showData(error, Stone) {
 
// var #Coord: projection formerly here
 
// var #Path: formerly here
    var countries = topojson.feature(Stone, Stone.objects.admin_0),
        subunits = topojson.feature(Stone, Stone.objects.admin_1),
        disputed = topojson.feature(Stone, Stone.objects.disputed),
        places = topojson.feature(Stone, Stone.objects.places),
        neighbors = topojson.neighbors(Stone.objects.admin_1.geometries); // coloring: full line

// Focus area box compute for derive scale & translate.
// [​[left, bottom], [right, top]​] // E   W    N   S
var b = path.bounds(countries),
    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 = projection
    .scale(s)
    .translate(t);

/* Polygons ********************************************* */
//Append L0 polygons 
    svg.selectAll(".countries")
        .data(countries.features)
      .enter().append("path")
        .attr("class", "L0")
		.attr({fill:"url(#hash4_4);"})
        .attr("data-name-en", function(d) { return d.properties.id; })
        .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: fill
        .on("click", click);
 
//Append L1 polygons 
    svg.selectAll(".subunit")
        .data(subunits.features)
      .enter().append("path")
        .attr("class", function(d){ return d.properties.L0 === target? "L1": "L1 invisible"; } )
        .attr("data-name-en", function(d) { return d.id; })
        .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: fill
        .on("click", click);
	
 //Append disputed polygons 
    svg.selectAll(".disputed")
        .data(disputed.features)
      .enter().append("path")
        .attr("class", function(d){ return d.properties.L0 === target? "disputed in": "disputed out"; } )
        .attr("fill", function(d){ return d.properties.L0 === target? "url(#hash2_4)": "url(#hash4_2)"} )
		.attr("data-name-en", function(d) { return d.id; })
        .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: fill
        .on("click", click);
 

/* Arcs ************************************************* */
// Admin1-borders filtered
    svg.append("path")
        .datum(topojson.mesh(Stone, Stone.objects.admin_1, function(a,b) { return a !==b && a.properties.L0 === b.properties.L0 && a.properties.L0 === target ;}))
        .attr("d", path)
        .attr("class", "subunit-boundary");

// Admin0-borders filtered
    svg.append("path")
        .datum(topojson.mesh(Stone, Stone.objects.admin_0, function(a,b) { return a!==b;}))
        .attr("d", path)
        .attr("class", "international-boundary");

// Coast-borders filtered
    svg.append("path")
        .datum(topojson.mesh(Stone, Stone.objects.admin_0, function(a,b) { return a===b;}))
        .attr("d", path)
        .attr("class", "coastline");

/* DOT & LABELS ******************************************* */
// Places: dot placement ********************************** */
    svg.append("path")
        .datum(places)
        .attr("d", path)
        .attr("class", "place");
// Places label placement
    svg.selectAll(".place-label")
        .data(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.id;} )
        .attr("x",              function(d) { return d.geometry.coordinates[0] > -1 ? 6 : -6; })
        .style("text-anchor",   function(d) { return d.geometry.coordinates[0] > -1 ? "start" : "end"; });

/* L1 labels ******************************************** */
    svg.selectAll(".subunit-label")
        .data(subunits.features)
      .enter().append("text")
        .attr("class", function(d){ return d.properties.L0 === target? "subunit-label": "subunit-label invisible"; } )
        .attr("data-name-en", function(d) { return d.properties.id ;})
        .attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
        // Vertical adjustment custom: 
        .attr("dy", function(d){ 
            if(d.id==="Delhi"|| d.id==="2nd capital" ){return ".5em"}
            else{return ".2em"}}) // default
        // Vertical adjustment custom: 
        .attr("font-size", function(d){ 
            if(d.id==="Delhi"|| d.id==="2nd capital" ){return "1.2"}
            else{return "6px"} }) // default
        .text(function(d) { return d.id; });
}
</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 welcome for others web browsers.
</div>
<br />
</body>
</html>