-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FSR-897 and related | Accessibility Map Changes (#531)
* altered most high contrast map elements * altered flood warning polygon fill colour * fixed open and close buttons to work with high contrast * 5 day outlook map updated * white space removed * further alteration for alert opacity * updated symbol sprites to remove yellow highlight when selected * altered info description to work with screen reader. Added further description for flood alerts removed * viewport highlighting altered for high contrast users * sea stations showing correctly on map - no tidal * removed sea/tidal station filter changes from map * initial polygon work completed * altered polygon opacity. Fixed station numbering invisible stations. Added correct focus highlighting * removing commented out code
- Loading branch information
1 parent
0791c30
commit 0fe5fff
Showing
17 changed files
with
713 additions
and
668 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
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,184 @@ | ||
import { Feature } from 'ol' | ||
import { fromExtent } from 'ol/geom/Polygon' | ||
import GeoJSON from 'ol/format/GeoJSON' | ||
|
||
import { polygon, multiPolygon } from '@turf/helpers' | ||
import simplify from '@turf/simplify' | ||
import intersect from '@turf/intersect' | ||
|
||
const { getParameterByName, getSummaryList } = window.flood.utils | ||
|
||
// Generate feature name | ||
const featureName = (feature) => { | ||
let name = '' | ||
if (feature.get('type') === 'C') { | ||
name = `Sea level: ${feature.get('name')}` | ||
} else if (feature.get('type') === 'S' || feature.get('type') === 'M') { | ||
name = `River level: ${feature.get('name')}, ${feature.get('river')}` | ||
} else if (feature.get('type') === 'G') { | ||
name = `Groundwater level: ${feature.get('name')}` | ||
} else if (feature.get('type') === 'R') { | ||
name = `Rainfall: ${feature.get('name')}` | ||
} else if (feature.get('severity_value') === 3) { | ||
name = `Severe flood warning: ${feature.get('ta_name')}` | ||
} else if (feature.get('severity_value') === 2) { | ||
name = `Flood warning: ${feature.get('ta_name')}` | ||
} else if (feature.get('severity_value') === 1) { | ||
name = `Flood alert: ${feature.get('ta_name')}` | ||
} else if (feature.get('severity_value') === 4) { | ||
name = `Warning no longer in force: ${feature.get('ta_name')}` | ||
} | ||
return name | ||
} | ||
|
||
// Get features visible in the current viewport | ||
export const toggleVisibleFeatures = ({ labels, container, dataLayers, maps, targetAreaPolygons, warnings, bigZoom, targetArea, viewportDescription }) => { | ||
labels.getSource().clear() | ||
const lyrs = getParameterByName('lyr') ? getParameterByName('lyr').split(',') : [] | ||
const resolution = container.map.getView().getResolution() | ||
const isBigZoom = resolution <= bigZoom | ||
const extent = container.map.getView().calculateExtent(container.map.getSize()) | ||
const layers = dataLayers.filter(layer => layer !== targetAreaPolygons && lyrs.some(lyr => layer.get('featureCodes').includes(lyr))) | ||
// Add target area if it isn't an active alert or warning | ||
if (!layers.includes(warnings) && targetArea.pointFeature) layers.push(warnings) | ||
// Add vectortile polygons to labels | ||
if (layers.includes(warnings) && isBigZoom) { | ||
let warningPolygonFeatures = getWarningPolygonsIntersectingExtent({ extent, targetAreaPolygons, warnings }) | ||
warningPolygonFeatures = mergePolygons(warningPolygonFeatures, extent) | ||
addWarningPolygonsToLabels({ features: warningPolygonFeatures, labels }) | ||
} | ||
// Add point features to labels | ||
addPointFeaturesToLabels({ layers, extent, container, isBigZoom, labels }) | ||
const features = labels.getSource().getFeatures() | ||
// Show labels if count is between 1 and 9 | ||
const hasAccessibleFeatures = maps.isKeyboard && features.length <= 9 | ||
labels.setVisible(hasAccessibleFeatures) | ||
// Build model | ||
const numWarnings = features.filter(feature => [1, 2].includes(feature.get('severity'))).length | ||
const numAlerts = features.filter(feature => feature.get('severity') === 3).length | ||
const mumLevels = features.length - numWarnings - numAlerts | ||
const model = { | ||
numFeatures: features.length, | ||
summary: getSummaryList([ | ||
{ count: numWarnings, text: 'flood warning' }, | ||
{ count: numAlerts, text: 'flood alert' }, | ||
{ count: mumLevels, text: 'water level measurement' } | ||
]), | ||
features: features.map((feature, i) => ({ | ||
type: feature.get('type'), | ||
severity: feature.get('severity'), | ||
name: featureName(feature), | ||
river: feature.get('river') | ||
})) | ||
} | ||
// Update viewport description | ||
const html = window.nunjucks.render('description-live.html', { model }) | ||
viewportDescription.innerHTML = html | ||
// Set numeric id and move featureId to properties | ||
if (!hasAccessibleFeatures) return | ||
features.forEach((feature, i) => { | ||
feature.set('featureId', feature.getId()) | ||
feature.setId((i + 1)) | ||
}) | ||
} | ||
|
||
// Simplify, clip and merge vector tile polygons | ||
const mergePolygons = (features, extent) => { | ||
const mergedPolygons = [] | ||
const turfExtentPolygon = polygon(fromExtent(extent).getCoordinates()) | ||
features.forEach(feature => { | ||
const coordinates = feature.getGeometry().getCoordinates() | ||
// Simplify polygons | ||
const options = { tolerance: 100, highQuality: false } | ||
const turfPolygon = feature.getGeometry().getType() === 'MultiPolygon' | ||
? simplify(multiPolygon(coordinates), options) | ||
: simplify(polygon(coordinates), options) | ||
// Clip polygons to extent | ||
const clippedPolygon = intersect(turfPolygon, turfExtentPolygon) | ||
if (!clippedPolygon) return | ||
feature.setGeometry(new GeoJSON().readFeature(clippedPolygon).getGeometry()) | ||
|
||
mergedPolygons.push(feature) | ||
}) | ||
return mergedPolygons | ||
} | ||
|
||
// Get Warning Polygons Features Intersecting Extent | ||
const getWarningPolygonsIntersectingExtent = ({ extent, targetAreaPolygons, warnings }) => { | ||
const warningsPolygons = [] | ||
targetAreaPolygons.getSource().getFeaturesInExtent(extent).forEach(feature => { | ||
const warning = warnings.getSource().getFeatureById(feature.getId().replace(/^flood_warning_alert./, 'flood.')) | ||
if (warning && warning.get('isVisible')) { | ||
const warningsPolygon = new Feature({ | ||
geometry: feature.getGeometry(), | ||
name: warning.get('ta_name'), | ||
type: warning.get('severity'), | ||
severity: warning.get('severity_value') | ||
}) | ||
warningsPolygon.setId(feature.getId().replace(/^flood_warning_alert./, 'flood.')) | ||
warningsPolygons.push(warningsPolygon) | ||
} | ||
}) | ||
return warningsPolygons | ||
} | ||
|
||
// Add point features intersecting extent to labels source | ||
const addPointFeaturesToLabels = ({ layers, extent, container, isBigZoom, labels }) => { | ||
for (const layer of layers) { | ||
if (labels.getSource().getFeatures().length > 9) break | ||
const pointFeatures = layer.getSource().getFeaturesInExtent(extent) | ||
for (const feature of pointFeatures) { | ||
if ((feature.get('isVisible') && layer.get('ref') !== 'warnings') || (layer.get('ref') === 'warnings' && !isBigZoom)) { | ||
const pointFeature = new Feature({ | ||
geometry: feature.getGeometry(), | ||
name: feature.get('name'), | ||
type: feature.get('type'), | ||
severity: feature.get('severity'), | ||
river: feature.get('riverName') | ||
}) | ||
pointFeature.setId(feature.getId()) | ||
if (labels.getSource().getFeatures().length > 9) break | ||
labels.getSource().addFeature(pointFeature) | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Add warning polygons to labels source | ||
const addWarningPolygonsToLabels = ({ features, labels }) => { | ||
features.forEach(feature => { | ||
const geometry = feature.getGeometry() | ||
feature.setGeometry(geometry.getType() === 'MultiPolygon' | ||
? geometry.getInteriorPoints() | ||
: geometry.getInteriorPoint() | ||
) | ||
labels.getSource().addFeature(feature) | ||
}) | ||
} | ||
|
||
// Set selected feature | ||
export const toggleSelectedFeature = ({ newFeatureId = '', replaceHistory, dataLayers, selected, container, setFeatureHtml, state, targetAreaPolygons, maps }) => { | ||
selected.getSource().clear() | ||
dataLayers.forEach(layer => { | ||
if (layer === targetAreaPolygons) return | ||
const originalFeature = layer.getSource().getFeatureById(state.selectedFeatureId) | ||
const newFeature = layer.getSource().getFeatureById(newFeatureId) | ||
if (originalFeature) { | ||
originalFeature.set('isSelected', false) | ||
} | ||
if (newFeature) { | ||
newFeature.set('isSelected', true) | ||
setFeatureHtml(newFeature) | ||
selected.getSource().addFeature(newFeature) | ||
selected.setStyle(maps.styles[layer.get('ref') === 'warnings' ? 'warnings' : 'stations']) // WebGL: layers don't use a style function | ||
container.showInfo('Selected feature information', newFeature.get('html')) | ||
} | ||
if (layer.get('ref') === 'warnings') { | ||
// Refresh vector tiles | ||
targetAreaPolygons.setStyle(maps.styles.targetAreaPolygons) | ||
} | ||
}) | ||
state.selectedFeatureId = newFeatureId | ||
// Update url | ||
replaceHistory('fid', newFeatureId) | ||
} |
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
Oops, something went wrong.