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#include <kDB/SPARQL/Algebra/Builders.h>
6
7#include <knowCore/Uris/askcore_datatype.h>
8#include <knowCore/Uris/askcore_db.h>
9#include <knowCore/Uris/qudt.h>
10
11#include <knowGIS/Uris/geo.h>
12#include <knowGIS/Uris/geof.h>
13
14#include "FocusNodeDeclarationsRegistry.h"
15
16namespace
17{
18
19 cres_qresult<QList<kDB::SPARQL::Algebra::NodeCSP>> focus_node_filter_constructor(
20 const QList<QPair<knowCore::Uri, knowCore::ConstrainedValue>>& _constraints,
22 kDB::SPARQL::Algebra::Builders::Variable* uri_variable, const QList<knowCore::Uri>& datatypes,
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_datatype = knowCore::Uris::askcore_datatype;
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 }
49 else
50 {
52 for(int i = 0; i < datatypes.size(); ++i)
53 {
55 kDB::Repository::RDF::FocusNodeDeclarationsRegistry::declaration(datatypes[i]));
57 declaration.field(path),
58 message("In accessing property {} for type {}: {}", path, datatypes[i]));
59 if(i == 0)
60 {
61 field = field_i;
62 }
63 else if(field != field_i)
64 {
65 return cres_failure("Property {} has incompatible field in type {} and type {}", path,
66 datatypes[0], datatypes[i]);
67 }
68 }
69
70 if(field.datatype() == askcore_datatype::quantityDecimal)
71 {
72 SB::Variable value_variable_value_i(clog_qt::qformat("?{}_value", i));
73 SB::Variable value_variable_unit_i(clog_qt::qformat("?{}_unit", i));
74
75 SB::BlankNode object_node;
76
77 triples_pattern->append((*uri_variable), field.path(), object_node);
78 triples_pattern->append(object_node, qudt::value, value_variable_value_i);
79 triples_pattern->append(object_node, qudt::unit, value_variable_unit_i);
80
81 lhs_node_value = value_variable_value_i;
82 lhs_node_unit = value_variable_unit_i;
83 (*path2node)[path] = {lhs_node_value, lhs_node_unit};
84 }
85 else
86 {
87 SB::Variable value_variable_i(clog_qt::qformat("?{}", i));
88 triples_pattern->append((*uri_variable), field.path(), value_variable_i);
89 lhs_node_value = value_variable_i;
90 (*path2node)[path] = {lhs_node_value};
91 }
92 }
93
94 // Build the filter
95 for(knowCore::ConstrainedValue::Constraint constraint : _constraints[i].second.constraints())
96 {
97
98 SA::NodeCSP lhs_node;
99 SA::NodeCSP rhs_node;
100 if(lhs_node_unit)
101 {
102 if(knowCore::ValueIs<knowCore::QuantityNumber> qn = constraint.value)
103 {
104 lhs_node
105 = SB::FunctionCall()
106 .name(askcore_sparql_functions_extra::convertQuantityValue)
107 .parameters(lhs_node_value, lhs_node_unit, SB::Term().term(qn->unit().uri()));
108 rhs_node = SB::Value().value(knowRDF::Literal::fromValue(qn->value()));
109 }
110 else
111 {
112 return cres_failure("Constraint for property '{}' should be a quantity number", path);
113 }
114 }
115 else
116 {
117 lhs_node = lhs_node_value;
118 if(constraint.value.is<knowCore::Uri>())
119 {
120 rhs_node = SB::Term().term(constraint.value.value<knowCore::Uri>().expect_success());
121 }
122 else
123 {
124 rhs_node = SB::Value().value(constraint.value);
125 }
126 }
127 switch(constraint.type)
128 {
129 case knowCore::ConstrainedValue::Type::Equal:
130 filters.append(SB::RelationalEqual().left(lhs_node).right(rhs_node));
131 break;
132 case knowCore::ConstrainedValue::Type::Different:
133 filters.append(SB::RelationalDifferent().left(lhs_node).right(rhs_node));
134 break;
136 filters.append(SB::RelationalInferiorEqual().left(lhs_node).right(rhs_node));
137 break;
139 filters.append(SB::RelationalInferior().left(lhs_node).right(rhs_node));
140 break;
142 filters.append(SB::RelationalSuperiorEqual().left(lhs_node).right(rhs_node));
143 break;
145 filters.append(SB::RelationalSuperior().left(lhs_node).right(rhs_node));
146 break;
148 filters.append(SB::FunctionCall()
149 .name(knowGIS::Uris::geof::sfOverlaps)
150 .parameters(lhs_node, rhs_node));
151 break;
153 if(_intersectsPrecision > 0.0)
154 {
155 filters.append(
156 SB::FunctionCall()
157 .name(knowGIS::Uris::geof::sfIntersects)
158 .parameters(lhs_node, rhs_node, knowRDF::Literal::fromValue(_intersectsPrecision)));
159 }
160 else
161 {
162 filters.append(SB::FunctionCall()
163 .name(knowGIS::Uris::geof::sfIntersects)
164 .parameters(lhs_node, rhs_node));
165 }
166 break;
168 filters.append(
169 SB::FunctionCall().name(knowGIS::Uris::geof::sfWithin).parameters(lhs_node, rhs_node));
170 break;
172 filters.append(
173 SB::FunctionCall().name(knowGIS::Uris::geof::sfWithin).parameters(lhs_node, rhs_node));
174 break;
176 filters.append(
177 SB::FunctionCall().name(knowGIS::Uris::geof::sfTouches).parameters(lhs_node, rhs_node));
178 break;
180 filters.append(SB::FunctionCall()
181 .name(knowGIS::Uris::geof::sfDisjoint)
182 .parameters(lhs_node, rhs_node));
183 break;
188 return cres_failure("In operator not supported.");
189 }
190 }
191 }
192 // END Construct filters
193 return cres_success(filters);
194 }
195} // namespace
Definition Forward.h:10
Definition Revision.h:9
Definition FocusNodeDeclaration.h:22
Definition FocusNodeDeclaration.h:17
cres_qresult< Property > field(const knowCore::Uri &_uri)
Definition FocusNodeDeclaration.cpp:84
@ 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