Skip to content

Commit 820267c

Browse files
#684 Minimal GeoDataset Spatial Queries (#685)
1 parent ec18e13 commit 820267c

File tree

3 files changed

+67
-12
lines changed

3 files changed

+67
-12
lines changed

API/Backend/Geodatasets/routes/geodatasets.js

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,17 @@ function get(reqtype, req, res, next) {
239239
if (filters != null && filters.length > 0) {
240240
let filterSQL = [];
241241
filters.forEach((f, i) => {
242-
replacements[`filter_key_${i}`] = f.key;
242+
let fkey = f.key;
243+
let derivedKey = false;
244+
if (fkey === "Latitude (Centroid)") {
245+
fkey = `ST_Y(ST_Centroid(geom))`;
246+
derivedKey = true;
247+
} else if (fkey === "Longitude (Centroid)") {
248+
fkey = `ST_X(ST_Centroid(geom))`;
249+
derivedKey = true;
250+
}
251+
252+
replacements[`filter_key_${i}`] = fkey;
243253
replacements[`filter_value_${i}`] = f.value;
244254
let op = "=";
245255
switch (f.op) {
@@ -271,17 +281,48 @@ function get(reqtype, req, res, next) {
271281
}
272282
if (f.type === "number") {
273283
filterSQL.push(
274-
`(properties->>:filter_key_${i})::FLOAT ${op} ${value}`
284+
`${
285+
derivedKey === true
286+
? `${fkey}`
287+
: `(properties->>:filter_key_${i})`
288+
}::FLOAT ${op} ${value}`
275289
);
276290
} else {
277-
filterSQL.push(`properties->>:filter_key_${i} ${op} ${value}`);
291+
filterSQL.push(
292+
`${
293+
derivedKey === true
294+
? `${fkey}`
295+
: `properties->>:filter_key_${i}`
296+
} ${op} ${value}`
297+
);
278298
}
279299
});
280300
q += `${
281-
q.indexOf(" WHERE ") == -1 ? " WHERE " : " AND "
301+
q.indexOf(" WHERE ") === -1 ? " WHERE " : " AND "
282302
}${filterSQL.join(` AND `)}`;
283303
}
284304

305+
if (
306+
spatialFilter?.lat != null &&
307+
spatialFilter?.lng != null &&
308+
spatialFilter?.radius != null
309+
) {
310+
// prettier-ignore
311+
q += `${
312+
q.indexOf(" WHERE ") === -1 ? " WHERE " : " AND "
313+
}ST_Intersects(
314+
geom,
315+
ST_Transform(
316+
ST_Buffer(
317+
ST_Transform(
318+
ST_SetSRID(ST_MakePoint(${parseFloat(spatialFilter.lng)}, ${parseFloat(spatialFilter.lat)}), 4326), 3857
319+
),
320+
${parseFloat(spatialFilter.radius)}
321+
),
322+
4326
323+
))`;
324+
}
325+
285326
if (req.query?.limited) {
286327
q += ` ORDER BY id DESC LIMIT 3`;
287328
}
@@ -739,6 +780,14 @@ router.get("/aggregations", function (req, res, next) {
739780
});
740781
aggs[agg].aggs = sortedAggs;
741782
});
783+
aggs["Latitude (Centroid)"] = {
784+
type: "number",
785+
aggs: {},
786+
};
787+
aggs["Longitude (Centroid)"] = {
788+
type: "number",
789+
aggs: {},
790+
};
742791

743792
res.send({ status: "success", aggregations: aggs });
744793
})

src/essence/Basics/Layers_/Filtering/Filtering.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ const Filtering = {
9292
"</div>",
9393
"<div id='layerTool_filtering_filters'>",
9494
"<ul id='layerTool_filtering_filters_list'></ul>",
95-
Filtering.current.needsToQueryGeodataset === true ? null : [`<ul id='layerTool_filtering_filters_spatial' class='${spatialActive ? 'drawn' : ''}'>`,
95+
`<ul id='layerTool_filtering_filters_spatial' class='${spatialActive ? 'drawn' : ''}'>`,
9696
`<div id='layerTool_filtering_filters_spatial_draw' class='mmgisButton5' title='Place a point on the map to enable a spatial filter.'><i class='mdi mdi-pencil mdi-14px'></i><div>${spatialActive ? 'Active' : 'Place Point'}</div></div>`,
9797
"<div id='layerTool_filtering_filters_spatial_radius_wrapper' title='Radius\n= 0: Queries for features that contain this point.\n> 0: Queries for features intersecting this circle.'>",
9898
"<div>R:</div>",
9999
`<input id='layerTool_filtering_filters_spatial_radius' type='number' placeholder='Radius' value='${Filtering.filters[layerName].spatial.radius || 0}' min='0'></input>`,
100100
"<div>m</div>",
101101
"</div>",
102102
"<div id='layerTool_filtering_filters_spatial_clear' class='mmgisButton5 layerTool_filtering_filters_clear'><i class='mdi mdi-close mdi-18px'></i></div>",
103-
"</ul>"].join('\n'),
103+
"</ul>",
104104
"</div>",
105105
`<div id='layersTool_filtering_footer'>`,
106106
"<div id='layersTool_filtering_clear' class='mmgisButton5'><div>Clear Filter</div></div>",

src/essence/Basics/Layers_/Filtering/GeodatasetFilterer.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ const GeodatasetFilterer = {
7070
if (L_.layers.data[layerName]._filter) {
7171
let fspatial = L_.layers.data[layerName]._filter.spatial
7272
let fvalues = L_.layers.data[layerName]._filter.values
73-
if (fspatial != null && fspatial.radius > 0)
73+
if (
74+
fspatial != null &&
75+
fspatial.radius > 0 &&
76+
fspatial.center?.lat != null &&
77+
fspatial.center?.lng != null
78+
)
7479
L_.layers.data[
7580
layerName
7681
]._filterEncoded.spatialFilter = `${fspatial.center.lat},${fspatial.center.lng},${fspatial.radius}`
@@ -81,11 +86,12 @@ const GeodatasetFilterer = {
8186
if (fvalues.length > 0) {
8287
let encoded = []
8388
fvalues.forEach((v) => {
84-
encoded.push(
85-
`${v.key}+${v.op === ',' ? 'in' : v.op}+${
86-
v.type
87-
}+${v.value.replaceAll(',', '$')}`
88-
)
89+
if (v.value != null && v.key != null)
90+
encoded.push(
91+
`${v.key}+${v.op === ',' ? 'in' : v.op}+${
92+
v.type
93+
}+${v.value.replaceAll(',', '$')}`
94+
)
8995
})
9096
L_.layers.data[layerName]._filterEncoded.filters =
9197
encoded.join(',')

0 commit comments

Comments
 (0)