kDB: Knowledge DataBase
Loading...
Searching...
No Matches
FocusNodeFilterConstructor_p.h
1#include <knowCore/ConstrainedValue.h>
2#include <knowCore/QuantityValue.h>
3#include <knowCore/TypeDefinitions.h>
4
5
6#include <kDB/SPARQL/Algebra/Builders.h>
7
8#include <knowCore/Uris/askcore_db.h>
9#include <knowCore/Uris/askcore_types.h>
10#include <knowCore/Uris/qudt.h>
11
12#include <knowGIS/Uris/geo.h>
13#include <knowGIS/Uris/geof.h>
14
15#include "FocusNodeDeclarationsRegistry.h"
16
17namespace
18{
19
20 knowCore::ReturnValue<QList<kDB::SPARQL::Algebra::NodeCSP>> focus_node_filter_constructor(const QList<QPair<knowCore::Uri, knowCore::ConstrainedValue>>& _constraints,
21 QHash<QString, QList<kDB::SPARQL::Algebra::NodeCSP>>* path2node, kDB::SPARQL::Algebra::Builders::Variable* uri_variable,
22 const QList<knowCore::Uri>& datatypes, const kDB::Repository::RDF::FocusNodeDeclarationsRegistry& declaration_registry,
23 kDB::SPARQL::Algebra::Builders::TriplesList* triples_pattern, double _intersectsPrecision)
24 {
25 namespace SA = kDB::SPARQL::Algebra;
26 namespace SB = kDB::SPARQL::Algebra::Builders;
27 using askcore_types = knowCore::Uris::askcore_types;
28 using qudt = knowCore::Uris::qudt;
29 using askcore_sparql_functions_extra = knowCore::Uris::askcore_sparql_functions_extra;
30
31 //BEGIN Construct filters
32 QList<SA::NodeCSP> filters;
33 for(int i = 0; i < _constraints.size(); ++i)
34 {
35 knowCore::Uri path = _constraints[i].first;
36
37 SA::NodeCSP lhs_node_value;
38 SA::NodeCSP lhs_node_unit;
39
40 if((*path2node).contains(path))
41 {
42 QList<SA::NodeCSP> nodes = (*path2node)[path];
43 lhs_node_value = nodes[0];
44 if(nodes.size() > 1)
45 {
46 lhs_node_unit = nodes[1];
47 }
48 } else {
50 for(int i = 0; i < datatypes.size(); ++i)
51 {
52 KNOWCORE_RETURN_VALUE_TRY(declaration, declaration_registry.declaration(datatypes[i]));
53 KNOWCORE_RETURN_VALUE_TRY(field_i, declaration.field(path), "In accessing property {} for type {}: {}", path, datatypes[i]);
54 if(i == 0)
55 {
56 field = field_i;
57 } else if(field != field_i)
58 {
59 return kCrvError("Property {} has incompatible field in type {} and type {}", path, datatypes[0], datatypes[i]);
60 }
61 }
62
63 if(field.datatype() == askcore_types::quantityDecimal)
64 {
65 SB::Variable value_variable_value_i(clog_qt::qformat("?{}_value", i));
66 SB::Variable value_variable_unit_i(clog_qt::qformat("?{}_unit", i));
67
68 SB::BlankNode object_node;
69
70
71 triples_pattern->append((*uri_variable), field.path(), object_node);
72 triples_pattern->append(object_node, qudt::value, value_variable_value_i);
73 triples_pattern->append(object_node, qudt::unit, value_variable_unit_i);
74
75 lhs_node_value = value_variable_value_i;
76 lhs_node_unit = value_variable_unit_i;
77 (*path2node)[path] = {lhs_node_value, lhs_node_unit};
78 } else {
79 SB::Variable value_variable_i(clog_qt::qformat("?{}", i));
80 triples_pattern->append((*uri_variable), field.path(), value_variable_i);
81 lhs_node_value = value_variable_i;
82 (*path2node)[path] = {lhs_node_value};
83 }
84 }
85
86 // Build the filter
87 for(knowCore::ConstrainedValue::Constraint constraint : _constraints[i].second.constraints())
88 {
89
90 SA::NodeCSP lhs_node;
91 SA::NodeCSP rhs_node;
92 if(lhs_node_unit)
93 {
94 if(knowCore::ValueIs<knowCore::QuantityNumber> qn = constraint.value)
95 {
96 lhs_node = SB::FunctionCall().name(askcore_sparql_functions_extra::convertQuantityValue).parameters(lhs_node_value, lhs_node_unit, SB::Term().term(qn->unit().uri()));
97 rhs_node = SB::Value().value(knowRDF::Literal::fromValue(qn->value()));
98 } else {
99 return kCrvError("Constraint for property '{}' should be a quantity number", path);
100 }
101 } else {
102 lhs_node = lhs_node_value;
103 if(constraint.value.is<knowCore::Uri>())
104 {
105 rhs_node = SB::Term().term(constraint.value.value<knowCore::Uri>().expectSuccess());
106 } else {
107 rhs_node = SB::Value().value(constraint.value);
108 }
109 }
110 switch(constraint.type)
111 {
112 case knowCore::ConstrainedValue::Type::Equal:
113 filters.append(SB::RelationalEqual().left(lhs_node).right(rhs_node));
114 break;
115 case knowCore::ConstrainedValue::Type::Different:
116 filters.append(SB::RelationalDifferent().left(lhs_node).right(rhs_node));
117 break;
119 filters.append(SB::RelationalInferiorEqual().left(lhs_node).right(rhs_node));
120 break;
122 filters.append(SB::RelationalInferior().left(lhs_node).right(rhs_node));
123 break;
125 filters.append(SB::RelationalSuperiorEqual().left(lhs_node).right(rhs_node));
126 break;
128 filters.append(SB::RelationalSuperior().left(lhs_node).right(rhs_node));
129 break;
131 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfOverlaps).parameters(lhs_node, rhs_node));
132 break;
134 if(_intersectsPrecision > 0.0)
135 {
136 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfIntersects).parameters(lhs_node, rhs_node, knowRDF::Literal::fromValue( _intersectsPrecision)));
137 } else {
138 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfIntersects).parameters(lhs_node, rhs_node));
139 }
140 break;
142 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfWithin).parameters(lhs_node, rhs_node));
143 break;
145 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfWithin).parameters(lhs_node, rhs_node));
146 break;
148 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfTouches).parameters(lhs_node, rhs_node));
149 break;
151 filters.append(SB::FunctionCall().name(knowGIS::Uris::geof::sfDisjoint).parameters(lhs_node, rhs_node));
152 break;
157 return kCrvError("In operator not supported.");
158 }
159 }
160 }
161 //END Construct filters
162 return kCrvSuccess(filters);
163 }
164}
Definition Forward.h:10
Definition Revision.h:9
Definition FocusNodeDeclaration.h:22
Definition FocusNodeDeclarationsRegistry.h:6
@ Superior
such as constraint.value < value
@ GeoWithin
such as value is within the constraint.value
@ NotContains
such as list does not contains a value
@ GeoDisjoint
such as value disjoint with constraint.value,
@ InferiorEqual
such as value <= constraint.value
@ GeoTouches
such as value touches with constraint.value,
@ Contains
such as list contains a value
@ Inferior
such as value < constraint.value
@ NotIn
such as one value is not part of a list
@ SuperiorEqual
such as constraint.value <= value
@ GeoIntersects
such as value intersects with constraint.value,
@ GeoContains
such as constraint.value is within the value
@ In
such as one value is part of a list
Definition Uri.h:15
Definition Value.h:445
Definition ConstrainedValue.h:38