Skip to content

Commit

Permalink
Merge pull request #80 from ndsev/attribute-validities
Browse files Browse the repository at this point in the history
Release 2024.5.0
  • Loading branch information
Waguramu authored Dec 18, 2024
2 parents e08fe78 + a26420f commit 0109f9f
Show file tree
Hide file tree
Showing 49 changed files with 1,774 additions and 481 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_policy(SET CMP0117 NEW)

project(mapget CXX)

set(MAPGET_VERSION 2024.4.1)
set(MAPGET_VERSION 2024.5.0)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,22 @@ of a *Feature* in *mapget* is based on GeoJSON:
id: "<type-id>.<part-value-0>...<part-value-n>",
typeId: "<type-id>",
"<part-name-n>": "<part-value-n>",
"geometry": { /* GeoJSON geometry object */ },
"geometry": { /* GeoJSON geometry object with additional `name` field. */ },
"properties": {
"layers": {
"<attr-layer-name>": {
"<attr-name>": {
/* attr-fields ... */,
"direction": "<attr-direction>",
"validity": { /* attr-validity-geometry */ }
"validity": [{
direction: "<Optional validity direction along the feature>",
geometryName: { /* Optional reference to a specific feature geometry by name. */ },
geometry: { /* Optional nested GeoJSON geometry object. */ },
start: { /* Optional WGS84 point or scalar depending on type, indicating range. */ },
end: { /* Optional WGS84 point or scalar depending on type, indicating range. */ },
point: { /* Optional WGS84 point or scalar depending on type, indicating single position. */ },
offsetType: "GeoPosOffset|BufferOffset|RelativeLengthOffset|MetricLengthOffset",
featureId: id of the directly referenced feature if any, used to reference geometry of another feature
}]
}
},
// Additional attribute layers
Expand All @@ -133,8 +141,8 @@ of a *Feature* in *mapget* is based on GeoJSON:
{
"name": "<relation-name>",
"target": "<target-feature-id>",
"targetValidity": { /* geometry */ },
"sourceValidity": { /* geometry */ }
"targetValidity": [{ /* optional target validity-geom-description. see above for fields. */ }],
"sourceValidity": [{ /* optional source validity-geom-description. see above for fields. */ }]
}
// Additional relations
]
Expand All @@ -146,7 +154,7 @@ This structure provides a clear, hierarchical representation of a *Feature*, whe
- **`typeId`**: Indicates the feature type.
- **`id`**: A composite identifier based on the `typeId` and additional `part-values`.
- **`geometry`**: Encodes the spatial data of the feature in a format compliant with GeoJSON, but extended to support 3D geometries.
- **`properties`**: Contains feature attributes, organized into layers.
- **`properties`**: Contains both basic and layered feature attributes.
- **`relations`**: Defines relationships between this feature and others, including the spatial validity of these relationships.

### Feature ID Schemes
Expand Down
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def validate(self):

def requirements(self):
self.requires("fmt/10.2.1", override=True)
self.requires("simfil/0.3.3", transitive_headers=True)
self.requires("simfil/0.3.4", transitive_headers=True)
self.requires("spdlog/[~1]", transitive_headers=True)
self.requires("bitsery/[~5]")
# The override=True for is needed, until simfil 0.3.3 is released.
Expand Down
4 changes: 2 additions & 2 deletions deps.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ if (MAPGET_CONAN)
else()
FetchContent_Declare(glm
GIT_REPOSITORY "https://github.com/g-truc/glm.git"
GIT_TAG "0.9.9.8"
GIT_TAG "1.0.1"
GIT_SHALLOW ON)
FetchContent_MakeAvailable(glm)

Expand Down Expand Up @@ -111,7 +111,7 @@ else()
set(SIMFIL_SHARED NO CACHE BOOL "Simfil as static library")
FetchContent_Declare(simfil
GIT_REPOSITORY "https://github.com/Klebert-Engineering/simfil.git"
GIT_TAG "v0.3.3"
GIT_TAG "v0.3.4"
GIT_SHALLOW ON)
FetchContent_MakeAvailable(simfil)
endif()
Expand Down
Binary file modified docs/components.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion examples/cpp/http-datasource/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MyRemoteDataSource
// Add an attribute layer
auto attrLayer = feature1->attributeLayers()->newLayer("cheese");
auto attr = attrLayer->newAttribute("mozzarella");
attr->setDirection(Attribute::Direction::Positive);
attr->validity()->newDirection(Validity::Direction::Positive);
attr->addField("smell", "neutral");

// Set some additional info on the tile
Expand Down
2 changes: 1 addition & 1 deletion examples/cpp/local-datasource/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class MyLocalDataSource : public mapget::DataSource
// Add an attribute layer
auto attrLayer = feature1->attributeLayers()->newLayer("cheese");
auto attr = attrLayer->newAttribute("mozzarella");
attr->setDirection(Attribute::Direction::Positive);
attr->validity()->newDirection(Validity::Direction::Positive);
attr->addField("smell", "neutral");
}

Expand Down
3 changes: 2 additions & 1 deletion examples/python/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def handle_tile_request(tile: mapget.TileFeatureLayer):
# Add an attribute layer
attr_layer: mapget.Object = feature.attribute_layers().new_layer("rules")
attr: mapget.Attribute = attr_layer.new_attribute("SPEED_LIMIT")
attr.set_direction(mapget.Direction.POSITIVE)
# TODO: Add Python bindings for validities.
# attr.set_direction(mapget.Direction.POSITIVE)
attr.add_field("speedLimit", 50)

# Add a child feature ID
Expand Down
2 changes: 1 addition & 1 deletion libs/http-service/src/http-client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace mapget

struct HttpClient::Impl {
httplib::Client client_;
std::map<std::string, DataSourceInfo> sources_;
std::unordered_map<std::string, DataSourceInfo> sources_;
std::shared_ptr<TileLayerStream::StringPoolCache> stringPoolProvider_;

Impl(std::string const& host, uint16_t port) : client_(host, port)
Expand Down
8 changes: 4 additions & 4 deletions libs/http-service/src/http-service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ std::string stringToHash(const std::string& input)
*/
nlohmann::json yamlToJson(
const YAML::Node& yamlNode,
std::map<std::string, std::string>* maskedSecretMap = nullptr,
std::unordered_map<std::string, std::string>* maskedSecretMap = nullptr,
const bool mask = false)
{
if (yamlNode.IsScalar()) {
Expand Down Expand Up @@ -103,7 +103,7 @@ nlohmann::json yamlToJson(
* Recursively convert a JSON object to a YAML node,
* with special handling for sensitive fields.
*/
YAML::Node jsonToYaml(const nlohmann::json& json, std::map<std::string, std::string> const& maskedSecretMap)
YAML::Node jsonToYaml(const nlohmann::json& json, std::unordered_map<std::string, std::string> const& maskedSecretMap)
{
YAML::Node node;
if (json.is_object()) {
Expand Down Expand Up @@ -221,7 +221,7 @@ struct HttpService::Impl
};

mutable std::mutex clientRequestMapMutex_;
mutable std::map<std::string, std::shared_ptr<HttpTilesRequestState>> requestStatePerClientId_;
mutable std::unordered_map<std::string, std::shared_ptr<HttpTilesRequestState>> requestStatePerClientId_;

void abortRequestsForClientId(std::string clientId, std::shared_ptr<HttpTilesRequestState> newState = nullptr) const
{
Expand Down Expand Up @@ -591,7 +591,7 @@ struct HttpService::Impl

// Load the YAML, parse the secrets.
auto yamlConfig = YAML::Load(configFile);
std::map<std::string, std::string> maskedSecrets;
std::unordered_map<std::string, std::string> maskedSecrets;
yamlToJson(yamlConfig, &maskedSecrets);

// Create YAML nodes for from JSON nodes.
Expand Down
7 changes: 6 additions & 1 deletion libs/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ add_library(mapget-model STATIC
include/mapget/model/featureid.h
include/mapget/model/stream.h
include/mapget/model/relation.h
include/mapget/model/point.h
include/mapget/model/pointnode.h
include/mapget/model/geometry.h
include/mapget/model/simfil-geometry.h
include/mapget/model/sourcedata.h
include/mapget/model/sourcedatalayer.h
include/mapget/model/sourceinfo.h
include/mapget/model/sourcedatareference.h
include/mapget/model/validity.h

src/stringpool.cpp
src/layer.cpp
Expand All @@ -32,11 +35,13 @@ add_library(mapget-model STATIC
src/stream.cpp
src/geometry.cpp
src/point.cpp
src/pointnode.cpp
src/simfil-geometry.cpp
src/simfilutil.h
src/sourcedata.cpp
src/sourcedatalayer.cpp
src/sourcedatareference.cpp)
src/sourcedatareference.cpp
src/validity.cpp)

target_include_directories(mapget-model
PUBLIC
Expand Down
42 changes: 12 additions & 30 deletions libs/model/include/mapget/model/attr.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once

#include "featureid.h"
#include "geometry.h"
#include "sourcedatareference.h"
#include "validity.h"

namespace mapget
{
Expand All @@ -10,38 +11,21 @@ class Geometry;

/**
* Represents a feature attribute which belongs to an
* AttributeLayer, and may have typed `direction` and
* `validity` fields in addition to other arbitrary object fields.
* AttributeLayer, and may have reference several
* `Validity` objects in addition to other arbitrary object fields.
*/
class Attribute : public simfil::ProceduralObject<2, Attribute>
class Attribute : public simfil::ProceduralObject<2, Attribute, TileFeatureLayer>
{
friend class TileFeatureLayer;
template<typename> friend struct simfil::shared_model_ptr;
template<typename> friend struct simfil::model_ptr;

public:
/**
* Attribute direction values - may be used as flags.
*/
enum Direction : uint8_t {
Empty = 0x0, // No set direction
Positive = 0x1, // Positive (digitization) direction
Negative = 0x2, // Negative (against digitization) direction
Both = 0x3, // Both positive and negative direction
None = 0x4, // Not in any direction
};

/**
* Attribute direction accessors.
*/
[[nodiscard]] Direction direction() const;
void setDirection(Direction const& v);

/**
* Attribute validity accessors.
*/
[[nodiscard]] bool hasValidity() const;
[[nodiscard]] model_ptr<Geometry> validity() const;
void setValidity(model_ptr<Geometry> const& validityGeom);
[[nodiscard]] model_ptr<MultiValidity> validity();
[[nodiscard]] model_ptr<MultiValidity> validityOrNull() const;
void setValidity(const model_ptr<MultiValidity>& validities) const;

/**
* Read-only attribute name accessor.
Expand All @@ -58,23 +42,21 @@ class Attribute : public simfil::ProceduralObject<2, Attribute>
/**
* Source data related accessors.
*/
model_ptr<SourceDataReferenceCollection> sourceDataReferences() const;
[[nodiscard]] model_ptr<SourceDataReferenceCollection> sourceDataReferences() const;
void setSourceDataReferences(simfil::ModelNode::Ptr const& node);

protected:

/** Actual per-attribute data that is stored in the model's attributes-column. */
struct Data {
Direction direction_ = Empty;
simfil::ModelNodeAddress validity_;
simfil::ModelNodeAddress validities_;
simfil::ArrayIndex fields_ = -1;
simfil::StringId name_ = 0;
simfil::ModelNodeAddress sourceDataRefs_;

template<typename S>
void serialize(S& s) {
s.value1b(direction_);
s.object(validity_);
s.object(validities_);
s.value4b(fields_);
s.value2b(name_);
s.object(sourceDataRefs_);
Expand Down
6 changes: 4 additions & 2 deletions libs/model/include/mapget/model/attrlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ class AttributeLayerList;
* Represents a collection of Attributes which are semantically related.
* For example, all feature attributes which refer to road rules, such
* as speed limits, might belong to the same attribute layer.
* TODO: Convert to use BaseObject
*/
class AttributeLayer : public simfil::Object
{
friend class TileFeatureLayer;
friend class bitsery::Access;
template<typename> friend struct simfil::shared_model_ptr;
template<typename> friend struct simfil::model_ptr;

public:
/**
Expand Down Expand Up @@ -47,13 +48,14 @@ class AttributeLayer : public simfil::Object
/**
* Collection of attribute layers - this is merely a typed dict which
* stores (layer-name, layer) pairs.
* TODO: Convert to use BaseObject
*/
class AttributeLayerList : public simfil::Object
{
friend class TileFeatureLayer;
friend class bitsery::Access;
friend class Feature;
template<typename> friend struct simfil::shared_model_ptr;
template<typename> friend struct simfil::model_ptr;

public:
/**
Expand Down
15 changes: 7 additions & 8 deletions libs/model/include/mapget/model/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Feature : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
friend class bitsery::Access;
friend class TileFeatureLayer;
friend class BoundFeature;
template<typename> friend struct simfil::shared_model_ptr;
template<typename> friend struct simfil::model_ptr;

public:
/** Get the name of this feature's type. */
Expand All @@ -69,22 +69,22 @@ class Feature : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
* GeometryCollection if the feature does not have one yet.
*/
model_ptr<GeometryCollection> geom();
[[nodiscard]] model_ptr<GeometryCollection> geom() const;
[[nodiscard]] model_ptr<Geometry> firstGeometry() const;
[[nodiscard]] model_ptr<GeometryCollection> geomOrNull() const;
[[nodiscard]] SelfContainedGeometry firstGeometry() const;

/**
* Get this feature's Attribute layers. The non-const version adds a
* AttributeLayerList if the feature does not have one yet.
*/
model_ptr<AttributeLayerList> attributeLayers();
[[nodiscard]] model_ptr<AttributeLayerList> attributeLayers() const;
[[nodiscard]] model_ptr<AttributeLayerList> attributeLayersOrNull() const;

/**
* Get this feature's un-layered attributes.The non-const version adds a
* generic attribute storage if the feature does not have one yet.
*/
model_ptr<Object> attributes();
[[nodiscard]] model_ptr<Object> attributes() const;
[[nodiscard]] model_ptr<Object> attributesOrNull() const;

/** Add a point to the feature. */
void addPoint(Point const& p);
Expand Down Expand Up @@ -170,9 +170,10 @@ class Feature : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
* Relation list if the feature does not have one yet.
* Note: This accessor is private, to ensure that the relations
* array really only ever contains relations.
* TODO: Change relations to use a RelationCollection derived from BaseArray
*/
[[nodiscard]] model_ptr<Array> relations();
[[nodiscard]] model_ptr<Array> relations() const;
[[nodiscard]] model_ptr<Array> relationsOrNull() const;

/**
* Feature Data
Expand Down Expand Up @@ -209,8 +210,6 @@ class Feature : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
sfl::small_vector<std::pair<simfil::StringId, simfil::ModelNode::Ptr>, 32> fields_;
void updateFields();

nlohmann::json toJsonPrivate(simfil::ModelNode const&);

struct FeaturePropertyView : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
{
[[nodiscard]] simfil::ValueType type() const override;
Expand Down
4 changes: 2 additions & 2 deletions libs/model/include/mapget/model/featureid.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TileFeatureLayer;
using FeatureLayerConstPtr = std::shared_ptr<TileFeatureLayer const>;

template<typename T>
using model_ptr = simfil::shared_model_ptr<T>;
using model_ptr = simfil::model_ptr<T>;

using Object = simfil::Object;
using Array = simfil::Array;
Expand All @@ -24,7 +24,7 @@ class FeatureId : public simfil::MandatoryDerivedModelNodeBase<TileFeatureLayer>
friend class Feature;
friend class Relation;
friend class bitsery::Access;
template<typename> friend struct simfil::shared_model_ptr;
template<typename> friend struct simfil::model_ptr;

public:
/** Convert the FeatureId to a string like `<type-id>.<part-value-0>...<part-value-n>` */
Expand Down
Loading

0 comments on commit 0109f9f

Please sign in to comment.