diff --git a/src/ifcgeom/GeometrySerializer.h b/src/ifcgeom/GeometrySerializer.h index 7cedf8cf97..75cf038e40 100644 --- a/src/ifcgeom/GeometrySerializer.h +++ b/src/ifcgeom/GeometrySerializer.h @@ -76,11 +76,16 @@ inline namespace settings { " and any other value means that 6 or 7 decimals are used."; static constexpr int defaultvalue = 15; }; + + struct BaseUri : public SettingBase { + static constexpr const char* const name = "base-uri"; + static constexpr const char* const description = "Base URI for products to be used in RDF-based serializations."; + }; } class SerializerSettings : public SettingsContainer < // @todo should we use tuple_cat here to unify the settings into a single class? - std::tuple + std::tuple > {}; diff --git a/src/serializers/TtlWktSerializer.cpp b/src/serializers/TtlWktSerializer.cpp index 7fd8962c01..9920489860 100644 --- a/src/serializers/TtlWktSerializer.cpp +++ b/src/serializers/TtlWktSerializer.cpp @@ -223,9 +223,14 @@ bool TtlWktSerializer::ready() void TtlWktSerializer::writeHeader() { + using namespace ifcopenshell::geometry::settings; filename_.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n"; filename_.stream << "@prefix geo: .\n"; - filename_.stream << "@prefix ex: .\n"; + if (settings_.get().has()) { + filename_.stream << "@prefix base: <" << settings_.get().get() << "> .\n"; + } else { + filename_.stream << "@prefix base: .\n"; + } filename_.stream << "@prefix dcterms: .\n"; filename_.stream << "@prefix rdfs: .\n\n\n"; } @@ -233,19 +238,19 @@ void TtlWktSerializer::writeHeader() void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o) { auto ttl_object_id = [&]() { - return boost::replace_all_copy(object_id(o), "-", "_"); + return boost::replace_all_copy(boost::replace_all_copy(object_id(o), "-", "_"), "$", "%24"); }; - filename_.stream << "ex:" << ttl_object_id() << " a geo:Feature ;\n"; + filename_.stream << "base:" << ttl_object_id() << " a geo:Feature ;\n"; filename_.stream << " dcterms:identifier " << escape_for_turtle( IfcUtil::convert_utf8_to_utf32(o->guid())) << " ;\n"; filename_.stream << " rdfs:label " << escape_for_turtle( IfcUtil::convert_utf8_to_utf32(o->name()) ) << " ;\n"; - filename_.stream << " geo:hasGeometry ex:" << ttl_object_id() << "_geometry .\n\n"; + filename_.stream << " geo:hasGeometry base:" << ttl_object_id() << "_geometry .\n\n"; if (!o->geometry().polyhedral_faces_with_holes().empty()) { - filename_.stream << "ex:" << ttl_object_id() << "_geometry a geo:Geometry ;\n"; + filename_.stream << "base:" << ttl_object_id() << "_geometry a geo:Geometry ;\n"; filename_.stream << " geo:asWKT " << escape_for_turtle( IfcUtil::convert_utf8_to_utf32( capture_output( @@ -275,8 +280,8 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o) } if (lowest_face) { - filename_.stream << "ex:" << ttl_object_id() << " geo:hasGeometry ex:" << ttl_object_id() << "_footprint_geometry .\n\n"; - filename_.stream << "ex:" << ttl_object_id() << "_footprint_geometry a geo:Geometry ;\n"; + filename_.stream << "base:" << ttl_object_id() << " geo:hasGeometry base:" << ttl_object_id() << "_footprint_geometry .\n\n"; + filename_.stream << "base:" << ttl_object_id() << "_footprint_geometry a geo:Geometry ;\n"; filename_.stream << " geo:asWKT " << escape_for_turtle( IfcUtil::convert_utf8_to_utf32( capture_output( @@ -290,7 +295,7 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o) ) << "^^geo:wktLiteral .\n\n"; } } else { - filename_.stream << "ex:" << ttl_object_id() << "_geometry a geo:Geometry ;\n"; + filename_.stream << "base:" << ttl_object_id() << "_geometry a geo:Geometry ;\n"; bool force_2d = true; double z_value; for (size_t i = 2; i < o->geometry().verts().size(); i += 3) {