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.
Last active
May 29, 2016 09:33
-
-
Save Masoumeh/c498590531bfd378995e7ca8e8b08492 to your computer and use it in GitHub Desktop.
Concave Hull on Cornu Data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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