There are a couple of websites, where you can create a map of the countries you visited, e.g. http://www.amcharts.com/visited_countries. I think, this would be a cool thing to add to my travel blog. However, all pages I could find, use a Mercator projection for the map, which I don't particularly like. I was wondering, if anyone knows of a way to create these kind of maps for different map projections (like Hobo-Dyer or Gall-Peters).
-
2Ah, Gall-Peters, the projection of choice if you have to use an equal-area projection but want to avoid one that distorts central Europe visibly. And Hobo-Dyer is the same, but favoring the latitudes of the continental United States rather than Europe.– hmakholm left over MonicaCommented Dec 6, 2014 at 15:41
-
1If you want to make one for yourself you can download hobo dyer free outline image at odt.org/Pictures/hdpoutlinelarge.jpg– skvCommented Dec 7, 2014 at 5:30
2 Answers
I would suggest using something like python + matplotlib and it's basemap library.
Basemap offers a wide range of projections, (see here), and you can then plot your places that you have been to onto the map. This can then be saved in a variety of formats for posting on your blog or you can use something like plot.ly to produce them online. A good example in an iPython notebook, (but using the global temperatures), is here with nice explanations of how it was done.
An example of the code needed to make a projection, (with a single point):
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
width = 28000000; lon_0 = -105; lat_0 = 40 # Change the origin lat/long here
m = Basemap(width=width,height=width,projection='aeqd', # Change projection here
lat_0=lat_0,lon_0=lon_0)
# fill background.
m.drawmapboundary(fill_color='aqua')
# draw coasts and fill continents.
m.drawcoastlines(linewidth=0.5)
m.fillcontinents(color='coral',lake_color='aqua')
# 20 degree graticule.
m.drawparallels(np.arange(-80,81,20))
m.drawmeridians(np.arange(-180,180,20))
# draw a black dot at the center.
xpt, ypt = m(lon_0, lat_0)
m.plot([xpt],[ypt],'ko')
# draw the title.
plt.title('Azimuthal Equidistant Projection')
plt.show()
The results: Once you have the basic process set up you can change the projection or the projection center in seconds.
Available projections:
Azimuthal Equidistant Projection, Gnomonic Projection, Orthographic Projection, Geostationary Projection, Near-Sided Perspective Projection, Mollweide Projection, Hammer Projection, Robinson Projection, Eckert IV Projection, Kavrayskiy VII Projection, McBryde-Thomas Flat Polar Quartic, Sinusoidal Projection, Equidistant Cylindrical Projection, Cassini Projection, Mercator Projection, Transverse Mercator Projection, Oblique Mercator Projection, Polyconic Projection, Miller Cylindrical Projection, Gall Stereographic Projection, Cylindrial Equal-Area Projection, Lambert Conformal Projection, Lambert Azimuthal Equal Area Projection, Stereographic Projection, Equidistant Conic Projection, Albers Equal Area Projection, Polar Stereographic Projection, Polar Lambert Azimuthal Projection, Polar Azimuthal Equidistant Projection, van der Grinten Projection
All the above tools are all completely free both as in no charge and as in unconstrained open source tools.
-
Epic, and I upvoted, but a non-programmer is going to have trouble with this :/ Commented Dec 7, 2014 at 21:27
-
@MarkMayo - Python is free, easy to get started, quick to start to learn, has lots of online examples, can be addictive and there are a lot of very helpful people out there. Commented Dec 7, 2014 at 21:33
-
1sure, I know this (I've had python contracts) but to many people, any programming is scary :( However to anyone reading this, Python is a fun, relatively easy language to learn. :) Commented Dec 7, 2014 at 21:36
If you want something more interactive done in javascript, the d3js library has some lovely "choropleth" examples
Sorry this is another coding answer though, so you'll have to adapt it to your needs as well as persuading the whole thing to run within whatever blogging system you use.
Here I've adapted this choropleth example, swapped to a different projection, remove the "world populations" csv data source and replaced it with a few more basic lines of "countries visited" data (on a scale of 0 to 2)
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="http://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<!-- Create an element where the map will take place -->
<svg id="my_dataviz" width="600" height="500"></svg>
<script>
// The svg
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
// Map and projection
var path = d3.geoPath();
var projection = d3.geoNaturalEarth()
.scale(width / 2 / Math.PI)
.translate([width / 2, height / 2])
// Data and color scale
var data = d3.map();
var colorScale = d3.scaleThreshold()
.domain([0, 1, 2])
.range(d3.schemeBlues[3]);
// Load external data and boot
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson")
.await(ready);
function ready(error, topo) {
// Visited country codes. 1 time / 2 or more times.
data.set("GBR", 2);
data.set("IRL", 1);
data.set("FRA", 2);
data.set("ESP", 2);
data.set("BRA", 2);
data.set("ARG", 1);
data.set("CHN", 1);
data.set("EGY", 1);
let mouseOver = function(d) {
d3.selectAll(".Country")
.transition()
.duration(200)
.style("opacity", .5)
d3.select(this)
.transition()
.duration(200)
.style("opacity", 1)
}
let mouseLeave = function(d) {
d3.selectAll(".Country")
.transition()
.duration(200)
.style("opacity", .8)
d3.select(this)
.transition()
.duration(200)
.style("stroke", "transparent")
}
// Draw the map
svg.append("g")
.selectAll("path")
.data(topo.features)
.enter()
.append("path")
// draw each country
.attr("d", d3.geoPath()
.projection(projection)
)
// set the color of each country
.attr("fill", function (d) {
d.total = data.get(d.id) || 0;
return colorScale(d.total);
})
.style("stroke", "transparent")
.attr("class", function(d){ return "Country" } )
.style("opacity", .8)
.on("mouseover", mouseOver )
.on("mouseleave", mouseLeave )
}
</script>
For less coding I guess ideally you'd want something like this as for example a wordpress plugin.