Skip to content

Instantly share code, notes, and snippets.

@mohdali
Last active May 2, 2022 22:53
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mohdali/662bf79127f6e068ed6815c06f92bfb5 to your computer and use it in GitHub Desktop.
Save mohdali/662bf79127f6e068ed6815c06f92bfb5 to your computer and use it in GitHub Desktop.
Egypt Governates
license: mit
height: 600

A simple map of Egypt governates using Natural Earth data.

GDAL library is used to extract shape data. Then toplogy is created using TopoJson cli.

Convert Shape files to GeoJSON using shp2json, d3-geo-projection and ndjson-cli

shp2json -n ne_10m_admin_1_states_provinces\ne_10m_admin_1_states_provinces.shp /
    | ndjson-filter "d.properties.admin =='Egypt' && d.properties.name != null" /
    | ndjson-map "d.id = d.properties.adm1_code, d" | ndjson-reduce /
    | ndjson-map "{type: 'FeatureCollection', features: d}" >governate.json
shp2json ne_10m_ocean\ne_10m_ocean.shp | geoproject "d3.geoIdentity().clipExtent([[24.7100, 21.9900],[36.9000, 31.6500]])" /
    | ndjson-split "d.features" | ndjson-filter "d.geometry != null" /
    | ndjson-reduce | ndjson-map "{type: 'FeatureCollection', features: d}"> ocean.json
shp2json ne_10m_lakes\ne_10m_lakes.shp | geoproject "d3.geoIdentity().clipExtent([[24.7100, 21.9900],[36.9000, 31.6500]])" /
    | ndjson-split "d.features" | ndjson-filter "d.geometry != null" /
    | ndjson-reduce | ndjson-map "{type: 'FeatureCollection', features: d}"> lakes.json
shp2json ne_10m_rivers_lake_centerlines\ne_10m_rivers_lake_centerlines.shp /
    | geoproject "d3.geoIdentity().clipExtent([[24.7100, 21.9900],[36.9000, 31.6500]])" /
    | ndjson-split "d.features" | ndjson-filter "d.geometry != null" /
    | ndjson-reduce | ndjson-map "{type: 'FeatureCollection', features: d}"> rivers.json

Merge using TopoJSON

geo2topo governate.json ocean.json lakes.json rivers.json> egypt.json
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Egypt</title>
<script src="https://d3js.org/d3.v4.min.js" type="text/javascript"></script>
<script src="https://unpkg.com/topojson@3" type="text/javascript"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" type="text/javascript"></script>
<style type="text/css">
body {
font: 10px Tahoma, sans-serif;
}
svg {
font: 10px sans-serif;
}
#map {
float: left;
}
path.land {
fill: GhostWhite;
}
path.ocean {
fill: DeepSkyBlue;
}
path.river {
fill: none;
stroke: DeepSkyBlue;
}
path.governate {
fill-opacity: .5;
fill: #ccc;
stroke: white;
cursor: pointer;
}
path.governate.selected {
fill-opacity: .9;
}
path.governate.pinned {
fill: YellowGreen;
fill-opacity: .75;
}
li {
cursor: pointer;
background-color: steelBlue;
padding: 3px 5px;
margin: 1px;
color: white;
font-size: 12px;
display: inline-block;
}
li.selected {
background-color: #ccc;
}
li.pinned {
background-color: YellowGreen;
color: black;
}
</style>
</head>
<body>
<div class="container">
<div id="map"></div>
<div id="list"></div>
<button id="reset">Reset</button>
</div>
<script type="text/javascript">
var width = 620,
height = 600;
var zoom = d3.zoom()
.translateExtent([[0, 0], [width, height]])
.scaleExtent([1, 10]);
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(zoom.on("zoom", zoomed));
var controls = d3.select('svg').append("g")
.attr("width", 200)
.attr("height", height)
.attr("transform", "translate(50,50)");
var z = d3.scaleLinear()
.domain([1, 10])
.range([0, 150]);
var zoomAxis = d3.axisRight().scale(z);
var zoomCursor = controls.append("g")
.attr("transform", "translate(0," + z(1) + ")");;
var list = d3.select("#list").append("ul");
d3.json("egypt.json", function (error, egypt) {
var governate = topojson.feature(egypt, egypt.objects.governate);
var projection = d3.geoMercator()
.fitSize([width, height], governate);
var path = d3.geoPath()
.projection(projection);
svg.selectAll(".governate")
.data(governate.features)
.enter().append("path")
.attr("class", function (d) { return "governate " + d.id; })
.attr("d", path)
.on("mouseover", select)
.on("mouseout", unselect)
.on("click", click)
.append("title")
.text(function (d) { return d.properties.name; });
svg.selectAll(".river")
.data(topojson.feature(egypt, egypt.objects.rivers).features)
.enter().append("path")
.attr("class", "river")
.attr("d", path)
.attr("stroke-width", function (d) {
return 1 / d.properties.scalerank;
})
.append("title")
.text(function (d) { return d.properties.name; });
svg.append("path")
.datum(topojson.feature(egypt, egypt.objects.ocean))
.attr("class", "ocean")
.attr("d", path);
svg.append("path")
.datum(topojson.feature(egypt, egypt.objects.lakes))
.attr("class", "ocean")
.attr("d", path);
list.selectAll("li")
.data(topojson.feature(egypt, egypt.objects.governate).features)
.enter().append("li")
.text(function (d) { return d.properties.name; })
.on("mouseover", select)
.on("mouseout", unselect)
.on("click", click);
zoomCursor.append("path")
.attr("d", "M0,0H5L6,2L5,4H0z")
.attr("transform", "translate(-3,-2)");
controls.append("g")
.attr("transform", "translate(10,0)")
.call(zoomAxis);
});
$("#reset").click(reset);
function select(d) {
list.selectAll("li").classed("selected", function (e) { return e.id == d.id });
svg.selectAll(".governate").classed("selected", function (e) { return e.id == d.id });
}
function unselect(d) {
list.selectAll("li").classed("selected", false);
svg.selectAll(".governate").classed("selected", false);
}
function click(d) {
list.selectAll("li").classed("pinned", function (e) { return e.id == d.id });
svg.selectAll(".governate").classed("pinned", function (e) { return e.id == d.id });
}
function reset() {
svg.transition()
.duration(750)
.call(zoom.transform, d3.zoomIdentity);
list.selectAll("li").classed("pinned", false);
svg.selectAll(".governate").classed("pinned", false);
}
function zoomed() {
svg.attr("transform", d3.event.transform);
zoomCursor.attr("transform", "translate(0," + z(d3.event.transform.k) + ")");
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment