{"id":19428,"date":"2021-09-22T14:04:56","date_gmt":"2021-09-22T18:04:56","guid":{"rendered":"https:\/\/nuxx.net\/blog\/?p=19428"},"modified":"2021-09-22T14:04:57","modified_gmt":"2021-09-22T18:04:57","slug":"making-an-online-ramba-trails-map","status":"publish","type":"post","link":"https:\/\/nuxx.net\/blog\/2021\/09\/22\/making-an-online-ramba-trails-map\/","title":{"rendered":"Making an Online RAMBA Trails Map"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/nuxx.net\/rambamap\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"927\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-1024x927.png\" alt=\"\" class=\"wp-image-19452\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-1024x927.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-300x272.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-768x696.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-1536x1391.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/ramba_trail_map_1.0_in_firefox_showing_epic_loop-2048x1855.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>RAMBA Trails Map v1.0 (Default View w\/ Epic Loop Layer)<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>Kristen and I have been spending a good deal of time in the <a href=\"https:\/\/ishpemingcity.org\/\">Ishpeming<\/a> and <a href=\"https:\/\/cityofnegaunee.com\/\">Negaunee<\/a> area this year, and I&#8217;ve made it a personal goal to become more familiar the local trails &#8212; both <a href=\"https:\/\/www.rambatrails.com\/\">RAMBA<\/a>-supported and otherwise &#8212; and get them documented <a href=\"https:\/\/www.openstreetmap.org\/\">OpenStreetMap (OSM)<\/a>. Having these trails in OSM provides two big benefits: they appear in other mapping tools (such as <a href=\"https:\/\/www.gaiagps.com\/\">OsmAnd<\/a>, <a href=\"https:\/\/osmand.net\/\">GaiaGPS<\/a>, <a href=\"https:\/\/www.strava.com\/\">Strava<\/a>, <a href=\"https:\/\/www.mapmyride.com\">MapMyRide<\/a>\/<a href=\"https:\/\/www.mapmyrun.com\">MapMyRun<\/a>) and the trail data can be freely used to build other tools.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"232\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-300x232.jpg\" alt=\"\" class=\"wp-image-19432\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-300x232.jpg 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-1024x791.jpg 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-768x593.jpg 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-1536x1187.jpg 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/RAMBA-Trail-Map-2018-v6-2048x1583.jpg 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption>Official RAMBA Map v6 from 2018<\/figcaption><\/figure><\/div>\n\n\n\n<p>Over the years of making trail maps with OpenStreetMap I&#8217;ve mostly <a href=\"https:\/\/nuxx.net\/blog\/2012\/06\/05\/mtb-trail-mapping-workflow-with-openstreetmaps\/\" data-type=\"post\" data-id=\"4308\">produced PDFs for printing<\/a>, leaving mobile and online mapping to other apps. These work well, but have the big downside of rendering routes with their style. That is, online maps via these tools&#8217; show the routes, but look quite different from print maps, even if all the data for them to display more data (such as <a href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Key:colour\"><code>colour=*<\/code><\/a> tags on relations) is in OSM.<\/p>\n\n\n\n<p>While these apps work pretty well, and I <a href=\"https:\/\/nuxx.net\/blog\/2019\/10\/06\/using-osmand-offline-maps-during-remote-rides\/\" data-type=\"post\" data-id=\"18821\">use them myself routinely for navigation<\/a>, I got the itch to see if I could make a web-based <a href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Slippy_Map\">map<\/a> that looked more like locally produced print maps than app-based renderings. It seemed like a good project, a good way to learn some basics of modern web development, and maybe make something useful.<\/p>\n\n\n\n<p>What I ended up with was <a href=\"https:\/\/nuxx.net\/rambamap\">a slippy map of showing the RAMBA trails<\/a> that uses layers of pre-rendered tiles to show the different official trail routes, placed over a background map. The map viewer is client-side JavaScript that loads static tiles from a basic web server, making this a very simple app to host (just a bunch of static files on a site).<\/p>\n\n\n\n<p>In this post I intend to document the major steps of how I made this map, why I used the tools I did, and share the code to reproduce (and update) this build. Hopefully this&#8217;ll allow others to get their head around these map presentation basics, perhaps even reusing this work to make and host another map.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Update OSM Data<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"164\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-300x164.png\" alt=\"\" class=\"wp-image-19455\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-300x164.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-1024x560.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-768x420.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-1536x840.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/strava_global_heatmap_in_josm-2048x1120.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption>Strava Global Heatmap in JOSM<\/figcaption><\/figure><\/div>\n\n\n\n<p>Mostly outside the scope of this article but worth a mention, a significant amount of time was spent ensuring that the RAMBA area trails are accurately listed in OSM. Without good data it would not be possible to go further, as the OSM data is the base data used to create other maps.<\/p>\n\n\n\n<p>By combining information from a bunch of sources, and doing some personal surveying of trails while riding and hiking, I was able to get all of the official RAMBA trails documented, along with numerous other paths and tracks in the area. This building a complete picture of the usable trails in the area.<\/p>\n\n\n\n<p>Information used to get the RAMBA trails in OSM included:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>My own recorded ride\/hiking data, notes, etc. <\/li><li><a href=\"https:\/\/nuxx.net\/blog\/2020\/05\/24\/high-resolution-strava-global-heatmap-in-josm\/\" data-type=\"post\" data-id=\"18873\">Strava Heatmap data<\/a>.<\/li><li>Official route files (GPXs) from events such as <a href=\"https:\/\/marjigesick.com\/\">Marji Gesick<\/a> and <a href=\"https:\/\/thepolarroll.com\/\">Polar Roll<\/a>.<\/li><li>The official RAMBA map.<\/li><li>Hand-annotated map from Danny Hill listing local trail names.<\/li><\/ul>\n\n\n\n<p>These sources were combined in <a href=\"https:\/\/josm.openstreetmap.de\/\">JOSM<\/a>, cross-referenced, ways drawn and tagged, relations built out, and before long a complete picture of the RAMBA-area trails &#8212; official and otherwise &#8212; were in OpenStreetMap.<\/p>\n\n\n\n<p>Most importantly, beyond documenting the trail locations, trails were grouped into <a href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Relation:route\">route relations<\/a> to show each official route, and then all the official routes were grouped into a <a href=\"https:\/\/wiki.openstreetmap.org\/wiki\/Relation:superroute\">superroute<\/a> for all the RAMBA trails. As of time of writing, relation <a href=\"https:\/\/www.openstreetmap.org\/relation\/12425503\">RAMBA Trails (12425503)<\/a> is the superroute that aggregates the individual trail routes such as <a href=\"https:\/\/www.openstreetmap.org\/relation\/8467869\">Epic Loop (8467869)<\/a> and <a href=\"https:\/\/www.openstreetmap.org\/relation\/8468010\">Malton Loop (8468010)<\/a>.<\/p>\n\n\n\n<p>The result of this is accurate trail data that&#8217;s easy to query for and style using other tools.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Rendering Tiles with Maperitive<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"164\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-300x164.png\" alt=\"\" class=\"wp-image-19446\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-300x164.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-1024x560.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-768x420.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-1536x840.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/working_on_the_ramba_map_in_maperitive-2048x1120.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>There are myriad ways to render tiles from OSM data, with most of these involving setting up a database server and a toolchain which&#8217;ll generate, cache, and serve tiles on demand. For most large data sets this makes a lot of sense, but for a small trail system I really wanted to use static tiles I could serve from a simple webserver.<\/p>\n\n\n\n<p>Eventually I came across <a href=\"http:\/\/maperitive.net\/\">Maperitive<\/a>, a desktop application for Windows that takes GIS data (including OSM), stylizes it with a relatively simple ruleset, and can generate tiles in the standard XYZ format for use elsewhere. It can also be scripted, which meant I could use it as part of an automated workflow to generate new tiles as the OSM data changes. This seemed like a good solution, so I set about writing some rulesets that would reasonably show the RAMBA trail routes and some automation around it all.<\/p>\n\n\n\n<p>After a lot of experimenting I settled on a having separate tile set for each of the official loops, an overview of all trails, and a base map. The base map would always be shown, and a user can toggle between layers which highlight all the trails or individual loops.<\/p>\n\n\n\n<p>After a few iterations of custom rules, I settled on a simplified set based on the <code>Default.mrules<\/code> file which comes with Maperitive for rendering the base map. The only modification was changing the font to <a href=\"https:\/\/www.n1en.org\/roadgeek-fonts\/\">Michael Adams&#8217; Roadgeek 2005 Transport Medium<\/a> font, as it looks nicer than the default, Verdana. For the overview and route layers I created simple rules based on the the default rendering of <code>highway=path<\/code>, using the Heavy version of the font. The rule for each trail route (relation) selects the trails in a given relation then colors them accordingly.<\/p>\n\n\n\n<p>Creating these rules took a bit of fiddling, as Maperitive is both a bit of a dead project, not completely documented, and (in the latest Beta) sort-of buggy where sometimes the map display would stop updating. Still, even though I&#8217;m not great at making attractive things, I was able to come up with something that worked well enough.<\/p>\n\n\n\n<p>Conveniently, Maperitive also comes with a command line version (Maperitive.Console.exe). After settling on rendering rules and a tile generation script, I used this as part of an automated workflow which downloaded OSM data directly then rendered each of the tile sets.<\/p>\n\n\n\n<p>After tile generation I used a Windows binary of <a href=\"http:\/\/optipng.sourceforge.net\/\">OptiPNG<\/a> to losslessly compress the tiles, resulting in a ~62% space savings (original: 746MB, optimized: 286MB) which&#8217;ll reduce storage and bandwidth overhead.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Front End<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignright size-medium\"><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code.png\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"164\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-300x164.png\" alt=\"\" class=\"wp-image-19456\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-300x164.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-1024x560.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-768x420.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-1536x840.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2021\/09\/editing_ramba_trail_map_front_end_in_vs_code-2048x1120.png 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption>Editing in VS Code<\/figcaption><\/figure><\/div>\n\n\n\n<p>With tiles generated I needed a way to display them. It turns out that <a href=\"https:\/\/openlayers.org\/\">OpenLayers<\/a> was easy to use and it all ran as simple client side application in a browser. By using <a href=\"https:\/\/www.npmjs.com\/\">npm<\/a> and <a href=\"https:\/\/parceljs.org\/\">parcel<\/a>, with <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code<\/a> for editing, it was quite easy to get the site developed, tested, and bundled up for deployment. The only component I had to add was <a href=\"https:\/\/github.com\/walkermatt\/ol-layerswitcher\">ol-layerswitcher<\/a> control, which provides an easy way to toggle between layers.<\/p>\n\n\n\n<p>Prior to this I had very little experience with modern web development, with my exposure to JavaScript pretty much limited to reading others&#8217; code to figure out what it&#8217;s doing. After a bit of confusion (and having to accept the hidden complexity of using an application bundler), I was able to focus solely on writing a single <code>main.js<\/code> file with a basic <code>index.html<\/code> that together do what I wanted:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Run full screen by default.<\/li><li>Show all trails by default, with toggles for the defined routes (layers of the map).<\/li><li>Show an attractive background map below the routes to show the rest of the area.<\/li><li>Offer controls to use geolocation to showing one&#8217;s location on the map and reset the view to the original map extents.<\/li><li>Look sane on desktop and mobile devices.<\/li><\/ul>\n\n\n\n<p>This ended up being <em>much<\/em> easier than I thought, and between the <a href=\"https:\/\/openlayers.org\/en\/latest\/examples\/\">OpenLayers Examples<\/a> and just some basic programming I was able to get something I&#8217;m happy with. Far more time was spent designing the tiles and thinking about what I wanted it to do than writing the code to display it all.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Tile Hosting<\/h2>\n\n\n\n<p>The actual map tiles are a number of small PNG files, and a typical session of viewing and panning around the map can result in hundreds of image loads. This was seeming a bit slow when being served from nuxx.net via HTTP\/1.1, so I looked into using HTTP\/2 to improve performance.<\/p>\n\n\n\n<p>Unfortunately, it was not simple to turn on HTTP\/2 here at nuxx.net as I&#8217;m using <a href=\"https:\/\/www.php.net\/\">PHP<\/a> for <a href=\"https:\/\/wordpress.org\/\">WordPress<\/a>, which in turn requires <a href=\"https:\/\/httpd.apache.org\/docs\/current\/mod\/prefork.html\">MPM prefork<\/a>, which precludes <a href=\"https:\/\/httpd.apache.org\/docs\/current\/mod\/mod_http2.html\">mod_http2<\/a>. I could have set up another web server and such, but for now I&#8217;m hosting the tiles in <a href=\"https:\/\/aws.amazon.com\/\">AWS<\/a>, with the tiles uploaded to an <a href=\"https:\/\/aws.amazon.com\/s3\/\">S3<\/a> bucket and served via <a href=\"https:\/\/aws.amazon.com\/cloudfront\/\">CloudFront<\/a>.<\/p>\n\n\n\n<p>This <em>should<\/em> allow for better tile download performance than what I can do from my server. Despite potentially incurring a bit of a financial cost it is a good experiment in hosting tiles in the cloud. I may change this in the future, particularly if it becomes cost prohibitive, but for now it&#8217;s working well.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Follow Along At Home<\/h2>\n\n\n\n<p>If you would like to generate this same map, start by downloading this ZIP file: <a href=\"https:\/\/nuxx.net\/files\/ramba_trails_map_code_1.0.zip\"><code>ramba_trails_map_code_1.0.zip<\/code><\/a>. It contains the scripts and rules needed to generate the map tiles (<code>ramba.mscript<\/code> and the <code>.mrules<\/code> files), the <code>index.html<\/code>, <code>main.js<\/code>, and <code>package.json<\/code> for the OpenLayers-based front end, the <code>.osm<\/code> file used to generate the first release of the map, and a few batch files that tie it all together.<\/p>\n\n\n\n<p>You will need to download <a href=\"http:\/\/maperitive.net\/\">Maperitive<\/a> (latest beta: <a href=\"http:\/\/maperitive.net\/download\/Maperitive-latest.zip\">link<\/a> &#8212; from <a href=\"https:\/\/braincrunch.tumblr.com\/post\/26190799580\/maperitive-alpenglow-effect-using-a-custom-shader\">this post<\/a> \/ <a href=\"https:\/\/nuxx.net\/files\/Maperitive-latest.zip\">mirror<\/a>), <a href=\"https:\/\/curl.se\/\">curl<\/a>, <a href=\"http:\/\/optipng.sourceforge.net\/\">OptiPNG<\/a>, and <a href=\"https:\/\/www.n1en.org\/roadgeek-fonts\/\">the Roadgeek 2005 fonts<\/a> to generate and optimize the tiles. These scripts may work fine with older\/release versions of Maperitive, <a href=\"https:\/\/braincrunch.tumblr.com\/post\/10490479766\/maperitive-beta-update\">but betas incorporate a bit of collision detection for text<\/a>, making things look nicer.<\/p>\n\n\n\n<p>These batch files are included to will help you out, but may need some editing to fit on your environment:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>fetch_osm.bat<\/code>: Uses curl to download all OSM data within a bounding box that encompasses the Ishpeming\/Negaunee area.<\/li><li><code>generate_tiles.bat<\/code>: Runs <code>ramba.mscript<\/code> via <code>Maperitive.Console.exe<\/code> to generate the tiles.<\/li><li><code>optimize_tiles.bat<\/code>: Copies the unoptimized tiles from the <code>...\/tile_output\/raw<\/code> output directory to the <code>...\/tile_output\/optimized<\/code> directory, then runs OptiPNG against the tiles to optimize them in place.<\/li><\/ul>\n\n\n\n<p>To build the web app you&#8217;ll need to install <a href=\"https:\/\/nodejs.org\/en\/download\/\">npm<\/a>, <a href=\"https:\/\/parceljs.org\/getting_started.html\">parcel<\/a>, create a new OpenLayers app as per the directions <a href=\"https:\/\/openlayers.org\/en\/latest\/doc\/tutorials\/bundle.html\">here<\/a>. Then install <a href=\"https:\/\/github.com\/walkermatt\/ol-layerswitcher\">ol-layerswitcher<\/a> (<code>npm install ol-layerswitcher<\/code>), replace the default <code>index.html<\/code>, <code>main.js<\/code>, and <code>package.json<\/code> with the ones I provided, and you should be ready to go.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Updating the Map<\/h2>\n\n\n\n<p>As you can see, the map is two major pieces: the front end and the tiles. Whenever the map data changes in OSM the tiles can be regenerated to update those layers. The code for the front end web app only needs to change if the storage location changes, features are going to be added, etc.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>This map has worked out rather well and I&#8217;m happy calling it v1.0. It&#8217;s been a great learning experience, and I&#8217;ve even managed to produce something useful that didn&#8217;t exist before: an interactive map of some of the most rugged single track trails in Michigan; one of my favorite places to ride mountain bikes.<\/p>\n\n\n\n<p>It&#8217;s far from perfect, and there are some things I could do differently, but for now, I&#8217;m considering it a success. When in Negaunee for vacation last week I successfully used development versions of this map to find my way around, so I know it&#8217;s better than nothing.<\/p>\n\n\n\n<p>If you find any quirks in the map data &#8212; such as trails with wrong names or in the wrong location &#8212; please take a screenshot and show me what&#8217;s wrong and email that to <a href=\"mailto:steve@nuxx.net\">steve@nuxx.net<\/a>. I&#8217;ve done my best to ensure the RAMBA trails are accurately mapped, but I&#8217;ve certainly missed some things.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problems<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>No key or other ancillary information (such as logos) as are normally found on print maps.<\/li><li>No terrain. While 1m DEM elevation data is available from the USGS, I couldn&#8217;t figure out how to use it in Maperitive for generating hillshading.<\/li><li>No easy way to add clickable items to show additional info, link to external map apps (eg: for navigation).<\/li><li>Maperitive&#8217;s text rendering isn&#8217;t the best, resulting in goofy looking text at some zoom levels.<\/li><li>Long trails only have one label placed on the middle. Trails with one name broken into multiple ways will be labeled numerous times.<\/li><li>Due to being run in a browser it&#8217;s a sufficient, but not great, mobile experience. Specifically, selecting the geolocation, recenter, and layer controls can be fiddly because they are so small.<\/li><li>Does not work offline, but thankfully most of the RAMBA area now has good mobile data coverage.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Things To Investigate<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Keep an eye on AWS cost and performance.<\/li><li>Look at <a href=\"https:\/\/leafletjs.com\">Leaflet<\/a> for the front end, as it seems a bit more modern.<\/li><li>Consider rendering map tiles with <a href=\"https:\/\/tilemill-project.github.io\/tilemill\/\">TileMill<\/a>. This will add a lot of complexity both in setup and styling tiles, but once done should allow a lot more flexibility in styling and overcome most of Maperitive&#8217;s problems. <a href=\"https:\/\/github.com\/mapbox\/mbutil\">mapbox\/mbutil<\/a> should work for getting XYZ PNGs out of <a href=\"https:\/\/docs.mapbox.com\/help\/glossary\/mbtiles\/\">MBTiles<\/a> files.<\/li><li>Consider using a tile server if I don&#8217;t want to deal with discrete files.<\/li><li>Look more into using vector tiles with client-side styling. (I passed on this for now, as a GeoJSON file showing each of the route is a large download and had no benefit over raster tiles.)<\/li><li>Maperitive should run under <a href=\"https:\/\/www.mono-project.com\/\">Mono<\/a>, and OptiPNG is available for many platforms, meaning it should be possible to reproduce this build under macOS or Linux. Note that the GUI for Maperitive will not currently run on macOS due to Windows.Forms currently being based on Carbon, which is not available for 64-bit macOS. So while the CLI should work, the GUI version isn&#8217;t currently compatible with macOS 11.5 (Big Sur) and higher.<\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Kristen and I have been spending a good deal of time in the Ishpeming and Negaunee area this year, and I&#8217;ve made it a&#8230;<\/p>\n<div class=\"more-link-wrapper\"><a class=\"more-link\" href=\"https:\/\/nuxx.net\/blog\/2021\/09\/22\/making-an-online-ramba-trails-map\/\">Continue reading<span class=\"screen-reader-text\">Making an Online RAMBA Trails Map<\/span><\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,11,57,29],"tags":[],"class_list":["post-19428","post","type-post","status-publish","format-standard","hentry","category-cycling","category-making-things","category-mapping","category-outdoors","entry"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19428","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/comments?post=19428"}],"version-history":[{"count":22,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19428\/revisions"}],"predecessor-version":[{"id":19458,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/19428\/revisions\/19458"}],"wp:attachment":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/media?parent=19428"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/categories?post=19428"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/tags?post=19428"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}