- Notifications
You must be signed in to change notification settings - Fork337
an open source geocoder for openstreetmap data
License
komoot/photon
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
photon is an open source geocoder built forOpenStreetMap data. It is based onelasticsearch/OpenSearch -an efficient, powerful and highly scalable search platform.
photon was started bykomoot who also provide thepublic demo server atphoton.komoot.io.
- high performance
- highly scalability
- search-as-you-type
- multilingual search
- location bias
- typo tolerance
- filter by osm tag and value
- filter by bounding box
- reverse geocode a coordinate to an address
- OSM data import (built uponNominatim) inclusive continuous updates
- import and export dumps in concatenated JSON format
You can try out photon via the demo server athttps://photon.komoot.io. You are welcome to usethe API for your project as long as the number of requests stay in a reasonablelimit. Extensive usage will be throttled or completely banned. We do notgive guarantees for availability and reserve the right to implement changeswithout notice.
If you have a larger number of requests to make, please consider setting upyour own private instance. It is as simple as downloading two files and startingthe server. See instructions below.
photon was originally built on ElasticSearch. For technical reasons, we arestuck with a very old an unsupported version 5.6 of ElasticSearch. Over thelast year, photon has been ported to the latest version of OpenSearch. Thisversion can now be considered stable. When setting up a new instance ofphoton, please usephoton-opensearch. This will become the defaultand only available version soon.
photon requires Java, version 21+.
If you want to run against an external database instead of using the embeddedserver, OpenSearch 3.x is needed.
A planet-wide database requires about 220GB disk space (as of 2025, grows byabout 10% a year). Using SSDs for storage is strongly recommended, NVME wouldeven be better. At least 64GB RAM are recommended for smooth operations, more,if the server takes significant load. Running photon with less RAM is possiblebut consider increasing the available heap (usingjava -Xmx8G -jar ... forexample). Be careful to make sure that there remains enough free RAM that thesystem doesn't start swapping.
If you want to import data from Nominatim, there are additionalrequirements for Nominatim.
This is the easiest way to set up a self-hosted photon instance.Pre-built jar files can be downloaded from theGithub release page.Preferably get the photon-opensearch jar file.
GraphHopper kindly provides weekly updateddumps of the photon database athttps://download1.graphhopper.com/public.The dumps are available for the world-wide dataset and for selected country datasets.The dumps contain names in English, German, French and local language. Thereis no support forfull geometry output. If you needthis feature, you need to import your own database, see below.
For ElasticSearch photon use:
- world-wide:
https://download1.graphhopper.com/public/ - country extracts:
https://download1.graphhopper.com/public/extracts/
For OpenSearch photon use:
- world-wide:
https://download1.graphhopper.com/public/experimental/ - country extracts:
https://download1.graphhopper.com/public/experimental/extracts/
Make sure you have bzip2 or pbzip2 installed. Do not use WinRAR for unpacking,it is known to have issues with the files. Execute one of these twocommands in your shell to download, uncompress and extract the hugedatabase in one step:
wget -O - https://download1.graphhopper.com/public/photon-db-planet-0.7OS-latest.tar.bz2 | bzip2 -cd | tar x# you can significantly speed up extracting using pbzip2 (recommended):wget -O - https://download1.graphhopper.com/public/photon-db-planet-0.7OS-latest.tar.bz2 | pbzip2 -cd | tar xDon't forget to adapt the directory tomatch your photon version.
You need to swap out the databases atomically: download and unpack the new version, swap the directories to put the new directory in place of the old one, then restart photon. Now delete the old database. This unfortunately means you need twice the space of the database for updates.
Do not unpack the database in place of the old one. This will lead to corrupted data.
photon uses gradle for building. To build the package from source make sure you have a JDK installed. Then run:
./gradlew buildThis will build and test photon in the ElasticSearch and OpenSearch version.The final jar can be found in thetarget directory.
Start photon with the following command:
java -jar photon-*.jarUse-data-dir to point to theparent directory of thephoton_data directorywith the database. By default photon will look for aphoton_data directoryin the current working directory.
Alternatively, you can make photon connect to an external ElasticSearch/OpenSearchinstance. Use the parameter-transport-addresses to define a comma-separatedlist of addresses of external nodes.
When photon is started without any parameters, it starts up a webserver with thephoton API athttp://localhost:2322. You canchange the listening address with-listen-ip <ip address> and the port with-listen-port <port number>. A description of the API endpoints is at theend of this README.
To enable CORS (cross-site requests), use-cors-any to allow any origin or-cors-origin with a specific origin as the argument. By default, CORS supportis disabled.
-languages <languages> restricts which languages are supported to be searchedand returned by the API. This may be used to temporarily restrict the languageto a different set than what was originally imported.
-default-language allows to chose in which language results are returnedwhen the user hasn't explicitly (or implicitly via the Accept-Language header)chosen a language. The default is to return all results in the local language.
-enable-update-api adds a special endpoint that triggers updates from aNominatim API, see "Updating data via Nominatim" below. If this option isenabled, you also need to add the connection parameters for the database.
-max-results and-max-reverse-results can be used to change the upper limitof thelimit parameter, which defines the maximum number of results returned,for forward (/api) and reverse searches respectively. The limit parameter willbe silenty trimmed to what is set here. The default is 50 results.
-query-timeout sets the number of seconds after which a query to thedatabase will be canceled and an error returned to the user.
Photon has limited support for synonyms. Check out thesynonym documentation for more information.
If you want to have a database with a different set of data than provided bythe dumps, you can create a photon database by importing the data froma Nominatim instance. To learn how to set up a Nominatim database, referto theinstallation documentation.
If you haven't already set a password for your Nominatim database user,do it now (change user name and password as you like, below):
psql -d nominatim -c "ALTER USER nominatim WITH ENCRYPTED PASSWORD 'mysecretpassword'"Import the data to photon:
java -jar photon-*.jar -nominatim-import -host localhost -port 5432 -database nominatim -user nominatim -password mysecretpassword -languages es,frThe import of worldwide data set takes about half a day. SSD/NVME disks arerecommended to accelerate Nominatim queries.
There are a couple of parameters that influence which kind of data will beimported:
-languages <languages> states which languagesin addition to the local nameare added to the database. Give the languages as a comma-separated list oflanguage codes. Note that a very long list of languages will slow down queries.This is a known restriction we are working on. You can still import a large listbut then might need to restrict the languages that are actively used when startingthe API service.
-country-codes allows to filter the data to be imported by country. Set thisto a comma-separated list of two-letter language codes.
-extra-tags defines a set of tags to add from Nominatim'sextratags column.Either give a comma-separated list of OSM tags to include or set the specialkeywordALL to unconditionally include all extra tags. The default is toinclude nothing.
When-import-geometry-column is set, photon will not only include centroidand bounding box in results but the full geometry as well.WARNING:enabling this option will more than double the size of the database.(Experimental Feature!)
Once you have imported your own photon database from a Nominatim source, youcan keep up-to-date with the source through regular updates.
First prepare the Nominatim database with the appropriate triggers:
java -jar photon-*.jar -database nominatim -user nominatim -password ... -nominatim-update-init-for update_userThis script must be run with a user that has the right to create tables,functions and triggers.
'update-user' is the PostgreSQL user that will be used when updating thePhoton database. The user needs to already have read rights on the database.It also needs to be able to update the status table. The necessaryupdate rights will be granted during initialisation.
Now you can run updates on Nominatim using the usual methods as describedin thedocumentation.To bring the Photon database up-to-date, make sure the Nominatim updatesare not running and then run the Photon update process:
java -jar photon-*.jar -nominatim-update -database nominatim -user nominatim -password ...Alternatively, you can trigger updates via a special API endpoint. To be ableto do so, you need to run photon with the update API enabled:
java -jar photon-*.jar -enable-update-api -database nominatim -user nominatim -password ...The update is then triggered like this:
curl http://localhost:2322/nominatim-updateThis will trigger a single updates run. If another update is already in progress,the request returns with an error. You can also check if the updates havefinished by using the status API:
curl http://localhost:2322/nominatim-update/statusIt returns a single JSON string: "BUSY" when updates are in progress,or "OK" when another update round can be started.
For your convenience, this repository contains a script to continuouslyupdate both Nominatim and Photon using Photon's update API. Make sure youhave Photon started with -enable-update-api and then run:
export NOMINATIM_DIR=/srv/nominatim/..../continuously_update_from_nominatim.shwhere NOMINATIM_DIR is the project directory of your Nominatim installation.
Imports normally write the data directly into a ElasticSearch/OpenSearchdatabase. When adding the parameter-json <filename> the data is writtenout as a newline-delimited JSON dump file instead. All parameter that influencea database import are valid for a JSON dump as well. To dump the data tostandard output (for example, to directly pack the data), use-json -.
To read a dump file previously created with photon, use the following command:
java -jar photon-*.jar -nominatim-import -import-file <filename>When the filename is-, then photon reads from standard input allowing youto unpack dump files on the fly.
The file import accepts all the parameters of an import from a Nominatim database.That means that you can create a dump file of a full Nominatim database and thenlater import it into different photon databases with different filteringoptins like-country-code,-language or-extra-tags.
photon has three default endpoints:/api for forward search,/reverse forreverse geocding and/status as a health check of the server.
For the/structured endpoint for structured queries, seedocs/structured.md. This endpoint is not availableon the public demo server.
The/update endpoint for triggering updates is described in the section"Updating data via Nominatim" above.
A simple forward search for a place looks like this:
http://localhost:2322/api?q=berlinhttp://localhost:2322/api?q=berlin&lon=10&lat=52&zoom=12&location_bias_scale=0.1There are two optional parameters to influence the location bias. 'zoom'describes the radius around the center to focus on. This is a number thatshould correspond roughly to the map zoom parameter of a corresponding map.The default iszoom=16.
Thelocation_bias_scale describes how much the prominence of a result shouldstill be taken into account. Sensible values go from 0.0 (ignore prominencealmost completely) to 1.0 (prominence has approximately the same influence).The default is 0.2.
http://localhost:2322/api?q=berlin&bbox=9.5,51.5,11.5,53.5The expected format for the bounding box is minLon,minLat,maxLon,maxLat.
The basic lookup of a coordinate looks like this:
http://localhost:2322/reverse?lon=10&lat=52&radius=10The optional radius parameter can be used to specify a value in kilometersto reverse geocode within. The value has to be between 0 and 5000 km.
The following parameters work for search, reverse search andstructured search.
http://localhost:2322/api?q=berlin&limit=2http://localhost:2322/api?q=berlin&lang=itIf omitted the'accept-language' HTTP headerwill be used (browsers set this by default). If neither is set the local name of the place is returned. In OpenStreetMapdata that's usually the value of thename tag, for example the local name for Tokyo is 東京都.
Filter results bytags and values
Note: the filter only works on principal OSM tags and not all OSM tag/value combinations can be searched. The actual list depends on the import style used for the Nominatim database (e.g.settings/import-full.style). All tag/value combinations with a property 'main' are included in the photon database.If one or many query parameters namedosm_tag are present, photon will attempt to filter results by those tags. In general, here is the expected format (syntax) for the value of osm_tag request parameters.
- Include places with tag:
osm_tag=key:value - Exclude places with tag:
osm_tag=!key:value - Include places with tag key:
osm_tag=key - Include places with tag value:
osm_tag=:value - Exclude places with tag key:
osm_tag=!key - Exclude places with tag value:
osm_tag=:!value
For example, to search for all places namedberlin with tag oftourism=museum, one should construct url as follows:
http://localhost:2322/api?q=berlin&osm_tag=tourism:museumOr, just by they key
http://localhost:2322/api?q=berlin&osm_tag=tourismYou can also use this feature for reverse geocoding. Want to see the 5 pharmacies closest to a location ?
http://localhost:2322/reverse?lon=10&lat=52&osm_tag=amenity:pharmacy&limit=5List of available layers:
- house
- street
- locality
- district
- city
- county
- state
- country
- other (e.g. natural features)
http://localhost:2322/api?q=berlin&layer=city&layer=localityExample above will return both cities and localities.
Useinclude andexclude parameters to filter by category. Whatcategories are defined depends on the specific installation of Photon.
See thecategory documentation for more information.
http://localhost:2322/api?q=berlin&dedupe=1Sometimes you have several objects in OSM identifying the same place or object in reality.The simplest case is a street being split into many different OSM ways due to different characteristics.Photon will attempt to detect such duplicates and only return one match.Settingdedupe parameter to0 disables this deduplication mechanism and ensures that all results are returned.By default, Photon will attempt to deduplicate results which have the samename,postcode, andosm_value if exists.
Photon returns a response inGeocodeJson formatwith the following extra fields added:
extrais an object containing any extra tags, if available.
Example response:
json{ "features": [ { "properties": { "name": "Berlin", "state": "Berlin", "country": "Germany", "countrycode": "DE", "osm_key": "place", "osm_value": "city", "osm_type": "N", "osm_id": 240109189 }, "type": "Feature", "geometry": { "type": "Point", "coordinates": [13.3888599, 52.5170365] } }, { "properties": { "name": "Berlin Olympic Stadium", "street": "Olympischer Platz", "housenumber": "3", "postcode": "14053", "state": "Berlin", "country": "Germany", "countrycode": "DE", "osm_key": "leisure", "osm_value": "stadium", "osm_type": "W", "osm_id": 38862723, "extent": [13.23727, 52.5157151, 13.241757, 52.5135972] }, "type": "Feature", "geometry": { "type": "Point", "coordinates": [13.239514674078611, 52.51467945] } } ]}http://localhost:2322/statusreturns a JSON document containing the status and the last update date ofthe data. (That is the date, when the data is from, not when it was importedinto photon.)
All code contributions and bug reports are welcome.
For questions please either useGithub discussions or join theOpenStreetMap forum.
photon software is open source and licensed underApache License, Version 2.0
- photon's search configuration was developed with a specific test framework. It is written in Python andhosted separately.
- There is aleaflet-plugin for displaying a search box with a photon server in the backend.
About
an open source geocoder for openstreetmap data
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.