]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/indexer/runners.py
introduce name analyzer
[nominatim.git] / nominatim / indexer / runners.py
1 """
2 Mix-ins that provide the actual commands for the indexer for various indexing
3 tasks.
4 """
5 import functools
6
7 import psycopg2.extras
8
9 # pylint: disable=C0111
10
11 class AbstractPlacexRunner:
12     """ Returns SQL commands for indexing of the placex table.
13     """
14     SELECT_SQL = 'SELECT place_id, (placex_prepare_update(placex)).* FROM placex'
15
16     def __init__(self, rank, analyzer):
17         self.rank = rank
18         self.analyzer = analyzer
19
20
21     @staticmethod
22     @functools.lru_cache(maxsize=1)
23     def _index_sql(num_places):
24         return """ UPDATE placex
25                    SET indexed_status = 0, address = v.addr, token_info = v.ti
26                    FROM (VALUES {}) as v(id, addr, ti)
27                    WHERE place_id = v.id
28                """.format(','.join(["(%s, %s::hstore, %s::json)"]  * num_places))
29
30
31     def index_places(self, worker, places):
32         values = []
33         for place in places:
34             values.extend((place[x] for x in ('place_id', 'address')))
35             values.append(psycopg2.extras.Json(self.analyzer.process_place(place)))
36
37         worker.perform(self._index_sql(len(places)), values)
38
39
40 class RankRunner(AbstractPlacexRunner):
41     """ Returns SQL commands for indexing one rank within the placex table.
42     """
43
44     def name(self):
45         return "rank {}".format(self.rank)
46
47     def sql_count_objects(self):
48         return """SELECT count(*) FROM placex
49                   WHERE rank_address = {} and indexed_status > 0
50                """.format(self.rank)
51
52     def sql_get_objects(self):
53         return """{} WHERE indexed_status > 0 and rank_address = {}
54                      ORDER BY geometry_sector
55                """.format(self.SELECT_SQL, self.rank)
56
57
58 class BoundaryRunner(AbstractPlacexRunner):
59     """ Returns SQL commands for indexing the administrative boundaries
60         of a certain rank.
61     """
62
63     def name(self):
64         return "boundaries rank {}".format(self.rank)
65
66     def sql_count_objects(self):
67         return """SELECT count(*) FROM placex
68                   WHERE indexed_status > 0
69                     AND rank_search = {}
70                     AND class = 'boundary' and type = 'administrative'
71                """.format(self.rank)
72
73     def sql_get_objects(self):
74         return """{} WHERE indexed_status > 0 and rank_search = {}
75                            and class = 'boundary' and type = 'administrative'
76                      ORDER BY partition, admin_level
77                """.format(self.SELECT_SQL, self.rank)
78
79
80 class InterpolationRunner:
81     """ Returns SQL commands for indexing the address interpolation table
82         location_property_osmline.
83     """
84
85     @staticmethod
86     def name():
87         return "interpolation lines (location_property_osmline)"
88
89     @staticmethod
90     def sql_count_objects():
91         return """SELECT count(*) FROM location_property_osmline
92                   WHERE indexed_status > 0"""
93
94     @staticmethod
95     def sql_get_objects():
96         return """SELECT place_id FROM location_property_osmline
97                   WHERE indexed_status > 0
98                   ORDER BY geometry_sector"""
99
100     @staticmethod
101     def index_places(worker, ids):
102         worker.perform(""" UPDATE location_property_osmline
103                            SET indexed_status = 0 WHERE place_id IN ({})
104                        """.format(','.join((str(i[0]) for i in ids))))
105
106
107 class PostcodeRunner:
108     """ Provides the SQL commands for indexing the location_postcode table.
109     """
110
111     @staticmethod
112     def name():
113         return "postcodes (location_postcode)"
114
115     @staticmethod
116     def sql_count_objects():
117         return 'SELECT count(*) FROM location_postcode WHERE indexed_status > 0'
118
119     @staticmethod
120     def sql_get_objects():
121         return """SELECT place_id FROM location_postcode
122                   WHERE indexed_status > 0
123                   ORDER BY country_code, postcode"""
124
125     @staticmethod
126     def index_places(worker, ids):
127         worker.perform(""" UPDATE location_postcode SET indexed_status = 0
128                            WHERE place_id IN ({})
129                        """.format(','.join((str(i[0]) for i in ids))))