diff --git a/python/dbapi/api/raw.py b/python/dbapi/api/raw.py index b3d710c7..9dd084cb 100644 --- a/python/dbapi/api/raw.py +++ b/python/dbapi/api/raw.py @@ -22,23 +22,22 @@ RESULTS_PER_PAGE = 500 RESULTS_PER_PAGE_LIST = 100 -# TODO: improve this code def tagsQueryFilter(tagsQuery, table): query = "" tags = tagsQuery.split(",") keyValue = tags[0].split("=") if len(keyValue) == 2: - query += "{0}.tags->'{1}' ~* '^{2}'".format(table, keyValue[0], keyValue[1]) + query += "{0}.tags->>'{1}' ~* '^{2}'".format(table, keyValue[0], keyValue[1]) else: - query += "{0}.tags ? '{1}'".format(table, keyValue[0]) + query += "{0}.tags->>'{1}' IS NOT NULL".format(table, keyValue[0]) for tag in tags[1:]: keyValue = tag.split("=") if len(keyValue) == 2: - query += "OR {0}.tags->'{!}' ~* '^{2}'".format(table, keyValue[0], keyValue[1]) + query += "OR {0}.tags->>'{1}' ~* '^{2}'".format(table, keyValue[0], keyValue[1]) else: - query += "OR {0}.tags ? '{1}'".format(table, keyValue[0]) + query += "OR {0}.tags->>'{1}' IS NOT NULL".format(table, keyValue[0]) return query class Raw: diff --git a/setup/underpass.sql b/setup/underpass.sql index 089de92d..145f21c2 100644 --- a/setup/underpass.sql +++ b/setup/underpass.sql @@ -63,7 +63,7 @@ CREATE TABLE IF NOT EXISTS public.ways_poly ( osm_id int8, changeset int8, geom public.geometry(Polygon,4326), - tags public.hstore, + tags JSONB, refs int8[], timestamp timestamp with time zone, version int, @@ -75,7 +75,7 @@ CREATE TABLE IF NOT EXISTS public.ways_line ( osm_id int8, changeset int8, geom public.geometry(LineString,4326), - tags public.hstore, + tags JSONB, refs int8[], timestamp timestamp with time zone, version int, @@ -87,7 +87,7 @@ CREATE TABLE IF NOT EXISTS public.nodes ( osm_id int8, changeset int8, geom public.geometry(Point,4326), - tags public.hstore, + tags JSONB, timestamp timestamp with time zone, version int, "user" text, diff --git a/src/bootstrap/bootstrap.cc b/src/bootstrap/bootstrap.cc index a650e0a2..bbed47d9 100644 --- a/src/bootstrap/bootstrap.cc +++ b/src/bootstrap/bootstrap.cc @@ -67,47 +67,32 @@ void startProcessingWays(const underpassconfig::UnderpassConfig &config) { auto queryvalidate = std::make_shared(db); auto queryraw = std::make_shared(db); + std::vector tables = { + QueryRaw::polyTable, + QueryRaw::lineTable + }; - // TODO: improve duplicate code - int total = queryraw->getWaysCount(QueryRaw::polyTable); - if (total > 0) { - int count = 0; - long lastid = 0; - while (count < total) { - int percentage = (count * 100) / total; - auto task = std::make_shared(); - WayTask wayTask; - wayTask.plugin = validator; - wayTask.queryvalidate = queryvalidate; - wayTask.queryraw = queryraw; - wayTask.task = task; - wayTask.lastid = lastid; - processWaysPoly(wayTask); - db->query(task->query); - lastid = wayTask.lastid; - count += wayTask.processed; - std::cout << "\r" << "Processing polygons: " << count << "/" << total << " (" << percentage << "%)"; - } - } - - total = queryraw->getWaysCount(QueryRaw::lineTable); - if (total > 0) { - int count = 0; - long lastid = 0; - while (count < total) { - int percentage = (count * 100) / total; - auto task = std::make_shared(); - WayTask wayTask; - wayTask.plugin = validator; - wayTask.queryvalidate = queryvalidate; - wayTask.queryraw = queryraw; - wayTask.task = task; - wayTask.lastid = lastid; - processWaysLine(wayTask); - db->query(task->query); - lastid = wayTask.lastid; - count += wayTask.processed; - std::cout << "\r" << "Processing lines: " << count << "/" << total << " (" << percentage << "%)"; + for (auto table_it = tables.begin(); table_it != tables.end(); ++table_it) { + int total = queryraw->getWaysCount(*table_it); + if (total > 0) { + int count = 0; + long lastid = 0; + while (count < total) { + int percentage = (count * 100) / total; + auto task = std::make_shared(); + WayTask wayTask; + wayTask.plugin = validator; + wayTask.queryvalidate = queryvalidate; + wayTask.queryraw = queryraw; + wayTask.task = task; + wayTask.lastid = lastid; + + processWays(wayTask, *table_it); + db->query(task->query); + lastid = wayTask.lastid; + count += wayTask.processed; + std::cout << "\r" << "Processing " << *table_it << ": " << count << "/" << total << " (" << percentage << "%)"; + } } } @@ -115,7 +100,7 @@ void startProcessingWays(const underpassconfig::UnderpassConfig &config) { // This thread get started for every page of way void -processWaysPoly(WayTask &wayTask) +processWays(WayTask &wayTask, const std::string &tableName) { #ifdef TIMING_DEBUG boost::timer::auto_cpu_timer timer("bootstrap::processWays(wayTask): took %w seconds\n"); @@ -127,23 +112,26 @@ processWaysPoly(WayTask &wayTask) auto queryraw = wayTask.queryraw; auto lastid = wayTask.lastid; - auto ways = queryraw->getWaysFromDB(lastid, QueryRaw::polyTable); + auto ways = queryraw->getWaysFromDB(lastid, tableName); wayTask.processed = ways->size(); - - // Proccesing ways - for (auto way = ways->begin(); way != ways->end(); ++way) { - if (way->refs.front() == way->refs.back()) { - log_debug("Way Id: %1%", way->id); - - // Bad geometry - if (way->containsKey("building") && (boost::geometry::num_points(way->linestring) - 1 < 4 || - plugin->unsquared(way->linestring)) - ) { - auto status = ValidateStatus(*way); - status.timestamp = boost::posix_time::microsec_clock::universal_time(); - status.source = "building"; - boost::geometry::centroid(way->linestring, status.center); - task->query += queryvalidate->applyChange(status, badgeom); + if (wayTask.processed > 0) { + // Proccesing ways + for (auto way = ways->begin(); way != ways->end(); ++way) { + + // If it's closed polygon + if (way->refs.front() == way->refs.back()) { + log_debug("Way Id: %1%", way->id); + + // Bad geometry + if (way->containsKey("building") && (boost::geometry::num_points(way->linestring) - 1 < 4 || + plugin->unsquared(way->linestring)) + ) { + auto status = ValidateStatus(*way); + status.timestamp = boost::posix_time::microsec_clock::universal_time(); + status.source = "building"; + boost::geometry::centroid(way->linestring, status.center); + task->query += queryvalidate->applyChange(status, badgeom); + } } // Fill the way_refs table @@ -151,36 +139,8 @@ processWaysPoly(WayTask &wayTask) task->query += "INSERT INTO way_refs (way_id, node_id) VALUES (" + std::to_string(way->id) + "," + std::to_string(*ref) + "); "; } } + wayTask.lastid = ways->back().id; } - wayTask.lastid = ways->back().id; - -} - -void -processWaysLine(WayTask &wayTask) -{ -#ifdef TIMING_DEBUG - boost::timer::auto_cpu_timer timer("bootstrap::processWays(wayTask): took %w seconds\n"); -#endif - - auto plugin = wayTask.plugin; - auto task = wayTask.task; - auto queryvalidate = wayTask.queryvalidate; - auto queryraw = wayTask.queryraw; - auto lastid = wayTask.lastid; - - auto ways = queryraw->getWaysFromDB(lastid, QueryRaw::lineTable); - wayTask.processed = ways->size(); - - // Proccesing ways - for (auto way = ways->begin(); way != ways->end(); ++way) { - log_debug("Way Id: %1%", way->id); - // Fill the way_refs table - for (auto ref = way->refs.begin(); ref != way->refs.end(); ++ref) { - task->query += "INSERT INTO way_refs (way_id, node_id) VALUES (" + std::to_string(way->id) + "," + std::to_string(*ref) + "); "; - } - } - wayTask.lastid = ways->back().id; } diff --git a/src/bootstrap/bootstrap.hh b/src/bootstrap/bootstrap.hh index 3debf2d6..9e4aa966 100644 --- a/src/bootstrap/bootstrap.hh +++ b/src/bootstrap/bootstrap.hh @@ -47,7 +47,6 @@ struct WayTask { void startProcessingWays(const underpassconfig::UnderpassConfig &config); // This thread get started for every page of way -void processWaysPoly(WayTask &wayTask); -void processWaysLine(WayTask &wayTask); +void processWays(WayTask &wayTask, const std::string &tableName); } \ No newline at end of file diff --git a/src/data/pq.cc b/src/data/pq.cc index 03e81fdb..678bcd8e 100644 --- a/src/data/pq.cc +++ b/src/data/pq.cc @@ -180,7 +180,7 @@ Pq::escapedString(std::string text) } i++; } - return sdb->esc(boost::locale::conv::to_utf(newstr, "Latin1")); + return sdb->esc(newstr); } } // namespace pq diff --git a/src/raw/queryraw.cc b/src/raw/queryraw.cc index 60f0d23c..dc2daa2b 100644 --- a/src/raw/queryraw.cc +++ b/src/raw/queryraw.cc @@ -24,6 +24,8 @@ /// includes querying existing data in the database, as well as /// updating the database. +// TODO: add support for relations/multipolygon + // This is generated by autoconf #ifdef HAVE_CONFIG_H #include "unconfig.h" @@ -82,14 +84,14 @@ QueryRaw::applyChange(const OsmNode &node) const std::string tags = ""; if (node.tags.size() > 0) { for (auto it = std::begin(node.tags); it != std::end(node.tags); ++it) { - std::string tag_format = "\"%s\" => \"%s\","; + std::string tag_format = "\"%s\" : \"%s\","; boost::format tag_fmt(tag_format); tag_fmt % dbconn->escapedString(it->first); tag_fmt % dbconn->escapedString(it->second); tags += tag_fmt.str(); } tags.erase(tags.size() - 1); - tags = "'" + tags + "'"; + tags = "'{" + tags + "}'"; } else { tags = "null"; } @@ -161,14 +163,14 @@ QueryRaw::applyChange(const OsmWay &way) const std::string tags = ""; if (way.tags.size() > 0) { for (auto it = std::begin(way.tags); it != std::end(way.tags); ++it) { - std::string tag_format = "\"%s\" => \"%s\","; + std::string tag_format = "\"%s\" : \"%s\","; boost::format tag_fmt(tag_format); tag_fmt % dbconn->escapedString(it->first); tag_fmt % dbconn->escapedString(it->second); tags += tag_fmt.str(); } tags.erase(tags.size() - 1); - tags = "'" + tags + "'"; + tags = "'{" + tags + "}'"; } else { tags = "null"; } @@ -372,7 +374,7 @@ std::map parseTagsString(const std::string& input) { std::string token; while (std::getline(ss, token, ',')) { // Find the position of the arrow - size_t arrowPos = token.find("=>"); + size_t arrowPos = token.find(":"); if (arrowPos != std::string::npos) { std::string key = token.substr(1, arrowPos - 1); std::string value = token.substr(arrowPos + 2); @@ -393,8 +395,8 @@ QueryRaw::getWaysByNodesRefs(std::string &nodeIds) const // Get all ways that have references to nodes std::list> ways; - // TODO: add ways_line to the query - std::string waysQuery = "SELECT distinct(osm_id), refs, version, tags from way_refs join ways_poly rp on rp.osm_id = way_id where node_id = any(ARRAY[" + nodeIds + "]);"; + std::string waysQuery = "SELECT distinct(osm_id), refs, version, tags from way_refs join ways_poly wp on wp.osm_id = way_id where node_id = any(ARRAY[" + nodeIds + "])"; + waysQuery += " UNION SELECT distinct(osm_id), refs, version, tags from way_refs join ways_line wl on wl.osm_id = way_id where node_id = any(ARRAY[" + nodeIds + "]);"; auto ways_result = dbconn->query(waysQuery); // Fill vector of OsmWay objects diff --git a/utils/bootstrap.sh b/utils/bootstrap.sh index 30471312..f238fe45 100644 --- a/utils/bootstrap.sh +++ b/utils/bootstrap.sh @@ -23,8 +23,8 @@ # database with OSM data for a country # ----- -localfiles='false' -use_docker='false' +localfiles=false +use_docker=false while getopts r:c:h::u:p:d:l:k flag do @@ -35,8 +35,8 @@ do u) user=${OPTARG};; p) port=${OPTARG};; d) database=${OPTARG};; - l) localfiles=${OPTARG};; - k) use_docker=${OPTARG};; + l) localfiles=true;; + k) use_docker=true;; esac done @@ -53,6 +53,7 @@ else USER=underpass fi + if [ -n "${REGION}" ] && [ -n "${COUNTRY}" ] then @@ -63,11 +64,12 @@ then echo Port: $PORT echo Database: $DB - if [ -z "${localfiles}" ] + if "$localfiles"; then echo "Use local files?: yes" fi - if [ -z "${use_docker}" ] + + if "$use_docker"; then echo "Use Docker?: yes" fi @@ -91,7 +93,7 @@ then PGPASSWORD=$PASS psql --host $HOST --user $USER --port $PORT $DB -c 'DROP TABLE IF EXISTS ways_poly; DROP TABLE IF EXISTS ways_line; DROP TABLE IF EXISTS nodes; DROP TABLE IF EXISTS way_refs; DROP TABLE IF EXISTS validation; DROP TABLE IF EXISTS changesets;' PGPASSWORD=$PASS psql --host $HOST --user $USER --port $PORT $DB --file '../setup/underpass.sql' - if [ -z "${localfiles}" ] + if "$localfiles"; then echo "(Using local files)" else @@ -106,7 +108,7 @@ then echo "Configuring Underpass ..." python3 poly2geojson.py $COUNTRY.poly - if [ -z "${use_docker}" ] + if "$use_docker"; then docker cp $COUNTRY.geojson underpass:/usr/local/lib/underpass/config/priority.geojson docker cp $COUNTRY.geojson underpass:/code/config/priority.geojson @@ -114,15 +116,15 @@ then cp $COUNTRY.geojson /usr/local/lib/underpass/config/priority.geojson cp $COUNTRY.geojson ../config/priority.geojson fi - echo "Bootstrapping database ..." - if [ -z "${use_docker}" ] - then - docker exec -w /code/build -t underpass ./underpass --bootstrap - else - cd ../build && ./underpass --bootstrap - fi - echo "Done." - echo " " + # echo "Bootstrapping database ..." + # if "$use_docker"; + # then + # docker exec -w /code/build -t underpass ./underpass --bootstrap + # else + # cd ../build && ./underpass --bootstrap + # fi + # echo "Done." + # echo " " fi else @@ -141,6 +143,6 @@ else echo " -u user (Database user)" echo " -p port (Database port)" echo " -d database (Database name)" - echo " -l (Use local files instead of download them)" - echo " -k (Use Docker Underpass installation)" + echo " -l yes (Use local files instead of download them)" + echo " -k yes (Use Docker Underpass installation)" fi diff --git a/utils/raw-underpass.lua b/utils/raw-underpass.lua index 09018f52..348f4a6c 100644 --- a/utils/raw-underpass.lua +++ b/utils/raw-underpass.lua @@ -1,21 +1,21 @@ --- # Copyright (c) 2020, 2021, 2023 Humanitarian OpenStreetMap Team +-- Copyright (c) 2020, 2021, 2023 Humanitarian OpenStreetMap Team --- # This program is free software: you can redistribute it and/or modify --- # it under the terms of the GNU Affero General Public License as --- # published by the Free Software Foundation, either version 3 of the --- # License, or (at your option) any later version. +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU Affero General Public License as +-- published by the Free Software Foundation, either version 3 of the +-- License, or (at your option) any later version. --- # This program is distributed in the hope that it will be useful, --- # but WITHOUT ANY WARRANTY; without even the implied warranty of --- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- # GNU Affero General Public License for more details. +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. --- # You should have received a copy of the GNU Affero General Public License --- # along with this program. If not, see . +-- You should have received a copy of the GNU Affero General Public License +-- along with this program. If not, see . --- # Humanitarian OpenStreetmap Team --- # 1100 13th Street NW Suite 800 Washington, D.C. 20005 --- # +-- Humanitarian OpenStreetmap Team +-- 1100 13th Street NW Suite 800 Washington, D.C. 20005 +-- -- This is lua script for osm2pgsql in order to create and process custom schema to store incoming osm data efficiently -- osm2pgsql --create -H localhost -U admin -P 5432 -d postgres -W --extra-attributes --output=flex --style ./raw.lua nepal-latest-internal.osm.pbf @@ -36,10 +36,8 @@ tables.nodes = osm2pgsql.define_table{ { column = 'version', type = 'int' }, { column = 'changeset', type = 'int' }, { column = 'timestamp', sql_type = 'timestamp' }, - -- { column = 'tags', type = 'jsonb' }, - { column = 'tags', sql_type = 'public.hstore' }, + { column = 'tags', type = 'jsonb' }, { column = 'geom', type = 'point', projection = srid }, - -- { column = 'country', sql_type= 'int[]', create_only = true }, } } @@ -53,12 +51,10 @@ tables.ways_line = osm2pgsql.define_table{ { column = 'version', type = 'int' }, { column = 'changeset', type = 'int' }, { column = 'timestamp', sql_type = 'timestamp' }, - -- { column = 'tags', type = 'jsonb' }, - { column = 'tags', sql_type = 'public.hstore' }, + { column = 'tags', type = 'jsonb' }, { column = 'refs', type= 'text', sql_type = 'bigint[]'}, { column = 'geom', type = 'linestring', projection = srid }, - -- { column = 'country', sql_type= 'int[]', create_only = true }, - + { column = 'country', sql_type= 'int[]', create_only = true }, } } @@ -73,13 +69,11 @@ tables.ways_poly = osm2pgsql.define_table{ { column = 'version', type = 'int' }, { column = 'changeset', type = 'int' }, { column = 'timestamp', sql_type = 'timestamp' }, - -- This will store tags as jsonb type - -- { column = 'tags', type = 'jsonb' }, - { column = 'tags', sql_type = 'public.hstore' }, + { column = 'tags', type = 'jsonb' }, { column = 'refs', type= 'text', sql_type = 'bigint[]'}, { column = 'geom', type = 'polygon', projection = srid }, - -- { column = 'grid', type = 'int', create_only = true }, - -- { column = 'country', sql_type= 'int[]', create_only = true }, + { column = 'grid', type = 'int', create_only = true }, + { column = 'country', sql_type= 'int[]', create_only = true }, } } @@ -96,53 +90,27 @@ tables.rels = osm2pgsql.define_table{ { column = 'version', type = 'int' }, { column = 'changeset', type = 'int' }, { column = 'timestamp', sql_type = 'timestamp' }, - -- { column = 'tags', type = 'jsonb' }, - { column = 'tags', sql_type = 'public.hstore' }, + { column = 'tags', type = 'jsonb' }, { column = 'refs', type = 'jsonb'}, { column = 'geom', type = 'geometry', projection = srid }, - -- { column = 'country',sql_type= 'int[]', create_only = true }, - + { column = 'country',sql_type= 'int[]', create_only = true }, } } --- Returns true if there are no tags left. -function clean_tags(tags) - tags.odbl = nil - -- tags.created_by = nil - tags['source:ref'] = nil - return next(tags) == nil -end - -function tags_to_hstore(tags) - local hstore = '' - for k,v in pairs(tags) do - hstore = hstore .. string.format('%s=>%s,', string.format('%q', k), string.format('%q', v)) - end - return hstore:sub(1, -2) -end - function osm2pgsql.process_node(object) - if clean_tags(object.tags) then - return - end - tables.nodes:add_row({ uid = object.uid, user = object.user, version = object.version, changeset = object.changeset, timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ', object.timestamp), - -- tags = object.tags, - tags = tags_to_hstore(object.tags), + tags = object.tags, geom = { create = 'point' } }) end function osm2pgsql.process_way(object) - if clean_tags(object.tags) then - return - end if object.is_closed and #object.nodes>3 then tables.ways_poly:add_row({ @@ -151,8 +119,7 @@ function osm2pgsql.process_way(object) version = object.version, changeset = object.changeset, timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ', object.timestamp), - -- tags = object.tags, - tags = tags_to_hstore(object.tags), + tags = object.tags, refs = '{' .. table.concat(object.nodes, ',') .. '}', geom = { create = 'area' }, @@ -164,8 +131,7 @@ function osm2pgsql.process_way(object) version = object.version, changeset = object.changeset, timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ', object.timestamp), - -- tags = object.tags, - tags = tags_to_hstore(object.tags), + tags = object.tags, refs = '{' .. table.concat(object.nodes, ',') .. '}', geom = { create = 'line' }, @@ -174,9 +140,6 @@ function osm2pgsql.process_way(object) end function osm2pgsql.process_relation(object) - if clean_tags(object.tags) then - return - end if object.tags.type == 'multipolygon' or object.tags.type == 'boundary' then tables.rels:add_row({ uid = object.uid, @@ -184,8 +147,7 @@ function osm2pgsql.process_relation(object) version = object.version, changeset = object.changeset, timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ', object.timestamp), - -- tags = object.tags, - tags = tags_to_hstore(object.tags), + tags = object.tags, geom = { create = 'area' }, refs = object.members @@ -197,9 +159,8 @@ function osm2pgsql.process_relation(object) version = object.version, changeset = object.changeset, timestamp = os.date('!%Y-%m-%dT%H:%M:%SZ', object.timestamp), - -- tags = object.tags, - tags = tags_to_hstore(object.tags), - geom= { create = 'line' }, + tags = object.tags, + geom = { create = 'line' }, refs = object.members }) diff --git a/utils/raw_with_ref.lua b/utils/raw_with_ref.lua index d7985604..05527cb7 100644 --- a/utils/raw_with_ref.lua +++ b/utils/raw_with_ref.lua @@ -1,20 +1,21 @@ -- Copyright (c) 2020, 2021, 2023 Humanitarian OpenStreetMap Team --- --- This file is part of Underpass. --- --- Underpass is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- Underpass is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with Underpass. If not, see . +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU Affero General Public License as +-- published by the Free Software Foundation, either version 3 of the +-- License, or (at your option) any later version. + +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Affero General Public License for more details. + +-- You should have received a copy of the GNU Affero General Public License +-- along with this program. If not, see . + +-- Humanitarian OpenStreetmap Team +-- 1100 13th Street NW Suite 800 Washington, D.C. 20005 +-- -- This is lua script for osm2pgsql in order to create and process custom schema to store incoming osm data efficiently -- osm2pgsql --create -H localhost -U admin -P 5432 -d postgres -W --extra-attributes --output=flex --style ./raw.lua nepal-latest-internal.osm.pbf @@ -37,7 +38,7 @@ tables.nodes = osm2pgsql.define_table{ { column = 'timestamp', sql_type = 'timestamp' }, { column = 'tags', type = 'jsonb' }, { column = 'geom', type = 'point', projection = srid }, - { column = 'country', type= 'int', create_only = true }, + { column = 'country', sql_type= 'int[]', create_only = true }, } @@ -77,7 +78,7 @@ tables.ways_poly = osm2pgsql.define_table{ { column = 'refs', type= 'text', sql_type = 'bigint[]'}, { column = 'geom', type = 'polygon', projection = srid }, { column = 'grid', type = 'int', create_only = true }, - { column = 'country', type= 'int', create_only = true }, + { column = 'country', sql_type= 'int[]', create_only = true }, } } @@ -99,17 +100,14 @@ tables.rels = osm2pgsql.define_table{ { column = 'geom', type = 'geometry', projection = srid }, { column = 'country',sql_type= 'int[]', create_only = true }, - } } -- Returns true if there are no tags left. function clean_tags(tags) tags.odbl = nil - tags.created_by = nil - tags.source = nil + -- tags.created_by = nil tags['source:ref'] = nil - return next(tags) == nil end