Honua
Honua is Hawaiian for earth π
Honua is a simple geographic mapping Library for Ruby. It allows you to stitch geographic map images based on map tiles, provided by a rastered tile server (in Mercator projection). It was highly inspired by ModestMaps.
Requirements
Setup
To install, run:
gem install honua
Add the following to your Gemfile:
gem "honua"
Usage
Coordinate Systems
Like almost every popular mapping library it uses the Web Mercator Projection as basis for conversions and its tile coordinate system.
- A Location is a geographic place described in latitude and longitude coordinates in degrees.
- A Coordinate is a geographic place described in a tile coordinate system with columns (x), rows (y) and a zoom level.
To convert from Location
to Coordinate
at a certain zoom level:
- convert latitude and longitude to radians
- reproject coordinates to Web Mercator projections
- transform range of
column
androw
to 0 - 1 and shift origin to top left corner - multiply
row
andcolumn
with number of tiles (2**zoom) and round results
Configuration
At minimal you need to provide the url for a tile server and the appropriate attribution text for the used tiles. If the map is too small to show the attribution it will be skipped and you need to provide it separetly. Don't forget to check out terms and service for the tile server you are planning to use.
Honua.configure do |config|
# each zoom level is a directory, each column is a subdirectory, and each tile in that column is a file
config.tiles_url = 'http://localhost:8080/%<zoom>s/%<column>s/%<row>s.png'
config.attribution_text = '<b>Β© OpenStreetMap contributors</b>'
end
Checkout configuration.rb for further details.
A map is defined by a center location, map dimensions (width and height in pixels) and a zoom level. The draw
method downloads all necessary tiles for the map, stitches them together, adds the proper attribution at the bottom and finally returns a Vips::Image
.
map_center = Honua::Location.new(35.689487, 139.691711) # Tokyo
map = Honua::Map.new(center: map_center, width: 600, height: 600, zoom: 12)
map_image = map.draw
map_image.write_to_file('tokyo.png') # use Vips to write to file
Helpers
There might be use cases, where you have a bunch of location instead of map center, or you either have map dimensions or a zoom level but not both. Honua includes helpers that can be used to calculate the needed map input parameters:
-
Honua::Helpers.map_span(locations:)
returns the top left and bottom right coordinates at zoom level 0 -
Honua::Helpers.map_span(top_left:, bottom_right:)
returns the center coordinate based on map spanning top left and bottom right coordinates -
Honua::Helpers.calculate_zoom(top_left:, bottom_right:, width:, height:)
returns zoom level based on map spanning coordinates and map dimensions -
Honua::Helpers.calculate_map_dimensions(top_left:, bottom_right:, zoom:)
returns map dimensions (in pixels) based on map spanning coordinates and a zoom value -
Honua::Helpers.text_label((text:, dpi:, text_colour:, shadow_colour:))
generates a text label image with shadow and shadow offset, which can be places on the map. -
Honua::Helpers.hex2rgb(hex)
converts hex color strings to an array of RGB
Please refer to the examples for how these helpers might be used.
Development
To contribute, run:
git clone https://github.com//honua.git
cd honua
bundle install
You can also use the IRB console for direct access to all objects:
bin/console
Tile Server
If you want to use the included tile server be sure to install Docker and Docker Compose.
After you downloaded an .osm.pbf
extract and .poly
file from e.g Geofabrik for the region that you're interested in, replace the placeholders in docker-compose.yml
and run the importer with:
docker compose up osmimport
To start the tile server, run:
docker compose up osmtileserver
You can now go to localhost:8080
for a fullscreen Leaflet based map. To use the tile server in Honua, add the following configuration in your code:
Honua.configure do |config|
config.tiles_url = 'http://localhost:8080/tile/%<zoom>s/%<column>s/%<row>s.png'
config.attribution_text = '<b>Β© OpenStreetMap contributors</b>' # don't forget to attribute π
end
π If you want to merge 2 or more extracts you can use osmctools or osmctools-docker.
Tests
To test, run:
bundle exec rake
Versioning
Read Semantic Versioning for details. Briefly, it means:
- Major (X.y.z) - Incremented for any backwards incompatible public API changes.
- Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
- Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.
Contributions
Read CONTRIBUTING for details.
License
Copyright 2021 by dingsdax. Read LICENSE for details.
History
Read CHANGES for details. Built with Gemsmith.
Further Reading & Credits
Some of the resources that helped building and understanding the underlying logic behind this gem. This started out as a Ruby port of modest-maps.js but took on a life of its own. ModestMaps and Stamen are awesome! Big shoutout for their work and inspiration πββοΈ.
- Bing Maps Tile System
- OpenLayers FAQ
- OSM Slippy map tilenames
- ModestMaps Wiki
- Mercator Projection
- Tiles Γ la Google Maps
- Coordinate Systems Worldwide
Attributions
Toner & Terrain map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL.
Explorer Base Map header image NASA Earth Observatory map by Joshua Stevens using data from NASAβs MODIS Land Cover, the Shuttle Radar Topography Mission (SRTM), the General Bathymetric Chart of the Oceans (GEBCO), and Natural Earth boundaries.