Skip to content

Commit cbede11

Browse files
authored
Merge pull request #117 from STEMLab/op2rel
02/26 change parameter name op to rel in geometric query
2 parents ebb5c46 + c235727 commit cbede11

9 files changed

Lines changed: 40 additions & 41 deletions

File tree

data/PNU-201_with_interior_shell.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@
640640
{
641641
"id": "C3",
642642
"featureType": "CellSpace",
643-
"poi": true,
643+
"poi": false,
644644
"cellSpaceGeom": {
645645
"geometry3D": {
646646
"type": "Polyhedron",
@@ -34964,7 +34964,7 @@
3496434964
{
3496534965
"id": "C72",
3496634966
"featureType": "CellSpace",
34967-
"poi": false,
34967+
"poi": true,
3496834968
"cellSpaceGeom": {
3496934969
"geometry3D": {
3497034970
"type": "Polyhedron",
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -966,22 +966,22 @@ paths:
966966
Performs a spatial query against the **PrimalSpace** of a specific ThematicLayer using 2D geometric predicates.
967967
968968
**Functionality:**
969-
This operation filters `CellSpace` geometries based on a provided spatial operator (`op`) and a reference geometry. Unlike a standard bounding box filter, this endpoint supports complex topological predicates (e.g., *intersects*, *contains*, *within*) defined by the OGC Simple Features standard.
969+
This operation filters `CellSpace` geometries based on a provided spatial relation (`rel`) and a reference geometry. Unlike a standard bounding box filter, this endpoint supports complex topological predicates (e.g., *intersects*, *contains*, *within*) defined by the OGC Simple Features standard.
970970
971971
**Spatial Duality Logic:**
972972
- **Primal Space:** Only the `CellSpaceMember` items that satisfy the geometric predicate are returned.
973973
- **Dual Space:** All of the Nodes and Edges in specified ThematicLayer are returned.
974974
975975
**Parameters:**
976-
- `op`: The geometric predicate to apply (e.g., `intersects`, `within`, `contains`).
976+
- `rel`: The geometric predicate to apply (e.g., `intersects`, `within`, `contains`).
977977
- `geometry`: The reference geometry in WKT (Well-Known Text) format used for the predicate.
978978
- `level`: (Optional) Restricts the search to a specific floor or vertical level within the IndoorGML model.
979979
980980
**Response:**
981981
Returns a single `ThematicLayer` object containing the filtered Primal and Dual space components.
982982
operationId: geometricQuery
983983
parameters:
984-
- $ref: '#/components/parameters/op'
984+
- $ref: '#/components/parameters/rel'
985985
- $ref: '#/components/parameters/level'
986986
- $ref: '#/components/parameters/geometry'
987987
responses:
@@ -3577,12 +3577,12 @@ components:
35773577
description: Filter results to include only those matching the specified CellSpace name. Exact Match
35783578
schema:
35793579
type: string
3580-
op:
3581-
name: op
3580+
rel:
3581+
name: rel
35823582
in: query
35833583
required: true
35843584
description: |-
3585-
Spatial predicate operation applied between the input geometry
3585+
Spatial predicate relations applied between the input geometry
35863586
and CellSpace geometries.
35873587
35883588
Supported operations:

openAPI/openAPI_schema.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -620,22 +620,22 @@ paths:
620620
Performs a spatial query against the **PrimalSpace** of a specific ThematicLayer using 2D geometric predicates.
621621
622622
**Functionality:**
623-
This operation filters `CellSpace` geometries based on a provided spatial operator (`op`) and a reference geometry. Unlike a standard bounding box filter, this endpoint supports complex topological predicates (e.g., *intersects*, *contains*, *within*) defined by the OGC Simple Features standard.
623+
This operation filters `CellSpace` geometries based on a provided spatial relation (`rel`) and a reference geometry. Unlike a standard bounding box filter, this endpoint supports complex topological predicates (e.g., *intersects*, *contains*, *within*) defined by the OGC Simple Features standard.
624624
625625
**Spatial Duality Logic:**
626626
- **Primal Space:** Only the `CellSpaceMember` items that satisfy the geometric predicate are returned.
627627
- **Dual Space:** All of the Nodes and Edges in specified ThematicLayer are returned.
628628
629629
**Parameters:**
630-
- `op`: The geometric predicate to apply (e.g., `intersects`, `within`, `contains`).
630+
- `rel`: The geometric predicate to apply (e.g., `intersects`, `within`, `contains`).
631631
- `geometry`: The reference geometry in WKT (Well-Known Text) format used for the predicate.
632632
- `level`: (Optional) Restricts the search to a specific floor or vertical level within the IndoorGML model.
633633
634634
**Response:**
635635
Returns a single `ThematicLayer` object containing the filtered Primal and Dual space components.
636636
operationId: geometricQuery
637637
parameters:
638-
- $ref: './parameters/op.yml'
638+
- $ref: './parameters/rel.yml'
639639
- $ref: './parameters/level.yml'
640640
- $ref: './parameters/geometry.yml'
641641
responses:
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
name: op
1+
name: rel
22
in: query
33
required: true
44
description: |-
5-
Spatial predicate operation applied between the input geometry
5+
Spatial predicate relations applied between the input geometry
66
and CellSpace geometries.
77
88
Supported operations:

pygeoapi/api/indoorgml.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,7 +1443,7 @@ def get_geometric_query(api: API, request: APIRequest, collection_id: str, item_
14431443
:param item_id: Item ID
14441444
:param layer_id: Layer ID
14451445
:param geometry: Input geometry expressed as a 2D Well-Known Text (WKT) string.
1446-
:param op: Spatial predicate operation applied between the input geometry and CellSpace geometries.
1446+
:param rel: Spatial predicate relation applied between the input geometry and CellSpace geometries.
14471447
:param level: Filters the indoorFeatures, thematicLayer, and primalSpace content by a specific floor level.
14481448
14491449
:return: ThematicLayer computed by specific op with geometry
@@ -1453,17 +1453,17 @@ def get_geometric_query(api: API, request: APIRequest, collection_id: str, item_
14531453

14541454
headers = request.get_response_headers(SYSTEM_LOCALE)
14551455
pidb_provider = PostgresIndoorDB()
1456-
op_param = request.params.get('op')
1456+
rel_param = request.params.get('rel')
14571457
geom_param = request.params.get('geometry')
14581458
level = request.params.get('level')
1459-
if not op_param or not geom_param:
1460-
msg = 'parameter op and geom should be required'
1459+
if not rel_param or not geom_param:
1460+
msg = 'parameter rel and geometry should be required'
14611461
return api.get_exception(
14621462
HTTPStatus.BAD_REQUEST,
14631463
headers, request.format, 'InvalidParameterValue', msg)
14641464

1465-
elif op_param.lower() not in ["contains", "within", "intersects"]:
1466-
msg = 'parameter op should be an one of ["contains", "within", "intersects"]'
1465+
elif rel_param.lower() not in ["contains", "within", "intersects"]:
1466+
msg = 'parameter rel should be an one of ["contains", "within", "intersects"]'
14671467
return api.get_exception(
14681468
HTTPStatus.BAD_REQUEST,
14691469
headers, request.format, 'InvalidParameterValue', msg)
@@ -1479,14 +1479,14 @@ def get_geometric_query(api: API, request: APIRequest, collection_id: str, item_
14791479

14801480
try:
14811481
pidb_provider.connect()
1482-
result = pidb_provider.geometric_query(collection_id, item_id, layer_id, op=op_param.lower(), geometry=geom, level=level)
1482+
result = pidb_provider.geometric_query(collection_id, item_id, layer_id, rel=rel_param.lower(), geometry=geom, level=level)
14831483
if not result:
14841484
raise Exception()
14851485
base_url = f"{api.config['server']['url']}/collections/{collection_id}/items/{item_id}/layers/{layer_id}/geoquery"
14861486

14871487
query_params = {}
1488-
if op_param:
1489-
query_params['op'] = op_param
1488+
if rel_param:
1489+
query_params['rel'] = rel_param
14901490
if geom:
14911491
query_params['geometry'] = geom
14921492

pygeoapi/provider/postgresql_indoordb.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,10 +2911,10 @@ def delete_dual_member(self, collection_id:str, feature_id:str, layer_id:str, me
29112911
# endregion
29122912

29132913
# region Services
2914-
def geometric_query(self, collection_id:str, feature_id:str, layer_id:str, op:str=None, geometry:str=None, level:str=None):
2914+
def geometric_query(self, collection_id:str, feature_id:str, layer_id:str, rel:str=None, geometry:str=None, level:str=None):
29152915
with self.connection.cursor(cursor_factory=RealDictCursor) as cur:
2916-
if not op or not geometry:
2917-
LOGGER.debug("The 'op' and 'geometry' parameter are required.")
2916+
if not rel or not geometry:
2917+
LOGGER.debug("The 'rel' and 'geometry' parameter are required.")
29182918
return False
29192919
lookup_sql = """
29202920
SELECT t.*
@@ -2928,7 +2928,7 @@ def geometric_query(self, collection_id:str, feature_id:str, layer_id:str, op:st
29282928
if not row:
29292929
return {}
29302930

2931-
primal = self._get_primal_geometric_query(row['id'], row['primalspace_id_str'], op=op, geometry=geometry, level=level,
2931+
primal = self._get_primal_geometric_query(row['id'], row['primalspace_id_str'], rel=rel, geometry=geometry, level=level,
29322932
p_create=row['p_creation_datetime'], p_terminate=row['p_termination_datetime'])
29332933
dual = self._get_dual_space(row['id'], row['dualspace_id_str'], d_create=row['d_creation_datetime'],
29342934
d_terminate=row['d_termination_datetime'], is_logical=row['is_logical'], is_directed=row['is_directed'])
@@ -2944,7 +2944,7 @@ def geometric_query(self, collection_id:str, feature_id:str, layer_id:str, op:st
29442944

29452945
return result_layer
29462946

2947-
def _get_primal_geometric_query(self, layer_id:str, pSpace_id:str, op: str, geometry: str, level: str = None, p_create=None, p_terminate=None):
2947+
def _get_primal_geometric_query(self, layer_id:str, pSpace_id:str, rel: str, geometry: str, level: str = None, p_create=None, p_terminate=None):
29482948
primal_space = {
29492949
"id": pSpace_id,
29502950
"featureType": "PrimalSpaceLayer",
@@ -2971,14 +2971,14 @@ def _get_primal_geometric_query(self, layer_id:str, pSpace_id:str, op: str, geom
29712971
geometric_query += " AND c.level = %s "
29722972
params_cells.append(level)
29732973

2974-
if op == 'contains':
2974+
if rel == 'contains':
29752975
geometric_query += """ AND ST_Contains(c."2D_geometry", ST_GeomFromText(%s, 0)) """
29762976
LOGGER.debug(geometry)
29772977
params_cells.append(geometry)
2978-
elif op == 'within':
2978+
elif rel == 'within':
29792979
geometric_query += """ AND ST_Within(c."2D_geometry", ST_GeomFromText(%s, 0)) """
29802980
params_cells.append(geometry)
2981-
elif op == 'intersects':
2981+
elif rel == 'intersects':
29822982
geometric_query += """ AND ST_Intersects(c."2D_geometry", ST_GeomFromText(%s, 0)) """
29832983
params_cells.append(geometry)
29842984
else:

pygeoapi/static/workSpace/demo.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
<details class="dropdown">
8181
<summary class="dropdown-summary">[ThematicLayer]Geometric query</summary>
8282
<div class="dropdown-content">
83-
<select id="geoquery-op-input">
83+
<select id="geoquery-rel-input">
8484
<option value="contains">contains</option>
8585
<option value="contains">intersects</option>
8686
<option value="contains">within</option>

pygeoapi/static/workSpace/viewer_demo.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,10 +1244,11 @@ function clearAll(){
12441244
cellStatus.textContent = "";
12451245
routeStatus.textContent = "";
12461246
vizStatus.textContent = "";
1247-
ROUTE=null;
1247+
ROUTE = null;
1248+
BBOX = null;
12481249
GEOQUERY = null;
12491250
drawerEl.classList.add("hidden");
1250-
document.getElementById("geoquery-op-input").value = null;
1251+
document.getElementById("geoquery-rel-input").value = null;
12511252
document.getElementById("geoquery-geometry-input").value = null;
12521253
document.getElementById("geoquery-level-input").value = null;
12531254
document.getElementById("bbox-min").value = null;
@@ -1295,16 +1296,16 @@ bboxBtn.addEventListener("click", async () => {
12951296

12961297
geoQueryBtn.addEventListener("click", async () => {
12971298

1298-
const operation = document.getElementById("geoquery-op-input").value;
1299+
const relation = document.getElementById("geoquery-rel-input").value;
12991300
const geometry = document.getElementById("geoquery-geometry-input").value;
13001301
const level = document.getElementById("geoquery-level-input").value;
13011302

1302-
if (!operation || !geometry) {
1303-
alert("Please select an operation and enter WKT geometry.");
1303+
if (!relation || !geometry) {
1304+
alert("Please select an relation and enter WKT geometry.");
13041305
return;
13051306
}
13061307
try {
1307-
geoqueryResult = await api.geometricQuery(selectedCollectionId, selectedFeatureId, selectedLayerId, operation, geometry, level);
1308+
geoqueryResult = await api.geometricQuery(selectedCollectionId, selectedFeatureId, selectedLayerId, relation, geometry, level);
13081309
apiLog.textContent = JSON.stringify(geoqueryResult, null, 2);
13091310
GEOQUERY = buildOverlayModel(geoqueryResult);
13101311
renderAll();
@@ -1315,8 +1316,6 @@ geoQueryBtn.addEventListener("click", async () => {
13151316
});
13161317

13171318
vizAllBtn.addEventListener("click", async () => {
1318-
1319-
13201319
try {
13211320
selectedFeatureDataAll = await api.getSingleFeature(selectedCollectionId, selectedFeatureId, true);
13221321
vizStatus.textContent = "Generating 3D Model...";

tests/IndoorGML/test_postgresql_indoordb.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,14 +765,14 @@ def test_query_get_dual_member(context):
765765

766766
def test_query_geometric_query(context):
767767
geometry = "POINT(10 10)"
768-
op = "intersects"
768+
rel = "intersects"
769769
level = "1F"
770770
pidb_provider = PostgresIndoorDB()
771771
pidb_provider.connect()
772772
result = pidb_provider.geometric_query(context.get('collection_id'),
773773
context.get('ifeature_id'),
774774
context.get('layer_id'),
775-
op=op,
775+
rel=rel,
776776
geometry=geometry,
777777
level=level)
778778
assert result

0 commit comments

Comments
 (0)