]> git.openstreetmap.org Git - nominatim.git/blob - docs/customize/Import-Styles.md
Merge pull request #3617 from mtmail/pr-3615-wording
[nominatim.git] / docs / customize / Import-Styles.md
1 # Configuring the Import of OSM data
2
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
9 different detail. The
10 [Import section](../admin/Import.md#filtering-imported-data) explains
11 these default configurations in detail.
12
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.
18
19 The remainder of the page describes how the flex style works and how to
20 customize it.
21
22 ## The `flex-base` lua module
23
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.
28
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:
31
32 ``` lua
33 local flex = require('flex-base')
34 ```
35
36 ### Using preset configurations
37
38 If you want to start with one of the existing presets, then you can import
39 its settings using the `import_topic()` function:
40
41 ```
42 local flex = require('flex-base')
43
44 flex.import_topic('streets')
45 ```
46
47 The `import_topic` function takes an optional second configuration
48 parameter. The available options are explained in the
49 [themepark section](#using-osm2pgsql-themepark).
50
51 !!! note
52     You can also directly import the preset style files, e.g.
53     `local flex = require('import-street')`. It is not possible to
54     set extra configuration this way.
55
56 ### How processing works
57
58 When Nominatim processes an OSM object, it looks for four kinds of tags:
59 The _main tags_ classify what kind of place the OSM object represents. One
60 OSM object can have more than one main tag. In such case one database entry
61 is created for each main tag. _Name tags_ represent searchable names of the
62 place. _Address tags_ are used to compute the address hierarchy of the place.
63 Address tags are used for searching and for creating a display name of the place.
64 _Extra tags_ are any tags that are not directly related to search but
65 contain interesting additional information.
66
67 !!! danger
68     Some tags in the extratags category are used by Nominatim to better
69     classify the place. You want to make sure these are always present
70     in custom styles.
71
72 Configuring the style means deciding which key and/or key/value is used
73 in which category.
74
75 ## Changing the recognized tags
76
77 The flex style offers a number of functions to set the classification of
78 each OSM tag. Most of these functions can also take a preset string instead
79 of a tag description. These presets describe common configurations that
80 are also used in the definition of the predefined styles. This section
81 lists the configuration functions and the accepted presets.
82
83 #### Key match lists
84
85 Some of the following functions take _key match lists_. These lists can
86 contain three kinds of strings to match against tag keys:
87 A string that ends in an asterisk `*` is a prefix match and accordingly matches
88 against any key that starts with the given string (minus the `*`). 
89 A suffix match can be defined similarly with a string that starts with a `*`.
90 Any other string is matched exactly against tag keys.
91
92 ###  Main tags
93
94 `set/modify_main_tags()` allow to define which tags are used as main tags. It
95 takes a lua table parameter which defines for keys and key/value
96 combinations, how they are classified.
97
98 The following classifications are recognized:
99
100 | classification  | meaning |
101 | :-------------- | :------ |
102 | always          | Unconditionally use this tag as a main tag. |
103 | named           | Consider as main tag, when the object has a primary name (see [names](#name-tags) below) |
104 | 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. |
105 | 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. |
106 | delete          | Completely ignore the tag in any further processing |
107 | extra           | Move the tag to extratags and then ignore it for further processing |
108 | `<function>`| Advanced handling, see [below](#advanced-main-tag-handling) |
109
110 Each key in the table parameter defines an OSM tag key. The value may
111 be directly a classification as described above. Then the tag will
112 be considered a main tag for any possible value that is not further defined.
113 To further restrict which values are acceptable, give a table with the
114 permitted values and their kind of main tag. If the table contains a simple
115 value without key, then this is used as default for values that are not listed.
116
117 `set_main_tags()` will completely replace the current main tag configuration
118 with the new configuration. `modify_main_tags()` will merge the new
119 configuration with the existing one. Otherwise, the two functions do exactly
120 the same.
121
122 !!! example
123     ``` lua
124     local flex = require('import-full')
125
126     flex.set_main_tags{
127         boundary = {administrative = 'named'},
128         highway = {'always', street_lamp = 'named', no = 'delete'},
129         landuse = 'fallback'
130     }
131     ```
132
133     In this example an object with a `boundary` tag will only be included
134     when it has a value of `administrative`. Objects with `highway` tags are
135     always included with two exceptions: the troll tag `highway=no` is
136     deleted on the spot. And when the value is `street_lamp` then the object
137     must have a name, too. Finally, if a `landuse` tag is present then
138     it will be used independently of the concrete value when neither boundary
139     nor highway tags were found and the object is named.
140
141 ##### Presets
142
143 | Name   | Description |
144 | :----- | :---------- |
145 | 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. |
146 | all_boundaries | Extends the set of recognized boundaries and places to all available ones. |
147 | natural | Tags for natural features like rivers and mountain peaks. |
148 | street/default | Tags for streets. Major streets are always included, minor ones only when they have a name. |
149 | street/car | Tags for all streets that can be used by a motor vehicle. |
150 | street/all | Includes all highway features named and unnamed. |
151 | poi/delete | Adds most POI features with and without name. Some frequent but very domain-specific values are excluded by deleting them. |
152 | poi/extra | Like 'poi/delete' but excluded values are moved to extratags. |
153
154
155 ##### Advanced main tag handling
156
157 The groups described above are in fact only a preset for a filtering function
158 that is used to make the final decision how a pre-selected main tag is entered
159 into Nominatim's internal table. To further customize handling you may also
160 supply your own filtering function.
161
162 The function takes up to three parameters: a Place object of the object
163 being processed, the key of the main tag and the value of the main tag.
164 The function may return one of three values:
165
166 * `nil` or `false` causes the entry to be ignored
167 * the Place object causes the place to be added as is
168 * `Place.copy(names=..., address=..., extratags=...) causes the
169   place to be enter into the database but with name/address/extratags
170   set to the given different values.
171
172 The Place object has some read-only values that can be used to determine
173 the handling:
174
175 * **object** is the original OSM object data handed in by osm2pgsql
176 * **admin_level** is the content of the admin_level tag, parsed into an integer and normalized to a value between 0 and 15
177 * **has_name** is a boolean indicating if the object has a primary name tag
178 * **names** is a table with the collected list of name tags
179 * **address** is a table with the collected list of address tags
180 * **extratags** is a table with the collected list of additional tags to save
181
182 !!! example
183     ``` lua
184     local flex = require('flex-base')
185
186     flex.add_topic('street')
187
188     local function no_sidewalks(place, k, v)
189         if place.object.tags.footway == 'sidewalk' then
190             return false
191         end
192
193         -- default behaviour is to have all footways
194         return place
195     end
196
197     flex.modify_main_tags(highway = {'footway' = no_sidewalks}
198     ```
199     This script adds a custom handler for `highway=footway`. It only includes
200     them in the database, when the object doesn't have a tag `footway=sidewalk`
201     indicating that it is just part of a larger street which should already
202     be indexed. Note that it is not necessary to check the key and value
203     of the main tag because the function is only used for the specific
204     main tag.
205
206
207 ### Ignored tags
208
209 The function `ignore_keys()` sets the `delete` classification for keys.
210 This function takes a _key match list_ so that it is possible to exclude
211 groups of keys.
212
213 Note that full matches always take precedence over suffix matches, which
214 in turn take precedence over prefix matches.
215
216 !!! example
217     ``` lua
218     local flex = require('flex-base')
219
220     flex.add_topic('admin')
221     flex.ignore_keys{'old_name', 'old_name:*'}
222     ```
223
224     This example uses the `admin` preset with the exception that names
225     that are no longer are in current use, are ignored.
226
227 ##### Presets
228
229 | Name     | Description |
230 | :-----   | :---------- |
231 | metatags | Tags with meta information about the OSM tag like source, notes and import sources. |
232 | name     | Non-names that actually describe properties or name parts. These names can throw off search and should always be removed. |
233 | address  | Extra `addr:*` tags that are not useful for Nominatim. |
234
235
236 ### Tags for `extratags`
237
238 The function `add_for_extratags()` sets the `extra` classification for keys.
239 This function takes a
240 _key match list_ so that it is possible to move groups of keys to extratags.
241
242 Note that full matches always take precedence over suffix matches, which
243 in turn take precedence over prefix matches.
244
245 !!! example
246     ``` lua
247     local flex = require('flex-base')
248
249     flex.add_topic('street')
250     flex.add_for_extratags{'surface', 'access', 'vehicle', 'maxspeed'}
251     ```
252
253     This example uses the `street` preset but adds a couple of tags that
254     are of interest about the condition of the street.
255
256 ##### Presets
257
258 | Name     | Description |
259 | :-----   | :---------- |
260 | required | Tags that Nominatim will use for various computations when present in extratags. Always include these. |
261
262 In addition, all [presets from ignored tags](#presets_1) are accepted.
263
264 ### General pre-filtering
265
266 _(deprecated)_ `set_prefilters()` allows to set the `delete` and `extra`
267 classification for main tags.
268
269 This function removes all previously set main tags with `delete` and `extra`
270 classification and then adds the newly defined tags.
271
272 `set_prefilters()` takes a table with four optional fields:
273
274 * __delete_keys__ is a _key match list_ for tags that should be deleted
275 * __delete_tags__ contains a table of tag keys pointing to a list of tag
276   values. Tags with matching key/value pairs are deleted.
277 * __extra_keys__ is a _key match list_ for tags which should be saved into
278   extratags
279 * __extra_tags__ contains a table of tag keys pointing to a list of tag
280   values. Tags with matching key/value pairs are moved to extratags.
281
282 !!! danger "Deprecation warning"
283     Use of this function should be replaced with `modify_main_tags()` to
284     set the data from `delete_tags` and `extra_tags`, with `ignore_keys()`
285     for the `delete_keys` parameter and with `add_for_extratags()` for the
286     `extra_keys` parameter.
287
288 ### Name tags
289
290 `set/modify_name_tags()` allow to define the tags used for naming places. Name tags
291 can only be selected by their keys. The import script distinguishes
292 between primary and auxiliary names. A primary name is the given name of
293 a place. Having a primary name makes a place _named_. This is important
294 for main tags that are only included when a name is present. Auxiliary names
295 are identifiers like references. They may be searched for but should not
296 be included on their own.
297
298 The functions take a table with two optional fields `main` and `extra`.
299 They take _key match lists_ for primary and auxiliary names respectively.
300 A third field `house` can contain tags for names that appear in place of
301 house numbers in addresses. This field can only contain complete key names.
302 'house tags' are special in that they cause the OSM object to be added to
303 the database independently of the presence of other main tags.
304
305 `set_name_tags()` overwrites the current configuration, while
306 `modify_name_tags()` replaces the fields that are given. (Be aware that
307 the fields are replaced as a whole. `main = {'foo_name'}` will cause
308 `foo_name` to become the only recognized primary name. Any previously
309 defined primary names are forgotten.)
310
311 !!! example
312     ``` lua
313     local flex = require('flex-base')
314
315     flex.set_main_tags{highway = {traffic_light = 'named'}}
316     flex.set_name_tags{main = {'name', 'name:*'},
317                        extra = {'ref'}
318                       }
319     ```
320
321     This example creates a search index over traffic lights but will
322     only include those that have a common name and not those which just
323     have some reference ID from the city.
324
325 ##### Presets
326
327 | Name     | Description |
328 | :-----   | :---------- |
329 | core     | Basic set of recogniced names for all places. |
330 | address  | Additional names useful when indexing full addresses. |
331 | poi      | Extended set of recognized names for pois. Use on top of the core set. |
332
333 ### Address tags
334
335 `set/modify_address_tags()` defines the tags that will be used to build
336 up the address of an object. Address tags can only be chosen by their key.
337
338 The functions take a table with arbitrary fields, each defining
339 a key list or _key match list_. Some fields have a special meaning:
340
341 | Field     | Type      | Description |
342 | :---------| :-------- | :-----------|
343 | 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. |
344 | 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. |
345 | interpolation | key list | Tags that identify address interpolation lines. |
346 | 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. |
347 | _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. |
348
349 `set_address_tags()` overwrites the current configuration, while
350 `modify_address_tags()` replaces the fields that are given. (Be aware that
351 the fields are replaced as a whole.)
352
353 !!! example
354     ``` lua
355     local flex = require('import-full')
356
357     flex.set_address_tags{
358         main = {'addr:housenumber'},
359         extra = {'addr:*'},
360         postcode = {'postal_code', 'postcode', 'addr:postcode'},
361         country = {'country_code', 'ISO3166-1'}
362     }
363     ```
364
365     In this example all tags which begin with `addr:` will be saved in
366     the address tag list. If one of the tags is `addr:housenumber`, the
367     object will fall back to be entered as a `place=house` in the database
368     unless there is another interested main tag to be found.
369
370     Tags with keys `country_code` and `ISO3166-1` are saved with their
371     value under `country` in the address tag list. The same thing happens
372     to postcodes, they will always be saved under the key `postcode` thus
373     normalizing the multitude of keys that are used in the OSM database.
374
375 ##### Presets
376
377 | Name     | Description |
378 | :-----   | :---------- |
379 | core     | Basic set of tags needed to recognize address relationship for any place. Always include this. |
380 | houses   | Additional set of tags needed to recognize proper addresses |
381
382 ### Handling of unclassified tags
383
384 `set_unused_handling()` defines what to do with tags that remain after all tags
385 have been classified using the functions above. There are two ways in
386 which the function can be used:
387
388 `set_unused_handling(delete_keys = ..., delete_tags = ...)` deletes all
389 keys that match the descriptions in the parameters and moves all remaining
390 tags into the extratags list.
391
392 `set_unused_handling(extra_keys = ..., extra_tags = ...)` moves all tags
393 matching the parameters into the extratags list and then deletes the remaining
394 tags. For the format of the parameters see the description in `set_prefilters()`
395 above.
396
397 When no special handling is set, then unused tags will be discarded with one
398 exception: place tags are kept in extratags for administrative boundaries.
399 When using a custom setting, you should also make sure that the place tag
400 is added for extratags.
401
402 !!! example
403     ``` lua
404     local flex = require('import-full')
405
406     flex.set_address_tags{
407         main = {'addr:housenumber'},
408         extra = {'addr:*', 'tiger:county'}
409     }
410     flex.set_unused_handling{delete_keys = {'tiger:*'}}
411     ```
412
413     In this example all remaining tags except those beginning with `tiger:`
414     are moved to the extratags list. Note that it is not possible to
415     already delete the tiger tags with `set_prefilters()` because that
416     would remove tiger:county before the address tags are processed.
417
418 ## Customizing osm2pgsql callbacks
419
420 osm2pgsql expects the flex style to implement three callbacks, one process
421 function per OSM type. If you want to implement special handling for
422 certain OSM types, you can override the default implementations provided
423 by the flex-base module.
424
425 ### Enabling additional relation types
426
427 OSM relations can represent very diverse
428 [types of real-world objects](https://wiki.openstreetmap.org/wiki/Key:type). To
429 be able to process them correctly, Nominatim needs to understand how to
430 create a geometry for each type. By default, the script knows how to
431 process relations of type `multipolygon`, `boundary` and `waterway`. All
432 other relation types are ignored.
433
434 To add other types relations, set `RELATION_TYPES` for
435 the type to the kind of geometry that should be created. The following
436 kinds of geometries can be used:
437
438 * __relation_as_multipolygon__ creates a (Multi)Polygon from the ways in
439   the relation. If the ways do not form a valid area, then the object is
440   silently discarded.
441 * __relation_as_multiline__ creates a (Multi)LineString from the ways in
442   the relations. Ways are combined as much as possible without any regards
443   to their order in the relation.
444
445 !!! Example
446     ``` lua
447     local flex = require('import-full')
448
449     flex.RELATION_TYPES['site'] = flex.relation_as_multipolygon
450     ```
451
452     With this line relations of `type=site` will be included in the index
453     according to main tags found. This only works when the site relation
454     resolves to a valid area. Nodes in the site relation are not part of the
455     geometry.
456
457
458 ### Adding additional logic to processing functions
459
460 The default processing functions are also exported by the flex-base module
461 as `process_node`, `process_way` and `process_relation`. These can be used
462 to implement your own processing functions with some additional processing
463 logic.
464
465 !!! Example
466     ``` lua
467     local flex = require('import-full')
468
469     function osm2pgsql.process_relation(object)
470         if object.tags.boundary ~= 'administrative' or object.tags.admin_level ~= '2' then
471           flex.process_relation(object)
472         end
473     end
474     ```
475
476     This example discards all country-level boundaries and uses standard
477     handling for everything else. This can be useful if you want to use
478     your own custom country boundaries.
479
480
481 ### Customizing the main processing function
482
483 !!! danger "Deprecation Warning"
484     The style used to allow overwriting the internal processing function
485     `process_tags()`. While this is currently still possible, it is no longer
486     encouraged and may stop working in future versions. The internal
487     `Place` class should now be considered read-only.
488
489
490 ## Using osm2pgsql-themepark
491
492 The Nominatim osm2pgsql style is designed so that it can also be used as
493 a theme for [osm2pgsql-themepark](https://osm2pgsql.org/themepark/). This
494 makes it easy to combine Nominatim with other projects like
495 [openstreetmap-carto](https://github.com/gravitystorm/openstreetmap-carto)
496 in the same database.
497
498 To set up one of the preset styles, simply include a topic with the same name:
499
500 ```
501 local themepark = require('themepark')
502 themepark:add_topic('nominatim/address')
503 ```
504
505 Themepark topics offer two configuration options:
506
507 * **street_theme** allows to choose one of the sub topics for streets:
508     * _default_ - include all major streets and named minor paths
509     * _car_ - include all streets physically usable by cars
510     * _all_ - include all major streets and minor paths
511 * **with_extratags**, when set to a truthy value, then tags that are
512   not specifically used for address or naming are added to the
513   extratags column
514
515 The customization functions described in the
516 [Changing recognized tags](#changing-the-recognized-tags) section
517 are available from the theme. To access the theme you need to explicitly initialize it.
518
519 !!! Example
520     ``` lua
521     local themepark = require('themepark')
522
523     themepark:add_topic('nominatim/full', {with_extratags = true})
524
525     local flex = themepark:init_theme('nominatim')
526
527     flex.modify_main_tags{'amenity' = {
528                            'waste_basket' = 'delete'}
529                       }
530     ```
531     This example uses the full Nominatim configuration but disables
532     importing waste baskets.
533
534 You may also write a new configuration from scratch. Simply omit including
535 a Nominatim topic and only call the required customization functions.
536
537 Customizing the osm2pgsql processing functions as explained
538 [above](#adding-additional-logic-to-processing-functions) is not possible
539 when running under themepark. Instead include other topics that make the
540 necessary modifications or add an additional processor before including
541 the Nominatim topic.
542
543 !!! Example
544     ``` lua
545     local themepark = require('themepark')
546
547     local function discard_country_boundaries(object)
548         if object.tags.boundary == 'administrative' and object.tags.admin_level == '2' then
549             return 'stop'
550         end
551     end
552
553     themepark:add_proc('relation', discard_country_boundaries)
554     -- Order matters here. The topic needs to be added after the custom callback.
555     themepark:add_topic('nominatim/full', {with_extratags = true})
556     ```
557     Discarding country-level boundaries when running under themepark.
558
559 ## osm2pgsql gazetteer output
560
561 Nominatim still allows you to configure the gazetteer output to remain
562 backwards compatible with older imports. It will be automatically used
563 when the style file name ends in `.style`. For documentation of the
564 old import style, please refer to the documentation of older releases
565 of Nominatim. Do not use the gazetteer output for new imports. There is no
566 guarantee that new versions of Nominatim are fully compatible with the
567 gazetteer output.
568
569 ## Changing the style of existing databases
570
571 There is usually no issue changing the style of a database that is already
572 imported and now kept up-to-date with change files. Just be aware that any
573 change in the style applies to updates only. If you want to change the data
574 that is already in the database, then a reimport is necessary.