[Qt] Added QMapbox::Feature

This commit is contained in:
Bruno de Oliveira Abinader
2017-02-07 15:48:05 +02:00
parent 59d279b689
commit 7db79da501
4 changed files with 147 additions and 9 deletions

View File

@@ -220,7 +220,7 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
QMapbox::Coordinate topLeft = m_map->coordinateForPixel({ 0, 0 });
QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
QMapbox::CoordinatesCollections geometry { { { topLeft, bottomRight } } };
QMapbox::LineAnnotation line { { QMapbox::ShapeAnnotationGeometry::Type::LineStringType, geometry }, 0.5f, 1.0f, Qt::red };
QMapbox::LineAnnotation line { { QMapbox::ShapeAnnotationGeometry::LineStringType, geometry }, 0.5f, 1.0f, Qt::red };
m_lineAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::LineAnnotation>(line));
} else {
m_map->removeAnnotation(m_lineAnnotationId.toUInt());
@@ -235,7 +235,7 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
QMapbox::Coordinate bottomLeft = m_map->coordinateForPixel({ qreal(size().width()), 0 });
QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
QMapbox::CoordinatesCollections geometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } };
QMapbox::FillAnnotation fill { { QMapbox::ShapeAnnotationGeometry::Type::PolygonType, geometry }, 0.5f, Qt::green, QVariant::fromValue<QColor>(QColor(Qt::black)) };
QMapbox::FillAnnotation fill { { QMapbox::ShapeAnnotationGeometry::PolygonType, geometry }, 0.5f, Qt::green, QVariant::fromValue<QColor>(QColor(Qt::black)) };
m_fillAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::FillAnnotation>(fill));
} else {
m_map->removeAnnotation(m_fillAnnotationId.toUInt());
@@ -250,7 +250,7 @@ void MapWindow::keyPressEvent(QKeyEvent *ev)
QMapbox::Coordinate bottomLeft = m_map->coordinateForPixel({ qreal(size().width()), 0 });
QMapbox::Coordinate bottomRight = m_map->coordinateForPixel({ qreal(size().width()), qreal(size().height()) });
QMapbox::CoordinatesCollections geometry { { { bottomLeft, bottomRight, topRight, topLeft, bottomLeft } } };
QMapbox::StyleSourcedAnnotation styleSourced { { QMapbox::ShapeAnnotationGeometry::Type::PolygonType, geometry }, "water" };
QMapbox::StyleSourcedAnnotation styleSourced { { QMapbox::ShapeAnnotationGeometry::PolygonType, geometry }, "water" };
m_styleSourcedAnnotationId = m_map->addAnnotation(QVariant::fromValue<QMapbox::StyleSourcedAnnotation>(styleSourced));
} else {
m_map->removeAnnotation(m_styleSourcedAnnotationId.toUInt());

View File

@@ -11,19 +11,32 @@
namespace QMapbox {
// Reflects mapbox::geometry::point<double>.
// Reflects mbgl::Point<double>.
typedef QPair<double, double> Coordinate;
typedef QPair<Coordinate, double> CoordinateZoom;
// Reflects mapbox::geometry::line_string<double> and mapbox::geometry::linear_ring<double>.
// Reflects mbgl::{LineString,LinearRing,MultiPoint}<double>.
typedef QList<Coordinate> Coordinates;
// Reflects mapbox::geometry::multi_line_string<double> and mapbox::geometry::polygon<double>.
// Reflects mbgl::{MultiLineString,Polygon}<double>.
typedef QList<Coordinates> CoordinatesCollection;
// Reflects mapbox::geometry::multi_polygon<double>.
// Reflects mbgl::MultiPolygon<double>.
typedef QList<CoordinatesCollection> CoordinatesCollections;
// Reflects mbgl::Feature.
struct Q_DECL_EXPORT Feature {
enum Type {
PointType = 1,
LineStringType,
PolygonType
};
Type type;
CoordinatesCollections geometry;
QVariantMap properties;
QVariant id;
};
// Reflects mbgl::ShapeAnnotationGeometry.
struct Q_DECL_EXPORT ShapeAnnotationGeometry {
enum Type {
@@ -105,6 +118,7 @@ Q_DECLARE_METATYPE(QMapbox::Coordinate);
Q_DECLARE_METATYPE(QMapbox::Coordinates);
Q_DECLARE_METATYPE(QMapbox::CoordinatesCollection);
Q_DECLARE_METATYPE(QMapbox::CoordinatesCollections);
Q_DECLARE_METATYPE(QMapbox::Feature);
Q_DECLARE_METATYPE(QMapbox::SymbolAnnotation);
Q_DECLARE_METATYPE(QMapbox::ShapeAnnotationGeometry);

View File

@@ -4,6 +4,7 @@
#include <mbgl/map/change.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/default_styles.hpp>
#include <mbgl/util/geometry.hpp>
#include <mbgl/util/traits.hpp>
#if QT_VERSION >= 0x050000
@@ -16,6 +17,11 @@
static_assert(mbgl::underlying_type(QMapbox::Online) == mbgl::underlying_type(mbgl::NetworkStatus::Status::Online), "error");
static_assert(mbgl::underlying_type(QMapbox::Offline) == mbgl::underlying_type(mbgl::NetworkStatus::Status::Offline), "error");
// mbgl::FeatureType
static_assert(mbgl::underlying_type(QMapbox::Feature::PointType) == mbgl::underlying_type(mbgl::FeatureType::Point), "error");
static_assert(mbgl::underlying_type(QMapbox::Feature::LineStringType) == mbgl::underlying_type(mbgl::FeatureType::LineString), "error");
static_assert(mbgl::underlying_type(QMapbox::Feature::PolygonType) == mbgl::underlying_type(mbgl::FeatureType::Polygon), "error");
namespace QMapbox {
Q_DECL_EXPORT NetworkMode networkMode()

View File

@@ -7,6 +7,7 @@
#include <QMapbox>
#include <QByteArray>
#include <QDebug>
#include <QVariant>
#include <sstream>
@@ -14,11 +15,24 @@
namespace QMapbox {
mbgl::Point<double> asMapboxGLPoint(const QMapbox::Coordinate &coordinate) {
return mbgl::Point<double> { coordinate.second, coordinate.first };
}
mbgl::MultiPoint<double> asMapboxGLMultiPoint(const QMapbox::Coordinates &multiPoint) {
mbgl::MultiPoint<double> mbglMultiPoint;
mbglMultiPoint.reserve(multiPoint.size());
for (const auto &point: multiPoint) {
mbglMultiPoint.emplace_back(asMapboxGLPoint(point));
}
return mbglMultiPoint;
};
mbgl::LineString<double> asMapboxGLLineString(const QMapbox::Coordinates &lineString) {
mbgl::LineString<double> mbglLineString;
mbglLineString.reserve(lineString.size());
for (const auto &coordinate : lineString) {
mbglLineString.emplace_back(mbgl::Point<double> { coordinate.second, coordinate.first });
mbglLineString.emplace_back(asMapboxGLPoint(coordinate));
}
return mbglLineString;
};
@@ -39,7 +53,7 @@ mbgl::Polygon<double> asMapboxGLPolygon(const QMapbox::CoordinatesCollection &po
mbgl::LinearRing<double> mbglLinearRing;
mbglLinearRing.reserve(linearRing.size());
for (const auto &coordinate: linearRing) {
mbglLinearRing.emplace_back(mbgl::Point<double> { coordinate.second, coordinate.first });
mbglLinearRing.emplace_back(asMapboxGLPoint(coordinate));
}
mbglPolygon.emplace_back(std::move(mbglLinearRing));
}
@@ -55,6 +69,110 @@ mbgl::MultiPolygon<double> asMapboxGLMultiPolygon(const QMapbox::CoordinatesColl
return mbglMultiPolygon;
};
mbgl::Value asMapboxGLPropertyValue(const QVariant &value) {
auto valueList = [](const QVariantList &list) {
std::vector<mbgl::Value> mbglList;
mbglList.reserve(list.size());
for (const auto& listValue : list) {
mbglList.emplace_back(asMapboxGLPropertyValue(listValue));
}
return mbglList;
};
auto valueMap = [](const QVariantMap &map) {
std::unordered_map<std::string, mbgl::Value> mbglMap;
mbglMap.reserve(map.size());
auto it = map.constBegin();
while (it != map.constEnd()) {
mbglMap.emplace(std::make_pair(it.key().toStdString(), asMapboxGLPropertyValue(it.value())));
++it;
}
return mbglMap;
};
switch (value.type()) {
#if QT_VERSION >= 0x050000
case QMetaType::UnknownType:
#else
case QVariant::Invalid:
#endif
return mbgl::NullValue {};
case QMetaType::Bool:
return { value.toBool() };
case QMetaType::ULongLong:
return { uint64_t(value.toULongLong()) };
case QMetaType::LongLong:
return { int64_t(value.toLongLong()) };
case QMetaType::Double:
return { value.toDouble() };
case QMetaType::QString:
return { value.toString().toStdString() };
case QMetaType::QVariantList:
return valueList(value.toList());
case QMetaType::QVariantMap:
return valueMap(value.toMap());
default:
qWarning() << "Unsupported feature property value:" << value;
return {};
}
}
mbgl::FeatureIdentifier asMapboxGLFeatureIdentifier(const QVariant &id) {
switch (id.type()) {
#if QT_VERSION >= 0x050000
case QMetaType::UnknownType:
#else
case QVariant::Invalid:
#endif
return {};
case QMetaType::ULongLong:
return { uint64_t(id.toULongLong()) };
case QMetaType::LongLong:
return { int64_t(id.toLongLong()) };
case QMetaType::Double:
return { id.toDouble() };
case QMetaType::QString:
return { id.toString().toStdString() };
default:
qWarning() << "Unsupported feature identifier:" << id;
return {};
}
}
mbgl::Feature asMapboxGLFeature(const QMapbox::Feature &feature) {
mbgl::PropertyMap properties;
properties.reserve(feature.properties.size());
auto it = feature.properties.constBegin();
while (it != feature.properties.constEnd()) {
properties.emplace(std::make_pair(it.key().toStdString(), asMapboxGLPropertyValue(it.value())));
}
mbgl::FeatureIdentifier id = asMapboxGLFeatureIdentifier(feature.id);
if (feature.type == QMapbox::Feature::PointType) {
const QMapbox::Coordinates &points = feature.geometry.first().first();
if (points.size() == 1) {
return { asMapboxGLPoint(points.first()), std::move(properties), std::move(id) };
} else {
return { asMapboxGLMultiPoint(points), std::move(properties), std::move(id) };
}
} else if (feature.type == QMapbox::Feature::LineStringType) {
const QMapbox::CoordinatesCollection &lineStrings = feature.geometry.first();
if (lineStrings.size() == 1) {
return { asMapboxGLLineString(lineStrings.first()), std::move(properties), std::move(id) };
} else {
return { asMapboxGLMultiLineString(lineStrings), std::move(properties), std::move(id) };
}
} else { // PolygonType
const QMapbox::CoordinatesCollections &polygons = feature.geometry;
if (polygons.size() == 1) {
return { asMapboxGLPolygon(polygons.first()), std::move(properties), std::move(id) };
} else {
return { asMapboxGLMultiPolygon(polygons), std::move(properties), std::move(id) };
}
}
};
} // namespace QMapbox
namespace mbgl {