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