This small example was made to explore how to add geo satellite positions onto a world map.
forked from d3noob's block: Adding names to places
xxxxxxxxxx
<meta charset="utf-8">
<style>
path {
stroke: white;
stroke-width: 0.25px;
fill: grey;
}
svg {
/*background: #e6f2ff;*/
background: #fff;
fill-opacity: .5;
}
.graticule {
fill: none;
stroke: #666;
stroke-width: 0.2px;
stroke-opacity: 1;
}
.city {
fill:red;
stroke:black;
stroke-opacity: 1;
fill-opacity: 1;
}
.cityname {
fill-opacity: 0.8;
fill:black;
font-size:8px;
font-family: "Arial", sans-serif;
}
.country {
stroke: #fff;
stroke-width: 0.5;
fill-opacity: .7;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-array.v1.min.js"></script>
<script src="https://d3js.org/d3-geo.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script src="https://d3js.org/d3-scale.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script>
// TODO:
// change land colour from styles
// hover over countries?
// make the graticule zoom
// show equator
// add satellite positions in blue - maybe a satellite icon
// add some solution so satellites at same long are not on top of each other
// button to reset zoom
// keyboard keys - right/left/spacebar?
var width = 960,
height = 600;
//var projection = d3.geoOrthographic()
var projection = d3.geoMercator()
.center([0, 20 ])
.scale(145)
.rotate([0,0]);
color = d3.scaleOrdinal().
range(["#666"])
// can use multiple colours
// range(["#a1d99b", "#74c476" , "#31a354", "#c7e9c0"]);
var graticule = d3.geoGraticule10();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var path = d3.geoPath()
.projection(projection);
var g = svg.append("g");
g.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
// load and display the World
d3.json("world.json", function(error, world) {
var countries = topojson.feature(world, world.objects.countries).features,
neighbors = topojson.neighbors(world.objects.countries.geometries);
// load and display the cities
d3.csv("cities.csv", function(error, data) {
g.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("r", 4)
.attr("class", "city")
g.selectAll("text")
.data(data)
.enter()
.append("text") // append text
.attr("x", function(d) {
return projection([d.lon, d.lat])[0];
})
.attr("y", function(d) {
return projection([d.lon, d.lat])[1];
})
.attr("dy", -3) // set y position of bottom of text
.attr("dx", 3) // set y position of bottom of text
.attr("class", "cityname")
.attr("text-anchor", "start") // set anchor y justification
.text(function(d) {return d.city;}); // define the text to display
});
// show countries and colour them on a scale
g.selectAll(".country")
.data(countries)
.enter().insert("path", ".graticule")
.attr("class", "country")
.attr("d", path)
.style("fill", function(d, i) { return color(d.color = d3.max(neighbors[i], function(n) { return countries[n].color; }) + 1 | 0); })
.on('mouseenter', function(d, i) {
d3.select(this).style('fill-opacity', 1);
})
.on('mouseleave', function(d, i) {
d3.select(this).style('fill-opacity',.7);
});
});
// zoom and pan
var zoom = d3.zoom()
.scaleExtent([1, 20])
.translateExtent([[0,0],[960,600]])
.on("zoom",function() {
g.attr("transform",d3.event.transform)
g.selectAll("circle")
.attr("d", path.projection(projection));
});
svg.call(zoom)
</script>
</body>
</html>
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-array.v1.min.js
https://d3js.org/d3-geo.v1.min.js
https://d3js.org/d3-geo-projection.v2.min.js
https://d3js.org/topojson.v1.min.js
https://d3js.org/d3-scale.v1.min.js
https://d3js.org/d3-scale-chromatic.v1.min.js