block by davo f6975e059ecfae21290f

Voronoi CABA

Full Screen

A demonstration of how to calculate the areas of Voronoi regions clipped by geographic features using D3.

[D3’s implementation](Sutherland–Hodgman algorithm) of the Sutherland–Hodgman algorithm only works for convex clip polygons, but we exploit the fact that Voronoi regions are guaranteed to be convex, and use each Voronoi region as a clip polygon, with the projected geographic boundary as a subject polygon.

In response to a question by Gonzalo Bellver.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>
svg {
  fill: white;
}

path {
  stroke-linejoin: round;
}

.points {
  fill: black;
}

.subunit {
  fill: none;
  stroke: #999;
  stroke-size: 1px;
}

.voronoi {
  fill: none;
  fill-opacity: 0.5;
  stroke: white;
  stroke-width: .5px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var width = 960,
    height = 500;

var fill = d3.scale.linear()
    .domain([0, 10000])
    .range(["#F14E2F","#333399","#1DBDFF"]);

var projection = d3.geo.mercator()
    .scale(132000)
    .center([-58.45000,-34.61600]);

var path = d3.geo.path()
    .projection(projection)
    .pointRadius(1.5);

var voronoi = d3.geom.voronoi();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

queue()
    .defer(d3.json, "caba.json")
    .defer(d3.csv, "comisarias.csv")
    .await(ready);

function ready(error, caba, comisarias) {
  var limits = topojson.feature(caba, caba.objects.limites);

  var exterior = projectLineString(limits, projection);

  svg.append("path")
      .datum(limits)
      .attr("class", "limits")
      .attr("d", path);

  svg.append("path")
      .datum(topojson.mesh(caba, caba.objects.barrios))
      .attr("class", "subunit")
      .attr("d", path);

  var coordinates = comisarias.map(function(d) { return [+d.longitude, +d.latitude]; });

  svg.append("path")
      .datum({type: "MultiPoint", coordinates: coordinates})
      .attr("class", "points")
      .attr("d", path);

  svg.append("g")
      .attr("class", "land")
    .selectAll(".voronoi")
      .data(voronoi(coordinates.map(projection)).map(function(d) {
        // Each voronoi region is a convex polygon, therefore we can use
        // d3.geom.polygon.clip, treating each regino as a clip region, with the
        // projected “exterior” as a subject polygon.
        return d3.geom.polygon(d).clip(exterior.slice());
      }))
    .enter().append("path")
      .attr("class", "voronoi")
      .style("fill", function(d) { return fill(Math.abs(d3.geom.polygon(d).area())); })
      .attr("d", polygon);
}

function polygon(d) {
  return "M" + d.join("L") + "Z";
}

// Extracts a single LineString from the given feature, projected (and
// resampled) using the given projection.
function projectLineString(feature, projection) {
  var line;
  d3.geo.stream(feature, projection.stream({
    polygonStart: noop,
    polygonEnd: noop,
    lineStart: function() { line = []; },
    lineEnd: noop,
    point: function(x, y) { line.push([x, y]); },
    sphere: noop
  }));
  return line;
}

function noop() {}

</script>

comisarias.csv

id,nombre,direccion,comuna,barrio,circunscri,longitude,latitude,geojson
1,Comisaría 1,451 LAVALLE,COMUNA 1,SAN NICOLAS,I,-58.3732,-34.6019,"{""type"":""Point"",""coordinates"":[-58.37324,-34.60191]}"
2,Comisaría 2,1050 PERU,COMUNA 1,SAN TELMO,I,-58.374,-34.6202,"{""type"":""Point"",""coordinates"":[-58.37405,-34.62019]}"
3,Comisaría 3,1560 TUCUMAN,COMUNA 1,SAN NICOLAS,I,-58.3889,-34.6019,"{""type"":""Point"",""coordinates"":[-58.3889,-34.60194]}"
4,Comisaría 4,770 TACUARI,COMUNA 1,MONSERRAT,I,-58.3786,-34.6172,"{""type"":""Point"",""coordinates"":[-58.37858,-34.61716]}"
5,Comisaría 5,1958 LAVALLE,COMUNA 3,BALVANERA,II,-58.3948,-34.6034,"{""type"":""Point"",""coordinates"":[-58.39479,-34.60342]}"
6,Comisaría 7,2625 LAVALLE,COMUNA 3,BALVANERA,II,-58.404,-34.6032,"{""type"":""Point"",""coordinates"":[-58.40401,-34.60321]}"
7,Comisaría 9,471 BILLINGHURST,COMUNA 5,ALMAGRO,II,-58.4156,-34.6044,"{""type"":""Point"",""coordinates"":[-58.41556,-34.60443]}"
8,Comisaría 12,1454 VALLE,COMUNA 6,CABALLITO,VI,-58.4481,-34.6268,"{""type"":""Point"",""coordinates"":[-58.44809,-34.62678]}"
9,Comisaría 14,1419 BOLIVAR,COMUNA 1,SAN TELMO,I,-58.3729,-34.6246,"{""type"":""Point"",""coordinates"":[-58.37288,-34.62456]}"
10,Comisaría 15,1156 SUIPACHA,COMUNA 1,RETIRO,III,-58.3802,-34.5946,"{""type"":""Point"",""coordinates"":[-58.38018,-34.59464]}"
11,Comisaría 17,1861 LAS HERAS GRAL.,COMUNA 2,RECOLETA,III,-58.3924,-34.5911,"{""type"":""Point"",""coordinates"":[-58.39236,-34.59114]}"
12,Comisaría 24,456 PINZON,COMUNA 4,BOCA,IV,-58.3606,-34.6342,"{""type"":""Point"",""coordinates"":[-58.36059,-34.63417]}"
13,Comisaría 26,861 MONTES DE OCA MANUEL,COMUNA 4,BARRACAS,IV,-58.3749,-34.6381,"{""type"":""Point"",""coordinates"":[-58.37491,-34.63806]}"
14,Comisaría 28,170 VELEZ SARSFIELD,COMUNA 4,BARRACAS,IV,-58.39,-34.6362,"{""type"":""Point"",""coordinates"":[-58.38997,-34.63617]}"
15,Comisaría 30,1850 CALIFORNIA,COMUNA 4,BARRACAS,IV,-58.3747,-34.6473,"{""type"":""Point"",""coordinates"":[-58.37473,-34.64729]}"
16,Comisaría 32,2724 CASEROS,COMUNA 4,PARQUE PATRICIOS,IV,-58.4008,-34.6365,"{""type"":""Point"",""coordinates"":[-58.40083,-34.63645]}"
17,Comisaría 33,2263 MENDOZA,COMUNA 13,BELGRANO,V,-58.4563,-34.5601,"{""type"":""Point"",""coordinates"":[-58.45628,-34.56014]}"
18,Comisaría 35,3145 CUBA,COMUNA 13,NUÑEZ,VII,-58.4633,-34.5514,"{""type"":""Point"",""coordinates"":[-58.46333,-34.55138]}"
19,Comisaría 36,3405 PEDERNERA,COMUNA 8,VILLA SOLDATI,VIII,-58.432,-34.6604,"{""type"":""Point"",""coordinates"":[-58.43198,-34.66039]}"
20,Comisaría 40,3748 REMEDIOS,COMUNA 9,PARQUE AVELLANEDA,VIII,-58.4763,-34.6415,"{""type"":""Point"",""coordinates"":[-58.47634,-34.64146]}"
21,Comisaría 41,1800 BUFANO ALFREDO R.,COMUNA 11,VILLA GRAL. MITRE,VII,-58.473,-34.6111,"{""type"":""Point"",""coordinates"":[-58.47299,-34.61112]}"
22,Comisaría 42,2343 DE LA TORRE LISANDRO,COMUNA 9,MATADEROS,VIII,-58.5012,-34.662,"{""type"":""Point"",""coordinates"":[-58.50117,-34.66199]}"
23,Comisaría 43,453 CHIVILCOY,COMUNA 10,FLORESTA,VII,-58.4838,-34.6288,"{""type"":""Point"",""coordinates"":[-58.48378,-34.62881]}"
24,Comisaría 47,4254 NAZCA,COMUNA 12,VILLA PUEYRREDON,VII,-58.4994,-34.5897,"{""type"":""Point"",""coordinates"":[-58.49937,-34.58971]}"
25,Comisaría 48,4347 LEGUIZAMON MARTINIANO,COMUNA 8,VILLA LUGANO,VIII,-58.475,-34.679,"{""type"":""Point"",""coordinates"":[-58.47503,-34.67904]}"
26,Comisaría 49,3045 MACHAIN,COMUNA 12,VILLA URQUIZA,VII,-58.4825,-34.5651,"{""type"":""Point"",""coordinates"":[-58.48253,-34.56515]}"
27,Comisaría 45,4154 CUBAS JOSE,COMUNA 11,VILLA DEVOTO,VII,-58.5156,-34.5983,"{""type"":""Point"",""coordinates"":[-58.51561,-34.59831]}"
28,Comisaría 46,2550 DE LOS INMIGRANTES,COMUNA 1,RETIRO,I,-58.3694,-34.5843,"{""type"":""Point"",""coordinates"":[-58.36945,-34.58425]}"
29,Comisaría 19,2844 CHARCAS,COMUNA 2,RECOLETA,III,-58.4067,-34.5941,"{""type"":""Point"",""coordinates"":[-58.40672,-34.59408]}"
30,Comisaría 23,4000 SANTA FE,COMUNA 14,PALERMO,III,-58.4201,-34.5825,"{""type"":""Point"",""coordinates"":[-58.42014,-34.58252]}"
31,Comisaría 25,1350 SCALABRINI ORTIZ RAUL,COMUNA 14,PALERMO,V,-58.4276,-34.5924,"{""type"":""Point"",""coordinates"":[-58.42761,-34.59244]}"
32,Comisaría 31,232 CABILDO,COMUNA 14,PALERMO,V,-58.439,-34.5733,"{""type"":""Point"",""coordinates"":[-58.43896,-34.57331]}"
33,Comisaría 37,4367 JURAMENTO,COMUNA 12,VILLA URQUIZA,V,-58.4758,-34.5731,"{""type"":""Point"",""coordinates"":[-58.47582,-34.57312]}"
34,Comisaría 21,2373 ALVAREZ JULIAN,COMUNA 14,PALERMO,III,-58.4159,-34.5877,"{""type"":""Point"",""coordinates"":[-58.41593,-34.58773]}"
35,Comisaría 8,550 URQUIZA GRAL.,COMUNA 3,BALVANERA,II,-58.4092,-34.6171,"{""type"":""Point"",""coordinates"":[-58.40921,-34.61705]}"
36,Comisaría 6,1931 VENEZUELA,COMUNA 3,BALVANERA,II,-58.3937,-34.6149,"{""type"":""Point"",""coordinates"":[-58.39368,-34.61489]}"
37,Comisaría 10,1250 MUÑIZ,COMUNA 5,BOEDO,VI,-58.4249,-34.6286,"{""type"":""Point"",""coordinates"":[-58.42493,-34.62864]}"
38,Comisaría 13,1548 AVELLANEDA,COMUNA 6,CABALLITO,VI,-58.4532,-34.6204,"{""type"":""Point"",""coordinates"":[-58.45322,-34.62038]}"
39,Comisaría 11,5152 DIAZ VELEZ,COMUNA 6,CABALLITO,VI,-58.4395,-34.609,"{""type"":""Point"",""coordinates"":[-58.4395,-34.60898]}"
40,Comisaría 22,640 HUERGO ING.,COMUNA 1,PUERTO MADERO,I,-58.3666,-34.615,"{""type"":""Point"",""coordinates"":[-58.36659,-34.61497]}"
41,Comisaría 20,1345 CATAMARCA,COMUNA 3,SAN CRISTOBAL,II,-58.4032,-34.626,"{""type"":""Point"",""coordinates"":[-58.40323,-34.62603]}"
42,Comisaría 18,1757 SAN JUAN,COMUNA 1,CONSTITUCION,II,-58.3908,-34.6225,"{""type"":""Point"",""coordinates"":[-58.39081,-34.62251]}"
43,Comisaría 16,1224 SAN JOSE,COMUNA 1,CONSTITUCION,IV,-58.3856,-34.6227,"{""type"":""Point"",""coordinates"":[-58.38561,-34.62267]}"
44,Comisaría 52,CAFAYATE & DIAZ ANA,COMUNA 8,VILLA LUGANO,VIII,-58.4694,-34.6839,"{""type"":""Point"",""coordinates"":[-58.46942,-34.68393]}"
45,Comisaría 27,645 CAMARGO,COMUNA 15,VILLA CRESPO,V,-58.4411,-34.5993,"{""type"":""Point"",""coordinates"":[-58.44108,-34.59932]}"
46,Comisaría 29,4350 DUMONT SANTOS,COMUNA 15,CHACARITA,V,-58.4526,-34.5922,"{""type"":""Point"",""coordinates"":[-58.45263,-34.59216]}"
47,Comisaría 34,456 QUILMES,COMUNA 4,NUEVA POMPEYA,VI,-58.4172,-34.6448,"{""type"":""Point"",""coordinates"":[-58.41716,-34.64479]}"
48,Comisaría 38,258 BONORINO ESTEBAN CNEL.,COMUNA 7,FLORES,VI,-58.4583,-34.6309,"{""type"":""Point"",""coordinates"":[-58.45826,-34.63092]}"
49,Comisaría 39,5437 OLAZABAL,COMUNA 12,VILLA URQUIZA,VII,-58.4901,-34.5787,"{""type"":""Point"",""coordinates"":[-58.49006,-34.57869]}"
50,Comisaría 44,726 PORCEL DE PERALTA MANUEL,COMUNA 10,VERSALLES,VIII,-58.524,-34.6295,"{""type"":""Point"",""coordinates"":[-58.52404,-34.62954]}"
51,Comisaría 50,2738 GAONA,COMUNA 7,FLORES,VI,-58.4648,-34.6161,"{""type"":""Point"",""coordinates"":[-58.46482,-34.61611]}"
52,Comisaría 51,2081 ARTILLEROS,COMUNA 13,BELGRANO,V,-58.4441,-34.5548,"{""type"":""Point"",""coordinates"":[-58.44407,-34.55482]}"
53,Comisaría 53,2961 REPUBLICA ARABE-SIRIA,COMUNA 14,PALERMO,III,-58.4137,-34.5813,"{""type"":""Point"",""coordinates"":[-58.41366,-34.58127]}"