Skip to content

Commit

Permalink
Merge pull request #60 from ndsev/feature/point-visualization
Browse files Browse the repository at this point in the history
Basic point support with test data
  • Loading branch information
josephbirkner authored Dec 15, 2023
2 parents c7837a5 + c472dd2 commit f930c35
Show file tree
Hide file tree
Showing 15 changed files with 275 additions and 31 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,18 @@ rule that matches it.
Each rule within the YAML `rules` array can have the following fields. Any field marked with __`*`__ is optional:

| Field | Description | Type | Example Value |
|----------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------|---------------------|
| `geometry` | List of feature geometry type(s) the rule applies to. | At least one of `"point"`,`"mesh"`, `"line"`, `"polygon"`. | `["point", "mesh"]` |
| `type`__*__ | A regular expression to match against a feature type. | String | `"Lane\|Boundary"` |
| `filter`__*__ | A [simfil](https://github.com/klebert-engineering/simfil) filter expression. | String | `*roadClass == 4` |
| `color`__*__ | A hexadecimal color code or [CSS color name](https://www.w3.org/wiki/CSS/Properties/color/keywords). | String | `"#FF5733"`, `red` |
| `opacity`__*__ | A float value between 0 and 1 indicating the opacity. | Float | `0.8` |
| `width`__*__ | Specifies the line width or point diameter (default in pixels). | Float | `4.5` |
| `flat`__*__ | Clamps the feature to the ground (meshes not supported) | Boolean | `true`, `false` |
| Field | Description | Type | Example Value |
|-----------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------|----------------------|
| `geometry` | List of feature geometry type(s) the rule applies to. | At least one of `"point"`,`"mesh"`, `"line"`, `"polygon"`. | `["point", "mesh"]` |
| `type`__*__ | A regular expression to match against a feature type. | String | `"Lane\|Boundary"` |
| `filter`__*__ | A [simfil](https://github.com/klebert-engineering/simfil) filter expression. | String | `*roadClass == 4` |
| `color`__*__ | A hexadecimal color code or [CSS color name](https://www.w3.org/wiki/CSS/Properties/color/keywords). | String | `"#FF5733"`, `red` |
| `opacity`__*__ | A float value between 0 and 1 indicating the opacity. | Float | `0.8` |
| `width`__*__ | Specifies the line width or point diameter (default in pixels). | Float | `4.5` |
| `flat`__*__ | Clamps the feature to the ground (Does not work for meshes). | Boolean | `true`, `false` |
| `outline-color`__*__ | Feature outline color (works only for points). | String | `green`, `#fff` |
| `outline-width`__*__ | Point outline width in px. | Float | `3.6` |
| `near-far-scale`__*__ | For points, indicate (`near-alt-meters`, `near-scale`, `far-alt-meters`, `far-scale`). | Array of four Floats. | `[1.5e2,10,8.0e6,0]` |

**A brief example:**

Expand Down
2 changes: 2 additions & 0 deletions libs/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(ERDBLICK_SOURCE_FILES
include/erdblick/cesium-interface/primitive.h
include/erdblick/cesium-interface/cesium.h
include/erdblick/cesium-interface/point-conversion.h
include/erdblick/cesium-interface/points.h

src/visualization.cpp
src/style.cpp
Expand All @@ -27,6 +28,7 @@ set(ERDBLICK_SOURCE_FILES
src/cesium-interface/object.cpp
src/cesium-interface/primitive.cpp
src/cesium-interface/cesium.cpp
src/cesium-interface/points.cpp
)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
Expand Down
8 changes: 5 additions & 3 deletions libs/core/include/erdblick/cesium-interface/cesium.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ struct CesiumLib
CesiumClass Geometry;
CesiumClass GeometryAttribute;
CesiumClass GeometryInstance;
CesiumClass GroundPolylineGeometry;
CesiumClass GroundPolylinePrimitive;
CesiumClass GroundPrimitive;
CesiumClass Material;
CesiumClass NearFarScalar;
CesiumClass PerInstanceColorAppearance;
CesiumClass PointPrimitiveCollection;
CesiumClass PolygonGeometry;
CesiumClass PolygonHierarchy;
CesiumClass PolylineColorAppearance;
Expand All @@ -26,9 +31,6 @@ struct CesiumLib
CesiumClass Primitive;
CesiumClass PrimitiveCollection;
CesiumClass PrimitiveType;
CesiumClass GroundPolylineGeometry;
CesiumClass GroundPolylinePrimitive;
CesiumClass GroundPrimitive;

[[nodiscard]] JsValue MaterialFromType(std::string const& type, JsValue const& options);

Expand Down
4 changes: 2 additions & 2 deletions libs/core/include/erdblick/cesium-interface/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ using NativeJsValue = nlohmann::json;

/**
* Class representing an emscripten JavaScript object,
* or a mock object based on an nlohmann::json value when compiling
* without emscripten support.
* or a mock object based on an nlohmann::json value
* for debugging or compiling without emscripten support.
*
* The mock object has two JSON fields:
* - `properties` is a dict recording all field accesses.
Expand Down
41 changes: 41 additions & 0 deletions libs/core/include/erdblick/cesium-interface/points.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include "cesium.h"
#include "simfil/model/model.h"
#include "mapget/model/featurelayer.h"
#include "../rule.h"

namespace erdblick
{

struct CesiumPointPrimitiveCollection
{
CesiumPointPrimitiveCollection();

/**
* Add an individual point to the collection
*/
void addPoint(
const JsValue& position,
FeatureStyleRule const& style,
uint32_t id);

/**
* Construct a JS Primitive from the provided Geometry instances.
*/
[[nodiscard]] NativeJsValue toJsObject() const;

/**
* Check if any geometry has been added to the primitive.
*/
bool empty() const;

private:
/** Number of points in this collection. */
size_t numGeometryInstances_ = 0;

/** Wrapped point primitive object from Cesium */
JsValue pointPrimitiveCollection_;
};

}
7 changes: 7 additions & 0 deletions libs/core/include/erdblick/rule.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ class FeatureStyleRule
[[nodiscard]] glm::fvec4 const& color() const;
[[nodiscard]] float width() const;
[[nodiscard]] bool flat() const;
[[nodiscard]] glm::fvec4 const& outlineColor() const;
[[nodiscard]] float outlineWidth() const;
[[nodiscard]] std::optional<std::array<float, 4>> const& nearFarScale() const;

private:
static inline uint32_t geomTypeBit(mapget::Geometry::GeomType const& g) {
Expand All @@ -33,6 +36,10 @@ class FeatureStyleRule
glm::fvec4 color_{.0, .0, .0, 1.};
float width_ = 1.;
bool flat_ = false;

glm::fvec4 outlineColor_{.0, .0, .0, .0};
float outlineWidth_ = .0;
std::optional<std::array<float, 4>> nearFarScale_;
};

}
68 changes: 68 additions & 0 deletions libs/core/include/erdblick/testdataprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,40 @@ class TestDataProvider
}
]
]
},
{
"name": "PointOfInterest",
"uniqueIdCompositions": [
[
{
"partId": "areaId",
"description": "String which identifies the map area.",
"datatype": "STR"
},
{
"partId": "pointId",
"description": "Globally Unique 32b integer.",
"datatype": "U32"
}
]
]
},
{
"name": "PointOfNoInterest",
"uniqueIdCompositions": [
[
{
"partId": "areaId",
"description": "String which identifies the map area.",
"datatype": "STR"
},
{
"partId": "pointId",
"description": "Globally Unique 32b integer.",
"datatype": "U32"
}
]
]
}
]
})"_json);
Expand Down Expand Up @@ -151,6 +185,24 @@ class TestDataProvider
feature->attributes()->addField("signType", signTypes[randomIndex]);
}

// Add some points of interest...
for (int i = 0; i < 5; i++) {
std::cout << "Generated POI " << i << std::endl;

auto feature = result->newFeature("PointOfInterest", {{"pointId", 200 + i}});
auto points = generateRandomPoints(1, 1, tileId.ne(), tileId.sw());
feature->addPoints(points);
}

// ...and points of no interest.
for (int i = 0; i < 5; i++) {
std::cout << "Generated PONI " << i << std::endl;

auto feature = result->newFeature("PointOfNoInterest", {{"pointId", 300 + i}});
auto points = generateRandomPoints(1, 1, tileId.ne(), tileId.sw());
feature->addPoints(points);
}

// Add a diamond mesh in the center of the tile.
auto diamondMeshFeature = result->newFeature("Diamond", {{"diamondId", 999}});
auto center = tileId.center();
Expand Down Expand Up @@ -187,6 +239,7 @@ class TestDataProvider
static FeatureLayerStyle style()
{
return FeatureLayerStyle(SharedUint8Array(R"yaml(
name: "TestDataProviderStyle"
rules:
- geometry:
- line
Expand Down Expand Up @@ -265,6 +318,21 @@ class TestDataProvider
type: "Diamond"
color: gold
opacity: 0.5
- geometry:
- point
type: "PointOfInterest"
color: "#2ecc71" # Green color for Points of Interest
width: 10
- geometry:
- point
type: "PointOfNoInterest"
color: "#e74c3c" # Red color for Points of No Interest
width: 5
outline-color: orange
outline-width: 3
near-far-scale: [1.5e2, 3, 8.0e6, 0.0]
)yaml"));
}

Expand Down
5 changes: 3 additions & 2 deletions libs/core/include/erdblick/visualization.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

#include <map>
#include <vector>
#include "style.h"
#include "cesium-interface/point-conversion.h"
#include "cesium-interface/points.h"
#include "cesium-interface/primitive.h"
#include "style.h"

namespace erdblick
{
Expand Down Expand Up @@ -56,7 +57,7 @@ class FeatureLayerVisualization
CesiumPrimitive coloredTrivialMeshes_;
CesiumPrimitive coloredGroundLines_;
CesiumPrimitive coloredGroundMeshes_;

CesiumPointPrimitiveCollection coloredPoints_;
};

} // namespace erdblick
10 changes: 6 additions & 4 deletions libs/core/src/cesium-interface/cesium.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ CesiumLib::CesiumLib() :
Geometry("Geometry"),
GeometryAttribute("GeometryAttribute"),
GeometryInstance("GeometryInstance"),
GroundPolylineGeometry("GroundPolylineGeometry"),
GroundPolylinePrimitive("GroundPolylinePrimitive"),
GroundPrimitive("GroundPrimitive"),
Material("Material"),
NearFarScalar("NearFarScalar"),
PerInstanceColorAppearance("PerInstanceColorAppearance"),
PointPrimitiveCollection("PointPrimitiveCollection"),
PolygonGeometry("PolygonGeometry"),
PolygonHierarchy("PolygonHierarchy"),
PolylineColorAppearance("PolylineColorAppearance"),
PolylineGeometry("PolylineGeometry"),
PolylineMaterialAppearance("PolylineMaterialAppearance"),
Primitive("Primitive"),
PrimitiveCollection("PrimitiveCollection"),
PrimitiveType("PrimitiveType"),
GroundPolylineGeometry("GroundPolylineGeometry"),
GroundPolylinePrimitive("GroundPolylinePrimitive"),
GroundPrimitive("GroundPrimitive")
PrimitiveType("PrimitiveType")
{
}

Expand Down
52 changes: 52 additions & 0 deletions libs/core/src/cesium-interface/points.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "cesium-interface/points.h"
#include "cesium-interface/cesium.h"
#include "cesium-interface/point-conversion.h"
#include "simfil/model/model.h"

#include <iostream>

namespace erdblick
{

CesiumPointPrimitiveCollection::CesiumPointPrimitiveCollection() :
pointPrimitiveCollection_(Cesium().PointPrimitiveCollection.New())
{}

void CesiumPointPrimitiveCollection::addPoint(
const JsValue& position,
FeatureStyleRule const& style,
uint32_t id)
{
auto const& color = style.color();
auto const& oColor = style.outlineColor();

auto options = JsValue::Dict({
{"position", position},
{"color", Cesium().Color.New(color.r, color.g, color.b, color.a)},
{"pixelSize", JsValue(style.width())},
{"id", JsValue(id)},
{"outlineColor", Cesium().Color.New(oColor.r, oColor.g, oColor.b, oColor.a)},
{"outlineWidth", JsValue(style.outlineWidth())},
});

if (auto const& nfs = style.nearFarScale()) {
options.set(
"scaleByDistance",
Cesium().NearFarScalar.New((*nfs)[0], (*nfs)[1], (*nfs)[2], (*nfs)[3]));
}

pointPrimitiveCollection_.call<void>("add", *options);
++numGeometryInstances_;
}

[[nodiscard]] NativeJsValue CesiumPointPrimitiveCollection::toJsObject() const
{
return *pointPrimitiveCollection_;
}

bool CesiumPointPrimitiveCollection::empty() const
{
return numGeometryInstances_ == 0;
}

}
15 changes: 11 additions & 4 deletions libs/core/src/cesium-interface/primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ CesiumPrimitive CesiumPrimitive::withPolylineColorAppearance(bool clampToGround)
return result;
}

CesiumPrimitive CesiumPrimitive::withPerInstanceColorAppearance(bool flatAndSynchronous, bool clampToGround)
CesiumPrimitive CesiumPrimitive::withPerInstanceColorAppearance(
bool flatAndSynchronous, bool clampToGround)
{
CesiumPrimitive result;
result.flatAndSynchronous_ = flatAndSynchronous;
Expand Down Expand Up @@ -86,9 +87,15 @@ void CesiumPrimitive::addGeometryInstance(
auto geometryInstance = Cesium().GeometryInstance.New({
{"geometry", geom},
{"attributes",
JsValue::Dict(
{{"color",
Cesium().ColorGeometryInstanceAttribute.New(color.r, color.g, color.b, color.a)}})},
JsValue::Dict({{
"color",
Cesium().ColorGeometryInstanceAttribute.New(
color.r,
color.g,
color.b,
color.a)
}})
},
{"id", JsValue(id)}
});
++numGeometryInstances_;
Expand Down
Loading

0 comments on commit f930c35

Please sign in to comment.