From 34fa2e8d7177ef5841fd4e7b24c7ee04a66f2aef Mon Sep 17 00:00:00 2001 From: tariqksoliman Date: Thu, 7 Nov 2024 18:51:25 -0800 Subject: [PATCH] Fix: geodatasets_search last, Next/Prev and with restrict to geom type --- API/Backend/Geodatasets/routes/geodatasets.js | 22 +++++++++- API/Backend/Users/routes/users.js | 14 +++++-- CHANGELOG.md | 2 +- src/essence/Ancillary/Description.css | 1 + src/essence/Ancillary/Description.js | 40 +++++++++++++++++++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/API/Backend/Geodatasets/routes/geodatasets.js b/API/Backend/Geodatasets/routes/geodatasets.js index 43612b82..8a2bfe41 100644 --- a/API/Backend/Geodatasets/routes/geodatasets.js +++ b/API/Backend/Geodatasets/routes/geodatasets.js @@ -379,6 +379,7 @@ router.post("/entries", function (req, res, next) { * req.body.value * req.body.id (specific feature id instead of key:value) * req.body.orderBy + * req.body.restrictToGeometryType * req.body.offset (i.e. if -1, then return feature previous to key:val) (can also be 'first' or 'last') */ router.post("/search", function (req, res, next) { @@ -424,19 +425,36 @@ router.post("/search", function (req, res, next) { )}, ${Utils.forceAlphaNumUnder(parseFloat(maxy))}, 4326), geom)`; } + const geometryTypes = [ + "Point", + "LineString", + "Polygon", + "MultiPoint", + "MultiLineString", + "MultiPolygon", + ]; + + const geomTypeWhere = + geometryTypes.indexOf(req.body.restrictToGeometryType) != -1 + ? " AND geometry_type = :geomtype" + : ""; + let q = `SELECT properties, ST_AsGeoJSON(geom), id FROM ${Utils.forceAlphaNumUnder( table )}` + (req.body.last || offset != null - ? `${where} ORDER BY id ${offset != null ? "ASC" : "DESC LIMIT 1"}` - : " WHERE properties ->> :key = :value"); + ? `${where}${geomTypeWhere} ORDER BY id ${ + offset != null && !req.body.last ? "ASC" : "DESC LIMIT 1" + }` + : ` WHERE properties ->> :key = :value${geomTypeWhere}`); sequelize .query(q + ";", { replacements: { orderBy: orderBy || "id", key: req.body.key, + geomType: req.body.restrictToGeometryType, value: typeof req.body.value === "string" ? req.body.value.replace(/[`;'"]/gi, "") diff --git a/API/Backend/Users/routes/users.js b/API/Backend/Users/routes/users.js index cfae2239..86fd0b6c 100644 --- a/API/Backend/Users/routes/users.js +++ b/API/Backend/Users/routes/users.js @@ -161,9 +161,17 @@ router.post("/login", function (req, res) { clearLoginSession(req); req.session.regenerate((err) => { - let MMGISUser = req.cookies.MMGISUser - ? JSON.parse(req.cookies.MMGISUser) - : false; + let MMGISUser; + try { + let userCookie = req.cookies.MMGISUser; + if (typeof userCookie === "string" && userCookie.endsWith("}undefined")) + userCookie = userCookie.substring(0, userCookie.length - 9); + + MMGISUser = userCookie ? JSON.parse(userCookie) : false; + } catch (err) { + res.send({ status: "failure", message: "Malformed MMGISUser cookie." }); + return; + } let username = req.body.username || (MMGISUser ? MMGISUser.username : null); if (username == null) { diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f358c34..9531265e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -95,7 +95,7 @@ Disable Globe more thoroughly when off Additional Body Metadata for Draw Webhooks Remove restriction on Layer names Check for empty time configs in TimeControl -Dropdown in the topbar for a selected feature’s properties links +Dropdown in the topbar for a selected feature's properties links #### Fixed diff --git a/src/essence/Ancillary/Description.css b/src/essence/Ancillary/Description.css index 241a8640..456aea3e 100644 --- a/src/essence/Ancillary/Description.css +++ b/src/essence/Ancillary/Description.css @@ -88,6 +88,7 @@ } #mainDescNavPopoverExtent, #mainDescNavPopoverTimeExtent, +#mainDescNavPopoverGeometryType, #mainDescNavPopoverPanTo { display: flex; justify-content: space-between; diff --git a/src/essence/Ancillary/Description.js b/src/essence/Ancillary/Description.js index 966dbdd9..301fef22 100644 --- a/src/essence/Ancillary/Description.js +++ b/src/essence/Ancillary/Description.js @@ -83,6 +83,10 @@ const Description = { `
Restrict to Time Range
`, `
`, ``, + `
`, + `
Restrict to Geometry Type
`, + `
`, + `
`, `
`, `
Pan To Feature
`, `
`, @@ -234,6 +238,7 @@ const Description = { if ( properties.indexOf(p) === -1 && p.indexOf('images') !== 0 && + p.indexOf('style') !== 0 && p[0] !== '_' ) properties.push(p) @@ -402,6 +407,22 @@ const Description = { ) { hasTimeBounds = true } + + let geomTypeRestriction = false + if ( + $('#mainDescNavPopoverGeometryType input').is( + ':checked' + ) + ) { + geomTypeRestriction = + active?.feature?.geometry?.type || false + } + if (geomTypeRestriction) { + features = features.filter((f) => { + return geomTypeRestriction === f?.geometry?.type + }) + } + // Limit to current map extent if checkbox is true let hasBounds = false const b = Description.Map_.map.getBounds() @@ -478,6 +499,7 @@ const Description = { direction === 'last' ? direction : offset, + restrictToGeometryType: geomTypeRestriction, } if (hasBounds) { @@ -552,6 +574,22 @@ const Description = { features[i].properties._ || {} features[i].properties._.id = i } + + // Reapply restrictions in this case + if (geomTypeRestriction) { + features = features.filter((f) => { + return ( + geomTypeRestriction === + f?.geometry?.type + ) + }) + } + + if (hasBounds) { + features = features.filter((f) => { + return booleanIntersects(bounds, f) + }) + } } if ( @@ -755,6 +793,7 @@ const Description = { return } if ( + !hasBounds && Description.navPopoverField === NAV_DEFAULT_FIELD && direction === 'previous' ) { @@ -762,6 +801,7 @@ const Description = { return } if ( + !hasBounds && Description.navPopoverField === NAV_DEFAULT_FIELD && direction === 'next' ) {