Skip to content

Instantly share code, notes, and snippets.

@Masoumeh
Last active May 29, 2016 09:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Masoumeh/c498590531bfd378995e7ca8e8b08492 to your computer and use it in GitHub Desktop.
Save Masoumeh/c498590531bfd378995e7ca8e8b08492 to your computer and use it in GitHub Desktop.
Concave Hull on Cornu Data

This is a visualization of concave hull on cornu data. Each set of points regarding their distances shape a concave hull. Using d3 carto map, concave hulls are a new layer (featureLayer) showing the areas shaped with a close set of points.

html,body {
height: 100%;
width: 100%;
}
path,circle,rect,polygon,ellipse,line {
vector-effect: non-scaling-stroke;
}
svg, canvas {
top: 0;
}
#geoMap {
width: 100%;
height: 100%;
position: absolute;
z-index: 0;
}
.pols {
fill: "red";
stroke-width: 2px;
stroke: red;
opacity: 0.6;
}
.buttonContainer {
width: 100%;
margin-top:10px;
float: left;
position: relative;
}
#displayOptionsContainer {
background: white;
overflow: auto;
height: auto;
padding: 5px;
width: auto;
}
#rightControls {
padding: 0 10px 10px;
top: 120px;
right: 15px;
width: 120px;
overflow:auto;
z-index: 100;
}
.controlsDiv {
background: #4C6447;/*rgba(65,64,66,.85);*/
position: fixed;
-webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<link rel="stylesheet"
href="https://rawgit.com/emeeks/abcc82cc61c52fc47b19/raw/61a7ad001f0a3c4323b8b21071d2e749df367519/d3map.css">
<link rel="stylesheet"
href="https://rawgit.com/emeeks/abcc82cc61c52fc47b19/raw/61a7ad001f0a3c4323b8b21071d2e749df367519/example.css">
<link rel="stylesheet" href="index.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.min.js" type="text/javascript"></script>
<script src="http://d3js.org/topojson.v1.min.js" type="text/javascript"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js" type="text/javascript"></script>
<script src="https://rawgit.com/Masoumeh/0390.IbnAhmadMuqaddasi.AhsanTaqasim/master/js/ext_lib/tile.js"
type="text/javascript"></script>
<script src="https://rawgit.com/Masoumeh/0390.IbnAhmadMuqaddasi.AhsanTaqasim/master/js/ext_lib/d3.geom.concaveHull.js"
type="text/javascript"></script>
<script src="index.js" charset="utf-8" type="text/javascript"></script>
</head>
<body onload="make_concave();">
<div style="height: auto; width: auto; right: 15px;" id="rightControls" class="controlsDiv">
<div class="buttonContainer" style="height: auto; width: auto;">
<div id="displayOptionsContainer" class="buttonContainer">
<span style="color:gray;">DISPLAY</span>
</div>
</div>
</div>
<div id="geoMap"></div>
</body>
</html>
function make_concave() {
var svg = d3.select("body").append("svg")
.attr("width", 1000)
.attr("height", 600);
var g = svg.append("g");
map = d3.carto.map();
d3.select("#geoMap").call(map);
map.centerOn([44.361488, 33.312806], "latlong");
map.setScale(4);
map.refresh();
var wcLayer = d3.carto.layer.tile();
wcLayer
.tileType("stamen")
.path("watercolor")
.label("Watercolor")
.visibility(true);
map.addCartoLayer(wcLayer);
var cityLayer = d3.carto.layer.csv();
cityLayer.path("https://rawgit.com/Masoumeh/0390.IbnAhmadMuqaddasi.AhsanTaqasim/master/Data/cornuFiltered.csv")
.label("Cities")
.renderMode("svg")
.x("lon")
.y("lat")
.clickableFeatures(true)
.on("load", function () {
d3.selectAll("circle").transition().duration(1000)
.style("fill", "seagreen")
.attr("r", 2);
d3.csv("https://rawgit.com/Masoumeh/0390.IbnAhmadMuqaddasi.AhsanTaqasim/master/Data/cornu.csv",
mapCities)
});
map.addCartoLayer(cityLayer);
function mapCities(cities) {
var projection = d3.geo.mercator();
colorScale = d3.scale.ordinal().domain(cities.map(function (d) {
return d.region
})).range(["#8dd3c7", "#ffffb3", "#bebada", "#fb8072",
"#80b1d3", "#fdb462", "#b3de69", "#fccde5", "#d9d9d9",
"#bc80bd", "#ccebc5", "#ffed6f"]);
countries = colorScale.domain();
cities.forEach(function (d) {
d.x = projection([d.lon, d.lat])[0];
d.y = projection([d.lon, d.lat])[1];
});
var layer = createConcaveHull(countries, cities, undefined);
var uniqueTopType = {};
cities.forEach(function (f) {
uniqueTopType[f['topType']] = 0;
});
var disOpts = d3.select("#displayOptionsContainer").on("change", function () {
layer = createConcaveHull(countries, cities, layer);
});
Object.keys(uniqueTopType).forEach(function (type) {
topTypeDiv(disOpts, type);
});
}
}
function topTypeDiv(disOpts, type) {
var div = disOpts.append("div")
.style("width", "100%")
.append("div")
.attr("id", function () {
return type;
})
.attr("class", "eyeButton");
var input = div.append("input")
.attr("id",'voronoi-select')
.attr("class", "mode-checkbox")
.attr("name", "display")
.attr("checked", "checked")
.attr("type", "checkbox")
.attr("value", function () {
return type;
})
.on("change", function () {
});
div.append("label")
.attr("for", function () {
return type + "button";
})
.attr("class", "mode-picker-label")
.attr("name", "display")
.html(function () {
return type;
});
}
var selectedTypes = function(identifier) {
return d3.selectAll('#voronoi-select')[0].filter(function(elem) {
return !elem.checked;
}).map(function(elem) {
return elem.value;
});
}
function polygon(d) {
return "M" + d.join("L") + "Z";
}
function createConcaveHull(countries,cities, layer) {
var projection = d3.geo.mercator();
concaveHull = d3.geom.concaveHull();
var all = [];
var vorGeodata = [];
var selected = [];
if(layer !== undefined)
selected = selectedTypes('voronoi-select');
countries.forEach(function (ccode) {
theseCities = cities
.filter(function (d) {
var ret = true;
selected.forEach(function (s) {
if(s === d.topType) {
ret=false;
}
});
return d.region === ccode && ret;
})
.map(function (d) {
return [d.x, d.y]
});
if (theseCities.length > 3) {
var res = concaveHull(theseCities);
var resLatLon = [];
res.forEach(function (r) {
var arr = [];
r.forEach(function (rr) {
arr.push(projection.invert(rr));
});
resLatLon.push(arr);
var vorFeature = {
type: "Feature",
geometry: {
"type": "LineString",
coordinates: arr,
properties: {'region': ccode}
}
};
vorGeodata.push(vorFeature);
});
all.push({'region': ccode, 'pos': resLatLon});
}
});
if(layer !== undefined) {
map.deleteCartoLayer(layer);
}
var farr = d3.carto.layer.featureArray();
farr.features(vorGeodata)
.label("Polygons")
.renderMode("svg")
.cssClass("pols");
//.clickableFeatures(true);
map.addCartoLayer(farr);
d3.selectAll("path").style("fill",function(d){
return colorScale(JSON.stringify(d['geometry']['properties']['region']));
});
return farr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment