interactive and styled middle earth map

[This article was first published on Jkunst - R category, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

This is pure nerdism. There is a project to create a shapfile
from a fictional world, the Middle Earth. The data is in this
https://github.com/jvangeld/ME-GIS repository. The author of the
r-chart.com web site made a ggplot version of this map which
you can see in this link.

Well, as the highcharter developer I wanted to try to made
this map using this package and add some styles to give
the old magic fashioned Middle Earth look. My try to achieve
this…

Just because we can
Me.

… Is summarized as:

  • Use the #F4C283 color as background.
  • use the Tangerine font in the title and Macondo in the
    legends, tooltips and labels.
  • Search hexadecimal color forest to get the the colors for forests.

The packages to made this possible were:

<span class="n">rm</span><span class="p">(</span><span class="n">list</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ls</span><span class="p">())</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">dplyr</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">maptools</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">highcharter</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">geojsonio</span><span class="p">)</span><span class="w">
</span><span class="n">library</span><span class="p">(</span><span class="n">rmapshaper</span><span class="p">)</span><span class="w">
</span>

Note we used the rmapshaper
package (wapper for the mapshaper js library)
to simplify the rivers beacuse this file is kind of huge to put
in a htmlwidget.

I made some auxiliar functions to simplify the shapefile and to converte this info in
geojson format using the geojsonio
package.

<span class="n">fldr</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="s2">"~/ME-GIS-master"</span><span class="w">

</span><span class="n">shp_to_geoj_smpl</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">file</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Coastline2.shp"</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0.5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">d</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">readShapeSpatial</span><span class="p">(</span><span class="n">file.path</span><span class="p">(</span><span class="n">fldr</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="p">))</span><span class="w">
  </span><span class="n">d</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">ms_simplify</span><span class="p">(</span><span class="n">d</span><span class="p">,</span><span class="w"> </span><span class="n">keep</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">k</span><span class="p">)</span><span class="w">
  </span><span class="n">d</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">geojson_list</span><span class="p">(</span><span class="n">d</span><span class="p">)</span><span class="w">
  </span><span class="n">d</span><span class="w">
</span><span class="p">}</span><span class="w">

</span><span class="n">shp_points_to_geoj</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="k">function</span><span class="p">(</span><span class="n">file</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="n">outp</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">readShapeSpatial</span><span class="p">(</span><span class="n">file.path</span><span class="p">(</span><span class="n">fldr</span><span class="p">,</span><span class="w"> </span><span class="n">file</span><span class="p">))</span><span class="w">
  </span><span class="n">outp</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">geojson_json</span><span class="p">(</span><span class="n">outp</span><span class="p">)</span><span class="w"> 
  </span><span class="n">outp</span><span class="w">
</span><span class="p">}</span><span class="w">

  
</span><span class="n">cstln</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_to_geoj_smpl</span><span class="p">(</span><span class="s2">"Coastline2.shp"</span><span class="p">,</span><span class="w"> </span><span class="m">.65</span><span class="p">)</span><span class="w">
</span><span class="n">rvers</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_to_geoj_smpl</span><span class="p">(</span><span class="s2">"Rivers19.shp"</span><span class="p">,</span><span class="w"> </span><span class="m">.01</span><span class="p">)</span><span class="w">
</span><span class="n">frsts</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_to_geoj_smpl</span><span class="p">(</span><span class="s2">"Forests.shp"</span><span class="p">,</span><span class="w"> </span><span class="m">0.90</span><span class="p">)</span><span class="w">
</span><span class="n">lakes</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_to_geoj_smpl</span><span class="p">(</span><span class="s2">"Lakes2.shp"</span><span class="p">,</span><span class="w"> </span><span class="m">0.1</span><span class="p">)</span><span class="w">
</span><span class="n">roads</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_to_geoj_smpl</span><span class="p">(</span><span class="s2">"PrimaryRoads.shp"</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w">


</span><span class="n">cties</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_points_to_geoj</span><span class="p">(</span><span class="s2">"Cities.shp"</span><span class="p">)</span><span class="w">
</span><span class="n">towns</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">shp_points_to_geoj</span><span class="p">(</span><span class="s2">"Towns.shp"</span><span class="p">)</span><span class="w">



</span><span class="n">pointsyles</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">
  </span><span class="n">symbol</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"circle"</span><span class="p">,</span><span class="w">
  </span><span class="n">lineWidth</span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w">
  </span><span class="n">radius</span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w">
  </span><span class="n">fillColor</span><span class="o">=</span><span class="w"> </span><span class="s2">"transparent"</span><span class="p">,</span><span class="w">
  </span><span class="n">lineColor</span><span class="o">=</span><span class="w"> </span><span class="kc">NULL</span><span class="w">
</span><span class="p">)</span><span class="w">
</span>

Now, to create the chart we need to add the geographic info one by one setting
the type of info:

  • mappoint for cities.
  • mapline for rivers and the coast.
  • And map for lakes and forests.
<span class="n">hcme</span><span class="w"> </span><span class="o"><-</span><span class="w"> </span><span class="n">highchart</span><span class="p">(</span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"map"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_chart</span><span class="p">(</span><span class="n">style</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">fontFamily</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Macondo"</span><span class="p">),</span><span class="w"> </span><span class="n">backgroundColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#F4C283"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_title</span><span class="p">(</span><span class="n">text</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"The Middle Earth"</span><span class="p">,</span><span class="w"> </span><span class="n">style</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">fontFamily</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Tangerine"</span><span class="p">,</span><span class="w"> </span><span class="n">fontSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"40px"</span><span class="p">))</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cstln</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mapline"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"brown"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Coast"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rvers</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mapline"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#7e88ee"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Rivers"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">roads</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mapline"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#634d53"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Main Roads"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">frsts</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"map"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#228B22"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Forest"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">lakes</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"map"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"#7e88ee"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Lakes"</span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w">
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cties</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mappoint"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Cities"</span><span class="p">,</span><span class="w">
                </span><span class="n">dataLabels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">),</span><span class="w"> </span><span class="n">marker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">radius</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">4</span><span class="p">,</span><span class="w"> </span><span class="n">lineColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">))</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_add_series</span><span class="p">(</span><span class="n">data</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">towns</span><span class="p">,</span><span class="w"> </span><span class="n">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"mappoint"</span><span class="p">,</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"black"</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"Towns"</span><span class="p">,</span><span class="w">
                </span><span class="n">dataLabels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">),</span><span class="w"> </span><span class="n">marker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">radius</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">fillColor</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"rgba(190,190,190,0.7)"</span><span class="p">))</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_plotOptions</span><span class="p">(</span><span class="w">
    </span><span class="n">series</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="w">
      </span><span class="n">marker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pointsyles</span><span class="p">,</span><span class="w">
      </span><span class="n">tooltip</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">headerFormat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">""</span><span class="p">,</span><span class="w"> </span><span class="n">poinFormat</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"{series.name}"</span><span class="p">),</span><span class="w">
      </span><span class="n">dataLabels</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nf">list</span><span class="p">(</span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">FALSE</span><span class="p">,</span><span class="w"> </span><span class="n">format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'{point.properties.Name}'</span><span class="p">)</span><span class="w">
    </span><span class="p">)</span><span class="w">
  </span><span class="p">)</span><span class="w"> </span><span class="o">%>%</span><span class="w"> 
  </span><span class="n">hc_mapNavigation</span><span class="p">(</span><span class="n">enabled</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">TRUE</span><span class="p">)</span><span class="w"> 
</span>

And you have a super styled chart using only R :D!

<span class="n">hcme</span><span class="w">
</span>

open

If you deselect the Towns series the chart will zoom smoothly. There
are some many point that you can see the chart/browser lag when you
make a zoom.

giphy gif source

To leave a comment for the author, please follow the link and comment on their blog: Jkunst - R category.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)