Almost there, need to make changes in geojson-support first
This commit is contained in:
parent
f25be89952
commit
9067a7da19
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumVectorData/VectorNode.h"
|
||||
|
||||
#include <CesiumVectorData/GeoJsonDocument.h>
|
||||
#include <CesiumVectorData/GeoJsonObject.h>
|
||||
#include <CesiumAsync/AsyncSystem.h>
|
||||
#include <CesiumGeospatial/CartographicPolygon.h>
|
||||
#include <CesiumGeospatial/Ellipsoid.h>
|
||||
|
|
@ -11,7 +11,6 @@
|
|||
#include <CesiumRasterOverlays/RasterOverlayTileProvider.h>
|
||||
#include <CesiumUtility/IntrusivePointer.h>
|
||||
#include <CesiumVectorData/Color.h>
|
||||
#include <CesiumVectorData/VectorDocument.h>
|
||||
#include <CesiumVectorData/VectorStyle.h>
|
||||
|
||||
#include <spdlog/fwd.h>
|
||||
|
|
@ -28,8 +27,8 @@ namespace CesiumRasterOverlays {
|
|||
*/
|
||||
using VectorDocumentRasterOverlayStyleCallback = std::function<std::optional<
|
||||
CesiumVectorData::VectorStyle>(
|
||||
const CesiumUtility::IntrusivePointer<CesiumVectorData::VectorDocument>&,
|
||||
const CesiumVectorData::VectorNode*)>;
|
||||
const CesiumUtility::IntrusivePointer<CesiumVectorData::GeoJsonDocument>&,
|
||||
const CesiumVectorData::GeoJsonObject*)>;
|
||||
|
||||
/**
|
||||
* @brief A set of options for configuring a VectorDocumentRasterOverlay.
|
||||
|
|
@ -79,7 +78,7 @@ struct IonVectorDocumentRasterOverlaySource {
|
|||
* @brief Possible sources for a VectorDocumentRasterOverlay's vector data.
|
||||
*/
|
||||
using VectorDocumentRasterOverlaySource = std::variant<
|
||||
CesiumUtility::IntrusivePointer<CesiumVectorData::VectorDocument>,
|
||||
CesiumUtility::IntrusivePointer<CesiumVectorData::GeoJsonDocument>,
|
||||
IonVectorDocumentRasterOverlaySource>;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
#include <CesiumAsync/IAssetAccessor.h>
|
||||
#include <CesiumGeospatial/BoundingRegionBuilder.h>
|
||||
#include <CesiumGeospatial/Cartographic.h>
|
||||
#include <CesiumGeospatial/CompositeCartographicPolygon.h>
|
||||
#include <CesiumGeospatial/GeographicProjection.h>
|
||||
#include <CesiumGeospatial/GlobeRectangle.h>
|
||||
#include <CesiumGeospatial/Projection.h>
|
||||
|
|
@ -18,8 +17,8 @@
|
|||
#include <CesiumUtility/CreditSystem.h>
|
||||
#include <CesiumUtility/IntrusivePointer.h>
|
||||
#include <CesiumVectorData/Color.h>
|
||||
#include <CesiumVectorData/VectorDocument.h>
|
||||
#include <CesiumVectorData/VectorNode.h>
|
||||
#include <CesiumVectorData/GeoJsonDocument.h>
|
||||
#include <CesiumVectorData/GeoJsonObject.h>
|
||||
#include <CesiumVectorData/VectorRasterizer.h>
|
||||
|
||||
#include <glm/common.hpp>
|
||||
|
|
@ -46,8 +45,7 @@ namespace CesiumRasterOverlays {
|
|||
|
||||
namespace {
|
||||
struct QuadtreePrimitiveData {
|
||||
const VectorPrimitive* pPrimitive;
|
||||
const VectorNode* pNode;
|
||||
const GeoJsonObject* pObject;
|
||||
const VectorStyle* pStyle;
|
||||
GlobeRectangle rectangle;
|
||||
};
|
||||
|
|
@ -72,55 +70,129 @@ struct Quadtree {
|
|||
std::vector<uint32_t> dataNodeIndicesBegin;
|
||||
};
|
||||
|
||||
struct GlobeRectangleFromPrimitiveVisitor {
|
||||
GlobeRectangle
|
||||
operator()(const CesiumGeospatial::Cartographic& cartographic) {
|
||||
return GlobeRectangle(
|
||||
cartographic.longitude,
|
||||
cartographic.latitude,
|
||||
cartographic.longitude,
|
||||
cartographic.latitude);
|
||||
struct GlobeRectangleFromObjectVisitor {
|
||||
BoundingRegionBuilder& builder;
|
||||
void operator()(GeoJsonPoint& point) {
|
||||
builder.expandToIncludePosition(point.coordinates);
|
||||
}
|
||||
|
||||
GlobeRectangle
|
||||
operator()(const std::vector<CesiumGeospatial::Cartographic>& points) {
|
||||
BoundingRegionBuilder builder;
|
||||
for (const Cartographic& point : points) {
|
||||
void operator()(GeoJsonMultiPoint& points) {
|
||||
for (const Cartographic& point : points.coordinates) {
|
||||
builder.expandToIncludePosition(point);
|
||||
}
|
||||
return builder.toGlobeRectangle();
|
||||
}
|
||||
void operator()(GeoJsonLineString& line) {
|
||||
for (const Cartographic& point : line.coordinates) {
|
||||
builder.expandToIncludePosition(point);
|
||||
}
|
||||
}
|
||||
void operator()(GeoJsonMultiLineString& lines) {
|
||||
for (const std::vector<Cartographic>& line : lines.coordinates) {
|
||||
for (const Cartographic& point : line) {
|
||||
builder.expandToIncludePosition(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
void operator()(GeoJsonPolygon& polygon) {
|
||||
for (const std::vector<Cartographic>& ring : polygon.coordinates) {
|
||||
for (const Cartographic& point : ring) {
|
||||
builder.expandToIncludePosition(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
void operator()(GeoJsonMultiPolygon& polygons) {
|
||||
for (const std::vector<std::vector<Cartographic>>& polygon :
|
||||
polygons.coordinates) {
|
||||
for (const std::vector<Cartographic>& ring : polygon) {
|
||||
for (const Cartographic& point : ring) {
|
||||
builder.expandToIncludePosition(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void operator()(auto& /*catchAll*/) {}
|
||||
};
|
||||
|
||||
GlobeRectangle
|
||||
operator()(const CesiumGeospatial::CompositeCartographicPolygon& polygon) {
|
||||
return polygon.getBoundingRectangle();
|
||||
struct GeoJsonObjectStyleVisitor {
|
||||
const std::optional<VectorStyle>& operator()(const auto& object) {
|
||||
return object.style;
|
||||
}
|
||||
};
|
||||
|
||||
void addPrimitivesToData(
|
||||
const VectorNode& vectorNode,
|
||||
const GeoJsonObject& geoJsonObject,
|
||||
std::vector<QuadtreePrimitiveData>& data,
|
||||
BoundingRegionBuilder& documentRegionBuilder,
|
||||
const VectorStyle& style);
|
||||
|
||||
struct GeoJsonChildVisitor {
|
||||
std::vector<QuadtreePrimitiveData>& data;
|
||||
BoundingRegionBuilder& documentRegionBuilder;
|
||||
const VectorStyle& style;
|
||||
|
||||
void operator()(const GeoJsonFeature& feature) {
|
||||
if (feature.geometry) {
|
||||
const std::optional<VectorStyle>& geometryStyle =
|
||||
std::visit(GeoJsonObjectStyleVisitor{}, *feature.geometry);
|
||||
const std::optional<VectorStyle>& featureStyle =
|
||||
geometryStyle ? geometryStyle : feature.style;
|
||||
addPrimitivesToData(
|
||||
geoJsonGeometryObjectToObject(*feature.geometry),
|
||||
data,
|
||||
documentRegionBuilder,
|
||||
featureStyle ? *featureStyle : style);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const GeoJsonFeatureCollection& collection) {
|
||||
for (const GeoJsonFeature& feature : collection.features) {
|
||||
if (feature.geometry) {
|
||||
const std::optional<VectorStyle>& geometryStyle =
|
||||
std::visit(GeoJsonObjectStyleVisitor{}, *feature.geometry);
|
||||
const std::optional<VectorStyle>& featureStyle =
|
||||
geometryStyle ? geometryStyle : feature.style;
|
||||
const std::optional<VectorStyle>& collectionStyle =
|
||||
featureStyle ? featureStyle : collection.style;
|
||||
addPrimitivesToData(
|
||||
geoJsonGeometryObjectToObject(*feature.geometry),
|
||||
data,
|
||||
documentRegionBuilder,
|
||||
collectionStyle ? *collectionStyle : style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const GeoJsonGeometryCollection& collection) {
|
||||
for (const GeoJsonGeometryObject& geometry : collection.geometries) {
|
||||
const std::optional<VectorStyle>& childStyle =
|
||||
std::visit(GeoJsonObjectStyleVisitor{}, geometry);
|
||||
const std::optional<VectorStyle>& useStyle =
|
||||
childStyle ? childStyle : collection.style;
|
||||
addPrimitivesToData(
|
||||
geoJsonGeometryObjectToObject(geometry),
|
||||
data,
|
||||
documentRegionBuilder,
|
||||
useStyle ? *useStyle : style);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const auto& /*catchAll*/) {}
|
||||
};
|
||||
|
||||
void addPrimitivesToData(
|
||||
const GeoJsonObject& geoJsonObject,
|
||||
std::vector<QuadtreePrimitiveData>& data,
|
||||
BoundingRegionBuilder& documentRegionBuilder,
|
||||
const VectorStyle& style) {
|
||||
for (const VectorPrimitive& primitive : vectorNode.primitives) {
|
||||
GlobeRectangle rect =
|
||||
std::visit(GlobeRectangleFromPrimitiveVisitor{}, primitive);
|
||||
documentRegionBuilder.expandToIncludePosition(rect.getSouthwest());
|
||||
documentRegionBuilder.expandToIncludePosition(rect.getNortheast());
|
||||
data.emplace_back(QuadtreePrimitiveData{
|
||||
&primitive,
|
||||
&vectorNode,
|
||||
&style,
|
||||
std::move(rect)});
|
||||
}
|
||||
BoundingRegionBuilder thisBuilder;
|
||||
std::visit(GlobeRectangleFromObjectVisitor{thisBuilder}, geoJsonObject);
|
||||
GlobeRectangle rect = thisBuilder.toGlobeRectangle();
|
||||
data.emplace_back(&geoJsonObject, &style, std::move(rect));
|
||||
documentRegionBuilder.expandToIncludePosition(rect.getSouthwest());
|
||||
documentRegionBuilder.expandToIncludePosition(rect.getNortheast());
|
||||
|
||||
for (const VectorNode& child : vectorNode.children) {
|
||||
addPrimitivesToData(
|
||||
child,
|
||||
data,
|
||||
documentRegionBuilder,
|
||||
child.style ? *child.style : style);
|
||||
}
|
||||
std::visit(
|
||||
GeoJsonChildVisitor{data, documentRegionBuilder, style},
|
||||
geoJsonObject);
|
||||
}
|
||||
|
||||
const uint32_t DEPTH_LIMIT = 8;
|
||||
|
|
@ -229,11 +301,17 @@ uint32_t buildQuadtreeNode(
|
|||
}
|
||||
|
||||
Quadtree buildQuadtree(
|
||||
const IntrusivePointer<VectorDocument>& document,
|
||||
const IntrusivePointer<GeoJsonDocument>& document,
|
||||
const VectorStyle& defaultStyle) {
|
||||
BoundingRegionBuilder builder;
|
||||
std::vector<QuadtreePrimitiveData> data;
|
||||
addPrimitivesToData(document->getRootNode(), data, builder, defaultStyle);
|
||||
const std::optional<VectorStyle>& rootObjectStyle =
|
||||
std::visit(GeoJsonObjectStyleVisitor{}, document->getRootObject());
|
||||
addPrimitivesToData(
|
||||
document->getRootObject(),
|
||||
data,
|
||||
builder,
|
||||
rootObjectStyle ? *rootObjectStyle : defaultStyle);
|
||||
|
||||
Quadtree tree{
|
||||
builder.toGlobeRectangle(),
|
||||
|
|
@ -282,7 +360,7 @@ void rasterizeQuadtreeNode(
|
|||
}
|
||||
primitivesRendered[dataIdx] = true;
|
||||
const QuadtreePrimitiveData& data = tree.data[dataIdx];
|
||||
rasterizer.drawPrimitive(*data.pPrimitive, *data.pStyle);
|
||||
rasterizer.drawGeoJsonObject(*data.pObject, *data.pStyle);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
|
|
@ -332,7 +410,7 @@ class CESIUMRASTEROVERLAYS_API VectorDocumentRasterOverlayTileProvider final
|
|||
: public RasterOverlayTileProvider {
|
||||
|
||||
private:
|
||||
IntrusivePointer<VectorDocument> _document;
|
||||
IntrusivePointer<GeoJsonDocument> _document;
|
||||
VectorStyle _defaultStyle;
|
||||
Quadtree _tree;
|
||||
Ellipsoid _ellipsoid;
|
||||
|
|
@ -348,7 +426,7 @@ public:
|
|||
pPrepareRendererResources,
|
||||
const std::shared_ptr<spdlog::logger>& pLogger,
|
||||
const VectorDocumentRasterOverlayOptions& options,
|
||||
const CesiumUtility::IntrusivePointer<CesiumVectorData::VectorDocument>&
|
||||
const CesiumUtility::IntrusivePointer<CesiumVectorData::GeoJsonDocument>&
|
||||
document)
|
||||
: RasterOverlayTileProvider(
|
||||
pOwner,
|
||||
|
|
@ -457,13 +535,35 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
this->recomputeStyles(this->_document->getRootNode());
|
||||
this->recomputeStyles(this->_document->getRootObject());
|
||||
}
|
||||
|
||||
private:
|
||||
void recomputeStyles(VectorNode& node) {
|
||||
node.style = (*this->_styleCallback)(this->_document, &node);
|
||||
for (VectorNode& child : node.children) {
|
||||
void recomputeStyles(GeoJsonObject& object) {
|
||||
struct SetStyleVisitor {
|
||||
const std::optional<VectorStyle>& style;
|
||||
void operator()(GeoJsonPoint& o) { o.style = style; }
|
||||
void operator()(GeoJsonMultiPoint& o) { o.style = style; }
|
||||
void operator()(GeoJsonLineString& o) { o.style = style; }
|
||||
void operator()(GeoJsonMultiLineString& o) { o.style = style; }
|
||||
void operator()(GeoJsonPolygon& o) { o.style = style; }
|
||||
void operator()(GeoJsonMultiPolygon& o) { o.style = style; }
|
||||
void operator()(GeoJsonFeature& o) { o.style = style; }
|
||||
void operator()(GeoJsonFeatureCollection& o) { o.style = style; }
|
||||
void operator()(GeoJsonGeometryCollection& o) { o.style = style; }
|
||||
};
|
||||
const std::optional<VectorStyle>& style = (*this->_styleCallback)(this->_document, &object);
|
||||
std::visit(SetStyleVisitor{style}, object);
|
||||
|
||||
struct RecomputeChildStylesVisitor {
|
||||
VectorDocumentRasterOverlayTileProvider* pThis;
|
||||
void operator()(GeoJsonFeature& f) {
|
||||
if(f.geometry) {
|
||||
pThis->recomputeStyles();
|
||||
}
|
||||
}
|
||||
};
|
||||
for (GeoJsonObject& child : node.children) {
|
||||
this->recomputeStyles(child);
|
||||
}
|
||||
}
|
||||
|
|
@ -495,15 +595,15 @@ VectorDocumentRasterOverlay::createTileProvider(
|
|||
struct DocumentSourceVisitor {
|
||||
CesiumAsync::AsyncSystem asyncSystem;
|
||||
std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor;
|
||||
CesiumAsync::Future<Result<IntrusivePointer<VectorDocument>>>
|
||||
operator()(const IntrusivePointer<VectorDocument>& document) {
|
||||
CesiumAsync::Future<Result<IntrusivePointer<GeoJsonDocument>>>
|
||||
operator()(const IntrusivePointer<GeoJsonDocument>& document) {
|
||||
return asyncSystem
|
||||
.createResolvedFuture<Result<IntrusivePointer<VectorDocument>>>(
|
||||
.createResolvedFuture<Result<IntrusivePointer<GeoJsonDocument>>>(
|
||||
Result(document));
|
||||
}
|
||||
CesiumAsync::Future<Result<IntrusivePointer<VectorDocument>>>
|
||||
CesiumAsync::Future<Result<IntrusivePointer<GeoJsonDocument>>>
|
||||
operator()(const IonVectorDocumentRasterOverlaySource& ion) {
|
||||
return VectorDocument::fromCesiumIonAsset(
|
||||
return GeoJsonDocument::fromCesiumIonAsset(
|
||||
asyncSystem,
|
||||
pAssetAccessor,
|
||||
ion.ionAssetID,
|
||||
|
|
@ -522,7 +622,7 @@ VectorDocumentRasterOverlay::createTileProvider(
|
|||
pPrepareRendererResources,
|
||||
pLogger,
|
||||
options = this->_options](
|
||||
Result<IntrusivePointer<VectorDocument>>&& result)
|
||||
Result<IntrusivePointer<GeoJsonDocument>>&& result)
|
||||
-> CreateTileProviderResult {
|
||||
if (!result.pValue) {
|
||||
return nonstd::make_unexpected(RasterOverlayLoadFailureDetails{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumVectorData/VectorStyle.h"
|
||||
#include <CesiumGeospatial/BoundingRegion.h>
|
||||
#include <CesiumUtility/JsonValue.h>
|
||||
#include <CesiumVectorData/Library.h>
|
||||
|
|
@ -59,6 +60,11 @@ struct GeoJsonPoint {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -89,6 +95,11 @@ struct GeoJsonMultiPoint {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -120,6 +131,11 @@ struct GeoJsonLineString {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -152,6 +168,11 @@ struct GeoJsonMultiLineString {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -191,6 +212,11 @@ struct GeoJsonPolygon {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -224,6 +250,11 @@ struct GeoJsonMultiPolygon {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
struct GeoJsonGeometryCollection;
|
||||
|
|
@ -270,6 +301,11 @@ struct GeoJsonGeometryCollection {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -312,6 +348,11 @@ struct GeoJsonFeature {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -343,6 +384,11 @@ struct GeoJsonFeatureCollection {
|
|||
*/
|
||||
CesiumUtility::JsonValue::Object foreignMembers =
|
||||
CesiumUtility::JsonValue::Object();
|
||||
|
||||
/**
|
||||
* @brief The style for this specific GeoJSON object, if any.
|
||||
*/
|
||||
std::optional<VectorStyle> style = std::nullopt;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "CesiumGeospatial/Cartographic.h"
|
||||
#include "Color.h"
|
||||
#include "VectorStyle.h"
|
||||
|
||||
|
|
@ -9,6 +10,7 @@
|
|||
#include <CesiumGeospatial/GlobeRectangle.h>
|
||||
#include <CesiumGltf/ImageAsset.h>
|
||||
#include <CesiumUtility/IntrusivePointer.h>
|
||||
#include <CesiumUtility/ReferenceCounted.h>
|
||||
#include <CesiumVectorData/GeoJsonObject.h>
|
||||
|
||||
#include <blend2d.h>
|
||||
|
|
@ -45,13 +47,15 @@ public:
|
|||
CesiumGeospatial::Ellipsoid::WGS84);
|
||||
|
||||
/**
|
||||
* @brief Draws a \ref CesiumGeospatial::CartographicPolygon to the canvas.
|
||||
* @brief Draws a \ref GeoJsonPolygon to the canvas.
|
||||
*
|
||||
* @param polygon The polygon to draw.
|
||||
* @param polygon The polygon to draw. It is assumed to have right-hand
|
||||
* winding order (exterior rings are counterclockwise, holes are clockwise) as
|
||||
* is the case in GeoJSON.
|
||||
* @param style The \ref VectorStyle to use when drawing the polygon.
|
||||
*/
|
||||
void drawPolygon(
|
||||
const CesiumGeospatial::CartographicPolygon& polygon,
|
||||
const std::vector<std::vector<CesiumGeospatial::Cartographic>>& polygon,
|
||||
const VectorStyle& style);
|
||||
|
||||
/**
|
||||
|
|
@ -65,16 +69,17 @@ public:
|
|||
const VectorStyle& style);
|
||||
|
||||
/**
|
||||
* @brief Rasterizes the provided `VectorPrimitive` to the canvas.
|
||||
* @brief Rasterizes the provided `GeoJsonObject` to the canvas.
|
||||
*
|
||||
* Polygons are equivalent to calls to `drawPolygon`. Polylines are equivalent
|
||||
* to calls to `drawPolyline`. Points are currently not drawn.
|
||||
*
|
||||
* @param primitive The primitive to draw.
|
||||
* @param style The \ref VectorStyle to use when drawing the primitive.
|
||||
* @param geoJsonObject The GeoJSON object to draw.
|
||||
* @param style The \ref VectorStyle to use when drawing the object.
|
||||
*/
|
||||
void
|
||||
drawGeoJsonObject(const GeoJsonObject& primitive, const VectorStyle& style);
|
||||
void drawGeoJsonObject(
|
||||
const GeoJsonObject& geoJsonObject,
|
||||
const VectorStyle& style);
|
||||
|
||||
/**
|
||||
* @brief Fills the entire canvas with the given color.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include "CesiumVectorData/GeoJsonObject.h"
|
||||
|
||||
#include <CesiumGeospatial/Cartographic.h>
|
||||
#include <CesiumGeospatial/CartographicPolygon.h>
|
||||
#include <CesiumGeospatial/CompositeCartographicPolygon.h>
|
||||
|
|
@ -99,49 +101,24 @@ VectorRasterizer::VectorRasterizer(
|
|||
}
|
||||
|
||||
void VectorRasterizer::drawPolygon(
|
||||
const CartographicPolygon& polygon,
|
||||
const VectorStyle& style) {
|
||||
if (_finalized) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<BLPoint> vertices;
|
||||
vertices.reserve(polygon.getVertices().size());
|
||||
|
||||
for (const glm::dvec2& vertex : polygon.getVertices()) {
|
||||
vertices.emplace_back(
|
||||
radiansToPoint(vertex.x, vertex.y, this->_bounds, this->_context));
|
||||
}
|
||||
|
||||
if (style.polygon.fill) {
|
||||
this->_context.fillPolygon(
|
||||
vertices.data(),
|
||||
vertices.size(),
|
||||
BLRgba32(style.polygon.getColor().toRgba32()));
|
||||
}
|
||||
|
||||
if (style.polygon.outline) {
|
||||
setStrokeWidth(this->_context, style.line, this->_ellipsoid, this->_bounds);
|
||||
this->_context.strokePolygon(
|
||||
vertices.data(),
|
||||
vertices.size(),
|
||||
BLRgba32(style.line.getColor().toRgba32()));
|
||||
}
|
||||
}
|
||||
|
||||
void VectorRasterizer::drawPolygon(
|
||||
const CompositeCartographicPolygon& polygon,
|
||||
const std::vector<std::vector<CesiumGeospatial::Cartographic>>& polygon,
|
||||
const VectorStyle& style) {
|
||||
if (_finalized || (!style.polygon.fill && !style.polygon.outline)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<BLPoint> vertices;
|
||||
vertices.reserve(polygon.getWoundVertices().size());
|
||||
vertices.reserve(polygon.size());
|
||||
|
||||
for (const glm::dvec2& vertex : polygon.getWoundVertices()) {
|
||||
vertices.emplace_back(
|
||||
radiansToPoint(vertex.x, vertex.y, this->_bounds, this->_context));
|
||||
for (const std::vector<Cartographic>& ring : polygon) {
|
||||
// GeoJSON polygons have the reverse winding order from blend2D
|
||||
for (auto it = ring.rbegin(); it != ring.rend(); ++it) {
|
||||
vertices.emplace_back(radiansToPoint(
|
||||
it->longitude,
|
||||
it->latitude,
|
||||
this->_bounds,
|
||||
this->_context));
|
||||
}
|
||||
}
|
||||
|
||||
if (style.polygon.fill) {
|
||||
|
|
@ -198,22 +175,36 @@ void VectorRasterizer::drawPolyline(
|
|||
BLRgba32(style.line.getColor().toRgba32()));
|
||||
}
|
||||
|
||||
void VectorRasterizer::drawPrimitive(
|
||||
const VectorPrimitive& primitive,
|
||||
void VectorRasterizer::drawGeoJsonObject(
|
||||
const GeoJsonObject& geoJsonObject,
|
||||
const VectorStyle& style) {
|
||||
struct PrimitiveDrawVisitor {
|
||||
VectorRasterizer& rasterizer;
|
||||
const VectorStyle& style;
|
||||
void operator()(const Cartographic& /*point*/) {}
|
||||
void operator()(const std::vector<Cartographic>& points) {
|
||||
rasterizer.drawPolyline(points, style);
|
||||
void operator()(const GeoJsonLineString& line) {
|
||||
rasterizer.drawPolyline(line.coordinates, style);
|
||||
}
|
||||
void operator()(const CompositeCartographicPolygon& polygon) {
|
||||
rasterizer.drawPolygon(polygon, style);
|
||||
void operator()(const GeoJsonMultiLineString& lines) {
|
||||
for (const std::vector<Cartographic>& line : lines.coordinates) {
|
||||
rasterizer.drawPolyline(line, style);
|
||||
}
|
||||
}
|
||||
void operator()(const GeoJsonPolygon& polygon) {
|
||||
rasterizer.drawPolygon(polygon.coordinates, style);
|
||||
}
|
||||
void operator()(const GeoJsonMultiPolygon& polygons) {
|
||||
for(const std::vector<std::vector<Cartographic>>& polygon : polygons.coordinates) {
|
||||
rasterizer.drawPolygon(polygon, style);
|
||||
}
|
||||
}
|
||||
void operator()(const GeoJsonPoint& /*catchAll*/) {}
|
||||
void operator()(const GeoJsonMultiPoint& /*catchAll*/) {}
|
||||
void operator()(const GeoJsonFeature& /*catchAll*/) {}
|
||||
void operator()(const GeoJsonFeatureCollection& /*catchAll*/) {}
|
||||
void operator()(const GeoJsonGeometryCollection& /*catchAll*/) {}
|
||||
};
|
||||
|
||||
std::visit(PrimitiveDrawVisitor{*this, style}, primitive);
|
||||
std::visit(PrimitiveDrawVisitor{*this, style}, geoJsonObject);
|
||||
}
|
||||
|
||||
void VectorRasterizer::clear(const Color& clearColor) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue