A cross-platform application for displaying vector and raster maps, built on Tangram-ES and supporting plugins for search, routing, map sources and more. Includes a simple, customizable style for OpenStreetMap vector tiles.
Features include offline search, managing saved places, creating and editing tracks and routes, and saving map tiles for offline use.
Available for Android, Linux, and iOS: App Store, Testflight.
- Build or download
- Download OSM extracts and generate tiles
- Add some online tile sources
- Submit bug reports, pull requests, feature suggestions, and plugin ideas!
On Linux, git clone --recurse-submodules https://github.com/styluslabs/maps
, install build dependencies (apt install cmake libgtk-3-dev libcurl4-openssl-dev libfontconfig-dev libxinerama-dev
on Debian/Ubuntu), then run cd maps && make linux
to generate Release/ascend
. To build and install for Android (on Linux w/ Android SDK and NDK installed), cd maps/app/android && ./gww installRelease
. The gww
(gradle wrapper wrapper) script will download and run gradlew
. To install the Android SDK and NDK, run gww --install-sdk
.
The releases page includes pre-generated tiles for a few regions.
scripts/tilemaker contains the files necessary to generate tiles for the included vector map style stylus-osm.yaml using Tilemaker.
- download an OpenStreetMap extract, e.g., from geofabrik or osmtoday
- Download tilemaker v2.4.0 and run:
tilemaker --config maps/scripts/tilemaker/config.json --process maps/scripts/tilemaker/process.lua <extract>.osm.pbf --output <output>.mbtiles
- it may be necessary to add
--skip-integrity
for some extracts.
- it may be necessary to add
- In the application, navigate to Map sources -> Offline maps -> Open, choose the mbtiles file generated by tilemaker (if prompted, choose "Ascend OSM Base" as the destination source). The tiles will be imported and indexed for offline search based on configuration
application.search_data
in stylus-osm.yaml. On Android, it is necessary to enable file access permission for Ascend in the system app settings in order to open files outside the application's private folder.
To avoid time-consuming search indexing on mobile devices, the Linux version can be used to add the search data to the mbtiles file before copying it to the mobile device (note that this will also import the map to the Linux version's storage):
ascend --import <output>.mbtiles --storage.export_pois true
New map sources can be added by combining existing sources (the "+" button on the toolbar), editing mapsources.yaml (with the application closed), editing mapsources.default.yaml and choosing Restore default sources from the overflow menu, or via "Import source" on the overflow menu, where a YAML fragment or map tile URL (e.g. https://some.tile.server/tiles/{z}/{x}/{y}.png
) can be entered, or a YAML scene file chosen, for custom vector map styles.
To save online tiles for offline use, pan and zoom the view to show the desired region, tap the download button on the Offline maps toolbar, enter the maximum zoom level to include, then tap Download. Tiles for all layers of the current map source will be downloaded.
The default configuration includes markers.yaml for all maps to support the display of search results, saved places, tracks, routes, the location marker, and other markers.
Application data is stored in the executable's folder on Linux (will be changed to ~/.config/styluslabs/maps
in the future) and in /Android/media/com.styluslabs.maps/files
on Android (this folder can be read and written by other applications, so it is possible to edit files). Currently, there are only a few configuration options available in the GUI, but many more can be set by editing config.yaml
(after exiting the app) in the application data folder. See config.default.yaml
for documentation.
On Android, all files created by the application (except config.yaml
and mapsources.yaml
) will be replaced when a newer APK is installed, so edits should only be made to copies, not the original files.
Plugins written in Javascript can add search providers, routing providers, map tile providers, and more.
Files in plugins/
with .js
extension are executed at application startup. To reload, tap the reload button on the Plugin Console toolbar. Some plugins (openroute.js
and sentinel2.js
currently) require third-party API keys to work - follow the instructions in the plugin's js file to obtain an API key, then create a file plugins/_secrets.js
to set secrets = { "some_api_key": value, "another_api_key": value }
.
Currently uses Duktape, so support for features from ES2015 and later is limited. On iOS, JavascriptCore will be used.
The included plugins give a sample of what's possible:
- google-import.js - import list of places from GeoJSON exported by Google Maps; run from the plugin console
- nominatim-search.js - search with nominatim service
- openroute.js - routing with OpenRouteService
- osm-place-info.js - gather place information (website, opening hours, etc.) from OSM API and Wikipedia
- sentinel2.js - weekly worldwide 10m satellite imagery from ESA Sentinel-2, with date picker in GUI.
- transform-query.js - modify search query, e.g., for categorial searches
- valhalla-osmde.js - routing with Valhalla provided by osm.de
- wikipedia-search.js - search for geotagged Wikipedia articles
- worldview.js - show daily worldwide satellite imagery from NASA Worldview, with date picker in GUI.
If you have an idea for a plugin, I'm happy to help and to expose the necessary APIs.
Vector maps are styled using Tangram YAML scene files with a few additions:
application.gui_variables
to provide GUI controls in the Edit Source panel linked to scene file globals or shader uniformsapplication.search_data
to define which features and tags should be indexed for offline searchapplication.legend
to define SVG images to be optionally displayed over the map$latitude
and$longitude
for tile center are available for filters to make location-specific adjustments to styling- SVG images are supported for textures; sprites can be created automatically using SVG id attributes.
Tangram styles can include custom shaders. The hillshading, contour lines, and slope angle shading in the above screenshots are all calculated on-the-fly from elevation tiles in a shader - see raster-contour.yaml.
scripts/mb2mz.js is provided to convert a Mapbox style spec JSON file to a Tangram scene file. See scripts/runmb2mz.jz for an example. The included osm-bright.yaml applies the widely-used OSM Bright style to vector tiles using the OpenMapTiles schema.
Displaying a vector map requires a source of vector tiles and a style for specifying how to draw features from the tiles.
The hierarchy for vector tiles consists of:
- Container: filesystem (each tile as a separate file), mbtiles (an sqlite file), pmtiles (special flat file format)
- Tile encoding: PBF (protocol buffer format), GeoJSON, etc.
- Tile format: mapbox vector tiles is dominant - specifies PBF encoding
- Tile schema: Shortbread, OpenMapTiles, Mapzen/Tilezen, Mapbox
A vector tile schema specifies how to group features into layers, which features to include at each zoom level, and which attributes to include for each feature.
The included vector map style stylus-osm.yaml (seen in the above screenshots) uses a custom schema because none of the existing tile schemas satisfied all the requirements for the application. For example, most other schemas define some mapping from OSM tags to feature attributes, but because of the complex and fluid state of OSM tagging this schema just uses unmodified OSM tags for feature attributes.
The schema aims to include more information for transit and for outdoor activities, such as bike and trail features at lower zoom levels and the common trail_visibility tag. The schema layers are: place, boundary, poi, transportation, transit, building, water, and landuse.
The schema is a work-in-progress. Suggestions and comments are welcome.
The application is provided under the GPL-3.0 license. The modified Tangram-ES library retains the MIT license.
- builds for iOS, Windows, and Mac
- 3D terrain and globe view
- contour line labels
- integrate Valhalla for offline routing
- more plugins
- Use QuickJS javascript engine instead of Duktape
- pmtiles support
Tangram-ES supports RTL text and complex shaping through Harfbuzz and Freetype. However, the ugui library used for the GUI does not (yet), so this support is not enabled by default in the application (which incidentally reduces the executable size by almost 50%). Set the TANGRAM_USE_FONTCONTEXT_STB
cmake option to OFF to restore RTL and complex shaping for the map display. Note that such text will not be displayed correctly in the GUI, e.g., when showing place information.
cache/*.mbtiles
- map tile storage; deleting this folder will delete all map tiles, including offline mapsplugins/*.js
- pluginsres/
- various resources for application, e.g. GUI iconsscenes/
- map stylestracks/*.gpx
- tracks and routesconfig.yaml
- settings; exit application before editingfts1.sqlite
- index for offline searchmapsources.yaml
- map sources; exit application before editingplaces.sqlite
- saved places, etc.
Storage use can be controlled with the shrink_at
and shrink_to
values in the storage
section of config.yaml
.
styluslabs/ugui is used for cross-platform GUI. It is a work-in-progress. Suggestions and contributions are welcome.
Search: offline search for local vector tiles, online search via plugins Saved places (bookmarks): import via plugins, export and import GPX, create place list from geotagged photos, choose colors in GUI; further customize styling in [markers.yaml](assets/scenes/markers.yaml] Tracks and routes: record and edit tracks, draw direct (straight-line segments) routes or using plugin for routing Map sources: create and manage map sources, access GUI controls for current map source, show legends Offline maps (via Map sources): create offline map from current source and view, import mbtiles file, manage offline maps Plugin console (via overflow menu): reload plugins, execute Javascript in plugin environment.