score:2

Here's a very simplistic approach. It's the closest any of my attempts at this have come. Leaving it here while hoping someone will come up with something better.

  • Create a throwaway fake geojson-like object purely for calculating the bounds
  • Merge the features arrays of each feature into it
  • Use it to calculate the bounds and adjust the projections once

This feels very clunky though, and I can't find a way to draw one layer at a time with this, I'm resorting to using the throwaway flattened collection to draw the paths.

Also, strangely d3.merge() doesn't seem to work with geojson.features, which is why I'm using Array.concat() instead. Don't understand that one, but this does get it done.

//Width and height
var w = 300;
var h = 200;

//Define map projection
var projection = d3.geoEquirectangular()
  .translate([0, 0])
  .scale(1);

//Define path generator
var path = d3.geoPath()
  .projection(projection);

//Create SVG element
var svg = d3.select("body")
  .append("svg")
  .attr("width", w)
  .attr("height", h);

//Load in GeoJSON data

var json = someUKJSON();

//Create a fake bounds layer
var boundsCollection = {
  type: "FeatureCollection",
  features: []
}

for (var key in json.objects) {
  if (json.objects.hasOwnProperty(key)) {

    // Topojson unpacks one layer at a time
    var layer = json.objects[key];
    var geojson = topojson.feature(json, layer);

  boundsCollection.features = boundsCollection.features.concat( geojson.features );

  };
}


// Calculate bounding box transforms for entire collection
var b = path.bounds(boundsCollection),
  s = .95 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h),
  t = [(w - s * (b[1][0] + b[0][0])) / 2, (h - s * (b[1][1] + b[0][1])) / 2];

// Update the projection    
projection
  .scale(s)
  .translate(t);

    // Bind data and create one path per GeoJSON feature
    svg.selectAll("path")
      .data(boundsCollection.features)
      .enter()
      .append("path")
      .attr("d", path)
      .style("fill", "steelblue");


function someUKJSON() {
  return {
    "type": "Topology",
    "transform": {
      "scale": [0.0034431267161520807, 0.002017902170346754],
      "translate": [-7.8508544159644345, 51.47680014500252]
    },
    "arcs": [
      [
        [1366, 700],
        [-216, -155]
      ],
      [
        [1150, 545],
        [-121, 275],
        [292, 101],
        [45, -221]
      ],
      [
        [1366, 700],
        [23, -449]
      ],
      [
        [1389, 251],
        [-77, -96]
      ],
      [
        [1312, 155],
        [-75, -18]
      ],
      [
        [1237, 137],
        [-62, 17]
      ],
      [
        [1175, 154],
        [-35, 383]
      ],
      [
        [1140, 537],
        [10, 8]
      ],
      [
        [1175, 154],
        [-71, -37]
      ],
      [
        [1104, 117],
        [-314, 73],
        [350, 347]
      ],
      [
        [1237, 137],
        [27, -119]
      ],
      [
        [1264, 18],
        [-35, -18]
      ],
      [
        [1229, 0],
        [-125, 117]
      ],
      [
        [1312, 155],
        [28, -118]
      ],
      [
        [1340, 37],
        [-76, -19]
      ],
      [
        [1385, 12],
        [-45, 25]
      ],
      [
        [1389, 251],
        [-4, -239]
      ],
      [
        [1385, 12],
        [-156, -12]
      ],
      [
        [563, 1572],
        [16, -7]
      ],
      [
        [579, 1565],
        [-55, -14]
      ],
      [
        [524, 1551],
        [39, 21]
      ],
      [
        [397, 1870],
        [166, -298]
      ],
      [
        [524, 1551],
        [-63, -5]
      ],
      [
        [461, 1546],
        [-96, -18]
      ],
      [
        [365, 1528],
        [-109, 10]
      ],
      [
        [256, 1538],
        [35, 290]
      ],
      [
        [291, 1828],
        [106, 42]
      ],
      [
        [574, 1342],
        [-124, 192]
      ],
      [
        [450, 1534],
        [6, 4],
        [5, 8]
      ],
      [
        [579, 1565],
        [-5, -223]
      ],
      [
        [365, 1528],
        [85, 6]
      ],
      [
        [574, 1342],
        [-219, -72],
        [-162, 148]
      ],
      [
        [193, 1418],
        [63, 120]
      ],
      [
        [0, 1515],
        [291, 313]
      ],
      [
        [193, 1418],
        [-193, 97]
      ]
    ],
    "objects": {
      "Wales": {
        "type": "GeometryCollection",
        "geometries": [{
          "arcs": [
            [0, 1]
          ],
          "type": "Polygon",
          "id": "Bedr"
        }, {
          "arcs": [
            [2, 3, 4, 5, 6, 7, -1]
          ],
          "type": "Polygon",
          "id": "Pong"
        }, {
          "arcs": [
            [8, 9, -7]
          ],
          "type": "Polygon",
          "id": "Hyda"
        }, {
          "arcs": [
            [-6, 10, 11, 12, -9]
          ],
          "type": "Polygon",
          "id": "Abwg"
        }, {
          "arcs": [
            [13, 14, -11, -5]
          ],
          "type": "Polygon",
          "id": "Cwaf"
        }, {
          "arcs": [
            [15, -14, -4, 16]
          ],
          "type": "Polygon",
          "id": "Anan"
        }, {
          "arcs": [
            [17, -12, -15, -16]
          ],
          "type": "Polygon",
          "id": "Cave"
        }]
      },
      "nernIrel": {
        "type": "GeometryCollection",
        "geometries": [{
          "arcs": [
            [18, 19, 20]
          ],
          "type": "Polygon",
          "id": "Blft"
        }, {
          "arcs": [
            [21, -21, 22, 23, 24, 25, 26]
          ],
          "type": "Polygon",
          "id": "nern"
        }, {
          "arcs": [
            [27, 28, -23, -20, 29]
          ],
          "type": "Polygon",
          "id": "hern"
        }, {
          "arcs": [
            [30, -28, 31, 32, -25]
          ],
          "type": "Polygon",
          "id": "sorn"
        }, {
          "arcs": [
            [33, -26, -33, 34]
          ],
          "type": "Polygon",
          "id": "wern"
        }]
      }
    }
  };
};
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>


Related Query

More Query from same tag