-
-
Notifications
You must be signed in to change notification settings - Fork 474
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This large commit adds a framework to generalize OSM data using different strategies and implements several strategies. The source is all in the new `src/gen` directory. It includes a new command `osm2pgsql-gen` to access this functionality. Future versions might integrate it with the `osm2pgsql` command, but because this is all experimental it is kept separate for now. Call `osm2pgsql-gen` with `-h` to get usage help. See also https://osm2pgsql.org/generalization/ and the chapter on Generalization in the manual: https://osm2pgsql.org/doc/manual.html#generalization For the raster support this adds two new library dependency: CImg and potrace. Both have been around for a long time and are readily available on all systems. The following strategies work on a tile-by-tile basis and operate on polygons: The "vector-union" strategy buffers and unionizes polygons using vector operations. The "raster-union" strategy does a similar thing but does it in raster space which is much faster. First the polygons are rendered into a raster, an open/close operation is called (which basically does the same thing as the buffering in vector space) and finally the resulting raster is vectorized again. The "builtup" strategy is intended to derive a layer of builtup areas from landuse=residential/industrial etc. as well as building cover and dense road networks. The following strategies always work on all data (not tile-based): The "discrete-isolation" strategy rates places based on some importance metric to get a more even distribution of places on the map. The new "rivers" strategy finds important rivers, this is still very much work in progress.
- Loading branch information
Showing
33 changed files
with
3,274 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# NAME | ||
|
||
osm2pgsql-gen - Generalize OpenStreetMap data - EXPERIMENTAL! | ||
|
||
# SYNOPSIS | ||
|
||
**osm2pgsql-gen** \[*OPTIONS*\]... | ||
|
||
# DESCRIPTION | ||
|
||
THIS PROGRAM IS EXPERIMENTAL AND MIGHT CHANGE WITHOUT NOTICE! | ||
|
||
**osm2pgsql-gen** reads data imported by **osm2pgsql** from the database, | ||
performs various generalization steps specified by a Lua config file and | ||
writes the data back to the database. It is used in conjunction with and | ||
after **osm2pgsql** and reads the same config file. | ||
|
||
This man page can only cover some of the basics and describe the command line | ||
options. See the [Generalization chapter in the osm2pgsql | ||
Manual](https://osm2pgsql.org/doc/manual.html#generalization) for more | ||
information. | ||
|
||
# OPTIONS | ||
|
||
This program follows the usual GNU command line syntax, with long options | ||
starting with two dashes (`--`). Mandatory arguments to long options are | ||
mandatory for short options too. | ||
|
||
# MAIN OPTIONS | ||
|
||
-a, \--append | ||
: Run in append mode. | ||
|
||
-c, \--create | ||
: Run in create mode. This is the default if **-a, \--append** is not | ||
specified. | ||
|
||
-S, \--style=FILE | ||
: The Lua config file. Same as for **osm2pgsql**. | ||
|
||
-j, \-jobs=NUM | ||
: Specifies the number of parallel threads used for certain operations. | ||
Setting this to the number of available CPU cores is a reasonable starting | ||
point. | ||
|
||
# HELP/VERSION OPTIONS | ||
|
||
-h, \--help | ||
: Print help. | ||
|
||
-V, \--version | ||
: Print osm2pgsql version. | ||
|
||
# LOGGING OPTIONS | ||
|
||
\--log-level=LEVEL | ||
: Set log level ('debug', 'info' (default), 'warn', or 'error'). | ||
|
||
\--log-sql | ||
: Enable logging of SQL commands for debugging. | ||
|
||
# DATABASE OPTIONS | ||
|
||
-d, \--database=NAME | ||
: The name of the PostgreSQL database to connect to. If this parameter | ||
contains an `=` sign or starts with a valid URI prefix (`postgresql://` or | ||
`postgres://`), it is treated as a conninfo string. See the PostgreSQL | ||
manual for details. | ||
|
||
-U, \--username=NAME | ||
: Postgresql user name. | ||
|
||
-W, \--password | ||
: Force password prompt. | ||
|
||
-H, \--host=HOSTNAME | ||
: Database server hostname or unix domain socket location. | ||
|
||
-P, \--port=PORT | ||
: Database server port. | ||
|
||
# SEE ALSO | ||
|
||
* [osm2pgsql website](https://osm2pgsql.org) | ||
* [osm2pgsql manual](https://osm2pgsql.org/doc/manual.html) | ||
* **postgres**(1) | ||
* **osm2pgsql**(1) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
* | ||
* This file is part of osm2pgsql (https://osm2pgsql.org/). | ||
* | ||
* Copyright (C) 2006-2023 by the osm2pgsql developer community. | ||
* For a full list of authors see the git log. | ||
*/ | ||
|
||
#include "canvas.hpp" | ||
#include "raster.hpp" | ||
|
||
cimg_library::CImg<int> canvas_t::create_pointlist(geom::point_list_t const &pl, | ||
tile_t const &tile) const | ||
{ | ||
cimg_library::CImg<int> points{static_cast<unsigned int>(pl.size()), 2}; | ||
|
||
int n = 0; | ||
for (auto const point : pl) { | ||
auto const tp = tile.to_tile_coords(point, m_extent); | ||
points(n, 0) = static_cast<int>(static_cast<double>(m_buffer) + tp.x()); | ||
points(n, 1) = | ||
static_cast<int>(static_cast<double>(m_buffer + m_extent) - tp.y()); | ||
++n; | ||
} | ||
|
||
return points; | ||
} | ||
|
||
std::size_t canvas_t::draw_polygon(geom::polygon_t const &polygon, | ||
tile_t const &tile) | ||
{ | ||
if (polygon.inners().empty()) { | ||
m_rast.draw_polygon(create_pointlist(polygon.outer(), tile), &White); | ||
return polygon.outer().size(); | ||
} | ||
|
||
std::size_t num_points = polygon.outer().size(); | ||
m_temp.draw_polygon(create_pointlist(polygon.outer(), tile), &White); | ||
for (auto const &inner : polygon.inners()) { | ||
num_points += inner.size(); | ||
m_temp.draw_polygon(create_pointlist(inner, tile), &Black); | ||
} | ||
m_rast |= m_temp; | ||
|
||
return num_points; | ||
} | ||
|
||
std::size_t canvas_t::draw_linestring(geom::linestring_t const &linestring, | ||
tile_t const &tile) | ||
{ | ||
m_rast.draw_line(create_pointlist(linestring, tile), &White); | ||
return linestring.size(); | ||
} | ||
|
||
std::size_t canvas_t::draw(geom::geometry_t const &geometry, tile_t const &tile) | ||
{ | ||
if (geometry.is_linestring()) { | ||
auto const &linestring = geometry.get<geom::linestring_t>(); | ||
return draw_linestring(linestring, tile); | ||
} | ||
|
||
if (geometry.is_polygon()) { | ||
auto const &polygon = geometry.get<geom::polygon_t>(); | ||
return draw_polygon(polygon, tile); | ||
} | ||
|
||
if (geometry.is_multipolygon()) { | ||
auto const &mp = geometry.get<geom::multipolygon_t>(); | ||
std::size_t num_points = 0; | ||
for (auto const &p : mp) { | ||
num_points += draw_polygon(p, tile); | ||
} | ||
return num_points; | ||
} | ||
|
||
// XXX other geometry types? | ||
|
||
return 0; | ||
} | ||
|
||
void canvas_t::save(std::string const &filename) const | ||
{ | ||
m_rast.save(filename.c_str()); | ||
} | ||
|
||
std::string canvas_t::to_wkb(tile_t const &tile, double margin) const | ||
{ | ||
std::string wkb; | ||
wkb.reserve(61 + 2 + m_rast.size()); | ||
|
||
// header | ||
wkb_raster_header header{}; | ||
header.nBands = 1; | ||
header.scaleX = tile.extent() / static_cast<double>(m_extent); | ||
header.scaleY = -header.scaleX; | ||
header.ipX = tile.xmin(margin); | ||
header.ipY = tile.ymax(margin); | ||
header.width = m_extent + 2 * m_buffer; | ||
header.height = header.width; | ||
add_raster_header(&wkb, header); | ||
|
||
// band | ||
wkb_raster_band band{}; | ||
band.bits = 4; | ||
add_raster_band(&wkb, band); | ||
|
||
// rasterdata | ||
wkb.append(reinterpret_cast<char const *>(m_rast.data()), m_rast.size()); | ||
|
||
assert(wkb.size() == 61 + 2 + m_rast.size()); | ||
|
||
return wkb; | ||
} | ||
|
||
void canvas_t::merge(canvas_t const &other) { m_rast |= other.m_rast; } | ||
|
||
std::string to_hex(std::string const &in) | ||
{ | ||
std::string result; | ||
char const *const lookup_hex = "0123456789ABCDEF"; | ||
|
||
for (const auto c : in) { | ||
unsigned int const num = static_cast<unsigned char>(c); | ||
result += lookup_hex[(num >> 4U) & 0xfU]; | ||
result += lookup_hex[num & 0xfU]; | ||
} | ||
|
||
return result; | ||
} |
Oops, something went wrong.