1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
|
-- This config example file is released into the Public Domain.
-- This configuration for the flex output tries to be compatible with the
-- original pgsql C transform output. There might be some corner cases but
-- it should do exactly the same in almost all cases.
-- The output projection used (3857, web mercator is the default). Set this
-- to 4326 if you were using the -l|--latlong option or to the EPSG
-- code you were using on the -E|-proj option.
local srid = 3857
-- Set this to true if you were using option -K|--keep-coastlines.
local keep_coastlines = false
-- Set this to the table name prefix (what used to be option -p|--prefix).
local prefix = 'planet_osm'
-- Set this to true if multipolygons should be written as multipolygons into
-- db (what used to be option -G|--multi-geometry).
local multi_geometry = false
-- Set this to true if you want an hstore column (what used to be option
-- -k|--hstore). Can not be true if "hstore_all" is true.
local hstore = false
-- Set this to true if you want all tags in an hstore column (what used to
-- be option -j|--hstore-all). Can not be true if "hstore" is true.
local hstore_all = false
-- Only keep objects that have a value in one of the non-hstore columns
-- (normal action with --hstore is to keep all objects). Equivalent to
-- what used to be set through option --hstore-match-only.
local hstore_match_only = false
-- Set this to add an additional hstore (key/value) column containing all tags
-- that start with the specified string, eg "name:". Will produce an extra
-- hstore column that contains all "name:xx" tags. Equivalent to what used to
-- be set through option -z|--hstore-column. Unlike the -z option which can
-- be specified multiple time, this does only support a single additional
-- hstore column.
local hstore_column = nil
-- If this is set, area calculations are always in Mercator coordinates units
-- irrespective of the srid setting.
-- Set this to true if you used --reproject-area before.
local reproject_area = false
-- There is some very old specialized handling of route relations in osm2pgsql,
-- which you probably don't need. This is disabled here, but you can enable
-- it by setting this to true. If you don't understand this, leave it alone.
local enable_legacy_route_processing = false
-- ---------------------------------------------------------------------------
if hstore and hstore_all then
error("hstore and hstore_all can't be both true")
end
-- Used for splitting up long linestrings
local max_length = 1
if srid == 3857 then
max_length = 100000
end
-- Ways with any of the following keys will be treated as polygon
local polygon_keys = {
'aeroway',
'amenity',
'building',
'harbour',
'historic',
'landuse',
'leisure',
'man_made',
'military',
'natural',
'office',
'place',
'power',
'public_transport',
'shop',
'sport',
'tourism',
'water',
'waterway',
'wetland',
'abandoned:aeroway',
'abandoned:amenity',
'abandoned:building',
'abandoned:landuse',
'abandoned:power',
'area:highway'
}
-- Objects without any of the following keys will be deleted
local generic_keys = {
'access',
'addr:housename',
'addr:housenumber',
'addr:interpolation',
'admin_level',
'aerialway',
'aeroway',
'amenity',
'area',
'barrier',
'bicycle',
'boundary',
'brand',
'bridge',
'building',
'capital',
'construction',
'covered',
'culvert',
'cutting',
'denomination',
'disused',
'ele',
'embankment',
'foot',
'generation:source',
'harbour',
'highway',
'historic',
'hours',
'intermittent',
'junction',
'landuse',
'layer',
'leisure',
'lock',
'man_made',
'military',
'motorcar',
'name',
'natural',
'office',
'oneway',
'operator',
'place',
'population',
'power',
'power_source',
'public_transport',
'railway',
'ref',
'religion',
'route',
'service',
'shop',
'sport',
'surface',
'toll',
'tourism',
'tower:type',
'tracktype',
'tunnel',
'water',
'waterway',
'wetland',
'width',
'wood',
'abandoned:aeroway',
'abandoned:amenity',
'abandoned:building',
'abandoned:landuse',
'abandoned:power',
'area:highway'
}
-- The following keys will be deleted
local delete_keys = {
'attribution',
'comment',
'created_by',
'fixme',
'note',
'note:*',
'odbl',
'odbl:note',
'source',
'source:*',
'source_ref',
'way',
'way_area',
'z_order',
}
local point_columns = {
'access',
'addr:housename',
'addr:housenumber',
'addr:interpolation',
'admin_level',
'aerialway',
'aeroway',
'amenity',
'area',
'barrier',
'bicycle',
'brand',
'bridge',
'boundary',
'building',
'capital',
'construction',
'covered',
'culvert',
'cutting',
'denomination',
'disused',
'ele',
'embankment',
'foot',
'generator:source',
'harbour',
'highway',
'historic',
'horse',
'intermittent',
'junction',
'landuse',
'layer',
'leisure',
'lock',
'man_made',
'military',
'motorcar',
'name',
'natural',
'office',
'oneway',
'operator',
'place',
'population',
'power',
'power_source',
'public_transport',
'railway',
'ref',
'religion',
'route',
'service',
'shop',
'sport',
'surface',
'toll',
'tourism',
'tower:type',
'tunnel',
'water',
'waterway',
'wetland',
'width',
'wood',
}
local non_point_columns = {
'access',
'addr:housename',
'addr:housenumber',
'addr:interpolation',
'admin_level',
'aerialway',
'aeroway',
'amenity',
'area',
'barrier',
'bicycle',
'brand',
'bridge',
'boundary',
'building',
'construction',
'covered',
'culvert',
'cutting',
'denomination',
'disused',
'embankment',
'foot',
'generator:source',
'harbour',
'highway',
'historic',
'horse',
'intermittent',
'junction',
'landuse',
'layer',
'leisure',
'lock',
'man_made',
'military',
'motorcar',
'name',
'natural',
'office',
'oneway',
'operator',
'place',
'population',
'power',
'power_source',
'public_transport',
'railway',
'ref',
'religion',
'route',
'service',
'shop',
'sport',
'surface',
'toll',
'tourism',
'tower:type',
'tracktype',
'tunnel',
'water',
'waterway',
'wetland',
'width',
'wood',
}
local function gen_columns(text_columns, with_hstore, area, geometry_type)
local columns = {}
local add_column = function (name, type)
columns[#columns + 1] = { column = name, type = type }
end
for _, c in ipairs(text_columns) do
add_column(c, 'text')
end
add_column('z_order', 'int')
if area then
add_column('way_area', 'real')
end
if hstore_column then
add_column(hstore_column, 'hstore')
end
if with_hstore then
add_column('tags', 'hstore')
end
add_column('way', geometry_type)
columns[#columns].projection = srid
columns[#columns].not_null = true
return columns
end
local tables = {}
tables.point = osm2pgsql.define_table{
name = prefix .. '_point',
ids = { type = 'node', id_column = 'osm_id' },
columns = gen_columns(point_columns, hstore or hstore_all, false, 'point')
}
tables.line = osm2pgsql.define_table{
name = prefix .. '_line',
ids = { type = 'way', id_column = 'osm_id' },
columns = gen_columns(non_point_columns, hstore or hstore_all, true, 'linestring')
}
tables.polygon = osm2pgsql.define_table{
name = prefix .. '_polygon',
ids = { type = 'area', id_column = 'osm_id' },
columns = gen_columns(non_point_columns, hstore or hstore_all, true, 'geometry')
}
tables.roads = osm2pgsql.define_table{
name = prefix .. '_roads',
ids = { type = 'way', id_column = 'osm_id' },
columns = gen_columns(non_point_columns, hstore or hstore_all, true, 'linestring')
}
local z_order_lookup = {
proposed = {1, false},
construction = {2, false},
steps = {10, false},
cycleway = {10, false},
bridleway = {10, false},
footway = {10, false},
path = {10, false},
track = {11, false},
service = {15, false},
tertiary_link = {24, false},
secondary_link = {25, true},
primary_link = {27, true},
trunk_link = {28, true},
motorway_link = {29, true},
raceway = {30, false},
pedestrian = {31, false},
living_street = {32, false},
road = {33, false},
unclassified = {33, false},
residential = {33, false},
tertiary = {34, false},
secondary = {36, true},
primary = {37, true},
trunk = {38, true},
motorway = {39, true}
}
local function as_bool(value)
return value == 'yes' or value == 'true' or value == '1'
end
local function get_z_order(tags)
local z_order = 100 * math.floor(tonumber(tags.layer or '0') or 0)
local roads = false
local highway = tags['highway']
if highway then
local r = z_order_lookup[highway] or {0, false}
z_order = z_order + r[1]
roads = r[2]
end
if tags.railway then
z_order = z_order + 35
roads = true
end
if tags.boundary and tags.boundary == 'administrative' then
roads = true
end
if as_bool(tags.bridge) then
z_order = z_order + 100
end
if as_bool(tags.tunnel) then
z_order = z_order - 100
end
return z_order, roads
end
local function make_check_in_list_func(list)
local h = {}
for _, k in ipairs(list) do
h[k] = true
end
return function(tags)
for k, _ in pairs(tags) do
if h[k] then
return true
end
end
return false
end
end
local is_polygon = make_check_in_list_func(polygon_keys)
local clean_tags = osm2pgsql.make_clean_tags_func(delete_keys)
local function make_column_hash(columns)
local h = {}
for _, k in ipairs(columns) do
h[k] = true
end
return h
end
local function make_get_output(columns)
local h = make_column_hash(columns)
if hstore_all then
return function(tags)
local output = {}
local hstore_entries = {}
for k, _ in pairs(tags) do
if h[k] then
output[k] = tags[k]
end
hstore_entries[k] = tags[k]
end
return output, hstore_entries
end
else
return function(tags)
local output = {}
local hstore_entries = {}
for k, _ in pairs(tags) do
if h[k] then
output[k] = tags[k]
else
hstore_entries[k] = tags[k]
end
end
return output, hstore_entries
end
end
end
local has_generic_tag = make_check_in_list_func(generic_keys)
local get_point_output = make_get_output(point_columns)
local get_non_point_output = make_get_output(non_point_columns)
local function get_hstore_column(tags)
local len = #hstore_column
local h = {}
for k, v in pairs(tags) do
if k:sub(1, len) == hstore_column then
h[k:sub(len + 1)] = v
end
end
if next(h) then
return h
end
return nil
end
function osm2pgsql.process_node(object)
if clean_tags(object.tags) then
return
end
local output
local output_hstore = {}
if hstore or hstore_all then
output, output_hstore = get_point_output(object.tags)
if not next(output) and not next(output_hstore) then
return
end
if hstore_match_only and not has_generic_tag(object.tags) then
return
end
else
output = object.tags
if not has_generic_tag(object.tags) then
return
end
end
output.tags = output_hstore
if hstore_column then
output[hstore_column] = get_hstore_column(object.tags)
end
output.way = object:as_point()
tables.point:insert(output)
end
local function add_line(output, geom, roads)
for sgeom in geom:segmentize(max_length):geometries() do
output.way = sgeom
tables.line:insert(output)
if roads then
tables.roads:insert(output)
end
end
end
local function compute_geom_and_area(geom)
local area, projected_geom
projected_geom = geom:transform(srid)
if reproject_area and srid ~= 3857 then
area = geom:transform(3857):area()
else
area = projected_geom:area()
end
return projected_geom, area
end
function osm2pgsql.process_way(object)
if clean_tags(object.tags) then
return
end
local add_area = false
if object.tags.natural == 'coastline' then
add_area = true
if not keep_coastlines then
object.tags.natural = nil
end
end
local output
local output_hstore = {}
if hstore or hstore_all then
output, output_hstore = get_non_point_output(object.tags)
if not next(output) and not next(output_hstore) then
return
end
if hstore_match_only and not has_generic_tag(object.tags) then
return
end
if add_area and hstore_all then
output_hstore.area = 'yes'
end
else
output = object.tags
if not has_generic_tag(object.tags) then
return
end
end
local polygon
local area_tag = object.tags.area
if area_tag == 'yes' or area_tag == '1' or area_tag == 'true' then
polygon = true
elseif area_tag == 'no' or area_tag == '0' or area_tag == 'false' then
polygon = false
else
polygon = is_polygon(object.tags)
end
if add_area then
output.area = 'yes'
polygon = true
end
local z_order, roads = get_z_order(object.tags)
output.z_order = z_order
output.tags = output_hstore
if hstore_column then
output[hstore_column] = get_hstore_column(object.tags)
end
if polygon and object.is_closed then
local pgeom, area = compute_geom_and_area(object:as_polygon())
output.way = pgeom
output.way_area = area
tables.polygon:insert(output)
else
add_line(output, object:as_linestring(), roads)
end
end
function osm2pgsql.process_relation(object)
if clean_tags(object.tags) then
return
end
local rtype = object:grab_tag('type')
if (rtype ~= 'route') and (rtype ~= 'multipolygon') and (rtype ~= 'boundary') then
return
end
local output
local output_hstore = {}
if hstore or hstore_all then
output, output_hstore = get_non_point_output(object.tags)
if not next(output) and not next(output_hstore) then
return
end
if hstore_match_only and not has_generic_tag(object.tags) then
return
end
else
output = object.tags
if not has_generic_tag(object.tags) then
return
end
end
if not next(output) and not next(output_hstore) then
return
end
if enable_legacy_route_processing and (hstore or hstore_all) and rtype == 'route' then
if not object.tags.route_name then
output_hstore.route_name = object.tags.name
end
local state = object.tags.state
if state ~= 'alternate' and state ~= 'connection' then
state = 'yes'
end
local network = object.tags.network
if network == 'lcn' then
output_hstore.lcn = output_hstore.lcn or state
output_hstore.lcn_ref = output_hstore.lcn_ref or object.tags.ref
elseif network == 'rcn' then
output_hstore.rcn = output_hstore.rcn or state
output_hstore.rcn_ref = output_hstore.rcn_ref or object.tags.ref
elseif network == 'ncn' then
output_hstore.ncn = output_hstore.ncn or state
output_hstore.ncn_ref = output_hstore.ncn_ref or object.tags.ref
elseif network == 'lwn' then
output_hstore.lwn = output_hstore.lwn or state
output_hstore.lwn_ref = output_hstore.lwn_ref or object.tags.ref
elseif network == 'rwn' then
output_hstore.rwn = output_hstore.rwn or state
output_hstore.rwn_ref = output_hstore.rwn_ref or object.tags.ref
elseif network == 'nwn' then
output_hstore.nwn = output_hstore.nwn or state
output_hstore.nwn_ref = output_hstore.nwn_ref or object.tags.ref
end
local pc = object.tags.preferred_color
if pc == '0' or pc == '1' or pc == '2' or pc == '3' or pc == '4' then
output_hstore.route_pref_color = pc
else
output_hstore.route_pref_color = '0'
end
end
local make_boundary = false
local make_polygon = false
if rtype == 'boundary' then
make_boundary = true
elseif rtype == 'multipolygon' and object.tags.boundary then
make_boundary = true
elseif rtype == 'multipolygon' then
make_polygon = true
end
local z_order, roads = get_z_order(object.tags)
output.z_order = z_order
output.tags = output_hstore
if hstore_column then
output[hstore_column] = get_hstore_column(object.tags)
end
if not make_polygon then
add_line(output, object:as_multilinestring(), roads)
end
if make_boundary or make_polygon then
local geom = object:as_multipolygon()
if multi_geometry then
local pgeom, area = compute_geom_and_area(geom)
output.way = pgeom
output.way_area = area
tables.polygon:insert(output)
else
for sgeom in geom:geometries() do
local pgeom, area = compute_geom_and_area(sgeom)
output.way = pgeom
output.way_area = area
tables.polygon:insert(output)
end
end
end
end
|