This article describes how to use the POI API in mapsforge POI library (from
If you have any questions or problems, don't hesitate to ask our public forum for help.
Points of Interest (POIs) are points with a given position, category and data. A POI database is used to store a set of POIs and to search for POIs within a given area.
The mapsforge POI library uses SQLite for storing POIs. For efficiency reasons Android's SQLite implementation is not used. Instead SQLite Android Bindings is used to provide an SQLite implementation with R-tree functionality.
All reading and writing operations are done via classes implementing the
PoiPersistenceManager interface. This allows adding, removing and changing POIs at any time. POI categories can be defined on creation time only. Categories are implemented as trees and can be accessed via classes implementing the
Externally you can use your favorite SQLite manager for browsing the database, e.g. spatialite-gui.
This section provides you with information how to create a POI database, how to use it for POI search and how to visualize the results.
Creating a POI Database
The tool is implemented as a plugin to the Osmosis software. To use the tool, you are required to have a working installation of Osmosis and the writer plugin copied to the plugins directory of Osmosis. You should also be familiar with the Osmosis tool.
To convert OSM data to a POI database execute the following command:
$OSMOSIS_HOME/bin/osmosis --rb file=your_map_file.osm.pbf --poi-writer file=your_database.poi
--poi-writer, or short
--pw task indicates that the POI writer plugin should handle the data that was read from the given OSM stream.
|Option||Description||Valid values||Default value|
||Path to the output file, the file will be overwritten if existent. By convention we use the file ending
||Bounding box definition as comma-separated list of coordinates in the form: minLat,minLon,maxLat,maxLon (be aware that osmosis does not allow white space in its command line parameters).||minLat, minLon, maxLat, maxLon in exactly this order as degrees||(blank)|
||Export all tags. If false only the name will be exported.||true/false||true|
||If not specified, only the default language with no tag will be written to the file. If a language is specified, it will be written if its tag is found, otherwise the default language will be written. Redundant if all-tags is true.||language code as defined in ISO 639-1 or ISO 639-2 if an ISO 639-1 code doesn't exist||(blank)|
||Writes a comment to the file.||(blank)|
||Enable progress logs||true/false||true|
Advanced Options (only use when you know what you are doing)
|Option||Description||Valid values||Default value|
||Path to an XML configuration file that contains mappings from OSM tags to category names and a hierarchy of those categories.||path to an XML file||(blank) internal default poi mapping is used|
||Add only named entities.||true/false||true|
||Also parse ways.||true/false||true|
||Add normalized_name (for accent insensitive search). Works if all-tags is true.||true/false||false|
||Add geo tags.||true/false||false|
||Drop empty categories.||true/false||true|
With the POI database created you can now use it with mapsforge. For testing purposes, you may also use one of our ready-to-use POI databases from our server (not suitable for mass downloads). You will also need the SQLite Android Bindings native library files in your project. You can use the Samples project as a boilerplate, as it already has all necessary files and dependencies. The library files are located each within a separate sub-folder for each target architecture (armeabi-v7a, arm64-v8a, x86, x86_64). You can delete unneeded architectures to reduce file size.
The sources for those libraries can be found at SQLite Android Bindings site. To compile these manually you need the Android NDK. The compilation process can be started with
ndk-build from within the
jni directory. The compiling process also moves the library files to their correct (sub)folders.
With everything set up you can check the 'POI search' example for:
- How a database is opened for read access. Any access to the database is encapsulated via classes implementing
PoiPersistenceManager. The instantiation of these classes is done via a factory class. The categories and their hierarchy are maintained via classes implementing
PoiCategoryManager. The category configuration is read-only.
PoiPersistenceManagerobject is used for querying the POIs in various ways. The query returns a collection of
PointOfInterestobjects. These are containers that contain a POI's position, ID, category and additional data. Additional data are stored as a string and can be arbitrary. There is no specification for the encoding of those data. The current implementation stores the POI's tags as an UTF-8 encoded string in the data field.
- It is always a good idea to close an open database when there will be no more operations on it. This can simply be done by the
- With this done you can simply retrieve the POIs and add them as overlays.
- In order to get POI write access call
getPoiPersistenceManager(filename, false)via the factory class.
Custom Category Configurations
If the provided category configuration does not fulfill your needs, you can easily create your own.
The default internal poi mapping is defined in https://github.com/mapsforge/mapsforge/blob/master/mapsforge-poi-writer/src/main/config/poi-mapping.xml. So if you want to define your own custom mapping, use the internal mapping as a reference.
Please consult the XML-Schema documentation of https://github.com/mapsforge/mapsforge/blob/master/resources/poi-mapping.xsd to learn about how to implement your custom mapping. The XML-Schema is very easy to understand. We recommend to use a proper editor for XML to allow auto-completion and validation if you provide an XML-Schema.
The API supports POI search inside a specified rectangle, near a given position or by a tag-data pattern.
You can also use category filters for filtering the results based on the categories added to them.
And lastly you can search by OSM tags. With '*' you can search through all tags,
Tag tag1 = new Tag("*", Pergamonmuseum);
Then you add them to a list
tagList.add(new Tag("addr:street", "Bodestraße")) and call
persistenceManager.findInRect(bbox, categoryFilter, tagList, 1)
POI DB Schema
The DB schema consists of:
poi_categorieswith the categories tree
poi_datawith the POI information
poi_category_mapwith the POI categories mapping
- Virtual & shadow correlated tables holding the R-tree index
metadatawith the DB metadata
|1||2016-06-11||Initial release of the specification|