]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_db/clicmd/add_data.py
Fix gunicorn invocation
[nominatim.git] / src / nominatim_db / clicmd / add_data.py
1 # SPDX-License-Identifier: GPL-3.0-or-later
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2024 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Implementation of the 'add-data' subcommand.
9 """
10 from typing import cast
11 import argparse
12 import logging
13 import asyncio
14
15 import psutil
16
17 from .args import NominatimArgs
18 from ..db.connection import connect
19 from ..tools.freeze import is_frozen
20
21 # Do not repeat documentation of subcommand classes.
22 # pylint: disable=C0111
23 # Using non-top-level imports to avoid eventually unused imports.
24 # pylint: disable=E0012,C0415
25
26 LOG = logging.getLogger()
27
28 class UpdateAddData:
29     """\
30     Add additional data from a file or an online source.
31
32     This command allows to add or update the search data in the database.
33     The data can come either from an OSM file or single OSM objects can
34     directly be downloaded from the OSM API. This function only loads the
35     data into the database. Afterwards it still needs to be integrated
36     in the search index. Use the `nominatim index` command for that.
37
38     The command can also be used to add external non-OSM data to the
39     database. At the moment the only supported format is TIGER housenumber
40     data. See the online documentation at
41     https://nominatim.org/release-docs/latest/customize/Tiger/
42     for more information.
43     """
44
45     def add_args(self, parser: argparse.ArgumentParser) -> None:
46         group_name = parser.add_argument_group('Source')
47         group1 = group_name.add_mutually_exclusive_group(required=True)
48         group1.add_argument('--file', metavar='FILE',
49                             help='Import data from an OSM file or diff file')
50         group1.add_argument('--diff', metavar='FILE',
51                             help='Import data from an OSM diff file (deprecated: use --file)')
52         group1.add_argument('--node', metavar='ID', type=int,
53                             help='Import a single node from the API')
54         group1.add_argument('--way', metavar='ID', type=int,
55                             help='Import a single way from the API')
56         group1.add_argument('--relation', metavar='ID', type=int,
57                             help='Import a single relation from the API')
58         group1.add_argument('--tiger-data', metavar='DIR',
59                             help='Add housenumbers from the US TIGER census database')
60         group2 = parser.add_argument_group('Extra arguments')
61         group2.add_argument('--use-main-api', action='store_true',
62                             help='Use OSM API instead of Overpass to download objects')
63         group2.add_argument('--osm2pgsql-cache', metavar='SIZE', type=int,
64                             help='Size of cache to be used by osm2pgsql (in MB)')
65         group2.add_argument('--socket-timeout', dest='socket_timeout', type=int, default=60,
66                             help='Set timeout for file downloads')
67
68
69     def run(self, args: NominatimArgs) -> int:
70         from ..tools import add_osm_data
71
72         with connect(args.config.get_libpq_dsn()) as conn:
73             if is_frozen(conn):
74                 print('Database is marked frozen. New data can\'t be added.')
75                 return 1
76
77         if args.tiger_data:
78             return asyncio.run(self._add_tiger_data(args))
79
80         osm2pgsql_params = args.osm2pgsql_options(default_cache=1000, default_threads=1)
81         if args.file or args.diff:
82             return add_osm_data.add_data_from_file(args.config.get_libpq_dsn(),
83                                                    cast(str, args.file or args.diff),
84                                                    osm2pgsql_params)
85
86         if args.node:
87             return add_osm_data.add_osm_object(args.config.get_libpq_dsn(),
88                                                'node', args.node,
89                                                args.use_main_api,
90                                                osm2pgsql_params)
91
92         if args.way:
93             return add_osm_data.add_osm_object(args.config.get_libpq_dsn(),
94                                                'way', args.way,
95                                                args.use_main_api,
96                                                osm2pgsql_params)
97
98         if args.relation:
99             return add_osm_data.add_osm_object(args.config.get_libpq_dsn(),
100                                                'relation', args.relation,
101                                                args.use_main_api,
102                                                osm2pgsql_params)
103
104         return 0
105
106
107     async def _add_tiger_data(self, args: NominatimArgs) -> int:
108         from ..tokenizer import factory as tokenizer_factory
109         from ..tools import tiger_data
110
111         assert args.tiger_data
112
113         tokenizer = tokenizer_factory.get_tokenizer_for_db(args.config)
114         return await tiger_data.add_tiger_data(args.tiger_data,
115                                                args.config,
116                                                args.threads or psutil.cpu_count()  or 1,
117                                                tokenizer)