-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merge conclude, finish adding current activity layer geo
- Loading branch information
Showing
34 changed files
with
760 additions
and
412 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { RequestHandler } from 'express'; | ||
import { Operation } from 'express-openapi'; | ||
import { SQLStatement } from 'sql-template-strings'; | ||
import { ALL_ROLES, SECURITY_ON } from 'constants/misc'; | ||
import { getLogger } from 'utils/logger'; | ||
import { getDBConnection } from 'database/db'; | ||
import { getIAPPSQLv2, sanitizeIAPPFilterObject } from '../iapp'; | ||
|
||
const NAMESPACE = 'IAPP-bbox'; | ||
|
||
const defaultLog = getLogger(NAMESPACE); | ||
export const POST: Operation = [postHandler()]; | ||
|
||
POST.apiDoc = { | ||
description: 'Fetch bounding box based on search criteria', | ||
tags: [NAMESPACE], | ||
security: SECURITY_ON ? [{ Bearer: ALL_ROLES }] : [], | ||
requestBody: { | ||
description: 'Recordset search filter criteria', | ||
content: { | ||
'application/json': { | ||
schema: { | ||
properties: {} | ||
} | ||
} | ||
} | ||
}, | ||
responses: { | ||
200: { | ||
description: 'Bounding box response object', | ||
content: { | ||
'application/json': { | ||
schema: { | ||
type: 'object', | ||
properties: { | ||
bbox: { | ||
type: 'string', | ||
description: 'Bounding box for the given filters' | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
401: { | ||
$ref: '#/components/responses/401' | ||
}, | ||
503: { | ||
$ref: '#/components/responses/503' | ||
}, | ||
default: { | ||
$ref: '#/components/responses/default' | ||
} | ||
} | ||
}; | ||
|
||
/** | ||
* @desc Create Bounding box based on the filter properties for a given recordset | ||
*/ | ||
function postHandler(): RequestHandler { | ||
return async (req, res) => { | ||
const connection = await getDBConnection(); | ||
if (!connection) { | ||
return res.status(503).json({ | ||
message: 'Database connection unavailable', | ||
namespace: NAMESPACE, | ||
code: 503 | ||
}); | ||
} | ||
try { | ||
defaultLog.debug({ label: NAMESPACE, message: 'postHandler', body: req.body }); | ||
if (req.body?.filterObjects?.[0]) { | ||
const filterObject = sanitizeIAPPFilterObject(req.body.filterObjects[0], req); | ||
filterObject.boundingBoxOnly = true; | ||
const iappSql: SQLStatement = getIAPPSQLv2(filterObject); | ||
const response = await connection.query(iappSql.text, iappSql.values); | ||
|
||
if (response.rowCount > 0) { | ||
return res.status(200).json(response.rows[0]); | ||
} else { | ||
return res.status(404).json({ | ||
message: 'No Results', | ||
request: req.body, | ||
namespace: NAMESPACE, | ||
code: 404 | ||
}); | ||
} | ||
} else { | ||
return res.status(400).json({ | ||
message: 'Missing filter Objects from request', | ||
request: req.body, | ||
namespace: NAMESPACE, | ||
code: 400 | ||
}); | ||
} | ||
} catch (error) { | ||
defaultLog.debug({ | ||
label: NAMESPACE, | ||
message: 'error', | ||
error | ||
}); | ||
return res.status(500).json({ | ||
message: 'Server Error occured', | ||
request: req.body, | ||
namespace: NAMESPACE, | ||
code: 500, | ||
error | ||
}); | ||
} finally { | ||
connection.release(); | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
app/src/UI/LegacyMap/helpers/components/CurrentActivityLayer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { useContext, useEffect, useState } from 'react'; | ||
import { MapContext } from 'UI/LegacyMap/helpers/components/MapContext'; | ||
import { LAYER_Z_FOREGROUND } from 'UI/LegacyMap/helpers/functional/layer-definitions'; | ||
import { useSelector } from 'utils/use_selector'; | ||
|
||
const CurrentActivityLayer = ({ mapReady }) => { | ||
const map = useContext(MapContext); | ||
const [geo, setGeo] = useState(null); | ||
|
||
const activityGeometryArray = useSelector((state) => state.ActivityPage.activity?.geometry); | ||
const { url } = useSelector((state) => state.AppMode); | ||
|
||
// react to changes in the geometry or current page and set our rendered geo appropriately | ||
// render if a) we're on the Activity page and b) There is a geo object in the Activity | ||
useEffect(() => { | ||
if (activityGeometryArray && activityGeometryArray[0] && url?.includes('Activity')) { | ||
setGeo(activityGeometryArray[0]); | ||
} else { | ||
setGeo(null); | ||
} | ||
}, [activityGeometryArray, url]); | ||
|
||
useEffect(() => { | ||
if (!map) return; | ||
if (!mapReady) return; | ||
|
||
// add the layer if needed | ||
|
||
const LAYER_ID = 'current-activity-'; | ||
|
||
const SHAPE_LAYER = `${LAYER_ID}-shape`; | ||
const OUTLINE_LAYER = `${LAYER_ID}-outline`; | ||
const ZOOM_CIRCLE_LAYER = `${LAYER_ID}-zoomoutcircle`; | ||
|
||
if (geo) { | ||
map | ||
.addSource(LAYER_ID, { | ||
type: 'geojson', | ||
data: geo | ||
}) | ||
.addLayer( | ||
{ | ||
id: SHAPE_LAYER, | ||
source: LAYER_ID, | ||
type: 'fill', | ||
paint: { | ||
'fill-color': 'white', | ||
'fill-outline-color': 'black', | ||
'fill-opacity': 0.7 | ||
}, | ||
minzoom: 0, | ||
maxzoom: 24 | ||
}, | ||
LAYER_Z_FOREGROUND | ||
) | ||
.addLayer( | ||
{ | ||
id: OUTLINE_LAYER, | ||
source: LAYER_ID, | ||
type: 'line', | ||
paint: { | ||
'line-color': 'black', | ||
'line-opacity': 1, | ||
'line-width': 3 | ||
}, | ||
minzoom: 0, | ||
maxzoom: 24 | ||
}, | ||
LAYER_Z_FOREGROUND | ||
) | ||
.addLayer( | ||
{ | ||
id: ZOOM_CIRCLE_LAYER, | ||
source: LAYER_ID, | ||
type: 'circle', | ||
paint: { | ||
'circle-color': 'white', | ||
'circle-radius': 3 | ||
}, | ||
minzoom: 0, | ||
maxzoom: 24 | ||
}, | ||
LAYER_Z_FOREGROUND | ||
); | ||
|
||
return () => { | ||
// cleanup effect -- remove created entries in reverse | ||
map.removeLayer(ZOOM_CIRCLE_LAYER); | ||
map.removeLayer(OUTLINE_LAYER); | ||
map.removeLayer(SHAPE_LAYER); | ||
map.removeSource(LAYER_ID); | ||
}; | ||
} | ||
}, [geo]); | ||
|
||
return null; | ||
}; | ||
|
||
export { CurrentActivityLayer }; |
Oops, something went wrong.