-
-
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.
WIP: Add code to generalize data using different strategies
This commit adds the code to generalize various types of data using different strategies. 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. This still needs some work... Also a new "discrete-isolation" strategy which rates places based on some importance metric. (This is not tile-based.) The new "rivers" strategy finds important rivers, this is still very much work in progress. For the raster support this adds two new library dependency: CImg and potrace. The functionality is accessed through a new command line program called osm2pgsql-gen. It reads the same Lua config file that osm2pgsql reads. Call it with -h to get some usage information. This program is for testing only, eventually the functionality should be accessible from osm2pgsql itself. See also https://osm2pgsql.org/generalization/ .
- Loading branch information
Showing
36 changed files
with
3,255 additions
and
30 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
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; | ||
} |
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 @@ | ||
#ifndef OSM2PGSQL_CANVAS_HPP | ||
#define OSM2PGSQL_CANVAS_HPP | ||
|
||
/** | ||
* 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 "geom.hpp" | ||
#include "tile.hpp" | ||
|
||
#define cimg_display 0 // NOLINT(cppcoreguidelines-macro-usage) | ||
#include "CImg.h" | ||
|
||
#include <cstddef> | ||
|
||
/** | ||
* This class wraps the image class from the CImg library. | ||
*/ | ||
class canvas_t | ||
{ | ||
public: | ||
static void info() { cimg_library::cimg::info(); } | ||
|
||
/** | ||
* Create a new image canvas. It will be quadratic and have the width and | ||
* height extent + 2*buffer. | ||
*/ | ||
canvas_t(std::size_t extent, std::size_t buffer) | ||
: m_extent(extent), | ||
m_buffer(buffer), m_rast{size(), size(), 1, 1, 0}, m_temp{size(), size(), | ||
1, 1, 0} | ||
{} | ||
|
||
unsigned int size() const noexcept | ||
{ | ||
return static_cast<unsigned int>(m_extent + 2 * m_buffer); | ||
} | ||
|
||
unsigned char const *begin() const noexcept { return m_rast.begin(); } | ||
unsigned char const *end() const noexcept { return m_rast.end(); } | ||
|
||
std::size_t draw(geom::geometry_t const &geometry, tile_t const &tile); | ||
|
||
unsigned char operator()(int x, int y) const noexcept | ||
{ | ||
return m_rast(x, y, 0, 0); | ||
} | ||
|
||
void open_close(unsigned int buffer_size) | ||
{ | ||
m_rast.dilate(buffer_size).erode(buffer_size * 2).dilate(buffer_size); | ||
} | ||
|
||
void save(std::string const &filename) const; | ||
|
||
std::string to_wkb(tile_t const &tile, double margin) const; | ||
|
||
void merge(canvas_t const &other); | ||
|
||
private: | ||
constexpr static unsigned char const Black = 0; | ||
constexpr static unsigned char const White = 255; | ||
|
||
using image_type = cimg_library::CImg<unsigned char>; | ||
|
||
cimg_library::CImg<int> create_pointlist(geom::point_list_t const &pl, | ||
tile_t const &tile) const; | ||
|
||
std::size_t draw_polygon(geom::polygon_t const &polygon, | ||
tile_t const &tile); | ||
|
||
std::size_t draw_linestring(geom::linestring_t const &linestring, | ||
tile_t const &tile); | ||
|
||
std::size_t m_extent; | ||
std::size_t m_buffer; | ||
image_type m_rast; | ||
image_type m_temp; | ||
}; // class canvas_t | ||
|
||
std::string to_hex(std::string const &in); | ||
|
||
#endif // OSM2PGSQL_CANVAS_HPP |
Oops, something went wrong.