1
0
Fork 0
mirror of https://github.com/systemed/tilemaker synced 2025-02-21 13:24:09 +01:00
tilemaker/include/shp_mem_tiles.h
2024-10-03 09:06:39 +01:00

89 lines
3 KiB
C++

/*! \file */
#ifndef _SHP_MEM_TILES
#define _SHP_MEM_TILES
#include "tile_data.h"
extern bool verbose;
class ShpMemTiles : public TileDataSource
{
public:
ShpMemTiles(size_t threadNum, uint indexZoom);
std::string name() const override { return "shp"; }
void CreateNamedLayerIndex(const std::string& layerName);
// Used in shape file loading
void StoreGeometry(
uint_least8_t layerNum,
const std::string& layerName,
enum OutputGeometryType geomType,
Geometry geometry,
bool isIndexed,
bool hasName,
const std::string& name,
uint minzoom,
AttributeIndex attrIdx
);
std::vector<uint> QueryMatchingGeometries(
const std::string& layerName,
bool once,
Box& box,
std::function<std::vector<IndexValue>(const RTree& rtree)> indexQuery,
std::function<bool(const OutputObject& oo)> checkQuery
) const;
bool mayIntersect(const std::string& layerName, const Box& box) const;
std::vector<std::string> namesOfGeometries(const std::vector<uint>& ids) const;
template <typename GeometryT>
double AreaIntersecting(const std::string& layerName, GeometryT& g) const {
auto f = indices.find(layerName);
if (f==indices.end()) {
if (verbose)
std::cerr << "Couldn't find indexed layer " << layerName << std::endl;
return false;
}
Box box;
geom::envelope(g, box);
std::vector<IndexValue> results;
f->second.query(geom::index::intersects(box), back_inserter(results));
MultiPolygon mp, tmp;
for (const auto &it : results) {
OutputObject oo = indexedGeometries.at(it.second);
if (oo.geomType!=POLYGON_) continue;
geom::union_(mp, retrieveMultiPolygon(oo.objectID), tmp);
geom::assign(mp, tmp);
}
geom::correct(mp);
return geom::covered_by(g, mp);
}
private:
std::vector<OutputObject> indexedGeometries; // prepared boost::geometry objects (from shapefiles)
std::map<uint, std::string> indexedGeometryNames; // | optional names for each one
std::map<std::string, RTree> indices; // Spatial indices, boost::geometry::index objects for shapefile indices
std::mutex indexMutex;
// This differs from indexZoom. indexZoom is clamped to z14, as there is a noticeable
// step function increase in memory use to go to higher zooms. For the
// bitset index, the increase in memory is not as significant.
unsigned int spatialIndexZoom;
// The map is from layer name to a sparse vector of tiles that might have shapes.
//
// The outer vector has an entry for each z6 tile. The inner vector is a bitset,
// indexed at spatialIndexZoom, where a bit is set if the z15 tiles at
// 2 * (x*width + y) might contain at least one shape.
// This is approximated by using the bounding boxes of the shapes. For large, irregular shapes, or
// shapes with holes, the bounding box may result in many false positives. The first time the index
// is consulted for a given tile, we'll do a more expensive intersects query to refine the index.
// This lets us quickly reject negative Intersects queryes
mutable std::map<std::string, std::vector<std::vector<bool>>> bitIndices;
};
#endif //_OSM_MEM_TILES