File: shp_mem_tiles.h

package info (click to toggle)
tilemaker 3.0.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 83,488 kB
  • sloc: cpp: 29,461; ansic: 12,510; makefile: 229; ruby: 77; sh: 43
file content (89 lines) | stat: -rw-r--r-- 3,083 bytes parent folder | download
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
/*! \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