Skip to content

Instantly share code, notes, and snippets.

@nitaku
Last active December 23, 2015 10:39
Show Gist options
  • Save nitaku/6622700 to your computer and use it in GitHub Desktop.
Save nitaku/6622700 to your computer and use it in GitHub Desktop.
GeoJSON squares

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.

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
}
}
.square {
stroke: black;
stroke-width: 2;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>GeoJSON squares</title>
<link type="text/css" href="index.css" rel="stylesheet"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="index.js"></script>
</head>
<body onload="main()"></body>
</html>
(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);
.square
stroke: black
stroke-width: 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment