Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
allow annotation bounds filtering by type
Browse files Browse the repository at this point in the history
  • Loading branch information
incanus committed Jun 1, 2015
1 parent b51f5e8 commit da01318
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
8 changes: 7 additions & 1 deletion include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ namespace util {
template <class T> class Thread;
}

enum class AnnotationType : uint8_t {
Any = 0,
Point = 1 << 0,
Shape = 1 << 1,
};

using AnnotationIDs = std::vector<uint32_t>;
using AnnotationSegment = std::vector<LatLng>;
using AnnotationSegments = std::vector<AnnotationSegment>;
Expand Down Expand Up @@ -130,7 +136,7 @@ class Map : private util::noncopyable {
const std::vector<StyleProperties>&);
void removeAnnotation(uint32_t);
void removeAnnotations(const AnnotationIDs&);
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&);
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const AnnotationType& = AnnotationType::Any);
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&);

// Memory
Expand Down
2 changes: 1 addition & 1 deletion platform/ios/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ - (void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTap
tapBounds.extend(coordinateToLatLng(coordinate));

// query for nearby annotations
std::vector<uint32_t> nearbyAnnotations = _mbglMap->getAnnotationsInBounds(tapBounds);
std::vector<uint32_t> nearbyAnnotations = _mbglMap->getAnnotationsInBounds(tapBounds, mbgl::AnnotationType::Point);

int32_t newSelectedAnnotationID = -1;

Expand Down
33 changes: 29 additions & 4 deletions src/mbgl/map/annotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Annotation::Annotation(AnnotationType type_,
geometry(geometry_),
bounds([this] {
LatLngBounds bounds_;
assert(type != AnnotationType::Any);
if (type == AnnotationType::Point) {
bounds_ = { getPoint(), getPoint() };
} else {
Expand Down Expand Up @@ -85,6 +86,8 @@ AnnotationManager::addAnnotations(const AnnotationType type,
const MapData& data) {
std::lock_guard<std::mutex> lock(mtx);

assert(type != AnnotationType::Any);

// We pre-generate tiles to contain each annotation up to the map's max zoom.
// We do this for fast rendering without projection conversions on the fly, as well as
// to simplify bounding box queries of annotations later. Tiles get invalidated when
Expand Down Expand Up @@ -186,6 +189,8 @@ AnnotationManager::addTileFeature(const uint32_t annotationID,
const std::unordered_map<std::string, std::string>& featureProperties,
const uint8_t maxZoom) {

assert(type != AnnotationType::Any);

// track the annotation global ID and its original geometry
auto anno_it = annotations.emplace(annotationID,
util::make_unique<Annotation>(type, segments, styleProperties));
Expand Down Expand Up @@ -394,7 +399,8 @@ const std::unique_ptr<Annotation>& AnnotationManager::getAnnotationWithID(uint32
}

AnnotationIDs AnnotationManager::getAnnotationsInBounds(const LatLngBounds& queryBounds,
const MapData& data) const {
const MapData& data,
const AnnotationType& type) const {
std::lock_guard<std::mutex> lock(mtx);

const uint8_t z = data.transform.getMaxZoom();
Expand All @@ -414,9 +420,22 @@ AnnotationIDs AnnotationManager::getAnnotationsInBounds(const LatLngBounds& quer
if (id.x >= nwTile.x && id.x <= seTile.x && id.y >= nwTile.y && id.y <= seTile.y) {
if (id.x > nwTile.x && id.x < seTile.x && id.y > nwTile.y && id.y < seTile.y) {
// Trivial accept; this tile is completely inside the query bounds, so
// we'll return all of its annotations.
std::copy(tile.second.first.begin(), tile.second.first.end(),
std::inserter(matchingAnnotations, matchingAnnotations.begin()));
// we'll return all of its annotations that match type (if specified).
if (type != AnnotationType::Any) {
std::copy_if(tile.second.first.begin(), tile.second.first.end(),
std::inserter(matchingAnnotations, matchingAnnotations.begin()),
[&](const uint32_t annotationID) -> bool {
const auto it = annotations.find(annotationID);
if (it != annotations.end()) {
return (it->second->type == type);
} else {
return false;
}
});
} else {
std::copy(tile.second.first.begin(), tile.second.first.end(),
std::inserter(matchingAnnotations, matchingAnnotations.begin()));
}
} else {
// This tile is intersected by the query bounds. We need to check the
// tile's annotations' bounding boxes individually.
Expand All @@ -425,6 +444,12 @@ AnnotationIDs AnnotationManager::getAnnotationsInBounds(const LatLngBounds& quer
[&](const uint32_t annotationID) -> bool {
const auto it = annotations.find(annotationID);
if (it != annotations.end()) {
// check type
if (type != AnnotationType::Any && it->second->type != type) {
return false;
}

// check bounds
const LatLngBounds annoBounds = it->second->getBounds();
return (annoBounds.sw.latitude >= queryBounds.sw.latitude &&
annoBounds.ne.latitude <= queryBounds.ne.latitude &&
Expand Down
7 changes: 1 addition & 6 deletions src/mbgl/map/annotation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ class MapData;

using AnnotationsProperties = std::unordered_map<std::string, std::vector<std::string>>;

enum class AnnotationType : uint8_t {
Point,
Shape
};

class Annotation : private util::noncopyable {
friend class AnnotationManager;
public:
Expand Down Expand Up @@ -73,7 +68,7 @@ class AnnotationManager : private util::noncopyable {
std::unordered_set<TileID, TileID::Hash> removeAnnotations(const AnnotationIDs&, const MapData&);
AnnotationIDs getOrderedShapeAnnotations() const { return orderedShapeAnnotations; }
const std::unique_ptr<Annotation>& getAnnotationWithID(uint32_t) const;
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const MapData&) const;
AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const MapData&, const AnnotationType& = AnnotationType::Any) const;
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&) const;

const LiveTile* getTile(const TileID& id);
Expand Down
4 changes: 2 additions & 2 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,8 @@ void Map::removeAnnotations(const std::vector<uint32_t>& annotations) {
context->invoke(&MapContext::updateAnnotationTiles, result);
}

std::vector<uint32_t> Map::getAnnotationsInBounds(const LatLngBounds& bounds) {
return data->annotationManager.getAnnotationsInBounds(bounds, *data);
std::vector<uint32_t> Map::getAnnotationsInBounds(const LatLngBounds& bounds, const AnnotationType& type) {
return data->annotationManager.getAnnotationsInBounds(bounds, *data, type);
}

LatLngBounds Map::getBoundsForAnnotations(const std::vector<uint32_t>& annotations) {
Expand Down

0 comments on commit da01318

Please sign in to comment.