-class UpdateRefresh:
- """\
- Recompute auxiliary data used by the indexing process.
-
- These functions must not be run in parallel with other update commands.
- """
-
- @staticmethod
- def add_args(parser):
- group = parser.add_argument_group('Data arguments')
- group.add_argument('--postcodes', action='store_true',
- help='Update postcode centroid table')
- group.add_argument('--word-counts', action='store_true',
- help='Compute frequency of full-word search terms')
- group.add_argument('--address-levels', action='store_true',
- help='Reimport address level configuration')
- group.add_argument('--functions', action='store_true',
- help='Update the PL/pgSQL functions in the database')
- group.add_argument('--wiki-data', action='store_true',
- help='Update Wikipedia/data importance numbers.')
- group.add_argument('--importance', action='store_true',
- help='Recompute place importances (expensive!)')
- group.add_argument('--website', action='store_true',
- help='Refresh the directory that serves the scripts for the web API')
- group = parser.add_argument_group('Arguments for function refresh')
- group.add_argument('--no-diff-updates', action='store_false', dest='diffs',
- help='Do not enable code for propagating updates')
- group.add_argument('--enable-debug-statements', action='store_true',
- help='Enable debug warning statements in functions')
-
- @staticmethod
- def run(args):
- from .tools import refresh
-
- conn = connect(args.config.get_libpq_dsn())
-
- if args.postcodes:
- LOG.warning("Update postcodes centroid")
- refresh.update_postcodes(conn, args.data_dir)
-
- if args.word_counts:
- LOG.warning('Recompute frequency of full-word search terms')
- refresh.recompute_word_counts(conn, args.data_dir)
-
- if args.address_levels:
- cfg = Path(args.config.ADDRESS_LEVEL_CONFIG)
- LOG.warning('Updating address levels from %s', cfg)
- refresh.load_address_levels_from_file(conn, cfg)
-
- if args.functions:
- LOG.warning('Create functions')
- refresh.create_functions(conn, args.config, args.data_dir,
- args.diffs, args.enable_debug_statements)
-
- if args.wiki_data:
- run_legacy_script('setup.php', '--import-wikipedia-articles',
- nominatim_env=args, throw_on_fail=True)
- # Attention: importance MUST come after wiki data import.
- if args.importance:
- run_legacy_script('update.php', '--recompute-importance',
- nominatim_env=args, throw_on_fail=True)
- if args.website:
- run_legacy_script('setup.php', '--setup-website',
- nominatim_env=args, throw_on_fail=True)
-
- conn.close()
-
- return 0
-
-
-class AdminCheckDatabase:
- """\
- Check that the database is complete and operational.
- """
-
- @staticmethod
- def add_args(parser):
- pass # No options
-
- @staticmethod
- def run(args):
- return run_legacy_script('check_import_finished.php', nominatim_env=args)
-
-
-class AdminWarm:
- """\
- Warm database caches for search and reverse queries.
- """
-
- @staticmethod
- def add_args(parser):
- group = parser.add_argument_group('Target arguments')
- group.add_argument('--search-only', action='store_const', dest='target',
- const='search',
- help="Only pre-warm tables for search queries")
- group.add_argument('--reverse-only', action='store_const', dest='target',
- const='reverse',
- help="Only pre-warm tables for reverse queries")
-
- @staticmethod
- def run(args):
- params = ['warm.php']
- if args.target == 'reverse':
- params.append('--reverse-only')
- if args.target == 'search':
- params.append('--search-only')
- return run_legacy_script(*params, nominatim_env=args)
-
-
-class QueryExport:
- """\
- Export addresses as CSV file from the database.
- """
-
- @staticmethod
- def add_args(parser):
- group = parser.add_argument_group('Output arguments')
- group.add_argument('--output-type', default='street',
- choices=('continent', 'country', 'state', 'county',
- 'city', 'suburb', 'street', 'path'),
- help='Type of places to output (default: street)')
- group.add_argument('--output-format',
- default='street;suburb;city;county;state;country',
- help="""Semicolon-separated list of address types
- (see --output-type). Multiple ranks can be
- merged into one column by simply using a
- comma-separated list.""")
- group.add_argument('--output-all-postcodes', action='store_true',
- help="""List all postcodes for address instead of
- just the most likely one""")
- group.add_argument('--language',
- help="""Preferred language for output
- (use local name, if omitted)""")
- group = parser.add_argument_group('Filter arguments')
- group.add_argument('--restrict-to-country', metavar='COUNTRY_CODE',
- help='Export only objects within country')
- group.add_argument('--restrict-to-osm-node', metavar='ID', type=int,
- help='Export only children of this OSM node')
- group.add_argument('--restrict-to-osm-way', metavar='ID', type=int,
- help='Export only children of this OSM way')
- group.add_argument('--restrict-to-osm-relation', metavar='ID', type=int,
- help='Export only children of this OSM relation')
-
-
- @staticmethod
- def run(args):
- params = ['export.php',
- '--output-type', args.output_type,
- '--output-format', args.output_format]
- if args.output_all_postcodes:
- params.append('--output-all-postcodes')
- if args.language:
- params.extend(('--language', args.language))
- if args.restrict_to_country:
- params.extend(('--restrict-to-country', args.restrict_to_country))
- if args.restrict_to_osm_node:
- params.extend(('--restrict-to-osm-node', args.restrict_to_osm_node))
- if args.restrict_to_osm_way:
- params.extend(('--restrict-to-osm-way', args.restrict_to_osm_way))
- if args.restrict_to_osm_relation:
- params.extend(('--restrict-to-osm-relation', args.restrict_to_osm_relation))
-
- return run_legacy_script(*params, nominatim_env=args)
-
-STRUCTURED_QUERY = (
- ('street', 'housenumber and street'),
- ('city', 'city, town or village'),
- ('county', 'county'),
- ('state', 'state'),
- ('country', 'country'),
- ('postalcode', 'postcode')
-)
-
-EXTRADATA_PARAMS = (
- ('addressdetails', 'Include a breakdown of the address into elements.'),
- ('extratags', """Include additional information if available
- (e.g. wikipedia link, opening hours)."""),
- ('namedetails', 'Include a list of alternative names.')
-)
-
-DETAILS_SWITCHES = (
- ('addressdetails', 'Include a breakdown of the address into elements.'),
- ('keywords', 'Include a list of name keywords and address keywords.'),
- ('linkedplaces', 'Include a details of places that are linked with this one.'),
- ('hierarchy', 'Include details of places lower in the address hierarchy.'),
- ('group_hierarchy', 'Group the places by type.'),
- ('polygon_geojson', 'Include geometry of result.')
-)
-
-def _add_api_output_arguments(parser):
- group = parser.add_argument_group('Output arguments')
- group.add_argument('--format', default='jsonv2',
- choices=['xml', 'json', 'jsonv2', 'geojson', 'geocodejson'],
- help='Format of result')
- for name, desc in EXTRADATA_PARAMS:
- group.add_argument('--' + name, action='store_true', help=desc)
-
- group.add_argument('--lang', '--accept-language', metavar='LANGS',
- help='Preferred language order for presenting search results')
- group.add_argument('--polygon-output',
- choices=['geojson', 'kml', 'svg', 'text'],
- help='Output geometry of results as a GeoJSON, KML, SVG or WKT.')
- group.add_argument('--polygon-threshold', type=float, metavar='TOLERANCE',
- help="""Simplify output geometry.
- Parameter is difference tolerance in degrees.""")
-
-
-class APISearch:
- """\
- Execute API search query.
- """
-
- @staticmethod
- def add_args(parser):
- group = parser.add_argument_group('Query arguments')
- group.add_argument('--query',
- help='Free-form query string')
- for name, desc in STRUCTURED_QUERY:
- group.add_argument('--' + name, help='Structured query: ' + desc)
-
- _add_api_output_arguments(parser)
-
- group = parser.add_argument_group('Result limitation')
- group.add_argument('--countrycodes', metavar='CC,..',
- help='Limit search results to one or more countries.')
- group.add_argument('--exclude_place_ids', metavar='ID,..',
- help='List of search object to be excluded')
- group.add_argument('--limit', type=int,
- help='Limit the number of returned results')
- group.add_argument('--viewbox', metavar='X1,Y1,X2,Y2',
- help='Preferred area to find search results')
- group.add_argument('--bounded', action='store_true',
- help='Strictly restrict results to viewbox area')
-
- group = parser.add_argument_group('Other arguments')
- group.add_argument('--no-dedupe', action='store_false', dest='dedupe',
- help='Do not remove duplicates from the result list')
-
-
- @staticmethod
- def run(args):
- if args.query:
- params = dict(q=args.query)
- else:
- params = {k : getattr(args, k) for k, _ in STRUCTURED_QUERY if getattr(args, k)}
-
- for param, _ in EXTRADATA_PARAMS:
- if getattr(args, param):
- params[param] = '1'
- for param in ('format', 'countrycodes', 'exclude_place_ids', 'limit', 'viewbox'):
- if getattr(args, param):
- params[param] = getattr(args, param)
- if args.lang:
- params['accept-language'] = args.lang
- if args.polygon_output:
- params['polygon_' + args.polygon_output] = '1'
- if args.polygon_threshold:
- params['polygon_threshold'] = args.polygon_threshold
- if args.bounded:
- params['bounded'] = '1'
- if not args.dedupe:
- params['dedupe'] = '0'
-
- return run_api_script('search', args.project_dir,
- phpcgi_bin=args.phpcgi_path, params=params)
-
-class APIReverse:
- """\
- Execute API reverse query.
- """
-
- @staticmethod
- def add_args(parser):
- group = parser.add_argument_group('Query arguments')
- group.add_argument('--lat', type=float, required=True,
- help='Latitude of coordinate to look up (in WGS84)')
- group.add_argument('--lon', type=float, required=True,
- help='Longitude of coordinate to look up (in WGS84)')
- group.add_argument('--zoom', type=int,
- help='Level of detail required for the address')
-
- _add_api_output_arguments(parser)
-
-
- @staticmethod
- def run(args):
- params = dict(lat=args.lat, lon=args.lon)
- if args.zoom is not None:
- params['zoom'] = args.zoom
-
- for param, _ in EXTRADATA_PARAMS:
- if getattr(args, param):
- params[param] = '1'
- if args.format:
- params['format'] = args.format
- if args.lang:
- params['accept-language'] = args.lang
- if args.polygon_output:
- params['polygon_' + args.polygon_output] = '1'
- if args.polygon_threshold:
- params['polygon_threshold'] = args.polygon_threshold
-
- return run_api_script('reverse', args.project_dir,
- phpcgi_bin=args.phpcgi_path, params=params)
-
-
-class APILookup: