Skip to content

Instantly share code, notes, and snippets.

@jgaffuri
Last active December 24, 2019 08:19
Show Gist options
  • Save jgaffuri/d0f47a2cd7e386c51e6119ee89bc1378 to your computer and use it in GitHub Desktop.
Save jgaffuri/d0f47a2cd7e386c51e6119ee89bc1378 to your computer and use it in GitHub Desktop.
Coastal margin with JSTS buffer 2
license: EUPL-1.2
height: 800
scrolling: no
border: no

This is an example of Nuts2json API showing European Union countries with D3.js with a coastal margin computed from JSTS buffer function.

<!DOCTYPE html>
<svg></svg>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://d3js.org/d3-request.v1.min.js"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://unpkg.com/jsts@1.6.1/dist/jsts.min.js"></script>
<script>
d3.json("https://raw.githubusercontent.com/eurostat/Nuts2json/master/2016/3035/60M/0.json",
function (error, nuts) {
if (error) throw error;
//prepare SVG element
var width = 900, height = width * (nuts.bbox[3] - nuts.bbox[1]) / (nuts.bbox[2] - nuts.bbox[0]),
svg = d3.select("svg").attr("width", width).attr("height", height),
path = d3.geoPath().projection(d3.geoIdentity()
.reflectY(true).fitSize([width, height], topojson.feature(nuts, nuts.objects.gra)));
//prepare data
var cnts = topojson.feature(nuts, nuts.objects.cntrg).features;
var nutsrg = topojson.feature(nuts, nuts.objects.nutsrg).features;
//some jsts functions
var reader = new jsts.io.GeoJSONReader();
var writer = new jsts.io.GeoJSONWriter();
//build land geometry as a union of all country geometries
//TODO: faster union: use CascadedPolygonUnion
var land;
for (var i = 0; i < cnts.length; i++) land = land ? land.union(reader.read(cnts[i].geometry)) : reader.read(cnts[i].geometry);
for (var i = 0; i < nutsrg.length; i++) land = land ? land.union(reader.read(nutsrg[i].geometry)) : reader.read(nutsrg[i].geometry);
//draw land buffers
for (var i = 1; i >= 0; i -= 0.15) {
var dist = i* 300000;
var col = d3.interpolatePuBu(1 - i);
svg.append("g").append("path").attr("d", path(writer.write(land.buffer(dist))))
.style("fill", "none").style("stroke", col).style("stroke-width", "2px");
}
//draw countries
svg.append("g").selectAll("path").data(cnts)
.enter().append("path").attr("d", path).attr("class", "cntrg");
svg.append("g").selectAll("path").data(nutsrg)
.enter().append("path").attr("d", path).attr("class", "nutsrg");
//draw boundaries
svg.append("g").selectAll("path").data(topojson.feature(nuts, nuts.objects.cntbn).features)
.enter().append("path").attr("d", path)
.attr("class", function (bn) { return "cntbn" + (bn.properties.co === "T" ? " coastal" : ""); });
svg.append("g").selectAll("path").data(topojson.feature(nuts, nuts.objects.nutsbn).features)
.enter().append("path").attr("d", path)
.attr("class", function (bn) {
return "nutsbn" + (bn.properties.co === "T" ? " coastal" : "")
+ ((bn.properties.oth === "T" || bn.properties.lvl == 0) ? " white" : "");
});
});
</script>
.cntrg {
fill: lightgray;
}
.cntrg:hover {
fill: #ffc890;
}
.nutsrg {
fill: #a5a5a5;
}
.nutsrg:hover {
fill: #ff7f00;
}
.cntbn {
fill: none;
stroke-width: 1px;
stroke: white;
}
.nutsbn {
fill: none;
stroke-width: 1px;
stroke: rgb(255, 255, 255);
}
.white { stroke: white; }
.coastal { stroke: #1f78b4; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment