[all] Rationalize annotation API
This commit is contained in:
@@ -1,11 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/types.hpp>
|
||||
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using AnnotationID = uint32_t;
|
||||
using AnnotationIDs = std::vector<AnnotationID>;
|
||||
|
||||
class SymbolAnnotation {
|
||||
public:
|
||||
Geometry<double> geometry;
|
||||
std::string icon;
|
||||
};
|
||||
|
||||
class LineAnnotation {
|
||||
public:
|
||||
Geometry<double> geometry;
|
||||
float opacity = 1;
|
||||
float width = 1;
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
};
|
||||
|
||||
class FillAnnotation {
|
||||
public:
|
||||
Geometry<double> geometry;
|
||||
float opacity = 1;
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
Color outlineColor = {{ 0, 0, 0, -1 }};
|
||||
};
|
||||
|
||||
// An annotation whose type and properties are sourced from a style layer.
|
||||
class StyleSourcedAnnotation {
|
||||
public:
|
||||
Geometry<double> geometry;
|
||||
std::string layerID;
|
||||
};
|
||||
|
||||
using Annotation = variant<
|
||||
SymbolAnnotation,
|
||||
LineAnnotation,
|
||||
FillAnnotation,
|
||||
StyleSourcedAnnotation>;
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class PointAnnotation {
|
||||
public:
|
||||
PointAnnotation(const LatLng& position_, const std::string& icon_ = "")
|
||||
: position(position_.wrapped()), icon(icon_) {}
|
||||
|
||||
const LatLng position;
|
||||
const std::string icon;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct FillAnnotationProperties {
|
||||
float opacity = 1;
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
Color outlineColor = {{ 0, 0, 0, -1 }};
|
||||
};
|
||||
|
||||
struct LineAnnotationProperties {
|
||||
float opacity = 1;
|
||||
float width = 1;
|
||||
Color color = {{ 0, 0, 0, 1 }};
|
||||
};
|
||||
|
||||
class ShapeAnnotation {
|
||||
public:
|
||||
using Properties = variant<
|
||||
FillAnnotationProperties, // creates a fill annotation
|
||||
LineAnnotationProperties, // creates a line annotation
|
||||
std::string>; // creates an annotation whose type and properties are sourced from a style layer
|
||||
|
||||
ShapeAnnotation(const Geometry<double>& geometry_, const Properties& properties_)
|
||||
: geometry(geometry_), properties(properties_) {}
|
||||
|
||||
const Geometry<double> geometry;
|
||||
const Properties properties;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -23,8 +23,6 @@ namespace mbgl {
|
||||
class FileSource;
|
||||
class View;
|
||||
class SpriteImage;
|
||||
class PointAnnotation;
|
||||
class ShapeAnnotation;
|
||||
struct CameraOptions;
|
||||
struct AnimationOptions;
|
||||
|
||||
@@ -142,16 +140,9 @@ public:
|
||||
void removeAnnotationIcon(const std::string&);
|
||||
double getTopOffsetPixelsForAnnotationIcon(const std::string&);
|
||||
|
||||
AnnotationID addPointAnnotation(const PointAnnotation&);
|
||||
AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&);
|
||||
|
||||
AnnotationID addShapeAnnotation(const ShapeAnnotation&);
|
||||
AnnotationIDs addShapeAnnotations(const std::vector<ShapeAnnotation>&);
|
||||
|
||||
void updatePointAnnotation(AnnotationID, const PointAnnotation&);
|
||||
|
||||
AnnotationID addAnnotation(const Annotation&);
|
||||
void updateAnnotation(AnnotationID, const Annotation&);
|
||||
void removeAnnotation(AnnotationID);
|
||||
void removeAnnotations(const AnnotationIDs&);
|
||||
|
||||
AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&);
|
||||
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
void report(float duration);
|
||||
|
||||
private:
|
||||
mbgl::LatLng makeRandomLatLng() const;
|
||||
mbgl::Point<double> makeRandomPoint() const;
|
||||
static std::shared_ptr<const mbgl::SpriteImage>
|
||||
makeSpriteImage(int width, int height, float pixelRatio);
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/platform/event.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
@@ -681,8 +680,10 @@ void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr,
|
||||
jdouble latitude = jni::GetField<jdouble>(*env, position, *latLngLatitudeId);
|
||||
jdouble longitude = jni::GetField<jdouble>(*env, position, *latLngLongitudeId);
|
||||
|
||||
// Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
|
||||
nativeMapView->getMap().updatePointAnnotation(markerId, mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), iconId));
|
||||
nativeMapView->getMap().updateAnnotation(markerId, mbgl::SymbolAnnotation {
|
||||
mbgl::Point<double>(longitude, latitude),
|
||||
iconId
|
||||
});
|
||||
}
|
||||
|
||||
jni::jarray<jlong>* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray<jni::jobject>* jarray) {
|
||||
@@ -693,30 +694,30 @@ jni::jarray<jlong>* nativeAddMarkers(JNIEnv *env, jni::jobject* obj, jlong nativ
|
||||
NullCheck(*env, jarray);
|
||||
std::size_t len = jni::GetArrayLength(*env, *jarray);
|
||||
|
||||
std::vector<mbgl::PointAnnotation> markers;
|
||||
markers.reserve(len);
|
||||
std::vector<mbgl::AnnotationID> ids;
|
||||
ids.reserve(len);
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
jni::jobject* marker = jni::GetObjectArrayElement(*env, *jarray, i);
|
||||
jni::jobject* position = jni::GetField<jni::jobject*>(*env, marker, *markerPositionId);
|
||||
jni::jobject* icon = jni::GetField<jni::jobject*>(*env, marker, *markerIconId);
|
||||
jni::DeleteLocalRef(*env, marker);
|
||||
|
||||
jni::jstring* jid = reinterpret_cast<jni::jstring*>(jni::GetField<jni::jobject*>(*env, icon, *iconIdId));
|
||||
jni::DeleteLocalRef(*env, icon);
|
||||
|
||||
std::string id = std_string_from_jstring(env, jid);
|
||||
jni::DeleteLocalRef(*env, jid);
|
||||
|
||||
jdouble latitude = jni::GetField<jdouble>(*env, position, *latLngLatitudeId);
|
||||
jdouble longitude = jni::GetField<jdouble>(*env, position, *latLngLongitudeId);
|
||||
jni::DeleteLocalRef(*env, position);
|
||||
|
||||
markers.emplace_back(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id));
|
||||
ids.push_back(nativeMapView->getMap().addAnnotation(mbgl::SymbolAnnotation {
|
||||
mbgl::Point<double>(longitude, latitude),
|
||||
std_string_from_jstring(env, jid)
|
||||
}));
|
||||
|
||||
jni::DeleteLocalRef(*env, position);
|
||||
jni::DeleteLocalRef(*env, jid);
|
||||
jni::DeleteLocalRef(*env, icon);
|
||||
jni::DeleteLocalRef(*env, marker);
|
||||
}
|
||||
|
||||
std::vector<uint32_t> pointAnnotationIDs = nativeMapView->getMap().addPointAnnotations(markers);
|
||||
return std_vector_uint_to_jobject(env, pointAnnotationIDs);
|
||||
return std_vector_uint_to_jobject(env, ids);
|
||||
}
|
||||
|
||||
static mbgl::Color toColor(jint color) {
|
||||
@@ -762,24 +763,23 @@ jni::jarray<jlong>* nativeAddPolylines(JNIEnv *env, jni::jobject* obj, jlong nat
|
||||
NullCheck(*env, jarray);
|
||||
std::size_t len = jni::GetArrayLength(*env, *jarray);
|
||||
|
||||
std::vector<mbgl::ShapeAnnotation> shapes;
|
||||
shapes.reserve(len);
|
||||
std::vector<mbgl::AnnotationID> ids;
|
||||
ids.reserve(len);
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
jni::jobject* polyline = jni::GetObjectArrayElement(*env, *jarray, i);
|
||||
|
||||
mbgl::LineAnnotationProperties lineProperties;
|
||||
lineProperties.opacity = jni::GetField<jfloat>(*env, polyline, *polylineAlphaId);
|
||||
lineProperties.color = toColor(jni::GetField<jint>(*env, polyline, *polylineColorId));
|
||||
lineProperties.width = jni::GetField<jfloat>(*env, polyline, *polylineWidthId);
|
||||
|
||||
jni::jobject* points = jni::GetField<jni::jobject*>(*env, polyline, *polylinePointsId);
|
||||
shapes.emplace_back(toGeometry<mbgl::LineString<double>>(env, points), lineProperties);
|
||||
|
||||
mbgl::LineAnnotation annotation { toGeometry<mbgl::LineString<double>>(env, points) };
|
||||
annotation.opacity = jni::GetField<jfloat>(*env, polyline, *polylineAlphaId);
|
||||
annotation.color = toColor(jni::GetField<jint>(*env, polyline, *polylineColorId));
|
||||
annotation.width = jni::GetField<jfloat>(*env, polyline, *polylineWidthId);
|
||||
ids.push_back(nativeMapView->getMap().addAnnotation(annotation));
|
||||
|
||||
jni::DeleteLocalRef(*env, polyline);
|
||||
}
|
||||
|
||||
return std_vector_uint_to_jobject(env, nativeMapView->getMap().addShapeAnnotations(shapes));
|
||||
return std_vector_uint_to_jobject(env, ids);
|
||||
}
|
||||
|
||||
jni::jarray<jlong>* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray<jni::jobject>* jarray) {
|
||||
@@ -790,24 +790,23 @@ jni::jarray<jlong>* nativeAddPolygons(JNIEnv *env, jni::jobject* obj, jlong nati
|
||||
NullCheck(*env, jarray);
|
||||
std::size_t len = jni::GetArrayLength(*env, *jarray);
|
||||
|
||||
std::vector<mbgl::ShapeAnnotation> shapes;
|
||||
shapes.reserve(len);
|
||||
std::vector<mbgl::AnnotationID> ids;
|
||||
ids.reserve(len);
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
jni::jobject* polygon = jni::GetObjectArrayElement(*env, *jarray, i);
|
||||
|
||||
mbgl::FillAnnotationProperties fillProperties;
|
||||
fillProperties.opacity = jni::GetField<jfloat>(*env, polygon, *polygonAlphaId);
|
||||
fillProperties.outlineColor = toColor(jni::GetField<jint>(*env, polygon, *polygonStrokeColorId));
|
||||
fillProperties.color = toColor(jni::GetField<jint>(*env, polygon, *polygonFillColorId));
|
||||
|
||||
jni::jobject* points = jni::GetField<jni::jobject*>(*env, polygon, *polygonPointsId);
|
||||
shapes.emplace_back(mbgl::Polygon<double> { toGeometry<mbgl::LinearRing<double>>(env, points) }, fillProperties);
|
||||
|
||||
mbgl::FillAnnotation annotation { mbgl::Polygon<double> { toGeometry<mbgl::LinearRing<double>>(env, points) } };
|
||||
annotation.opacity = jni::GetField<jfloat>(*env, polygon, *polygonAlphaId);
|
||||
annotation.outlineColor = toColor(jni::GetField<jint>(*env, polygon, *polygonStrokeColorId));
|
||||
annotation.color = toColor(jni::GetField<jint>(*env, polygon, *polygonFillColorId));
|
||||
ids.push_back(nativeMapView->getMap().addAnnotation(annotation));
|
||||
|
||||
jni::DeleteLocalRef(*env, polygon);
|
||||
}
|
||||
|
||||
return std_vector_uint_to_jobject(env, nativeMapView->getMap().addShapeAnnotations(shapes));
|
||||
return std_vector_uint_to_jobject(env, ids);
|
||||
}
|
||||
|
||||
void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jarray<jlong>* jarray) {
|
||||
@@ -817,20 +816,14 @@ void nativeRemoveAnnotations(JNIEnv *env, jni::jobject* obj, jlong nativeMapView
|
||||
|
||||
NullCheck(*env, jarray);
|
||||
std::size_t len = jni::GetArrayLength(*env, *jarray);
|
||||
|
||||
std::vector<uint32_t> ids;
|
||||
ids.reserve(len);
|
||||
|
||||
auto elements = jni::GetArrayElements(*env, *jarray);
|
||||
jlong* jids = std::get<0>(elements).get();
|
||||
|
||||
for (std::size_t i = 0; i < len; i++) {
|
||||
if(jids[i] == -1L)
|
||||
continue;
|
||||
ids.push_back(static_cast<uint32_t>(jids[i]));
|
||||
nativeMapView->getMap().removeAnnotation(jids[i]);
|
||||
}
|
||||
|
||||
nativeMapView->getMap().removeAnnotations(ids);
|
||||
}
|
||||
|
||||
jni::jarray<jlong>* nativeGetAnnotationsInBounds(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* latLngBounds_) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#endif
|
||||
|
||||
#import <mbgl/util/geo.hpp>
|
||||
#import <mbgl/util/geometry.hpp>
|
||||
|
||||
/// Returns the smallest rectangle that contains both the given rectangle and
|
||||
/// the given point.
|
||||
@@ -15,6 +16,10 @@ NS_INLINE mbgl::LatLng MGLLatLngFromLocationCoordinate2D(CLLocationCoordinate2D
|
||||
return mbgl::LatLng(coordinate.latitude, coordinate.longitude);
|
||||
}
|
||||
|
||||
NS_INLINE mbgl::Point<double> MGLPointFromLocationCoordinate2D(CLLocationCoordinate2D coordinate) {
|
||||
return mbgl::Point<double>(coordinate.longitude, coordinate.latitude);
|
||||
}
|
||||
|
||||
NS_INLINE CLLocationCoordinate2D MGLLocationCoordinate2DFromLatLng(mbgl::LatLng latLng) {
|
||||
return CLLocationCoordinate2DMake(latLng.latitude, latLng.longitude);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#import "MGLGeometry.h"
|
||||
#import "MGLTypes.h"
|
||||
|
||||
#import <mbgl/annotation/shape_annotation.hpp>
|
||||
#import <mbgl/annotation/annotation.hpp>
|
||||
#import <vector>
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
@@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (BOOL)intersectsOverlayBounds:(MGLCoordinateBounds)overlayBounds;
|
||||
|
||||
/** Constructs a shape annotation object, asking the delegate for style values. */
|
||||
- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate;
|
||||
- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -36,19 +36,19 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
|
||||
mbgl::FillAnnotationProperties fillProperties;
|
||||
fillProperties.opacity = [delegate alphaForShapeAnnotation:self];
|
||||
fillProperties.outlineColor = [delegate strokeColorForShapeAnnotation:self];
|
||||
fillProperties.color = [delegate fillColorForPolygonAnnotation:self];
|
||||
|
||||
- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
|
||||
mbgl::Polygon<double> geometry;
|
||||
geometry.push_back(self.ring);
|
||||
for (MGLPolygon *polygon in self.interiorPolygons) {
|
||||
geometry.push_back(polygon.ring);
|
||||
}
|
||||
|
||||
return mbgl::ShapeAnnotation(geometry, fillProperties);
|
||||
mbgl::FillAnnotation annotation { geometry };
|
||||
annotation.opacity = [delegate alphaForShapeAnnotation:self];
|
||||
annotation.outlineColor = [delegate strokeColorForShapeAnnotation:self];
|
||||
annotation.color = [delegate fillColorForPolygonAnnotation:self];
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,12 +13,7 @@
|
||||
return [[self alloc] initWithCoordinates:coords count:count];
|
||||
}
|
||||
|
||||
- (mbgl::ShapeAnnotation)shapeAnnotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
|
||||
mbgl::LineAnnotationProperties lineProperties;
|
||||
lineProperties.opacity = [delegate alphaForShapeAnnotation:self];
|
||||
lineProperties.color = [delegate strokeColorForShapeAnnotation:self];
|
||||
lineProperties.width = [delegate lineWidthForPolylineAnnotation:self];
|
||||
|
||||
- (mbgl::Annotation)annotationObjectWithDelegate:(id <MGLMultiPointDelegate>)delegate {
|
||||
NSUInteger count = self.pointCount;
|
||||
CLLocationCoordinate2D *coordinates = self.coordinates;
|
||||
|
||||
@@ -28,7 +23,12 @@
|
||||
geometry.push_back(mbgl::Point<double>(coordinates[i].longitude, coordinates[i].latitude));
|
||||
}
|
||||
|
||||
return mbgl::ShapeAnnotation(geometry, lineProperties);
|
||||
mbgl::LineAnnotation annotation { geometry };
|
||||
annotation.opacity = [delegate alphaForShapeAnnotation:self];
|
||||
annotation.color = [delegate strokeColorForShapeAnnotation:self];
|
||||
annotation.width = [delegate lineWidthForPolylineAnnotation:self];
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include <mbgl/platform/default/glfw_view.hpp>
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/style/property_transition.hpp>
|
||||
#include <mbgl/gl/gl.hpp>
|
||||
@@ -208,14 +207,10 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action,
|
||||
}
|
||||
}
|
||||
|
||||
mbgl::LatLng GLFWView::makeRandomLatLng() const {
|
||||
mbgl::Point<double> GLFWView::makeRandomPoint() const {
|
||||
const double x = width * double(std::rand()) / RAND_MAX;
|
||||
const double y = height * double(std::rand()) / RAND_MAX;
|
||||
return map->latLngForPixel({ x, y });
|
||||
}
|
||||
|
||||
mbgl::Point<double> GLFWView::makeRandomPoint() const {
|
||||
mbgl::LatLng latLng = makeRandomLatLng();
|
||||
mbgl::LatLng latLng = map->latLngForPixel({ x, y });
|
||||
return { latLng.longitude, latLng.latitude };
|
||||
}
|
||||
|
||||
@@ -259,53 +254,34 @@ void GLFWView::nextOrientation() {
|
||||
}
|
||||
|
||||
void GLFWView::addRandomCustomPointAnnotations(int count) {
|
||||
std::vector<mbgl::PointAnnotation> points;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
static int spriteID = 1;
|
||||
const auto name = std::string{ "marker-" } + mbgl::util::toString(spriteID++);
|
||||
map->addAnnotationIcon(name, makeSpriteImage(22, 22, 1));
|
||||
spriteIDs.push_back(name);
|
||||
points.emplace_back(makeRandomLatLng(), name);
|
||||
annotationIDs.push_back(map->addAnnotation(mbgl::SymbolAnnotation { makeRandomPoint(), name }));
|
||||
}
|
||||
|
||||
auto newIDs = map->addPointAnnotations(points);
|
||||
annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end());
|
||||
}
|
||||
|
||||
void GLFWView::addRandomPointAnnotations(int count) {
|
||||
std::vector<mbgl::PointAnnotation> points;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
points.emplace_back(makeRandomLatLng(), "default_marker");
|
||||
annotationIDs.push_back(map->addAnnotation(mbgl::SymbolAnnotation { makeRandomPoint(), "default_marker" }));
|
||||
}
|
||||
|
||||
auto newIDs = map->addPointAnnotations(points);
|
||||
annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end());
|
||||
}
|
||||
|
||||
void GLFWView::addRandomShapeAnnotations(int count) {
|
||||
std::vector<mbgl::ShapeAnnotation> shapes;
|
||||
|
||||
mbgl::FillAnnotationProperties properties;
|
||||
properties.opacity = .1;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
mbgl::Polygon<double> triangle;
|
||||
triangle.push_back({ makeRandomPoint(), makeRandomPoint(), makeRandomPoint() });
|
||||
shapes.emplace_back(triangle, properties);
|
||||
annotationIDs.push_back(map->addAnnotation(mbgl::FillAnnotation { triangle, .1 }));
|
||||
}
|
||||
|
||||
auto newIDs = map->addShapeAnnotations(shapes);
|
||||
annotationIDs.insert(annotationIDs.end(), newIDs.begin(), newIDs.end());
|
||||
}
|
||||
|
||||
void GLFWView::clearAnnotations() {
|
||||
if (annotationIDs.empty()) {
|
||||
return;
|
||||
for (const auto& id : annotationIDs) {
|
||||
map->removeAnnotation(id);
|
||||
}
|
||||
|
||||
map->removeAnnotations(annotationIDs);
|
||||
annotationIDs.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#import <OpenGLES/EAGL.h>
|
||||
|
||||
#include <mbgl/mbgl.hpp>
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
@@ -1776,9 +1775,9 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
// but safely updated.
|
||||
if (annotation == [self annotationWithTag:annotationTag])
|
||||
{
|
||||
const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate);
|
||||
const mbgl::Point<double> point = MGLPointFromLocationCoordinate2D(annotation.coordinate);
|
||||
MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
|
||||
_mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" });
|
||||
_mbglMap->updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, annotationImage.styleIconIdentifier.UTF8String ?: "" });
|
||||
if (annotationTag == _selectedAnnotationTag)
|
||||
{
|
||||
[self deselectAnnotation:annotation animated:YES];
|
||||
@@ -2796,11 +2795,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
if ( ! annotations) return;
|
||||
[self willChangeValueForKey:@"annotations"];
|
||||
|
||||
NSMutableArray *userPoints = [NSMutableArray array];
|
||||
std::vector<mbgl::PointAnnotation> points;
|
||||
NSMutableArray *userShapes = [NSMutableArray array];
|
||||
std::vector<mbgl::ShapeAnnotation> shapes;
|
||||
|
||||
NSMutableDictionary *annotationImagesForAnnotation = [NSMutableDictionary dictionary];
|
||||
NSMutableDictionary *annotationViewsForAnnotation = [NSMutableDictionary dictionary];
|
||||
|
||||
@@ -2820,8 +2814,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
if (!multiPoint.pointCount) {
|
||||
continue;
|
||||
}
|
||||
shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]);
|
||||
[userShapes addObject:annotation];
|
||||
|
||||
MGLAnnotationTag annotationTag = _mbglMap->addAnnotation([multiPoint annotationObjectWithDelegate:self]);
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
_annotationContextsByAnnotationTag[annotationTag] = context;
|
||||
}
|
||||
else if ([annotation isKindOfClass:[MGLMultiPolyline class]]
|
||||
|| [annotation isKindOfClass:[MGLMultiPolygon class]]
|
||||
@@ -2877,22 +2874,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
annotationImagesForAnnotation[annotationValue] = annotationImage;
|
||||
}
|
||||
|
||||
[userPoints addObject:annotation];
|
||||
points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: "");
|
||||
}
|
||||
}
|
||||
MGLAnnotationTag annotationTag = _mbglMap->addAnnotation(mbgl::SymbolAnnotation {
|
||||
MGLPointFromLocationCoordinate2D(annotation.coordinate),
|
||||
symbolName.UTF8String ?: ""
|
||||
});
|
||||
|
||||
if (points.size())
|
||||
{
|
||||
// refactor this to build contexts above and just associate with tags here
|
||||
|
||||
std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addPointAnnotations(points);
|
||||
|
||||
for (size_t i = 0; i < annotationTags.size(); ++i)
|
||||
{
|
||||
id<MGLAnnotation> annotation = userPoints[i];
|
||||
NSValue *annotationValue = [NSValue valueWithNonretainedObject:annotation];
|
||||
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
MGLAnnotationImage *annotationImage = annotationImagesForAnnotation[annotationValue];
|
||||
@@ -2900,13 +2886,11 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
if (annotationImage) {
|
||||
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
|
||||
}
|
||||
MGLAnnotationView *annotationView = annotationViewsForAnnotation[annotationValue];
|
||||
if (annotationView) {
|
||||
context.annotationView = annotationView;
|
||||
context.viewReuseIdentifier = annotationView.reuseIdentifier;
|
||||
}
|
||||
|
||||
MGLAnnotationTag annotationTag = annotationTags[i];
|
||||
_annotationContextsByAnnotationTag[annotationTag] = context;
|
||||
if ([annotation isKindOfClass:[NSObject class]]) {
|
||||
NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint.");
|
||||
@@ -2915,21 +2899,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
}
|
||||
}
|
||||
|
||||
if (shapes.size())
|
||||
{
|
||||
std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addShapeAnnotations(shapes);
|
||||
|
||||
for (size_t i = 0; i < annotationTags.size(); ++i)
|
||||
{
|
||||
MGLAnnotationTag annotationTag = annotationTags[i];
|
||||
id <MGLAnnotation> annotation = userShapes[i];
|
||||
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
_annotationContextsByAnnotationTag[annotationTag] = context;
|
||||
}
|
||||
}
|
||||
|
||||
[self updateAnnotationContainerViewWithAnnotationViews:newAnnotationViews];
|
||||
|
||||
[self didChangeValueForKey:@"annotations"];
|
||||
@@ -3072,8 +3041,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
{
|
||||
if ( ! annotations) return;
|
||||
|
||||
std::vector<MGLAnnotationTag> annotationTagsToRemove;
|
||||
annotationTagsToRemove.reserve(annotations.count);
|
||||
[self willChangeValueForKey:@"annotations"];
|
||||
|
||||
for (id <MGLAnnotation> annotation in annotations)
|
||||
{
|
||||
@@ -3088,8 +3056,6 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
MGLAnnotationContext &annotationContext = _annotationContextsByAnnotationTag.at(annotationTag);
|
||||
MGLAnnotationView *annotationView = annotationContext.annotationView;
|
||||
[annotationView removeFromSuperview];
|
||||
|
||||
annotationTagsToRemove.push_back(annotationTag);
|
||||
|
||||
if (annotationTag == _selectedAnnotationTag)
|
||||
{
|
||||
@@ -3102,15 +3068,12 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
{
|
||||
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
|
||||
}
|
||||
|
||||
_mbglMap->removeAnnotation(annotationTag);
|
||||
}
|
||||
|
||||
if ( ! annotationTagsToRemove.empty())
|
||||
{
|
||||
[self willChangeValueForKey:@"annotations"];
|
||||
_mbglMap->removeAnnotations(annotationTagsToRemove);
|
||||
[self didChangeValueForKey:@"annotations"];
|
||||
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
|
||||
}
|
||||
[self didChangeValueForKey:@"annotations"];
|
||||
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
|
||||
}
|
||||
|
||||
- (void)addOverlay:(id <MGLOverlay>)overlay
|
||||
@@ -3675,8 +3638,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
{
|
||||
if ([pair.second.imageReuseIdentifier isEqualToString:reuseIdentifier])
|
||||
{
|
||||
const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(pair.second.annotation.coordinate);
|
||||
_mbglMap->updatePointAnnotation(pair.first, { latLng, iconIdentifier.UTF8String ?: "" });
|
||||
const mbgl::Point<double> point = MGLPointFromLocationCoordinate2D(pair.second.annotation.coordinate);
|
||||
_mbglMap->updateAnnotation(pair.first, mbgl::SymbolAnnotation { point, iconIdentifier.UTF8String ?: "" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#import "MGLMapViewDelegate.h"
|
||||
|
||||
#import <mbgl/mbgl.hpp>
|
||||
#import <mbgl/annotation/point_annotation.hpp>
|
||||
#import <mbgl/annotation/annotation.hpp>
|
||||
#import <mbgl/map/camera.hpp>
|
||||
#import <mbgl/platform/darwin/reachability.h>
|
||||
#import <mbgl/gl/gl.hpp>
|
||||
@@ -481,9 +481,9 @@ public:
|
||||
// match a valid annotation tag, the annotation will be unnecessarily
|
||||
// but safely updated.
|
||||
if (annotation == [self annotationWithTag:annotationTag]) {
|
||||
const mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(annotation.coordinate);
|
||||
const mbgl::Point<double> point = MGLPointFromLocationCoordinate2D(annotation.coordinate);
|
||||
MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag];
|
||||
_mbglMap->updatePointAnnotation(annotationTag, { latLng, annotationImage.styleIconIdentifier.UTF8String ?: "" });
|
||||
_mbglMap->updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, annotationImage.styleIconIdentifier.UTF8String ?: "" });
|
||||
if (annotationTag == _selectedAnnotationTag) {
|
||||
[self deselectAnnotation:annotation];
|
||||
}
|
||||
@@ -1604,12 +1604,6 @@ public:
|
||||
|
||||
BOOL delegateHasImagesForAnnotations = [self.delegate respondsToSelector:@selector(mapView:imageForAnnotation:)];
|
||||
|
||||
NSMutableArray *userPoints = [NSMutableArray array];
|
||||
std::vector<mbgl::PointAnnotation> points;
|
||||
NSMutableArray *userShapes = [NSMutableArray array];
|
||||
std::vector<mbgl::ShapeAnnotation> shapes;
|
||||
NSMutableArray *annotationImages = [NSMutableArray arrayWithCapacity:annotations.count];
|
||||
|
||||
for (id <MGLAnnotation> annotation in annotations) {
|
||||
NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
|
||||
|
||||
@@ -1619,8 +1613,11 @@ public:
|
||||
if (!multiPoint.pointCount) {
|
||||
continue;
|
||||
}
|
||||
shapes.emplace_back([multiPoint shapeAnnotationObjectWithDelegate:self]);
|
||||
[userShapes addObject:annotation];
|
||||
|
||||
MGLAnnotationTag annotationTag = _mbglMap->addAnnotation([multiPoint annotationObjectWithDelegate:self]);
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
_annotationContextsByAnnotationTag[annotationTag] = context;
|
||||
} else if ([annotation isKindOfClass:[MGLMultiPolyline class]]
|
||||
|| [annotation isKindOfClass:[MGLMultiPolygon class]]
|
||||
|| [annotation isKindOfClass:[MGLShapeCollection class]]) {
|
||||
@@ -1647,28 +1644,12 @@ public:
|
||||
self.annotationImagesByIdentifier[annotationImage.reuseIdentifier] = annotationImage;
|
||||
[self installAnnotationImage:annotationImage];
|
||||
}
|
||||
[annotationImages addObject:annotationImage];
|
||||
|
||||
[userPoints addObject:annotation];
|
||||
points.emplace_back(MGLLatLngFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String ?: "");
|
||||
|
||||
// Opt into potentially expensive tooltip tracking areas.
|
||||
if (annotation.toolTip.length) {
|
||||
_wantsToolTipRects = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add any point annotations to mbgl and our own index.
|
||||
if (points.size()) {
|
||||
std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addPointAnnotations(points);
|
||||
|
||||
for (size_t i = 0; i < annotationTags.size(); ++i) {
|
||||
MGLAnnotationTag annotationTag = annotationTags[i];
|
||||
MGLAnnotationImage *annotationImage = annotationImages[i];
|
||||
annotationImage.styleIconIdentifier = @(points[i].icon.c_str());
|
||||
id <MGLAnnotation> annotation = userPoints[i];
|
||||
|
||||
|
||||
MGLAnnotationTag annotationTag = _mbglMap->addAnnotation(mbgl::SymbolAnnotation {
|
||||
MGLPointFromLocationCoordinate2D(annotation.coordinate),
|
||||
symbolName.UTF8String ?: ""
|
||||
});
|
||||
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
context.imageReuseIdentifier = annotationImage.reuseIdentifier;
|
||||
@@ -1678,23 +1659,14 @@ public:
|
||||
NSAssert(![annotation isKindOfClass:[MGLMultiPoint class]], @"Point annotation should not be MGLMultiPoint.");
|
||||
[(NSObject *)annotation addObserver:self forKeyPath:@"coordinate" options:0 context:(void *)(NSUInteger)annotationTag];
|
||||
}
|
||||
|
||||
// Opt into potentially expensive tooltip tracking areas.
|
||||
if (annotation.toolTip.length) {
|
||||
_wantsToolTipRects = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add any shape annotations to mbgl and our own index.
|
||||
if (shapes.size()) {
|
||||
std::vector<MGLAnnotationTag> annotationTags = _mbglMap->addShapeAnnotations(shapes);
|
||||
|
||||
for (size_t i = 0; i < annotationTags.size(); ++i) {
|
||||
MGLAnnotationTag annotationTag = annotationTags[i];
|
||||
id <MGLAnnotation> annotation = userShapes[i];
|
||||
|
||||
MGLAnnotationContext context;
|
||||
context.annotation = annotation;
|
||||
_annotationContextsByAnnotationTag[annotationTag] = context;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[self didChangeValueForKey:@"annotations"];
|
||||
|
||||
[self updateAnnotationTrackingAreas];
|
||||
@@ -1765,16 +1737,14 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<MGLAnnotationTag> annotationTagsToRemove;
|
||||
annotationTagsToRemove.reserve(annotations.count);
|
||||
|
||||
[self willChangeValueForKey:@"annotations"];
|
||||
|
||||
for (id <MGLAnnotation> annotation in annotations) {
|
||||
NSAssert([annotation conformsToProtocol:@protocol(MGLAnnotation)], @"Annotation does not conform to MGLAnnotation");
|
||||
|
||||
MGLAnnotationTag annotationTag = [self annotationTagForAnnotation:annotation];
|
||||
NSAssert(annotationTag != MGLAnnotationTagNotFound, @"No ID for annotation %@", annotation);
|
||||
annotationTagsToRemove.push_back(annotationTag);
|
||||
|
||||
|
||||
if (annotationTag == _selectedAnnotationTag) {
|
||||
[self deselectAnnotation:annotation];
|
||||
}
|
||||
@@ -1788,10 +1758,10 @@ public:
|
||||
![annotation isKindOfClass:[MGLMultiPoint class]]) {
|
||||
[(NSObject *)annotation removeObserver:self forKeyPath:@"coordinate" context:(void *)(NSUInteger)annotationTag];
|
||||
}
|
||||
|
||||
_mbglMap->removeAnnotation(annotationTag);
|
||||
}
|
||||
|
||||
[self willChangeValueForKey:@"annotations"];
|
||||
_mbglMap->removeAnnotations(annotationTagsToRemove);
|
||||
[self didChangeValueForKey:@"annotations"];
|
||||
|
||||
[self updateAnnotationTrackingAreas];
|
||||
|
||||
@@ -20,11 +20,9 @@ typedef quint32 AnnotationID;
|
||||
typedef QList<AnnotationID> AnnotationIDs;
|
||||
|
||||
typedef QPair<Coordinate, QString> PointAnnotation;
|
||||
typedef QList<PointAnnotation> PointAnnotations;
|
||||
|
||||
// FIXME: We need to add support for custom style properties
|
||||
typedef QPair<CoordinateSegments, QString> ShapeAnnotation;
|
||||
typedef QList<ShapeAnnotation> ShapeAnnotations;
|
||||
|
||||
enum NetworkMode {
|
||||
Online, // Default
|
||||
|
||||
@@ -165,15 +165,11 @@ public:
|
||||
QStringList getClasses() const;
|
||||
|
||||
QMapbox::AnnotationID addPointAnnotation(const QMapbox::PointAnnotation &);
|
||||
QMapbox::AnnotationIDs addPointAnnotations(const QMapbox::PointAnnotations &);
|
||||
|
||||
QMapbox::AnnotationID addShapeAnnotation(const QMapbox::ShapeAnnotation &);
|
||||
QMapbox::AnnotationIDs addShapeAnnotations(const QMapbox::ShapeAnnotations &);
|
||||
|
||||
void updatePointAnnotation(QMapbox::AnnotationID, const QMapbox::PointAnnotation &);
|
||||
|
||||
void removeAnnotation(QMapbox::AnnotationID);
|
||||
void removeAnnotations(const QMapbox::AnnotationIDs &);
|
||||
|
||||
bool isRotating() const;
|
||||
bool isScaling() const;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "qmapboxgl_p.hpp"
|
||||
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/gl/gl.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
@@ -376,40 +375,23 @@ QStringList QMapboxGL::getClasses() const
|
||||
return classNames;
|
||||
}
|
||||
|
||||
mbgl::PointAnnotation fromPointAnnotation(const PointAnnotation &pointAnnotation) {
|
||||
mbgl::Annotation fromPointAnnotation(const PointAnnotation &pointAnnotation) {
|
||||
const Coordinate &coordinate = pointAnnotation.first;
|
||||
const QString &icon = pointAnnotation.second;
|
||||
return { { coordinate.first, coordinate.second }, icon.toStdString() };
|
||||
return mbgl::SymbolAnnotation { mbgl::Point<double> { coordinate.second, coordinate.first }, icon.toStdString() };
|
||||
}
|
||||
|
||||
AnnotationID QMapboxGL::addPointAnnotation(const PointAnnotation &pointAnnotation)
|
||||
{
|
||||
return d_ptr->mapObj->addPointAnnotation(fromPointAnnotation(pointAnnotation));
|
||||
}
|
||||
|
||||
AnnotationIDs QMapboxGL::addPointAnnotations(const PointAnnotations &pointAnnotations)
|
||||
{
|
||||
std::vector<mbgl::PointAnnotation> mbglPointAnnotations;
|
||||
mbglPointAnnotations.reserve(pointAnnotations.size());
|
||||
|
||||
for (const PointAnnotation &pointAnnotation : pointAnnotations) {
|
||||
mbglPointAnnotations.emplace_back(fromPointAnnotation(pointAnnotation));
|
||||
}
|
||||
|
||||
AnnotationIDs ids;
|
||||
for (const mbgl::AnnotationID &id : d_ptr->mapObj->addPointAnnotations(mbglPointAnnotations)) {
|
||||
ids << id;
|
||||
}
|
||||
|
||||
return ids;
|
||||
return d_ptr->mapObj->addAnnotation(fromPointAnnotation(pointAnnotation));
|
||||
}
|
||||
|
||||
void QMapboxGL::updatePointAnnotation(AnnotationID id, const PointAnnotation &pointAnnotation)
|
||||
{
|
||||
d_ptr->mapObj->updatePointAnnotation(id, fromPointAnnotation(pointAnnotation));
|
||||
d_ptr->mapObj->updateAnnotation(id, fromPointAnnotation(pointAnnotation));
|
||||
}
|
||||
|
||||
mbgl::ShapeAnnotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeAnnotation) {
|
||||
mbgl::Annotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeAnnotation) {
|
||||
const CoordinateSegments &segments = shapeAnnotation.first;
|
||||
const QString &styleLayer = shapeAnnotation.second;
|
||||
|
||||
@@ -427,29 +409,12 @@ mbgl::ShapeAnnotation fromQMapboxGLShapeAnnotation(const ShapeAnnotation &shapeA
|
||||
polygon.emplace_back(linearRing);
|
||||
}
|
||||
|
||||
return { polygon, styleLayer.toStdString() };
|
||||
return mbgl::StyleSourcedAnnotation { polygon, styleLayer.toStdString() };
|
||||
}
|
||||
|
||||
AnnotationID QMapboxGL::addShapeAnnotation(const ShapeAnnotation &shapeAnnotation)
|
||||
{
|
||||
return d_ptr->mapObj->addShapeAnnotation(fromQMapboxGLShapeAnnotation(shapeAnnotation));
|
||||
}
|
||||
|
||||
AnnotationIDs QMapboxGL::addShapeAnnotations(const ShapeAnnotations &shapeAnnotations)
|
||||
{
|
||||
std::vector<mbgl::ShapeAnnotation> mbglShapeAnnotations;
|
||||
mbglShapeAnnotations.reserve(shapeAnnotations.size());
|
||||
|
||||
for (const ShapeAnnotation &shapeAnnotation : shapeAnnotations) {
|
||||
mbglShapeAnnotations.emplace_back(fromQMapboxGLShapeAnnotation(shapeAnnotation));
|
||||
}
|
||||
|
||||
AnnotationIDs ids;
|
||||
for (const mbgl::AnnotationID &id : d_ptr->mapObj->addShapeAnnotations(mbglShapeAnnotations)) {
|
||||
ids << id;
|
||||
}
|
||||
|
||||
return ids;
|
||||
return d_ptr->mapObj->addAnnotation(fromQMapboxGLShapeAnnotation(shapeAnnotation));
|
||||
}
|
||||
|
||||
void QMapboxGL::removeAnnotation(AnnotationID annotationID)
|
||||
@@ -457,18 +422,6 @@ void QMapboxGL::removeAnnotation(AnnotationID annotationID)
|
||||
d_ptr->mapObj->removeAnnotation(annotationID);
|
||||
}
|
||||
|
||||
void QMapboxGL::removeAnnotations(const AnnotationIDs &annotationIDs)
|
||||
{
|
||||
std::vector<mbgl::AnnotationID> mbglAnnotationIds;
|
||||
mbglAnnotationIds.reserve(annotationIDs.size());
|
||||
|
||||
for (const AnnotationID annotationID : annotationIDs) {
|
||||
mbglAnnotationIds.emplace_back(annotationID);
|
||||
}
|
||||
|
||||
d_ptr->mapObj->removeAnnotations(mbglAnnotationIds);
|
||||
}
|
||||
|
||||
bool QMapboxGL::isRotating() const
|
||||
{
|
||||
return d_ptr->mapObj->isRotating();
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
#include <mbgl/annotation/symbol_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/line_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/fill_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/style_sourced_annotation_impl.hpp>
|
||||
#include <mbgl/source/source.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/layer/symbol_layer.hpp>
|
||||
@@ -18,63 +22,54 @@ AnnotationManager::AnnotationManager(float pixelRatio)
|
||||
|
||||
AnnotationManager::~AnnotationManager() = default;
|
||||
|
||||
AnnotationIDs
|
||||
AnnotationManager::addPointAnnotations(const std::vector<PointAnnotation>& points, const uint8_t) {
|
||||
AnnotationIDs annotationIDs;
|
||||
annotationIDs.reserve(points.size());
|
||||
|
||||
for (const auto& point : points) {
|
||||
const uint32_t annotationID = nextID++;
|
||||
auto annotation = std::make_shared<PointAnnotationImpl>(annotationID, point);
|
||||
pointTree.insert(annotation);
|
||||
pointAnnotations.emplace(annotationID, annotation);
|
||||
annotationIDs.push_back(annotationID);
|
||||
}
|
||||
|
||||
return annotationIDs;
|
||||
AnnotationID AnnotationManager::addAnnotation(const Annotation& annotation, const uint8_t maxZoom) {
|
||||
AnnotationID id = nextID++;
|
||||
updateAnnotation(id, annotation, maxZoom);
|
||||
return id;
|
||||
}
|
||||
|
||||
AnnotationIDs
|
||||
AnnotationManager::addShapeAnnotations(const std::vector<ShapeAnnotation>& shapes, const uint8_t maxZoom) {
|
||||
AnnotationIDs annotationIDs;
|
||||
annotationIDs.reserve(shapes.size());
|
||||
|
||||
for (const auto& shape : shapes) {
|
||||
const uint32_t annotationID = nextID++;
|
||||
shapeAnnotations.emplace(annotationID,
|
||||
std::make_unique<ShapeAnnotationImpl>(annotationID, shape, maxZoom));
|
||||
annotationIDs.push_back(annotationID);
|
||||
}
|
||||
|
||||
return annotationIDs;
|
||||
void AnnotationManager::updateAnnotation(const AnnotationID& id, const Annotation& annotation, const uint8_t maxZoom) {
|
||||
removeAnnotation(id);
|
||||
Annotation::visit(annotation, [&] (const auto& annotation_) {
|
||||
this->add(id, annotation_, maxZoom);
|
||||
});
|
||||
}
|
||||
|
||||
void AnnotationManager::updatePointAnnotation(const AnnotationID& id, const PointAnnotation& point, const uint8_t) {
|
||||
auto foundAnnotation = pointAnnotations.find(id);
|
||||
if (foundAnnotation != pointAnnotations.end()) {
|
||||
auto updatedAnnotation = std::make_shared<PointAnnotationImpl>(id, point);
|
||||
pointTree.remove(foundAnnotation->second);
|
||||
pointTree.insert(updatedAnnotation);
|
||||
foundAnnotation->second = updatedAnnotation;
|
||||
void AnnotationManager::removeAnnotation(const AnnotationID& id) {
|
||||
if (symbolAnnotations.find(id) != symbolAnnotations.end()) {
|
||||
symbolTree.remove(symbolAnnotations.at(id));
|
||||
symbolAnnotations.erase(id);
|
||||
} else if (shapeAnnotations.find(id) != shapeAnnotations.end()) {
|
||||
obsoleteShapeAnnotationLayers.push_back(shapeAnnotations.at(id)->layerID);
|
||||
shapeAnnotations.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
void AnnotationManager::removeAnnotations(const AnnotationIDs& ids) {
|
||||
for (const auto& id : ids) {
|
||||
if (pointAnnotations.find(id) != pointAnnotations.end()) {
|
||||
pointTree.remove(pointAnnotations.at(id));
|
||||
pointAnnotations.erase(id);
|
||||
} else if (shapeAnnotations.find(id) != shapeAnnotations.end()) {
|
||||
obsoleteShapeAnnotationLayers.push_back(shapeAnnotations.at(id)->layerID);
|
||||
shapeAnnotations.erase(id);
|
||||
}
|
||||
}
|
||||
void AnnotationManager::add(const AnnotationID& id, const SymbolAnnotation& annotation, const uint8_t) {
|
||||
auto impl = std::make_shared<SymbolAnnotationImpl>(id, annotation);
|
||||
symbolTree.insert(impl);
|
||||
symbolAnnotations.emplace(id, impl);
|
||||
}
|
||||
|
||||
void AnnotationManager::add(const AnnotationID& id, const LineAnnotation& annotation, const uint8_t maxZoom) {
|
||||
shapeAnnotations.emplace(id,
|
||||
std::make_unique<LineAnnotationImpl>(id, annotation, maxZoom));
|
||||
}
|
||||
|
||||
void AnnotationManager::add(const AnnotationID& id, const FillAnnotation& annotation, const uint8_t maxZoom) {
|
||||
shapeAnnotations.emplace(id,
|
||||
std::make_unique<FillAnnotationImpl>(id, annotation, maxZoom));
|
||||
}
|
||||
|
||||
void AnnotationManager::add(const AnnotationID& id, const StyleSourcedAnnotation& annotation, const uint8_t maxZoom) {
|
||||
shapeAnnotations.emplace(id,
|
||||
std::make_unique<StyleSourcedAnnotationImpl>(id, annotation, maxZoom));
|
||||
}
|
||||
|
||||
AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds& bounds) const {
|
||||
AnnotationIDs result;
|
||||
|
||||
pointTree.query(boost::geometry::index::intersects(bounds),
|
||||
symbolTree.query(boost::geometry::index::intersects(bounds),
|
||||
boost::make_function_output_iterator([&](const auto& val){
|
||||
result.push_back(val->id);
|
||||
}));
|
||||
@@ -83,7 +78,7 @@ AnnotationIDs AnnotationManager::getPointAnnotationsInBounds(const LatLngBounds&
|
||||
}
|
||||
|
||||
std::unique_ptr<AnnotationTile> AnnotationManager::getTile(const CanonicalTileID& tileID) {
|
||||
if (pointAnnotations.empty() && shapeAnnotations.empty())
|
||||
if (symbolAnnotations.empty() && shapeAnnotations.empty())
|
||||
return nullptr;
|
||||
|
||||
auto tile = std::make_unique<AnnotationTile>();
|
||||
@@ -94,7 +89,7 @@ std::unique_ptr<AnnotationTile> AnnotationManager::getTile(const CanonicalTileID
|
||||
|
||||
LatLngBounds tileBounds(tileID);
|
||||
|
||||
pointTree.query(boost::geometry::index::intersects(tileBounds),
|
||||
symbolTree.query(boost::geometry::index::intersects(tileBounds),
|
||||
boost::make_function_output_iterator([&](const auto& val){
|
||||
val->updateLayer(tileID, pointLayer);
|
||||
}));
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/annotation/point_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/symbol_annotation_impl.hpp>
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
@@ -11,13 +10,14 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class PointAnnotation;
|
||||
class ShapeAnnotation;
|
||||
class AnnotationTile;
|
||||
class AnnotationTileMonitor;
|
||||
class SymbolAnnotationImpl;
|
||||
class ShapeAnnotationImpl;
|
||||
class Style;
|
||||
|
||||
class AnnotationManager : private util::noncopyable {
|
||||
@@ -25,10 +25,9 @@ public:
|
||||
AnnotationManager(float pixelRatio);
|
||||
~AnnotationManager();
|
||||
|
||||
AnnotationIDs addPointAnnotations(const std::vector<PointAnnotation>&, const uint8_t maxZoom);
|
||||
AnnotationIDs addShapeAnnotations(const std::vector<ShapeAnnotation>&, const uint8_t maxZoom);
|
||||
void updatePointAnnotation(const AnnotationID&, const PointAnnotation&, const uint8_t maxZoom);
|
||||
void removeAnnotations(const AnnotationIDs&);
|
||||
AnnotationID addAnnotation(const Annotation&, const uint8_t maxZoom);
|
||||
void updateAnnotation(const AnnotationID&, const Annotation&, const uint8_t maxZoom);
|
||||
void removeAnnotation(const AnnotationID&);
|
||||
|
||||
AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&) const;
|
||||
|
||||
@@ -46,12 +45,22 @@ public:
|
||||
static const std::string PointLayerID;
|
||||
|
||||
private:
|
||||
void add(const AnnotationID&, const SymbolAnnotation&, const uint8_t);
|
||||
void add(const AnnotationID&, const LineAnnotation&, const uint8_t);
|
||||
void add(const AnnotationID&, const FillAnnotation&, const uint8_t);
|
||||
void add(const AnnotationID&, const StyleSourcedAnnotation&, const uint8_t);
|
||||
|
||||
std::unique_ptr<AnnotationTile> getTile(const CanonicalTileID&);
|
||||
|
||||
AnnotationID nextID = 0;
|
||||
PointAnnotationImpl::Tree pointTree;
|
||||
PointAnnotationImpl::Map pointAnnotations;
|
||||
ShapeAnnotationImpl::Map shapeAnnotations;
|
||||
|
||||
using SymbolAnnotationTree = boost::geometry::index::rtree<std::shared_ptr<const SymbolAnnotationImpl>, boost::geometry::index::rstar<16, 4>>;
|
||||
using SymbolAnnotationMap = std::unordered_map<AnnotationID, std::shared_ptr<SymbolAnnotationImpl>>;
|
||||
using ShapeAnnotationMap = std::unordered_map<AnnotationID, std::unique_ptr<ShapeAnnotationImpl>>;
|
||||
|
||||
SymbolAnnotationTree symbolTree;
|
||||
SymbolAnnotationMap symbolAnnotations;
|
||||
ShapeAnnotationMap shapeAnnotations;
|
||||
std::vector<std::string> obsoleteShapeAnnotationLayers;
|
||||
std::set<AnnotationTileMonitor*> monitors;
|
||||
|
||||
|
||||
36
src/mbgl/annotation/fill_annotation_impl.cpp
Normal file
36
src/mbgl/annotation/fill_annotation_impl.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <mbgl/annotation/fill_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/layer/fill_layer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace geojsonvt = mapbox::geojsonvt;
|
||||
|
||||
FillAnnotationImpl::FillAnnotationImpl(const AnnotationID id_, const FillAnnotation& annotation_, const uint8_t maxZoom_)
|
||||
: ShapeAnnotationImpl(id_, maxZoom_),
|
||||
annotation(annotation_) {
|
||||
}
|
||||
|
||||
void FillAnnotationImpl::updateStyle(Style& style) const {
|
||||
if (style.getLayer(layerID))
|
||||
return;
|
||||
|
||||
std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>();
|
||||
|
||||
layer->paint.fillOpacity = annotation.opacity;
|
||||
layer->paint.fillColor = annotation.color;
|
||||
layer->paint.fillOutlineColor = annotation.outlineColor;
|
||||
|
||||
layer->id = layerID;
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
|
||||
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
|
||||
}
|
||||
|
||||
const Geometry<double>& FillAnnotationImpl::geometry() const {
|
||||
return annotation.geometry;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/annotation/fill_annotation_impl.hpp
Normal file
19
src/mbgl/annotation/fill_annotation_impl.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FillAnnotationImpl : public ShapeAnnotationImpl {
|
||||
public:
|
||||
FillAnnotationImpl(const AnnotationID, const FillAnnotation&, const uint8_t maxZoom);
|
||||
|
||||
void updateStyle(Style&) const final;
|
||||
const Geometry<double>& geometry() const final;
|
||||
|
||||
private:
|
||||
const FillAnnotation annotation;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
37
src/mbgl/annotation/line_annotation_impl.cpp
Normal file
37
src/mbgl/annotation/line_annotation_impl.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <mbgl/annotation/line_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/layer/line_layer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace geojsonvt = mapbox::geojsonvt;
|
||||
|
||||
LineAnnotationImpl::LineAnnotationImpl(const AnnotationID id_, const LineAnnotation& annotation_, const uint8_t maxZoom_)
|
||||
: ShapeAnnotationImpl(id_, maxZoom_),
|
||||
annotation(annotation_) {
|
||||
}
|
||||
|
||||
void LineAnnotationImpl::updateStyle(Style& style) const {
|
||||
if (style.getLayer(layerID))
|
||||
return;
|
||||
|
||||
std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>();
|
||||
layer->layout.lineJoin = LineJoinType::Round;
|
||||
|
||||
layer->paint.lineOpacity = annotation.opacity;
|
||||
layer->paint.lineWidth = annotation.width;
|
||||
layer->paint.lineColor = annotation.color;
|
||||
|
||||
layer->id = layerID;
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
|
||||
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
|
||||
}
|
||||
|
||||
const Geometry<double>& LineAnnotationImpl::geometry() const {
|
||||
return annotation.geometry;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/annotation/line_annotation_impl.hpp
Normal file
19
src/mbgl/annotation/line_annotation_impl.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class LineAnnotationImpl : public ShapeAnnotationImpl {
|
||||
public:
|
||||
LineAnnotationImpl(const AnnotationID, const LineAnnotation&, const uint8_t maxZoom);
|
||||
|
||||
void updateStyle(Style&) const final;
|
||||
const Geometry<double>& geometry() const final;
|
||||
|
||||
private:
|
||||
const LineAnnotation annotation;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,83 +1,21 @@
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/layer/line_layer.hpp>
|
||||
#include <mbgl/layer/fill_layer.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/math/wrap.hpp>
|
||||
#include <mbgl/math/clamp.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace geojsonvt = mapbox::geojsonvt;
|
||||
|
||||
ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_,
|
||||
const ShapeAnnotation& shape_,
|
||||
const uint8_t maxZoom_)
|
||||
: id(id_),
|
||||
layerID("com.mapbox.annotations.shape." + util::toString(id)),
|
||||
shape(shape_),
|
||||
maxZoom(maxZoom_) {
|
||||
}
|
||||
|
||||
void ShapeAnnotationImpl::updateStyle(Style& style) {
|
||||
if (style.getLayer(layerID))
|
||||
return;
|
||||
|
||||
if (shape.properties.is<LineAnnotationProperties>()) {
|
||||
type = geojsonvt::ProjectedFeatureType::LineString;
|
||||
|
||||
std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>();
|
||||
layer->layout.lineJoin = LineJoinType::Round;
|
||||
|
||||
const LineAnnotationProperties& properties = shape.properties.get<LineAnnotationProperties>();
|
||||
layer->paint.lineOpacity = properties.opacity;
|
||||
layer->paint.lineWidth = properties.width;
|
||||
layer->paint.lineColor = properties.color;
|
||||
|
||||
layer->id = layerID;
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
|
||||
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
|
||||
|
||||
} else if (shape.properties.is<FillAnnotationProperties>()) {
|
||||
type = geojsonvt::ProjectedFeatureType::Polygon;
|
||||
|
||||
std::unique_ptr<FillLayer> layer = std::make_unique<FillLayer>();
|
||||
|
||||
const FillAnnotationProperties& properties = shape.properties.get<FillAnnotationProperties>();
|
||||
layer->paint.fillOpacity = properties.opacity;
|
||||
layer->paint.fillColor = properties.color;
|
||||
layer->paint.fillOutlineColor = properties.outlineColor;
|
||||
|
||||
layer->id = layerID;
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
|
||||
style.addLayer(std::move(layer), AnnotationManager::PointLayerID);
|
||||
|
||||
} else {
|
||||
const StyleLayer* sourceLayer = style.getLayer(shape.properties.get<std::string>());
|
||||
if (!sourceLayer) return;
|
||||
|
||||
std::unique_ptr<StyleLayer> layer = sourceLayer->clone();
|
||||
|
||||
type = layer->is<LineLayer>()
|
||||
? geojsonvt::ProjectedFeatureType::LineString
|
||||
: geojsonvt::ProjectedFeatureType::Polygon;
|
||||
|
||||
layer->id = layerID;
|
||||
layer->ref = "";
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
layer->visibility = VisibilityType::Visible;
|
||||
|
||||
style.addLayer(std::move(layer), sourceLayer->id);
|
||||
}
|
||||
ShapeAnnotationImpl::ShapeAnnotationImpl(const AnnotationID id_, const uint8_t maxZoom_)
|
||||
: id(id_),
|
||||
maxZoom(maxZoom_),
|
||||
layerID("com.mapbox.annotations.shape." + util::toString(id)) {
|
||||
}
|
||||
|
||||
struct ToGeoJSONVT {
|
||||
@@ -166,7 +104,7 @@ void ShapeAnnotationImpl::updateTile(const CanonicalTileID& tileID, AnnotationTi
|
||||
const double tolerance = baseTolerance / (maxAmountOfTiles * util::EXTENT);
|
||||
|
||||
std::vector<geojsonvt::ProjectedFeature> features = {
|
||||
Geometry<double>::visit(shape.geometry, ToGeoJSONVT(tolerance))
|
||||
Geometry<double>::visit(geometry(), ToGeoJSONVT(tolerance))
|
||||
};
|
||||
|
||||
mapbox::geojsonvt::Options options;
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -18,20 +15,17 @@ class CanonicalTileID;
|
||||
|
||||
class ShapeAnnotationImpl {
|
||||
public:
|
||||
using Map = std::map<AnnotationID, std::unique_ptr<ShapeAnnotationImpl>>;
|
||||
ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom);
|
||||
virtual ~ShapeAnnotationImpl() = default;
|
||||
|
||||
ShapeAnnotationImpl(const AnnotationID, const ShapeAnnotation&, const uint8_t maxZoom);
|
||||
virtual void updateStyle(Style&) const = 0;
|
||||
virtual const Geometry<double>& geometry() const = 0;
|
||||
|
||||
void updateStyle(Style&);
|
||||
void updateTile(const CanonicalTileID&, AnnotationTile&);
|
||||
|
||||
const AnnotationID id;
|
||||
const std::string layerID;
|
||||
const ShapeAnnotation shape;
|
||||
|
||||
private:
|
||||
const uint8_t maxZoom;
|
||||
mapbox::geojsonvt::ProjectedFeatureType type;
|
||||
const std::string layerID;
|
||||
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> shapeTiler;
|
||||
};
|
||||
|
||||
|
||||
38
src/mbgl/annotation/style_sourced_annotation_impl.cpp
Normal file
38
src/mbgl/annotation/style_sourced_annotation_impl.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <mbgl/annotation/style_sourced_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace geojsonvt = mapbox::geojsonvt;
|
||||
|
||||
StyleSourcedAnnotationImpl::StyleSourcedAnnotationImpl(const AnnotationID id_, const StyleSourcedAnnotation& annotation_, const uint8_t maxZoom_)
|
||||
: ShapeAnnotationImpl(id_, maxZoom_),
|
||||
annotation(annotation_) {
|
||||
}
|
||||
|
||||
void StyleSourcedAnnotationImpl::updateStyle(Style& style) const {
|
||||
if (style.getLayer(layerID))
|
||||
return;
|
||||
|
||||
const StyleLayer* sourceLayer = style.getLayer(annotation.layerID);
|
||||
if (!sourceLayer)
|
||||
return;
|
||||
|
||||
std::unique_ptr<StyleLayer> layer = sourceLayer->clone();
|
||||
|
||||
layer->id = layerID;
|
||||
layer->ref = "";
|
||||
layer->source = AnnotationManager::SourceID;
|
||||
layer->sourceLayer = layer->id;
|
||||
layer->visibility = VisibilityType::Visible;
|
||||
|
||||
style.addLayer(std::move(layer), sourceLayer->id);
|
||||
}
|
||||
|
||||
const Geometry<double>& StyleSourcedAnnotationImpl::geometry() const {
|
||||
return annotation.geometry;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
19
src/mbgl/annotation/style_sourced_annotation_impl.hpp
Normal file
19
src/mbgl/annotation/style_sourced_annotation_impl.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/shape_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class StyleSourcedAnnotationImpl : public ShapeAnnotationImpl {
|
||||
public:
|
||||
StyleSourcedAnnotationImpl(const AnnotationID, const StyleSourcedAnnotation&, const uint8_t maxZoom);
|
||||
|
||||
void updateStyle(Style&) const final;
|
||||
const Geometry<double>& geometry() const final;
|
||||
|
||||
private:
|
||||
const StyleSourcedAnnotation annotation;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,24 +1,29 @@
|
||||
#include <mbgl/annotation/point_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/symbol_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
#include <mbgl/math/clamp.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
PointAnnotationImpl::PointAnnotationImpl(const AnnotationID id_, const PointAnnotation& point_)
|
||||
SymbolAnnotationImpl::SymbolAnnotationImpl(const AnnotationID id_, const SymbolAnnotation& annotation_)
|
||||
: id(id_),
|
||||
point(point_) {
|
||||
annotation(annotation_) {
|
||||
if (!annotation.geometry.is<Point<double>>()) {
|
||||
throw std::runtime_error("unsupported symbol annotation geometry type");
|
||||
}
|
||||
}
|
||||
|
||||
void PointAnnotationImpl::updateLayer(const CanonicalTileID& tileID, AnnotationTileLayer& layer) const {
|
||||
void SymbolAnnotationImpl::updateLayer(const CanonicalTileID& tileID, AnnotationTileLayer& layer) const {
|
||||
std::unordered_map<std::string, std::string> featureProperties;
|
||||
featureProperties.emplace("sprite", point.icon.empty() ? std::string("default_marker") : point.icon);
|
||||
featureProperties.emplace("sprite", annotation.icon.empty() ? std::string("default_marker") : annotation.icon);
|
||||
|
||||
const Point<double>& p = annotation.geometry.get<Point<double>>();
|
||||
|
||||
// Clamp to the latitude limits of Web Mercator.
|
||||
const double constrainedLatitude = util::clamp(point.position.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX);
|
||||
const double constrainedLatitude = util::clamp(p.y, -util::LATITUDE_MAX, util::LATITUDE_MAX);
|
||||
|
||||
// Project a coordinate into unit space in a square map.
|
||||
const double sine = std::sin(constrainedLatitude * util::DEG2RAD);
|
||||
const double x = point.position.longitude / util::DEGREES_MAX + 0.5;
|
||||
const double x = p.x / util::DEGREES_MAX + 0.5;
|
||||
const double y = 0.5 - 0.25 * std::log((1.0 + sine) / (1.0 - sine)) / M_PI;
|
||||
|
||||
Point<double> projected(x, y);
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <string>
|
||||
@@ -36,31 +35,29 @@ namespace mbgl {
|
||||
class AnnotationTileLayer;
|
||||
class CanonicalTileID;
|
||||
|
||||
class PointAnnotationImpl {
|
||||
class SymbolAnnotationImpl {
|
||||
public:
|
||||
using Map = std::map<AnnotationID, std::shared_ptr<PointAnnotationImpl>>;
|
||||
using Tree = boost::geometry::index::rtree<std::shared_ptr<const PointAnnotationImpl>, boost::geometry::index::rstar<16, 4>>;
|
||||
|
||||
PointAnnotationImpl(const AnnotationID, const PointAnnotation&);
|
||||
SymbolAnnotationImpl(const AnnotationID, const SymbolAnnotation&);
|
||||
|
||||
void updateLayer(const CanonicalTileID&, AnnotationTileLayer&) const;
|
||||
|
||||
const AnnotationID id;
|
||||
const PointAnnotation point;
|
||||
const SymbolAnnotation annotation;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
// Tell Boost Geometry how to access a std::shared_ptr<mbgl::PointAnnotation> object.
|
||||
// Tell Boost Geometry how to access a std::shared_ptr<mbgl::SymbolAnnotation> object.
|
||||
namespace boost {
|
||||
namespace geometry {
|
||||
namespace index {
|
||||
|
||||
template <>
|
||||
struct indexable<std::shared_ptr<const mbgl::PointAnnotationImpl>> {
|
||||
using result_type = const mbgl::LatLng&;
|
||||
inline const mbgl::LatLng& operator()(const std::shared_ptr<const mbgl::PointAnnotationImpl>& v) const {
|
||||
return v->point.position;
|
||||
struct indexable<std::shared_ptr<const mbgl::SymbolAnnotationImpl>> {
|
||||
using result_type = mbgl::LatLng;
|
||||
inline mbgl::LatLng operator()(const std::shared_ptr<const mbgl::SymbolAnnotationImpl>& v) const {
|
||||
const mbgl::Point<double>& p = v->annotation.geometry.get<mbgl::Point<double>>();
|
||||
return mbgl::LatLng(p.y, p.x);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <mbgl/map/view.hpp>
|
||||
#include <mbgl/map/transform.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_observer.hpp>
|
||||
@@ -693,37 +691,19 @@ double Map::getTopOffsetPixelsForAnnotationIcon(const std::string& name) {
|
||||
return impl->annotationManager->getTopOffsetPixelsForIcon(name);
|
||||
}
|
||||
|
||||
AnnotationID Map::addPointAnnotation(const PointAnnotation& annotation) {
|
||||
return addPointAnnotations({ annotation }).front();
|
||||
}
|
||||
|
||||
AnnotationIDs Map::addPointAnnotations(const std::vector<PointAnnotation>& annotations) {
|
||||
auto result = impl->annotationManager->addPointAnnotations(annotations, getMaxZoom());
|
||||
AnnotationID Map::addAnnotation(const Annotation& annotation) {
|
||||
auto result = impl->annotationManager->addAnnotation(annotation, getMaxZoom());
|
||||
update(Update::Annotations);
|
||||
return result;
|
||||
}
|
||||
|
||||
AnnotationID Map::addShapeAnnotation(const ShapeAnnotation& annotation) {
|
||||
return addShapeAnnotations({ annotation }).front();
|
||||
}
|
||||
|
||||
AnnotationIDs Map::addShapeAnnotations(const std::vector<ShapeAnnotation>& annotations) {
|
||||
auto result = impl->annotationManager->addShapeAnnotations(annotations, getMaxZoom());
|
||||
update(Update::Annotations);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Map::updatePointAnnotation(AnnotationID annotationId, const PointAnnotation& annotation) {
|
||||
impl->annotationManager->updatePointAnnotation(annotationId, annotation, getMaxZoom());
|
||||
void Map::updateAnnotation(AnnotationID id, const Annotation& annotation) {
|
||||
impl->annotationManager->updateAnnotation(id, annotation, getMaxZoom());
|
||||
update(Update::Annotations);
|
||||
}
|
||||
|
||||
void Map::removeAnnotation(AnnotationID annotation) {
|
||||
removeAnnotations({ annotation });
|
||||
}
|
||||
|
||||
void Map::removeAnnotations(const AnnotationIDs& annotations) {
|
||||
impl->annotationManager->removeAnnotations(annotations);
|
||||
impl->annotationManager->removeAnnotation(annotation);
|
||||
update(Update::Annotations);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/test/stub_file_source.hpp>
|
||||
|
||||
#include <mbgl/annotation/point_annotation.hpp>
|
||||
#include <mbgl/annotation/shape_annotation.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/platform/default/headless_display.hpp>
|
||||
@@ -29,7 +28,7 @@ void checkRendering(Map& map, const char * name) {
|
||||
|
||||
} // end namespace
|
||||
|
||||
TEST(Annotations, PointAnnotation) {
|
||||
TEST(Annotations, SymbolAnnotation) {
|
||||
util::RunLoop loop;
|
||||
|
||||
auto display = std::make_shared<mbgl::HeadlessDisplay>();
|
||||
@@ -39,7 +38,7 @@ TEST(Annotations, PointAnnotation) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double>(0, 0), "default_marker" });
|
||||
|
||||
checkRendering(map, "point_annotation");
|
||||
}
|
||||
@@ -56,11 +55,11 @@ TEST(Annotations, LineAnnotation) {
|
||||
|
||||
LineString<double> line = {{ { 0, 0 }, { 45, 45 } }};
|
||||
|
||||
LineAnnotationProperties properties;
|
||||
properties.color = {{ 255, 0, 0, 1 }};
|
||||
properties.width = 5;
|
||||
LineAnnotation annotation { line };
|
||||
annotation.color = {{ 255, 0, 0, 1 }};
|
||||
annotation.width = 5;
|
||||
|
||||
map.addShapeAnnotation(ShapeAnnotation(line, properties));
|
||||
map.addAnnotation(annotation);
|
||||
|
||||
checkRendering(map, "line_annotation");
|
||||
}
|
||||
@@ -77,10 +76,10 @@ TEST(Annotations, FillAnnotation) {
|
||||
|
||||
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
|
||||
|
||||
FillAnnotationProperties properties;
|
||||
properties.color = {{ 255, 0, 0, 1 }};
|
||||
FillAnnotation annotation { polygon };
|
||||
annotation.color = {{ 255, 0, 0, 1 }};
|
||||
|
||||
map.addShapeAnnotation(ShapeAnnotation(polygon, properties));
|
||||
map.addAnnotation(annotation);
|
||||
|
||||
checkRendering(map, "fill_annotation");
|
||||
}
|
||||
@@ -97,7 +96,7 @@ TEST(Annotations, StyleSourcedShapeAnnotation) {
|
||||
|
||||
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
|
||||
|
||||
map.addShapeAnnotation(ShapeAnnotation(polygon, "annotation"));
|
||||
map.addAnnotation(StyleSourcedAnnotation { polygon, "annotation" });
|
||||
|
||||
checkRendering(map, "style_sourced_shape_annotation");
|
||||
}
|
||||
@@ -112,11 +111,11 @@ TEST(Annotations, AddMultiple) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
map.addPointAnnotation(PointAnnotation({ 0, -10 }, "default_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
map.addPointAnnotation(PointAnnotation({ 0, 10 }, "default_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double> { 10, 0 }, "default_marker" });
|
||||
|
||||
checkRendering(map, "add_multiple");
|
||||
}
|
||||
@@ -135,10 +134,10 @@ TEST(Annotations, NonImmediateAdd) {
|
||||
|
||||
Polygon<double> polygon = {{ {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }};
|
||||
|
||||
FillAnnotationProperties properties;
|
||||
properties.color = {{ 255, 0, 0, 1 }};
|
||||
FillAnnotation annotation { polygon };
|
||||
annotation.color = {{ 255, 0, 0, 1 }};
|
||||
|
||||
map.addShapeAnnotation(ShapeAnnotation(polygon, properties));
|
||||
map.addAnnotation(annotation);
|
||||
|
||||
checkRendering(map, "non_immediate_add");
|
||||
}
|
||||
@@ -153,7 +152,7 @@ TEST(Annotations, UpdateIcon) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("flipped_marker", namedMarker("default_marker.png"));
|
||||
map.addPointAnnotation(PointAnnotation({ 0, 0 }, "flipped_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "flipped_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
@@ -175,11 +174,11 @@ TEST(Annotations, UpdatePoint) {
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
map.addAnnotationIcon("flipped_marker", namedMarker("flipped_marker.png"));
|
||||
AnnotationID point = map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker"));
|
||||
AnnotationID point = map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
map.updatePointAnnotation(point, PointAnnotation({ 0, -10 }, "flipped_marker"));
|
||||
map.updateAnnotation(point, SymbolAnnotation { Point<double> { -10, 0 }, "flipped_marker" });
|
||||
|
||||
checkRendering(map, "update_point");
|
||||
}
|
||||
@@ -194,7 +193,7 @@ TEST(Annotations, RemovePoint) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
AnnotationID point = map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker"));
|
||||
AnnotationID point = map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
@@ -212,13 +211,13 @@ TEST(Annotations, RemoveShape) {
|
||||
|
||||
LineString<double> line = {{ { 0, 0 }, { 45, 45 } }};
|
||||
|
||||
LineAnnotationProperties properties;
|
||||
properties.color = {{ 255, 0, 0, 1 }};
|
||||
properties.width = 5;
|
||||
LineAnnotation annotation { line };
|
||||
annotation.color = {{ 255, 0, 0, 1 }};
|
||||
annotation.width = 5;
|
||||
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
AnnotationID shape = map.addShapeAnnotation(ShapeAnnotation(line, properties));
|
||||
AnnotationID shape = map.addAnnotation(annotation);
|
||||
|
||||
test::render(map);
|
||||
|
||||
@@ -235,7 +234,7 @@ TEST(Annotations, ImmediateRemoveShape) {
|
||||
StubFileSource fileSource;
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
|
||||
map.removeAnnotation(map.addShapeAnnotation(ShapeAnnotation(LineString<double>(), {})));
|
||||
map.removeAnnotation(map.addAnnotation(LineAnnotation { LineString<double>() }));
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
|
||||
test::render(map);
|
||||
@@ -251,7 +250,7 @@ TEST(Annotations, SwitchStyle) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
map.addPointAnnotation(PointAnnotation({ 0, 0 }, "default_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
@@ -270,12 +269,11 @@ TEST(Annotations, QueryRenderedFeatures) {
|
||||
Map map(view, fileSource, MapMode::Still);
|
||||
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"), "");
|
||||
map.addAnnotationIcon("default_marker", namedMarker("default_marker.png"));
|
||||
const LatLng latLng(0, 0);
|
||||
map.addPointAnnotation(PointAnnotation(latLng, "default_marker"));
|
||||
map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" });
|
||||
|
||||
test::render(map);
|
||||
|
||||
auto point = map.pixelForLatLng(latLng);
|
||||
auto point = map.pixelForLatLng({ 0, 0 });
|
||||
auto features = map.queryRenderedFeatures(point);
|
||||
EXPECT_EQ(features.size(), 1);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <mbgl/layer/line_layer.hpp>
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
class SourceTest {
|
||||
|
||||
Reference in New Issue
Block a user