block by nitaku 6622700

GeoJSON squares

Full Screen

A really, really simple example about the usage of GeoJSON and D3’s geo path generators with purely geometrical (non-geographical) data.

It creates a GeoJSON polygon representing a square for each pair of coordinates in the input data, then it packs all polygons in a feature collection. In order to use the path generator, a custom projection is defined, representing the identity (I don’t know if there is a better way to implement that). A feature’s type property is then used to color the rendering.

index.js

(function() {
  var global, new_square;

  global = {
    SIDE: 80
  };

  window.main = function() {
    var colorify, d, data, height, path_generator, squares, svg, width;
    width = 960;
    height = 500;
    svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
    /* create the GeoJSON
    */
    data = [
      {
        i: 1,
        j: 1,
        type: 'A'
      }, {
        i: 4,
        j: 2,
        type: 'B'
      }, {
        i: 3,
        j: 3,
        type: 'C'
      }, {
        i: 3,
        j: 4,
        type: 'C'
      }, {
        i: 3,
        j: 7,
        type: 'B'
      }, {
        i: 2,
        j: 7,
        type: 'D'
      }
    ];
    squares = {
      type: 'FeatureCollection',
      features: (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = data.length; _i < _len; _i++) {
          d = data[_i];
          _results.push(new_square(d));
        }
        return _results;
      })()
    };
    /* define a color scale
    */
    colorify = d3.scale.category10().domain(['A', 'B', 'C', 'D']);
    /* identity projection. see http://bl.ocks.org/mbostock/5663666 for reference
    */
    path_generator = d3.geo.path().projection(d3.geo.transform({
      point: function(x, y) {
        return this.stream.point(x, y);
      }
    }));
    /* draw the result
    */
    return svg.selectAll('.square').data(squares.features).enter().append('path').attr('class', 'square').style('fill', function(d) {
      return colorify(d.properties.type);
    }).attr('d', path_generator);
  };

  /* create a new square
  */

  new_square = function(d) {
    return {
      type: 'Feature',
      geometry: {
        type: 'Polygon',
        coordinates: [[[d.j * global.SIDE, d.i * global.SIDE], [(d.j + 1) * global.SIDE, d.i * global.SIDE], [(d.j + 1) * global.SIDE, (d.i + 1) * global.SIDE], [d.j * global.SIDE, (d.i + 1) * global.SIDE], [d.j * global.SIDE, d.i * global.SIDE]]]
      },
      properties: {
        type: d.type
      }
    };
  };

}).call(this);

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>GeoJSON squares</title>
        <link type="text/css" href="index.css" rel="stylesheet"/>
        <script src="//d3js.org/d3.v3.min.js"></script>
        <script src="index.js"></script>
    </head>
    <body onload="main()"></body>
</html>

index.coffee

global = {
    SIDE: 80
}

window.main = () ->
    width = 960
    height = 500
    
    svg = d3.select('body').append('svg')
        .attr('width', width)
        .attr('height', height)
        
    ### create the GeoJSON ###
    data = [
        {i: 1, j: 1, type: 'A'},
        {i: 4, j: 2, type: 'B'},
        {i: 3, j: 3, type: 'C'},
        {i: 3, j: 4, type: 'C'},
        {i: 3, j: 7, type: 'B'},
        {i: 2, j: 7, type: 'D'}
    ]
    
    squares = {
        type: 'FeatureCollection',
        features: (new_square(d) for d in data)
    }
    
    ### define a color scale ###
    colorify = d3.scale.category10()
        .domain(['A','B','C','D'])
        
    ### identity projection. see http://bl.ocks.org/mbostock/5663666 for reference ###
    path_generator = d3.geo.path()
        .projection d3.geo.transform({point: (x,y) -> this.stream.point(x,y) })
        
    ### draw the result ###
    svg.selectAll('.square')
        .data(squares.features)
      .enter().append('path')
        .attr('class', 'square')
        .style('fill', (d) -> colorify(d.properties.type))
        .attr('d', path_generator)
        
### create a new square ###
new_square = (d) ->
    return {
        type: 'Feature',
        geometry: {
            type: 'Polygon',
            coordinates: [[
                [d.j*global.SIDE, d.i*global.SIDE],
                [(d.j+1)*global.SIDE, d.i*global.SIDE],
                [(d.j+1)*global.SIDE, (d.i+1)*global.SIDE],
                [d.j*global.SIDE, (d.i+1)*global.SIDE],
                [d.j*global.SIDE, d.i*global.SIDE]
            ]]
        },
        properties: {
            type: d.type
        }
    }
    

index.css

.square {
  stroke: black;
  stroke-width: 2;
}

index.sass

.square
    stroke: black
    stroke-width: 2