Sat, 26 Sep 2020 01:31:37 +0300
added square.svg from osm-carto
0 | 1 | -- This configuration for the flex backend tries to be compatible with the |
2 | -- original pgsql c-transform backend. There might be some corner cases but | |
3 | -- it should mostly do exactly the same. | |
4 | ||
5 | -- Set this to true if you were using option -K|--keep-coastlines. | |
6 | local keep_coastlines = true | |
7 | ||
8 | -- Set this to the table name prefix (what used to be option -p|--prefix). | |
9 | local prefix = 'planet_osm' | |
10 | ||
11 | -- Set this to true if multipolygons should be written as polygons into db | |
12 | -- (what used to be option -G|--multi-geometry). | |
13 | local multi_geometry = true | |
14 | ||
15 | -- Set this to true if you want an hstore column (what used to be option | |
16 | -- -k|--hstore). Can not be true if "hstore_all" is true. | |
17 | local hstore = true | |
18 | ||
19 | -- Set this to true if you want all tags in an hstore column (what used to | |
20 | -- be option -j|--hstore-all). Can not be true if "hstore" is true. | |
21 | local hstore_all = false | |
22 | ||
23 | -- Only keep objects that have a value in one of the non-hstore columns | |
24 | -- (normal action with --hstore is to keep all objects). Equivalent to | |
25 | -- what used to be set through option --hstore-match-only. | |
26 | local hstore_match_only = true | |
27 | ||
28 | -- Set this to add an additional hstore (key/value) column containing all tags | |
29 | -- that start with the specified string, eg "name:". Will produce an extra | |
30 | -- hstore column that contains all "name:xx" tags. Equivalent to what used to | |
31 | -- be set through option -z|--hstore-column. | |
32 | local hstore_column = nil | |
33 | ||
34 | -- There is some very old specialized handling of route relations in osm2pgsql, | |
35 | -- which you probably don't need. This is disabled here, but you can enable | |
36 | -- it by setting this to true. If you don't understand this, leave it alone. | |
37 | local enable_legacy_route_processing = false | |
38 | ||
39 | -- --------------------------------------------------------------------------- | |
40 | ||
41 | if hstore and hstore_all then | |
1 | 42 | error("hstore and hstore_all can't be both true") |
0 | 43 | end |
44 | ||
45 | -- Used for splitting up long linestrings | |
46 | if osm2pgsql.srid == 4326 then | |
1 | 47 | max_length = 1 |
0 | 48 | else |
1 | 49 | max_length = 100000 |
0 | 50 | end |
51 | ||
52 | -- Ways with any of the following keys will be treated as polygon | |
53 | local polygon_keys = { | |
1 | 54 | 'aeroway', |
55 | 'amenity', | |
56 | 'building', | |
57 | 'harbour', | |
58 | 'historic', | |
59 | 'landuse', | |
60 | 'leisure', | |
61 | 'man_made', | |
62 | 'military', | |
63 | 'natural', | |
64 | 'office', | |
65 | 'place', | |
66 | 'power', | |
67 | 'public_transport', | |
68 | 'shop', | |
69 | 'sport', | |
70 | 'tourism', | |
71 | 'water', | |
72 | 'waterway', | |
73 | 'wetland', | |
74 | 'abandoned:aeroway', | |
75 | 'abandoned:amenity', | |
76 | 'abandoned:building', | |
77 | 'abandoned:landuse', | |
78 | 'abandoned:power', | |
79 | 'area:highway' | |
0 | 80 | } |
81 | ||
82 | -- Objects without any of the following keys will be deleted | |
83 | local generic_keys = { | |
1 | 84 | 'access', |
85 | 'addr:housename', | |
86 | 'addr:housenumber', | |
87 | 'addr:interpolation', | |
88 | 'admin_level', | |
89 | 'aerialway', | |
90 | 'aeroway', | |
91 | 'amenity', | |
92 | 'area', | |
93 | 'barrier', | |
94 | 'bicycle', | |
95 | 'boundary', | |
96 | 'brand', | |
97 | 'bridge', | |
98 | 'building', | |
99 | 'capital', | |
100 | 'construction', | |
101 | 'covered', | |
102 | 'culvert', | |
103 | 'cutting', | |
104 | 'denomination', | |
105 | 'disused', | |
106 | 'ele', | |
107 | 'embankment', | |
108 | 'foot', | |
109 | 'generation:source', | |
110 | 'harbour', | |
111 | 'healthcare', | |
112 | 'highway', | |
113 | 'historic', | |
114 | 'hours', | |
115 | 'intermittent', | |
116 | 'junction', | |
117 | 'landuse', | |
118 | 'layer', | |
119 | 'leisure', | |
120 | 'lock', | |
121 | 'man_made', | |
122 | 'military', | |
123 | 'motorcar', | |
124 | 'name', | |
125 | 'natural', | |
126 | 'office', | |
127 | 'oneway', | |
128 | 'operator', | |
129 | 'place', | |
130 | 'population', | |
131 | 'power', | |
132 | 'power_source', | |
133 | 'public_transport', | |
134 | 'railway', | |
135 | 'ref', | |
136 | 'religion', | |
137 | 'route', | |
138 | 'service', | |
139 | 'shop', | |
140 | 'sport', | |
141 | 'surface', | |
142 | 'toll', | |
143 | 'tourism', | |
144 | 'tower:type', | |
145 | 'tracktype', | |
146 | 'tunnel', | |
147 | 'water', | |
148 | 'waterway', | |
149 | 'wetland', | |
150 | 'width', | |
151 | 'wood', | |
152 | 'abandoned:aeroway', | |
153 | 'abandoned:amenity', | |
154 | 'abandoned:building', | |
155 | 'abandoned:landuse', | |
156 | 'abandoned:power', | |
157 | 'area:highway' | |
0 | 158 | } |
159 | ||
160 | -- The following keys will be deleted | |
161 | local delete_keys = { | |
1 | 162 | 'attribution', |
163 | 'comment', | |
164 | 'created_by', | |
165 | 'fixme', | |
166 | 'note', | |
167 | 'note:*', | |
168 | 'odbl', | |
169 | 'odbl:note', | |
170 | 'source', | |
171 | 'source:*', | |
172 | 'source_ref', | |
173 | 'way', | |
174 | 'way_area', | |
175 | 'z_order', | |
0 | 176 | } |
177 | ||
178 | local point_columns = { | |
1 | 179 | 'access', |
180 | 'addr:housename', | |
181 | 'addr:housenumber', | |
182 | 'addr:interpolation', | |
183 | 'admin_level', | |
184 | 'aerialway', | |
185 | 'aeroway', | |
186 | 'amenity', | |
187 | 'area', | |
188 | 'barrier', | |
189 | 'bicycle', | |
190 | 'brand', | |
191 | 'bridge', | |
192 | 'boundary', | |
193 | 'building', | |
194 | 'capital', | |
195 | 'construction', | |
196 | 'covered', | |
197 | 'culvert', | |
198 | 'cutting', | |
199 | 'denomination', | |
200 | 'disused', | |
201 | 'ele', | |
202 | 'embankment', | |
203 | 'foot', | |
204 | 'generator:source', | |
205 | 'harbour', | |
206 | 'highway', | |
207 | 'historic', | |
208 | 'horse', | |
209 | 'intermittent', | |
210 | 'junction', | |
211 | 'landuse', | |
212 | 'layer', | |
213 | 'leisure', | |
214 | 'lock', | |
215 | 'man_made', | |
216 | 'military', | |
217 | 'motorcar', | |
218 | 'name', | |
219 | 'name:fi', | |
220 | 'name:sv', | |
221 | 'minority_name', | |
222 | 'majority_name', | |
223 | 'bilingual_name', | |
224 | 'natural', | |
225 | 'office', | |
226 | 'oneway', | |
227 | 'operator', | |
228 | 'place', | |
229 | 'population', | |
230 | 'power', | |
231 | 'power_source', | |
232 | 'public_transport', | |
233 | 'railway', | |
234 | 'ref', | |
235 | 'religion', | |
236 | 'route', | |
237 | 'service', | |
238 | 'shop', | |
239 | 'sport', | |
240 | 'surface', | |
241 | 'toll', | |
242 | 'tourism', | |
243 | 'tower:type', | |
244 | 'tunnel', | |
245 | 'water', | |
246 | 'waterway', | |
247 | 'wetland', | |
248 | 'width', | |
249 | 'wood', | |
0 | 250 | } |
251 | ||
252 | local non_point_columns = { | |
1 | 253 | 'access', |
254 | 'addr:housename', | |
255 | 'addr:housenumber', | |
256 | 'addr:interpolation', | |
257 | 'admin_level', | |
258 | 'aerialway', | |
259 | 'aeroway', | |
260 | 'amenity', | |
261 | 'area', | |
262 | 'barrier', | |
263 | 'bicycle', | |
264 | 'brand', | |
265 | 'bridge', | |
266 | 'boundary', | |
267 | 'building', | |
268 | 'construction', | |
269 | 'covered', | |
270 | 'culvert', | |
271 | 'cutting', | |
272 | 'denomination', | |
273 | 'disused', | |
274 | 'embankment', | |
275 | 'foot', | |
276 | 'generator:source', | |
277 | 'harbour', | |
278 | 'highway', | |
279 | 'historic', | |
280 | 'horse', | |
281 | 'intermittent', | |
282 | 'junction', | |
283 | 'landuse', | |
284 | 'layer', | |
285 | 'leisure', | |
286 | 'lock', | |
287 | 'man_made', | |
288 | 'military', | |
289 | 'motorcar', | |
290 | 'name', | |
291 | 'name:fi', | |
292 | 'name:sv', | |
293 | 'minority_name', | |
294 | 'majority_name', | |
295 | 'bilingual_name', | |
296 | 'natural', | |
297 | 'office', | |
298 | 'oneway', | |
299 | 'operator', | |
300 | 'place', | |
301 | 'population', | |
302 | 'power', | |
303 | 'power_source', | |
304 | 'public_transport', | |
305 | 'railway', | |
306 | 'ref', | |
307 | 'ref_class', | |
308 | 'ref_width', | |
309 | 'religion', | |
310 | 'route', | |
311 | 'service', | |
312 | 'shop', | |
313 | 'sport', | |
314 | 'surface', | |
315 | 'toll', | |
316 | 'tourism', | |
317 | 'tower:type', | |
318 | 'tracktype', | |
319 | 'tunnel', | |
320 | 'water', | |
321 | 'waterway', | |
322 | 'wetland', | |
323 | 'width', | |
324 | 'wood', | |
0 | 325 | } |
326 | ||
327 | -- highlight some suburbs in the capital region | |
328 | boroughs = { | |
1 | 329 | -- Helsinki |
330 | ["Q2116584"] = 1, -- Vuosaari / Nordsjö | |
331 | ["Q2510635"] = 1, -- Oulunkylä / Åggelby | |
332 | ["Q3130945"] = 1, -- Viikki / Vik | |
333 | ["Q1614778"] = 1, -- Herttoniemi / Hertonäs | |
334 | -- Espoo | |
335 | ["Q166942"] = 1, -- Leppävaara / Alberga | |
336 | ["Q3107346"] = 1, -- Matinkylä / Mattby | |
337 | ["Q211491"] = 1, -- Espoonlahti / Esboviken | |
338 | ["Q211489"] = 1, -- Espoon keskus / Esbo centrum | |
339 | ["Q219044"] = 1, -- Kauklahti / Köklax | |
340 | ["Q1668730"] = 1, -- Tapiola / Hagalund | |
341 | -- Vantaa | |
342 | ["Q2640455"] = 1, -- Tikkurila / Dickursby | |
343 | ["Q4412122"] = 1, -- Aviapolis | |
344 | ["Q3736737"] = 1, -- Myyrmäki / Myrbacka | |
345 | ["Q4557316"] = 1, -- Kivistö | |
346 | ["Q4556551"] = 1, -- Koivukylä / Björkby | |
347 | ["Q3742144"] = 1, -- Korso | |
348 | ["Q4556262"] = 1, -- Hakunila / Håkansböle | |
0 | 349 | } |
350 | ||
351 | -- | |
352 | -- Name in majority language for object. This is name unless both name:fi and | |
353 | -- name:sv disagree with name. | |
354 | -- @param tags Raw OSM tags | |
355 | -- @return Bilingual name | |
356 | -- | |
357 | function majority_name(tags) | |
1 | 358 | if tags.name ~= nil and tags['name:sv'] ~= nil and tags['name:fi'] and tags.name ~= tags['name:fi'] and tags.name ~= tags['name:sv'] |
359 | then | |
360 | return tags['name:fi'] | |
361 | else | |
362 | return tags.name | |
363 | end | |
0 | 364 | end |
365 | -- | |
366 | -- Name in minority language for object. This is the Swedish name if name is in | |
367 | -- Finnish, and the Finnish name if name is in Swedish. | |
368 | -- @param tags Raw OSM tags | |
369 | -- @return Bilingual name | |
370 | -- | |
371 | function minority_name(tags) | |
1 | 372 | if tags['name:sv'] ~= nil and tags['name'] ~= tags['name:sv'] |
373 | then | |
374 | return tags['name:sv'] | |
375 | elseif tags['name:fi'] ~= nil and tags['name'] ~= tags['name:fi'] | |
376 | then | |
377 | return tags['name:fi'] | |
378 | else | |
379 | return nil | |
380 | end | |
0 | 381 | end |
382 | ||
383 | function bilingual_name(tags) | |
1 | 384 | if tags.majority_name ~= nil and tags.minority_name ~= nil |
385 | then | |
386 | return tags.majority_name .. '\n' .. tags.minority_name | |
387 | else | |
388 | return tags.majority_name | |
389 | end | |
0 | 390 | end |
391 | ||
392 | -- Makes highway classes more sensible | |
393 | function highway_class(tags) | |
1 | 394 | if string.match(tags.highway, '_link$') |
395 | then | |
396 | if tags.tags.functional_class == 'service' or tags.tags.functional_class == 'unclassified' | |
397 | then | |
398 | return tags.tags.functional_class | |
399 | elseif tags.tags.functional_class ~= nil | |
400 | then | |
401 | return tags.tags.functional_class..'_link' | |
402 | elseif tags.highway == 'motorway_link' | |
403 | then | |
404 | return 'trunk_link' | |
405 | else | |
406 | return tags.highway | |
407 | end | |
408 | elseif tags.highway == 'motorway' | |
409 | then | |
410 | if tags.tags.functional_class == 'primary' or tags.tags.functional_class == 'secondary' or tags.tags.functional_class == 'tertiary' | |
411 | then | |
412 | return tags.tags.functional_class | |
413 | elseif tags.tags.functional_class == 'service' | |
414 | then | |
415 | return 'service' | |
416 | else | |
417 | return 'trunk' | |
418 | end | |
419 | else | |
420 | if tags.highway ~= nil and tags.tags.functional_class ~= nil | |
421 | then | |
422 | return tags.tags.functional_class | |
423 | else | |
424 | return tags.highway | |
425 | end | |
426 | end | |
0 | 427 | end |
428 | ||
429 | function has_shields(tags) | |
1 | 430 | return (tags.highway == 'trunk' or tags.highway == 'primary' or tags.highway == 'secondary' or tags.highway == 'tertiary') |
0 | 431 | end |
432 | ||
433 | -- https://stackoverflow.com/a/7615129 | |
434 | function mysplit(inputstr, sep) | |
1 | 435 | if sep == nil then |
436 | sep = "%s" | |
437 | end | |
438 | local t={} | |
439 | for str in string.gmatch(inputstr, "([^"..sep.."]+)") do | |
440 | table.insert(t, str) | |
441 | end | |
442 | return t | |
0 | 443 | end |
444 | ||
445 | function combine_stringlists(a, b) | |
1 | 446 | if a ~= nil and a ~= '' |
447 | then | |
448 | if b ~= nil and b ~= '' | |
449 | then | |
450 | return a..';'..b | |
451 | else | |
452 | return a | |
453 | end | |
454 | else | |
455 | return b | |
456 | end | |
0 | 457 | end |
458 | ||
459 | function combine_refs(a, b) | |
1 | 460 | return combine_stringlists(a, b) |
0 | 461 | end |
462 | ||
463 | -- Widths of ref characters in Liikenne font, used to calculate shield sizes | |
464 | character_widths = { | |
1 | 465 | ['0'] = 616, |
466 | ['1'] = 337, | |
467 | ['2'] = 600, | |
468 | ['3'] = 621, | |
469 | ['4'] = 689, | |
470 | ['5'] = 623, | |
471 | ['6'] = 566, | |
472 | ['7'] = 499, | |
473 | ['8'] = 616, | |
474 | ['9'] = 566, | |
475 | [' '] = 260, | |
476 | ['E'] = 613, | |
0 | 477 | } |
478 | ||
479 | function ref_width(ref) | |
1 | 480 | local result = 0 |
481 | for i = 1, #ref | |
482 | do | |
483 | result = result + (character_widths[ref:sub(i, i)] or 0) | |
484 | end | |
485 | return math.max(math.ceil((result - 1000) / 77), 1) | |
0 | 486 | end |
487 | ||
488 | function ref_widths(refs) | |
1 | 489 | local result = '' |
490 | for _, ref in ipairs(mysplit(refs, ';')) | |
491 | do | |
492 | result = combine_stringlists(result, ref_width(ref)) | |
493 | end | |
494 | return result | |
0 | 495 | end |
496 | ||
497 | -- Makes refs more sensible. | |
498 | -- 5-digit refs are not found on the ground so they are omitted. | |
499 | -- int_ref is added to refs. | |
500 | function highway_refs(tags) | |
1 | 501 | if has_shields(tags) and (tags.ref ~= nil or tags.tags.int_ref ~= nil) |
502 | then | |
503 | if tags.junction == 'roundabout' | |
504 | then | |
505 | return nil | |
506 | else | |
507 | local result = '' | |
508 | local all_refs = combine_refs(tags.ref, tags.tags.int_ref) | |
509 | for _, ref in ipairs(mysplit(all_refs, ';')) | |
510 | do | |
511 | if tonumber(ref) == nil or tonumber(ref) < 10000 | |
512 | then | |
513 | ref = string.gsub(ref, '^E 0', 'E ') | |
514 | result = combine_refs(result, ref) | |
515 | end | |
516 | end | |
517 | return result | |
518 | end | |
519 | else | |
520 | return tags.ref | |
521 | end | |
0 | 522 | end |
523 | ||
524 | -- classify road type by number | |
525 | function road_class_by_ref(ref) | |
1 | 526 | local n = tonumber(ref) |
527 | if n ~= nil and n > 0 | |
528 | then | |
529 | if n < 40 | |
530 | then | |
531 | return 'valtatie' | |
532 | elseif n < 100 | |
533 | then | |
534 | return 'kantatie' | |
535 | elseif n < 1000 | |
536 | then | |
537 | return 'seututie' | |
538 | else | |
539 | return 'yhdystie' | |
540 | end | |
541 | elseif string.match(ref, '^E ?%d+$') | |
542 | then | |
543 | return 'eurooppatie' | |
544 | else | |
545 | return 'unknown' | |
546 | end | |
0 | 547 | end |
548 | ||
549 | function classify_road_numbers(refs) | |
1 | 550 | local result = '' |
551 | for _, ref in ipairs(mysplit(refs, ';')) | |
552 | do | |
553 | result = combine_stringlists(result, road_class_by_ref(ref)) | |
554 | end | |
555 | return result | |
0 | 556 | end |
557 | ||
558 | function gen_columns(text_columns, with_hstore, area, geometry_type) | |
1 | 559 | columns = {} |
0 | 560 | |
1 | 561 | local add_column = function (name, type) |
562 | columns[#columns + 1] = { column = name, type = type } | |
563 | end | |
0 | 564 | |
1 | 565 | for _, c in ipairs(text_columns) do |
566 | add_column(c, 'text') | |
567 | end | |
0 | 568 | |
1 | 569 | add_column('z_order', 'int') |
0 | 570 | |
1 | 571 | if area ~= nil then |
572 | if area then | |
573 | add_column('way_area', 'area') | |
574 | else | |
575 | add_column('way_area', 'real') | |
576 | end | |
577 | end | |
0 | 578 | |
1 | 579 | if hstore_column then |
580 | add_column(hstore_column, 'hstore') | |
581 | end | |
0 | 582 | |
1 | 583 | if with_hstore then |
584 | add_column('tags', 'hstore') | |
585 | end | |
0 | 586 | |
1 | 587 | add_column('way', geometry_type) |
0 | 588 | |
1 | 589 | return columns |
0 | 590 | end |
591 | ||
592 | local tables = {} | |
593 | ||
594 | tables.point = osm2pgsql.define_table{ | |
1 | 595 | name = prefix .. '_point', |
596 | ids = { type = 'node', id_column = 'osm_id' }, | |
597 | columns = gen_columns(point_columns, hstore or hstore_all, nil, 'point') | |
0 | 598 | } |
599 | ||
600 | tables.line = osm2pgsql.define_table{ | |
1 | 601 | name = prefix .. '_line', |
602 | ids = { type = 'way', id_column = 'osm_id' }, | |
603 | columns = gen_columns(non_point_columns, hstore or hstore_all, false, 'linestring') | |
0 | 604 | } |
605 | ||
606 | tables.polygon = osm2pgsql.define_table{ | |
1 | 607 | name = prefix .. '_polygon', |
608 | ids = { type = 'area', id_column = 'osm_id' }, | |
609 | columns = gen_columns(non_point_columns, hstore or hstore_all, true, 'geometry') | |
0 | 610 | } |
611 | ||
612 | tables.roads = osm2pgsql.define_table{ | |
1 | 613 | name = prefix .. '_roads', |
614 | ids = { type = 'way', id_column = 'osm_id' }, | |
615 | columns = gen_columns(non_point_columns, hstore or hstore_all, false, 'linestring') | |
0 | 616 | } |
617 | ||
2 | 618 | tables.routes = osm2pgsql.define_way_table( |
619 | prefix .. '_routes', | |
620 | { | |
621 | { column = 'tags', type = 'hstore' }, | |
622 | { column = 'ref', type = 'text' }, | |
623 | { column = 'name', type = 'text' }, | |
624 | { column = 'network', type = 'text' }, | |
625 | { column = 'route', type = 'text' }, | |
626 | { column = 'layer', type = 'text' }, | |
627 | { column = 'osm_way_id', type = 'text' }, | |
628 | { column = 'way', type = 'linestring' }, | |
629 | } | |
630 | ) | |
631 | ||
632 | ||
0 | 633 | local z_order_lookup = { |
1 | 634 | proposed = {1, false}, |
635 | construction = {2, false}, | |
636 | steps = {10, false}, | |
637 | cycleway = {10, false}, | |
638 | bridleway = {10, false}, | |
639 | footway = {10, false}, | |
640 | path = {10, false}, | |
641 | track = {11, false}, | |
642 | service = {15, false}, | |
0 | 643 | |
1 | 644 | tertiary_link = {24, false}, |
645 | secondary_link = {25, true}, | |
646 | primary_link = {27, true}, | |
647 | trunk_link = {28, true}, | |
648 | motorway_link = {29, true}, | |
0 | 649 | |
1 | 650 | raceway = {30, false}, |
651 | pedestrian = {31, false}, | |
652 | living_street = {32, false}, | |
653 | road = {33, false}, | |
654 | unclassified = {33, false}, | |
655 | residential = {33, false}, | |
656 | tertiary = {34, false}, | |
657 | secondary = {36, true}, | |
658 | primary = {37, true}, | |
659 | trunk = {38, true}, | |
660 | motorway = {39, true} | |
0 | 661 | } |
662 | ||
663 | function as_bool(value) | |
1 | 664 | return value == 'yes' or value == 'true' or value == '1' |
0 | 665 | end |
666 | ||
667 | function get_z_order(tags) | |
1 | 668 | local z_order = 100 * math.floor(tonumber(tags.layer or '0') or 0) |
669 | local roads = false | |
0 | 670 | |
1 | 671 | local highway = tags['highway'] |
672 | if highway then | |
673 | local r = z_order_lookup[highway] or {0, false} | |
674 | z_order = z_order + r[1] | |
675 | roads = r[2] | |
676 | end | |
0 | 677 | |
1 | 678 | if tags.railway then |
679 | z_order = z_order + 35 | |
680 | roads = true | |
681 | end | |
0 | 682 | |
1 | 683 | if tags.boundary and tags.boundary == 'administrative' then |
684 | roads = true | |
685 | end | |
0 | 686 | |
1 | 687 | if as_bool(tags.bridge) then |
688 | z_order = z_order + 100 | |
689 | end | |
0 | 690 | |
1 | 691 | if as_bool(tags.tunnel) then |
692 | z_order = z_order - 100 | |
693 | end | |
0 | 694 | |
1 | 695 | return z_order, roads |
0 | 696 | end |
697 | ||
698 | function make_check_in_list_func(list) | |
1 | 699 | local h = {} |
700 | for _, k in ipairs(list) do | |
701 | h[k] = true | |
702 | end | |
703 | return function(tags) | |
704 | for k, _ in pairs(tags) do | |
705 | if h[k] then | |
706 | return true | |
707 | end | |
708 | end | |
709 | return false | |
710 | end | |
0 | 711 | end |
712 | ||
713 | local is_polygon = make_check_in_list_func(polygon_keys) | |
714 | local clean_tags = osm2pgsql.make_clean_tags_func(delete_keys) | |
715 | ||
716 | function make_column_hash(columns) | |
1 | 717 | local h = {} |
0 | 718 | |
1 | 719 | for _, k in ipairs(columns) do |
720 | h[k] = true | |
721 | end | |
0 | 722 | |
1 | 723 | return h |
0 | 724 | end |
725 | ||
726 | function make_get_output(columns, hstore_all) | |
1 | 727 | local h = make_column_hash(columns) |
728 | if hstore_all then | |
729 | return function(tags) | |
730 | local output = {} | |
731 | local hstore_entries = {} | |
0 | 732 | |
1 | 733 | for k, _ in pairs(tags) do |
734 | if h[k] then | |
735 | output[k] = tags[k] | |
736 | end | |
737 | hstore_entries[k] = tags[k] | |
738 | end | |
0 | 739 | |
1 | 740 | return output, hstore_entries |
741 | end | |
742 | else | |
743 | return function(tags) | |
744 | local output = {} | |
745 | local hstore_entries = {} | |
0 | 746 | |
1 | 747 | for k, _ in pairs(tags) do |
748 | if h[k] then | |
749 | output[k] = tags[k] | |
750 | else | |
751 | hstore_entries[k] = tags[k] | |
752 | end | |
753 | end | |
0 | 754 | |
1 | 755 | return output, hstore_entries |
756 | end | |
757 | end | |
0 | 758 | end |
759 | ||
760 | local has_generic_tag = make_check_in_list_func(generic_keys) | |
761 | ||
762 | local get_point_output = make_get_output(point_columns, hstore_all) | |
763 | local get_non_point_output = make_get_output(non_point_columns, hstore_all) | |
764 | ||
765 | function get_hstore_column(tags) | |
1 | 766 | local len = #hstore_column |
767 | local h = {} | |
768 | for k, v in pairs(tags) do | |
769 | if k:sub(1, len) == hstore_column then | |
770 | h[k:sub(len + 1)] = v | |
771 | end | |
772 | end | |
0 | 773 | |
1 | 774 | if next(h) then |
775 | return h | |
776 | end | |
777 | return nil | |
0 | 778 | end |
779 | ||
780 | function add_generic_tags(object, output) | |
1 | 781 | output.majority_name = majority_name(output) |
782 | output.minority_name = minority_name(output) | |
783 | output.bilingual_name = bilingual_name(output) | |
784 | return output | |
0 | 785 | end |
786 | ||
787 | function osm2pgsql.process_node(object) | |
1 | 788 | if clean_tags(object.tags) then |
789 | return | |
790 | end | |
0 | 791 | |
1 | 792 | if object.tags.layer then |
793 | object.tags.layer = tonumber(object.tags.layer) | |
794 | end | |
0 | 795 | |
1 | 796 | local output |
797 | local output_hstore = {} | |
798 | if hstore or hstore_all then | |
799 | output, output_hstore = get_point_output(object.tags) | |
800 | if not next(output) and not next(output_hstore) then | |
801 | return | |
802 | end | |
803 | if hstore_match_only and not has_generic_tag(object.tags) then | |
804 | return | |
805 | end | |
806 | else | |
807 | output = object.tags | |
808 | if not has_generic_tag(object.tags) then | |
809 | return | |
810 | end | |
811 | end | |
0 | 812 | |
1 | 813 | output = add_generic_tags(object, output) |
814 | output.tags = output_hstore | |
0 | 815 | |
1 | 816 | if hstore_column then |
817 | output[hstore_column] = get_hstore_column(object.tags) | |
818 | end | |
0 | 819 | |
1 | 820 | tables.point:add_row(output) |
0 | 821 | end |
822 | ||
2 | 823 | route_ways = {} |
824 | ||
0 | 825 | function osm2pgsql.process_way(object) |
1 | 826 | if clean_tags(object.tags) then |
827 | return | |
828 | end | |
0 | 829 | |
1 | 830 | if object.tags.layer then |
831 | object.tags.layer = tonumber(object.tags.layer) | |
832 | end | |
0 | 833 | |
834 | ||
1 | 835 | local add_area = false |
836 | if object.tags.natural == 'coastline' then | |
837 | add_area = true | |
838 | if not keep_coastlines then | |
839 | object.tags.natural = nil | |
840 | end | |
841 | end | |
0 | 842 | |
1 | 843 | local output |
844 | local output_hstore = {} | |
845 | if hstore or hstore_all then | |
846 | output, output_hstore = get_non_point_output(object.tags) | |
847 | if not next(output) and not next(output_hstore) then | |
848 | return | |
849 | end | |
850 | if hstore_match_only and not has_generic_tag(object.tags) then | |
851 | return | |
852 | end | |
853 | if add_area and hstore_all then | |
854 | output_hstore.area = 'yes' | |
855 | end | |
856 | else | |
857 | output = object.tags | |
858 | if not has_generic_tag(object.tags) then | |
859 | return | |
860 | end | |
861 | end | |
0 | 862 | |
1 | 863 | local polygon |
864 | local area_tag = object.tags.area | |
865 | if area_tag == 'yes' or area_tag == '1' or area_tag == 'true' then | |
866 | polygon = true | |
867 | elseif area_tag == 'no' or area_tag == '0' or area_tag == 'false' then | |
868 | polygon = false | |
869 | else | |
870 | polygon = is_polygon(object.tags) | |
871 | end | |
0 | 872 | |
1 | 873 | if add_area then |
874 | output.area = 'yes' | |
875 | polygon = true | |
876 | end | |
0 | 877 | |
1 | 878 | local z_order, roads = get_z_order(object.tags) |
879 | output.z_order = z_order | |
880 | output = add_generic_tags(object, output) | |
0 | 881 | |
1 | 882 | output.tags = output_hstore |
0 | 883 | |
1 | 884 | if output.highway ~= nil |
885 | then | |
886 | if output.highway == 'construction' | |
887 | then | |
888 | return | |
889 | end | |
890 | output.highway = highway_class(output) | |
891 | output.ref = highway_refs(output) | |
892 | if output.highway == 'construction' and output.construction == 'motorway' | |
893 | then | |
894 | output.construction = 'trunk' | |
895 | elseif output.highway == 'construction' and output.construction == 'motorway_link' | |
896 | then | |
897 | output.construction = 'trunk_link' | |
898 | end | |
0 | 899 | |
1 | 900 | -- classify references for for Finland shield rendering |
901 | if output.ref ~= nil | |
902 | then | |
903 | output.ref_class = classify_road_numbers(output.ref) | |
904 | output.ref_width = ref_widths(output.ref) | |
905 | end | |
906 | end | |
0 | 907 | |
1 | 908 | if hstore_column then |
909 | output[hstore_column] = get_hstore_column(object.tags) | |
910 | end | |
0 | 911 | |
1 | 912 | if polygon and object.is_closed then |
913 | output.way = { create = 'area' } | |
914 | tables.polygon:add_row(output) | |
915 | else | |
916 | output.way = { create = 'line', split_at = max_length } | |
917 | tables.line:add_row(output) | |
918 | if roads then | |
919 | tables.roads:add_row(output) | |
920 | end | |
921 | end | |
2 | 922 | |
923 | if osm2pgsql.stage == 2 | |
924 | then | |
925 | local routes = route_ways[object.id] | |
926 | if routes ~= nil | |
927 | then | |
928 | for index, route in ipairs(routes) do | |
929 | route_type = route.tags.route | |
930 | if route_type == 'bicycle' and route.tags.network ~= nil | |
931 | then | |
932 | route_type = route_type .. '_' .. route.tags.network | |
933 | end | |
934 | row = { | |
935 | tags = object.tags, | |
936 | ref = route.tags.ref, | |
937 | name = route.tags.name, | |
938 | network = route.tags.network, | |
939 | route = route_type, | |
940 | osm_way_id = object.id, | |
941 | layer = object.tags.layer or 0, | |
942 | geom = { create = 'line' } | |
943 | } | |
944 | tables.routes:add_row(row) | |
945 | end | |
946 | end | |
947 | end | |
0 | 948 | end |
949 | ||
2 | 950 | |
951 | function osm2pgsql.select_relation_members(relation) | |
4
34a84c0a427c
render commuter train refs
Teemu Piippo <teemu@hecknology.net>
parents:
2
diff
changeset
|
952 | if relation.tags.type == 'route' and (relation.tags.route == 'foot' or relation.tags.route == 'hiking' or relation.tags.route == 'bicycle' or relation.tags.route == 'train' or relation.tags.route == 'bus') |
2 | 953 | then |
954 | for _, member in ipairs(relation.members) do | |
955 | if member.type == 'w' then | |
956 | member_id = member.ref | |
957 | if not route_ways[member_id] then | |
958 | route_ways[member_id] = {} | |
959 | end | |
960 | table.insert(route_ways[member_id], relation) | |
961 | end | |
962 | end | |
963 | return { ways = osm2pgsql.way_member_ids(relation) } | |
964 | end | |
965 | end | |
966 | ||
967 | ||
0 | 968 | function osm2pgsql.process_relation(object) |
1 | 969 | if clean_tags(object.tags) then |
970 | return | |
971 | end | |
0 | 972 | |
1 | 973 | local type = object.tags.type |
974 | if (type ~= 'route') and (type ~= 'multipolygon') and (type ~= 'boundary') then | |
975 | return | |
976 | end | |
977 | object.tags.type = nil | |
0 | 978 | |
1 | 979 | local output |
980 | local output_hstore = {} | |
981 | if hstore or hstore_all then | |
982 | output, output_hstore = get_non_point_output(object.tags) | |
983 | if not next(output) and not next(output_hstore) then | |
984 | return | |
985 | end | |
986 | if hstore_match_only and not has_generic_tag(object.tags) then | |
987 | return | |
988 | end | |
989 | else | |
990 | output = object.tags | |
991 | if not has_generic_tag(object.tags) then | |
992 | return | |
993 | end | |
994 | end | |
0 | 995 | |
1 | 996 | if not next(output) and not next(output_hstore) then |
997 | return | |
998 | end | |
0 | 999 | |
1 | 1000 | if enable_legacy_route_processing and (hstore or hstore_all) and type == 'route' then |
1001 | if not object.tags.route_name then | |
1002 | output_hstore.route_name = object.tags.name | |
1003 | end | |
0 | 1004 | |
1 | 1005 | local state = object.tags.state |
1006 | if state ~= 'alternate' and state ~= 'connection' then | |
1007 | state = 'yes' | |
1008 | end | |
0 | 1009 | |
1 | 1010 | local network = object.tags.network |
1011 | if network == 'lcn' then | |
1012 | output_hstore.lcn = output_hstore.lcn or state | |
1013 | output_hstore.lcn_ref = output_hstore.lcn_ref or object.tags.ref | |
1014 | elseif network == 'rcn' then | |
1015 | output_hstore.rcn = output_hstore.rcn or state | |
1016 | output_hstore.rcn_ref = output_hstore.rcn_ref or object.tags.ref | |
1017 | elseif network == 'ncn' then | |
1018 | output_hstore.ncn = output_hstore.ncn or state | |
1019 | output_hstore.ncn_ref = output_hstore.ncn_ref or object.tags.ref | |
1020 | elseif network == 'lwn' then | |
1021 | output_hstore.lwn = output_hstore.lwn or state | |
1022 | output_hstore.lwn_ref = output_hstore.lwn_ref or object.tags.ref | |
1023 | elseif network == 'rwn' then | |
1024 | output_hstore.rwn = output_hstore.rwn or state | |
1025 | output_hstore.rwn_ref = output_hstore.rwn_ref or object.tags.ref | |
1026 | elseif network == 'nwn' then | |
1027 | output_hstore.nwn = output_hstore.nwn or state | |
1028 | output_hstore.nwn_ref = output_hstore.nwn_ref or object.tags.ref | |
1029 | end | |
0 | 1030 | |
1 | 1031 | local pc = object.tags.preferred_color |
1032 | if pc == '0' or pc == '1' or pc == '2' or pc == '3' or pc == '4' then | |
1033 | output_hstore.route_pref_color = pc | |
1034 | else | |
1035 | output_hstore.route_pref_color = '0' | |
1036 | end | |
1037 | end | |
0 | 1038 | |
1 | 1039 | local make_boundary = false |
1040 | local make_polygon = false | |
1041 | if type == 'boundary' then | |
1042 | make_boundary = true | |
1043 | elseif type == 'multipolygon' and object.tags.boundary then | |
1044 | make_boundary = true | |
1045 | elseif type == 'multipolygon' then | |
1046 | make_polygon = true | |
1047 | end | |
0 | 1048 | |
1 | 1049 | local z_order, roads = get_z_order(object.tags) |
1050 | output.z_order = z_order | |
1051 | output = add_generic_tags(object, output) | |
0 | 1052 | |
1 | 1053 | output.tags = output_hstore |
0 | 1054 | |
1 | 1055 | if hstore_column then |
1056 | output[hstore_column] = get_hstore_column(object.tags) | |
1057 | end | |
0 | 1058 | |
1 | 1059 | if not make_polygon then |
1060 | output.way = { create = 'line', split_at = max_length } | |
1061 | tables.line:add_row(output) | |
1062 | if roads then | |
1063 | tables.roads:add_row(output) | |
1064 | end | |
1065 | end | |
0 | 1066 | |
1 | 1067 | if make_boundary or make_polygon then |
1068 | output.way = { create = 'area', multi = multi_geometry } | |
1069 | tables.polygon:add_row(output) | |
1070 | end | |
0 | 1071 | end |
1072 |