1 # Configuring the Import of OSM data
 
   3 In the very first step of a Nominatim import, OSM data is loaded into the
 
   4 database. Nominatim uses [osm2pgsql](https://osm2pgsql.org) for this task.
 
   5 It comes with a [flex style](https://osm2pgsql.org/doc/manual.html#the-flex-output)
 
   6 specifically tailored to filter and convert OSM data into Nominatim's
 
   7 internal data representation. Nominatim ships with a few preset
 
   8 configurations for this import, each results in a geocoding database of
 
  10 [Import section](../admin/Import.md#filtering-imported-data) explains
 
  11 these default configurations in detail.
 
  13 If you want to have more control over which OSM data is added to the database,
 
  14 you can also create your own custom style. Create a new lua style file, put it
 
  15 into your project directory and then set `NOMINATIM_IMPORT_STYLE` to the name
 
  16 of the file. Custom style files can be used to modify the existing preset
 
  17 configurations or to implement your own configuration from scratch.
 
  19 The remainder of the page describes how the flex style works and how to
 
  22 ## The `flex-base` lua module
 
  24 The core of Nominatim's flex import configuration is the `flex-base` module.
 
  25 It defines the table layout used by Nominatim and provides standard
 
  26 implementations for the import callbacks that help with customizing
 
  27 how OSM tags are used by Nominatim.
 
  29 Every custom style must include this module to make sure that the correct
 
  30 tables are created. Thus start your custom style as follows:
 
  33 local flex = require('flex-base')
 
  36 ### Using preset configurations
 
  38 If you want to start with one of the existing presets, then you can import
 
  39 its settings using the `load_topic()` function:
 
  42 local flex = require('flex-base')
 
  44 flex.load_topic('streets')
 
  47 The `load_topic` function takes an optional second configuration
 
  48 parameter. The available options are explained in the
 
  49 [themepark section](#using-osm2pgsql-themepark).
 
  51 Available topics are: `admin`, `street`, `address`, `full`. These topic
 
  52 correspond to the [import styles](../admin/Import.md#filtering-imported-data)
 
  53 you can choose during import. To start with the 'extratags' style, use the
 
  54 `full` topic with the appropriate config parameter:
 
  57 flex.load_topic('full', {with_extratags = true})
 
  61     You can also directly import the preset style files, e.g.
 
  62     `local flex = require('import-street')`. It is not possible to
 
  63     set extra configuration this way.
 
  65 ### How processing works
 
  67 When Nominatim processes an OSM object, it looks for four kinds of tags:
 
  68 The _main tags_ classify what kind of place the OSM object represents. One
 
  69 OSM object can have more than one main tag. In such case one database entry
 
  70 is created for each main tag. _Name tags_ represent searchable names of the
 
  71 place. _Address tags_ are used to compute the address information of the place.
 
  72 Address tags are used for searching and for creating a display name of the place.
 
  73 _Extra tags_ are any tags that are not directly related to search but
 
  74 contain interesting additional information. These are just saved in the database
 
  75 and may be returned with the result [on request](../api/Search.md#output-details).
 
  78     Some tags in the extratags category are used by Nominatim to better
 
  79     classify the place. These tags will always be added, independent of
 
  80     any settings in the style.
 
  82 Configuring the style means deciding which key and/or key/value is used
 
  85 ## Changing the recognized tags
 
  87 The flex style offers a number of functions to set the classification of
 
  88 each OSM tag. Most of these functions can also take a preset string instead
 
  89 of a tag description. These presets describe common configurations that
 
  90 are also used in the definition of the predefined styles. This section
 
  91 lists the configuration functions and the accepted presets.
 
  95 Some of the following functions take _key match lists_. These lists can
 
  96 contain three kinds of strings to match against tag keys:
 
  97 A string that ends in an asterisk `*` is a prefix match and accordingly matches
 
  98 against any key that starts with the given string (minus the `*`). 
 
  99 A suffix match can be defined similarly with a string that starts with a `*`.
 
 100 Any other string is matched exactly against tag keys.
 
 104 `set/modify_main_tags()` allow to define which tags are used as main tags. It
 
 105 takes a lua table parameter which defines for keys and key/value
 
 106 combinations, how they are classified.
 
 108 The following classifications are recognized:
 
 110 | classification  | meaning |
 
 111 | :-------------- | :------ |
 
 112 | always          | Unconditionally use this tag as a main tag. |
 
 113 | named           | Consider as main tag, when the object has a primary name (see [names](#name-tags) below) |
 
 114 | named_with_key  | Consider as main tag, when the object has a primary name with a domain prefix. For example, if the main tag is  `bridge=yes`, then it will only be added as an extra entry, if there is a tag `bridge:name[:XXX]` for the same object. If this property is set, all names that are not domain-specific are ignored. |
 
 115 | fallback        | Consider as main tag only when no other main tag was found. Fallback always implies `named`, i.e. fallbacks are only tried for objects with primary names. |
 
 116 | delete          | Completely ignore the tag in any further processing |
 
 117 | extra           | Move the tag to extratags and then ignore it for further processing |
 
 118 | `<function>`| Advanced handling, see [below](#advanced-main-tag-handling) |
 
 120 Each key in the table parameter defines an OSM tag key. The value may
 
 121 be directly a classification as described above. Then the tag will
 
 122 be considered a main tag for any possible value that is not further defined.
 
 123 To further restrict which values are acceptable, give a table with the
 
 124 permitted values and their kind of main tag. If the table contains a simple
 
 125 value without key, then this is used as default for values that are not listed.
 
 127 `set_main_tags()` will completely replace the current main tag configuration
 
 128 with the new configuration. `modify_main_tags()` will merge the new
 
 129 configuration with the existing one. Merging is done at value level.
 
 130 For example, when the current setting is `highway = {'always', primary = 'named'}`,
 
 131 then `set_main_tags{highway = 'delete'}` will result in a rule
 
 132 `highway = {'delete', primary = 'named'}`.
 
 136     local flex = require('import-full')
 
 139         boundary = {administrative = 'named'},
 
 140         highway = {'always', street_lamp = 'named', no = 'delete'},
 
 145     In this example an object with a `boundary` tag will only be included
 
 146     when it has a value of `administrative`. Objects with `highway` tags are
 
 147     always included with two exceptions: the troll tag `highway=no` is
 
 148     deleted on the spot. And when the value is `street_lamp` then the object
 
 149     must also have a name, to be included. Finally, if a `landuse` tag is
 
 150     present then it will be used independently of the concrete value when
 
 151     neither boundary nor highway tags were found and the object is named.
 
 155 | Name   | Description |
 
 156 | :----- | :---------- |
 
 157 | admin  | Basic tag set collecting places and administrative boundaries. This set is needed also to ensure proper address computation and should therefore always be present. You can disable selected place types like `place=locality` after adding this set, if they are not relevant for your use case. |
 
 158 | all_boundaries | Extends the set of recognized boundaries and places to all available ones. |
 
 159 | natural | Tags for natural features like rivers and mountain peaks. |
 
 160 | street/default | Tags for streets. Major streets are always included, minor ones only when they have a name. |
 
 161 | street/car | Tags for all streets that can be used by a motor vehicle. |
 
 162 | street/all | Includes all highway features named and unnamed. |
 
 163 | poi/delete | Adds most POI features with and without name. Some frequent but very domain-specific values are excluded by deleting them. |
 
 164 | poi/extra | Like 'poi/delete' but excluded values are moved to extratags. |
 
 167 ##### Advanced main tag handling
 
 169 The groups described above are in fact only a preset for a filtering function
 
 170 that is used to make the final decision how a pre-selected main tag is entered
 
 171 into Nominatim's internal table. To further customize handling you may also
 
 172 supply your own filtering function.
 
 174 The function takes up to three parameters: a Place object of the object
 
 175 being processed, the key of the main tag and the value of the main tag.
 
 176 The function may return one of three values:
 
 178 * `nil` or `false` causes the entry to be ignored
 
 179 * the Place object causes the place to be added as is
 
 180 * `Place.copy(names=..., address=..., extratags=...) causes the
 
 181   place to be enter into the database but with name/address/extratags
 
 182   set to the given different values.
 
 184 The Place object has some read-only values that can be used to determine
 
 187 * **object** is the original OSM object data handed in by osm2pgsql
 
 188 * **admin_level** is the content of the admin_level tag, parsed into an integer and normalized to a value between 0 and 15
 
 189 * **has_name** is a boolean indicating if the object has a primary name tag
 
 190 * **names** is a table with the collected list of name tags
 
 191 * **address** is a table with the collected list of address tags
 
 192 * **extratags** is a table with the collected list of additional tags to save
 
 196     local flex = require('flex-base')
 
 198     flex.add_topic('street')
 
 200     local function no_sidewalks(place, k, v)
 
 201         if place.object.tags.footway == 'sidewalk' then
 
 205         -- default behaviour is to have all footways
 
 209     flex.modify_main_tags(highway = {'footway' = no_sidewalks}
 
 211     This script adds a custom handler for `highway=footway`. It only includes
 
 212     them in the database, when the object doesn't have a tag `footway=sidewalk`
 
 213     indicating that it is just part of a larger street which should already
 
 214     be indexed. Note that it is not necessary to check the key and value
 
 215     of the main tag because the function is only used for the specific
 
 221 The function `ignore_keys()` sets the `delete` classification for keys.
 
 222 This function takes a _key match list_ so that it is possible to exclude
 
 225 Note that full matches always take precedence over suffix matches, which
 
 226 in turn take precedence over prefix matches.
 
 230     local flex = require('flex-base')
 
 232     flex.add_topic('admin')
 
 233     flex.ignore_keys{'old_name', 'old_name:*'}
 
 236     This example uses the `admin` preset with the exception that names
 
 237     that are no longer are in current use, are ignored.
 
 241 | Name     | Description |
 
 242 | :-----   | :---------- |
 
 243 | metatags | Tags with meta information about the OSM tag like source, notes and import sources. |
 
 244 | name     | Non-names that actually describe properties or name parts. These names can throw off search and should always be removed. |
 
 245 | address  | Extra `addr:*` tags that are not useful for Nominatim. |
 
 248 ### Tags for `extratags`
 
 250 The function `add_for_extratags()` sets the `extra` classification for keys.
 
 251 This function takes a
 
 252 _key match list_ so that it is possible to move groups of keys to extratags.
 
 254 Note that full matches always take precedence over suffix matches, which
 
 255 in turn take precedence over prefix matches.
 
 259     local flex = require('flex-base')
 
 261     flex.add_topic('street')
 
 262     flex.add_for_extratags{'surface', 'access', 'vehicle', 'maxspeed'}
 
 265     This example uses the `street` preset but adds a couple of tags that
 
 266     are of interest about the condition of the street.
 
 270 Accepts all [presets from ignored tags](#presets_1).
 
 272 ### General pre-filtering
 
 274 _(deprecated)_ `set_prefilters()` allows to set the `delete` and `extra`
 
 275 classification for main tags.
 
 277 This function removes all previously set main tags with `delete` and `extra`
 
 278 classification and then adds the newly defined tags.
 
 280 `set_prefilters()` takes a table with four optional fields:
 
 282 * __delete_keys__ is a _key match list_ for tags that should be deleted
 
 283 * __delete_tags__ contains a table of tag keys pointing to a list of tag
 
 284   values. Tags with matching key/value pairs are deleted.
 
 285 * __extra_keys__ is a _key match list_ for tags which should be saved into
 
 287 * __extra_tags__ contains a table of tag keys pointing to a list of tag
 
 288   values. Tags with matching key/value pairs are moved to extratags.
 
 290 !!! danger "Deprecation warning"
 
 291     Use of this function should be replaced with `modify_main_tags()` to
 
 292     set the data from `delete_tags` and `extra_tags`, with `ignore_keys()`
 
 293     for the `delete_keys` parameter and with `add_for_extratags()` for the
 
 294     `extra_keys` parameter.
 
 298 `set/modify_name_tags()` allow to define the tags used for naming places. Name tags
 
 299 can only be selected by their keys. The import script distinguishes
 
 300 between primary and auxiliary names. A primary name is the given name of
 
 301 a place. Having a primary name makes a place _named_. This is important
 
 302 for main tags that are only included when a name is present. Auxiliary names
 
 303 are identifiers like references. They may be searched for but should not
 
 304 be included on their own.
 
 306 The functions take a table with two optional fields `main` and `extra`.
 
 307 They take _key match lists_ for primary and auxiliary names respectively.
 
 308 A third field `house` can contain tags for names that appear in place of
 
 309 house numbers in addresses. This field can only contain complete key names.
 
 310 'house tags' are special in that they cause the OSM object to be added to
 
 311 the database independently of the presence of other main tags.
 
 313 `set_name_tags()` overwrites the current configuration, while
 
 314 `modify_name_tags()` replaces the fields that are given. (Be aware that
 
 315 the fields are replaced as a whole. `main = {'foo_name'}` will cause
 
 316 `foo_name` to become the only recognized primary name. Any previously
 
 317 defined primary names are forgotten.)
 
 321     local flex = require('flex-base')
 
 323     flex.set_main_tags{highway = {traffic_light = 'named'}}
 
 324     flex.set_name_tags{main = {'name', 'name:*'},
 
 329     This example creates a search index over traffic lights but will
 
 330     only include those that have a common name and not those which just
 
 331     have some reference ID from the city.
 
 335 | Name     | Description |
 
 336 | :-----   | :---------- |
 
 337 | core     | Basic set of recognized names for all places. |
 
 338 | address  | Additional names useful when indexing full addresses. |
 
 339 | poi      | Extended set of recognized names for pois. Use on top of the core set. |
 
 343 `set/modify_address_tags()` defines the tags that will be used to build
 
 344 up the address of an object. Address tags can only be chosen by their key.
 
 346 The functions take a table with arbitrary fields, each defining
 
 347 a key list or _key match list_. Some fields have a special meaning:
 
 349 | Field     | Type      | Description |
 
 350 | :---------| :-------- | :-----------|
 
 351 | main      | key list  | Tags that make a full address object out of the OSM object. This is usually the house number or variants thereof. If a main address tag appears, then the object will always be included, if necessary with a fallback of `place=house`. If the key has a prefix of `addr:` or `is_in:` this will be stripped. |
 
 352 | extra     | key match list | Supplementary tags for addresses, tags like `addr:street`, `addr:city` etc. If the key has a prefix of `addr:` or `is_in:` this will be stripped. |
 
 353 | interpolation | key list | Tags that identify address interpolation lines. |
 
 354 | country   | key match list | Tags that may contain the country the place is in. The first found value with a two-letter code will be accepted, all other values are discarded. |
 
 355 | _other_   | key match list | Summary field. If a key matches the key match list, then its value will be added to the address tags with the name of the field as key. If multiple tags match, then an arbitrary one wins. |
 
 357 `set_address_tags()` overwrites the current configuration, while
 
 358 `modify_address_tags()` replaces the fields that are given. (Be aware that
 
 359 the fields are replaced as a whole.)
 
 363     local flex = require('import-full')
 
 365     flex.set_address_tags{
 
 366         main = {'addr:housenumber'},
 
 368         postcode = {'postal_code', 'postcode', 'addr:postcode'},
 
 369         country = {'country_code', 'ISO3166-1'}
 
 373     In this example all tags which begin with `addr:` will be saved in
 
 374     the address tag list. If one of the tags is `addr:housenumber`, the
 
 375     object will fall back to be entered as a `place=house` in the database
 
 376     unless there is another interested main tag to be found.
 
 378     Tags with keys `country_code` and `ISO3166-1` are saved with their
 
 379     value under `country` in the address tag list. The same thing happens
 
 380     to postcodes, they will always be saved under the key `postcode` thus
 
 381     normalizing the multitude of keys that are used in the OSM database.
 
 385 | Name     | Description |
 
 386 | :-----   | :---------- |
 
 387 | core     | Basic set of tags needed to recognize address relationship for any place. Always include this. |
 
 388 | houses   | Additional set of tags needed to recognize proper addresses |
 
 390 ### Handling of unclassified tags
 
 392 `set_unused_handling()` defines what to do with tags that remain after all tags
 
 393 have been classified using the functions above. There are two ways in
 
 394 which the function can be used:
 
 396 `set_unused_handling(delete_keys = ..., delete_tags = ...)` deletes all
 
 397 keys that match the descriptions in the parameters and moves all remaining
 
 398 tags into the extratags list.
 
 400 `set_unused_handling(extra_keys = ..., extra_tags = ...)` moves all tags
 
 401 matching the parameters into the extratags list and then deletes the remaining
 
 402 tags. For the format of the parameters see the description in `set_prefilters()`
 
 405 When no special handling is set, then unused tags will be discarded with one
 
 406 exception: place tags are kept in extratags for administrative boundaries.
 
 407 When using a custom setting, you should also make sure that the place tag
 
 408 is added for extratags.
 
 412     local flex = require('import-full')
 
 414     flex.set_address_tags{
 
 415         main = {'addr:housenumber'},
 
 416         extra = {'addr:*', 'tiger:county'}
 
 418     flex.set_unused_handling{delete_keys = {'tiger:*'}}
 
 421     In this example all remaining tags except those beginning with `tiger:`
 
 422     are moved to the extratags list. Note that it is not possible to
 
 423     already delete the tiger tags with `set_prefilters()` because that
 
 424     would remove tiger:county before the address tags are processed.
 
 426 ## Filling additional tables
 
 428 Most of the OSM objects are saved in the main `place` table for further
 
 429 processing. In addition to that, there are some smaller tables that save
 
 430 specialised information. The content of these tables can be customized as
 
 435 The table `place_entrance` saves information about OSM nodes that represent
 
 436 an entrance. This data is later mingled with buildings and other areas and
 
 437 can be returned [on request](../api/Search.md#output-details). The table
 
 438 saves the type of entrance as well as a set of custom extra tags.
 
 440 The function `set_entrance_filter()` can be used to customize the table's
 
 443 When called without any parameter, then filling the entrance table will be
 
 444 disabled. When called with a preset name, the appropriate preset will be
 
 447 To create a custom configuration, call the function
 
 448 with a table with the following fields:
 
 450 * __main_tags__ is a list of tags that mark an entrance node. The value of the
 
 451   first tag found in the list will be used as the entrance type.
 
 452 * __extra_include__ is an optional list of tags to be added to the extratags
 
 453   for this entrance. When left out, all tags except for the ones defined
 
 454   in 'main_tags' will be included. To disable saving of extra tags, set
 
 455   this to the empty list.
 
 456 * __extra_exclude__ defines an optional list of tags to drop before including
 
 457   the remaining tags as extratags. Note that the tags defined in 'main_tags'
 
 458   will always be excluded, independently of this setting.
 
 460 To have even more fine-grained control over the output, you can also hand
 
 461 in a callback for processing entrance information. The callback function
 
 462 receives a single parameter, the
 
 463 [osm2pgsql object](https://osm2pgsql.org/doc/manual.html#processing-callbacks).
 
 464 This object itself must not be modified. The callback should return either
 
 465 `nil` when the object is not an entrance. Or it returns a table with a
 
 466 mandatory `entrance` field containing a string with the type of entrance
 
 467 and an optional `extratags` field with a simple key-value table of extra
 
 472 | Name     | Description |
 
 473 | :-----   | :---------- |
 
 474 | default  | Standard configuration used with `full` and `extratags` styles. |
 
 476 ## Customizing osm2pgsql callbacks
 
 478 osm2pgsql expects the flex style to implement three callbacks, one process
 
 479 function per OSM type. If you want to implement special handling for
 
 480 certain OSM types, you can override the default implementations provided
 
 481 by the flex-base module.
 
 483 ### Enabling additional relation types
 
 485 OSM relations can represent very diverse
 
 486 [types of real-world objects](https://wiki.openstreetmap.org/wiki/Key:type). To
 
 487 be able to process them correctly, Nominatim needs to understand how to
 
 488 create a geometry for each type. By default, the script knows how to
 
 489 process relations of type `multipolygon`, `boundary` and `waterway`. All
 
 490 other relation types are ignored.
 
 492 To add other types relations, set `RELATION_TYPES` for
 
 493 the type to the kind of geometry that should be created. The following
 
 494 kinds of geometries can be used:
 
 496 * __relation_as_multipolygon__ creates a (Multi)Polygon from the ways in
 
 497   the relation. If the ways do not form a valid area, then the object is
 
 499 * __relation_as_multiline__ creates a (Multi)LineString from the ways in
 
 500   the relations. Ways are combined as much as possible without any regards
 
 501   to their order in the relation.
 
 505     local flex = require('import-full')
 
 507     flex.RELATION_TYPES['site'] = flex.relation_as_multipolygon
 
 510     With this line relations of `type=site` will be included in the index
 
 511     according to main tags found. This only works when the site relation
 
 512     resolves to a valid area. Nodes in the site relation are not part of the
 
 516 ### Adding additional logic to processing functions
 
 518 The default processing functions are also exported by the flex-base module
 
 519 as `process_node`, `process_way` and `process_relation`. These can be used
 
 520 to implement your own processing functions with some additional processing
 
 525     local flex = require('import-full')
 
 527     function osm2pgsql.process_relation(object)
 
 528         if object.tags.boundary ~= 'administrative' or object.tags.admin_level ~= '2' then
 
 529           flex.process_relation(object)
 
 534     This example discards all country-level boundaries and uses standard
 
 535     handling for everything else. This can be useful if you want to use
 
 536     your own custom country boundaries.
 
 539 ### Customizing the main processing function
 
 541 !!! danger "Deprecation Warning"
 
 542     The style used to allow overwriting the internal processing function
 
 543     `process_tags()`. While this is currently still possible, it is no longer
 
 544     encouraged and may stop working in future versions. The internal
 
 545     `Place` class should now be considered read-only.
 
 548 ## Using osm2pgsql-themepark
 
 550 The Nominatim osm2pgsql style is designed so that it can also be used as
 
 551 a theme for [osm2pgsql-themepark](https://osm2pgsql.org/themepark/). This
 
 552 makes it easy to combine Nominatim with other projects like
 
 553 [openstreetmap-carto](https://github.com/gravitystorm/openstreetmap-carto)
 
 554 in the same database.
 
 556 To set up one of the preset styles, simply include a topic with the same name:
 
 559 local themepark = require('themepark')
 
 560 themepark:add_topic('nominatim/address')
 
 563 Themepark topics offer two configuration options:
 
 565 * **street_theme** allows to choose one of the sub topics for streets:
 
 566     * _default_ - include all major streets and named minor paths
 
 567     * _car_ - include all streets physically usable by cars
 
 568     * _all_ - include all major streets and minor paths
 
 569 * **with_extratags**, when set to a truthy value, then tags that are
 
 570   not specifically used for address or naming are added to the
 
 573 The customization functions described in the
 
 574 [Changing recognized tags](#changing-the-recognized-tags) section
 
 575 are available from the theme. To access the theme you need to explicitly initialize it.
 
 579     local themepark = require('themepark')
 
 581     themepark:add_topic('nominatim/full', {with_extratags = true})
 
 583     local flex = themepark:init_theme('nominatim')
 
 585     flex.modify_main_tags{'amenity' = {
 
 586                            'waste_basket' = 'delete'}
 
 589     This example uses the full Nominatim configuration but disables
 
 590     importing waste baskets.
 
 592 You may also write a new configuration from scratch. Simply omit including
 
 593 a Nominatim topic and only call the required customization functions.
 
 595 Customizing the osm2pgsql processing functions as explained
 
 596 [above](#adding-additional-logic-to-processing-functions) is not possible
 
 597 when running under themepark. Instead include other topics that make the
 
 598 necessary modifications or add an additional processor before including
 
 603     local themepark = require('themepark')
 
 605     local function discard_country_boundaries(object)
 
 606         if object.tags.boundary == 'administrative' and object.tags.admin_level == '2' then
 
 611     themepark:add_proc('relation', discard_country_boundaries)
 
 612     -- Order matters here. The topic needs to be added after the custom callback.
 
 613     themepark:add_topic('nominatim/full', {with_extratags = true})
 
 615     Discarding country-level boundaries when running under themepark.
 
 617 ## Changing the style of existing databases
 
 619 There is usually no issue changing the style of a database that is already
 
 620 imported and now kept up-to-date with change files. Just be aware that any
 
 621 change in the style applies to updates only. If you want to change the data
 
 622 that is already in the database, then a reimport is necessary.