Skip to content

Commit

Permalink
Merge branch 'develop' into deck-migration/base-branch
Browse files Browse the repository at this point in the history
  • Loading branch information
j8seangel committed May 14, 2024
2 parents edcfa0e + 62ab1df commit 2d27e84
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 63 deletions.
3 changes: 2 additions & 1 deletion apps/fishing-map/data/layer-library/layers-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ export const LAYERS_LIBRARY_ENVIRONMENT: LibraryLayerConfig[] = [
{
id: 'species',
dataviewId: TEMPLATE_HEATMAP_STATIC_DATAVIEW_SLUG,
previewImageUrl: `${PATH_BASENAME}/images/layer-library/species.jpg`,
previewImageUrl: `${PATH_BASENAME}/images/layer-library/species-distribution.jpg`,
config: {
color: '#FFAE9B',
colorRamp: 'salmon',
maxZoom: 5,
},
datasetsConfig: [
{
Expand Down
8 changes: 7 additions & 1 deletion apps/fishing-map/features/datasets/datasets.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,17 @@ export type SupportedEnvDatasetSchema =
| 'vessel_type'
| 'Height'
| 'REALM'
// TODO: remove this when the dataset is updated
| 'specie' // species-mm
| 'species' // species-mm
| 'genus' // species-mm
| 'period' // species-mm
| 'scenario' // species-mm
export type SupportedContextDatasetSchema = 'removal_of' | 'vessel_id'
export type SupportedEventsDatasetSchema = 'duration'

const CONTEXT_DATASETS_SCHEMAS: SupportedContextDatasetSchema[] = ['removal_of']
const SINGLE_SELECTION_SCHEMAS: SupportedDatasetSchema[] = ['vessel-groups']
const SINGLE_SELECTION_SCHEMAS: SupportedDatasetSchema[] = ['vessel-groups', 'period', 'scenario']

export type SchemaCompatibilityOperation = 'every' | 'some'
export type SchemaOriginParam =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,12 @@ export const selectActiveHeatmapVesselDatasets = createSelector(
}
)

export const selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry = createSelector(
export const selectActiveHeatmapEnvironmentalDataviewsWithoutStatic = createSelector(
[selectActiveHeatmapEnvironmentalDataviews],
(dataviews) => {
return dataviews.filter((dv) => !isBathymetryDataview(dv))
return dataviews.filter(
(dv) => !isBathymetryDataview(dv) && dv.config?.type !== GeneratorType.HeatmapStatic
)
}
)

Expand Down Expand Up @@ -325,7 +327,7 @@ export const selectActiveActivityDataviewsByVisualisation = (
[
selectActiveReportActivityDataviews,
selectActiveDetectionsDataviews,
selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry,
selectActiveHeatmapEnvironmentalDataviewsWithoutStatic,
selectTimebarSelectedEnvId,
],
(activityDataviews, detectionsDataviews, environmentDataviews, timebarSelectedEnvId) => {
Expand Down
4 changes: 2 additions & 2 deletions apps/fishing-map/features/timebar/TimebarSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TimebarGraphs, TimebarVisualisations } from 'types'
import {
selectActiveReportActivityDataviews,
selectActiveDetectionsDataviews,
selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry,
selectActiveHeatmapEnvironmentalDataviewsWithoutStatic,
} from 'features/dataviews/selectors/dataviews.selectors'
import { getEventLabel } from 'utils/analytics'
import { ReactComponent as AreaIcon } from 'assets/icons/timebar-area.svg'
Expand Down Expand Up @@ -64,7 +64,7 @@ const TimebarSettings = ({ loading = false }: { loading: boolean }) => {
const activeActivityDataviews = useSelector(selectActiveReportActivityDataviews)
const activeDetectionsDataviews = useSelector(selectActiveDetectionsDataviews)
const activeEnvironmentalDataviews = useSelector(
selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry
selectActiveHeatmapEnvironmentalDataviewsWithoutStatic
)
const activeTrackDataviews = useSelector(selectActiveTrackDataviews)
const isStandaloneVesselLocation = useSelector(selectIsVesselLocation)
Expand Down
4 changes: 2 additions & 2 deletions apps/fishing-map/features/timebar/timebar.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useLocationConnect } from 'routes/routes.hook'
import {
selectActiveReportActivityDataviews,
selectActiveDetectionsDataviews,
selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry,
selectActiveHeatmapEnvironmentalDataviewsWithoutStatic,
} from 'features/dataviews/selectors/dataviews.selectors'
import { updateUrlTimerange } from 'routes/routes.actions'
import { selectIsAnyReportLocation } from 'routes/routes.selectors'
Expand Down Expand Up @@ -224,7 +224,7 @@ export const useTimebarVisualisation = () => {
const activeActivityDataviews = useSelector(selectActiveReportActivityDataviews)
const activeDetectionsDataviews = useSelector(selectActiveDetectionsDataviews)
const activeTrackDataviews = useSelector(selectActiveTrackDataviews)
const activeEnvDataviews = useSelector(selectActiveHeatmapEnvironmentalDataviewsWithoutBathymetry)
const activeEnvDataviews = useSelector(selectActiveHeatmapEnvironmentalDataviewsWithoutStatic)
const hasChangedSettingsOnce = useSelector(selectHasChangedSettingsOnce)

// const prevTimebarVisualisation = usePrevious(timebarVisualisation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ function EnvironmentalLayerPanel({ dataview, onToggle }: LayerPanelProps): React
{ field: 'speed', label: t('layer.speed', 'Speed') },
{ field: 'Height', label: t('layer.height', 'Height') },
{ field: 'REALM', label: t('layer.REALM', 'REALM') },
{ field: 'genus', label: t('layer.genus', 'Genus') },
{ field: 'specie', label: t('layer.specie', 'specie') },
{ field: 'period', label: t('layer.period', 'Period') },
{ field: 'scenario', label: t('layer.scenario', 'Scenario') },
],
[t]
)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/en/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "",
"moreInfoLink": ""
},
"species": {
"name": "Species",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
"name": "Wave height",
"description": "Wave height is the vertical distance from the trough (bottom) to the crest (top) of a wave on the sea surface. This dataset uses the significant wave height, which is the average of the highest one-third of all wave heights over a given sample period.",
Expand Down
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/es/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "",
"moreInfoLink": ""
},
"species": {
"name": "Species",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
"name": "Altura de ola",
"description": "La altura de ola es la distancia vertical desde el valle (abajo) hasta la cresta (arriba) de una ola sobre la superficie del mar. Este conjunto de datos utiliza la altura de ola significante, la cual es el promedio del tercio más alto de todas las alturas de ola durante un período de muestra determinado.",
Expand Down
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/fr/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "",
"moreInfoLink": ""
},
"species": {
"name": "Species",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
"name": "Hauteur de houle",
"description": "La hauteur de houle est la distance verticale entre le creux (bas) et la crête (haut) d'une vague à la surface de la mer. Ce jeu de données utilise la hauteur de houle significative, qui est la moyenne du tiers le plus élevé de toutes les hauteurs de houle sur une période d'échantillonnage donnée.",
Expand Down
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/id/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "",
"moreInfoLink": ""
},
"species": {
"name": "Species",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
"name": "Tinggi gelombang",
"description": "Tinggi gelombang adalah jarak vertikal dari palung (bawah) sampai puncak (puncak) gelombang di permukaan laut. Kumpulan data ini menggunakan tinggi gelombang signifikan, yang merupakan rata-rata sepertiga tertinggi dari seluruh tinggi gelombang selama periode sampel tertentu.",
Expand Down
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/pt/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "",
"moreInfoLink": ""
},
"species": {
"name": "Species",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
"name": "Altura da onda",
"description": "A altura da onda é a distância vertical do vale (fundo) até a crista (topo) de uma onda na superfície do mar. Este conjunto de dados usa a altura significativa da onda, que é a média do terço mais alto de todas as alturas das ondas durante um determinado período de amostragem.",
Expand Down
2 changes: 1 addition & 1 deletion apps/fishing-map/public/locales/source/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
},
"species": {
"name": "Species",
"description": "",
"description": "TODO",
"moreInfoLink": ""
},
"thgt": {
Expand Down
5 changes: 5 additions & 0 deletions apps/fishing-map/public/locales/val/layer-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"description": "crwdns82634:0crwdne82634:0",
"moreInfoLink": "crwdns82636:0crwdne82636:0"
},
"species": {
"name": "crwdns83156:0crwdne83156:0",
"description": "crwdns83158:0crwdne83158:0",
"moreInfoLink": "crwdns83160:0crwdne83160:0"
},
"thgt": {
"name": "crwdns82638:0crwdne82638:0",
"description": "crwdns82640:0crwdne82640:0",
Expand Down
2 changes: 1 addition & 1 deletion libs/dataviews-client/src/resolve-dataviews-generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,11 @@ export function getGeneratorConfig(
const heatmapDataset = dataview.datasets?.find(
(dataset) => dataset.type === DatasetTypes.Fourwings
)

generator = {
...generator,
maxZoom: dataview.config.maxZoom || 8,
breaks: dataview.config.breaks,
filters: dataview.config?.filter,
datasets: [heatmapDataset?.id],
metadata: {
color: dataview?.config?.color,
Expand Down
109 changes: 59 additions & 50 deletions libs/dataviews-client/src/resolve-dataviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const FILTER_OPERATOR_SQL: Record<FilterOperator, string> = {

export const FILTERABLE_GENERATORS: DataviewType[] = [
DataviewType.HeatmapAnimated,
DataviewType.HeatmapStatic,
DataviewType.TileCluster,
DataviewType.UserContext,
DataviewType.UserPoints,
Expand Down Expand Up @@ -280,6 +281,59 @@ export const resolveDataviewDatasetResource = (
return resolveDataviewDatasetResources(dataview, datasetTypeOrId)[0] || ({} as Resource)
}

export function getDataviewSqlFiltersResolved(dataview: UrlDataviewInstance) {
if (!dataview.config?.filters) {
return ''
}
const { filters, filterOperators } = dataview.config

const sqlFilters = Object.keys(filters)
.filter((key) => key !== 'vessel-groups')
.flatMap((filterKey) => {
if (!filters[filterKey]) return []
const filterValues = Array.isArray(filters[filterKey])
? filters[filterKey]
: [filters[filterKey]]

const dataset = dataview.datasets?.find(
(d) => getDatasetSchemaItem(d, filterKey) !== undefined
)
const datasetSchema = getDatasetSchemaItem(dataset as Dataset, filterKey)
const isUserDataset = dataview.category === DataviewCategory.User
const queryFilterKey =
// User context layers requires wrapping the filter key with double quotes
filterKey.includes('_') && isUserDataset ? `"${filterKey}"` : filterKey
if (datasetSchema && datasetSchema.type === 'range') {
const minPossible = Number(datasetSchema?.enum?.[0])
const minSelected = Number(filterValues[0])
const minValue = isUserDataset ? `'${minSelected}'` : minSelected
const maxPossible = Number(datasetSchema?.enum?.[datasetSchema.enum.length - 1])
const maxSelected = Number(filterValues[filterValues.length - 1])
const maxValue = isUserDataset ? `'${maxSelected}'` : maxSelected
if (minSelected !== minPossible && maxSelected !== maxPossible) {
return `${queryFilterKey} >= ${minValue} AND ${queryFilterKey} <= ${maxValue}`
}
if (minSelected !== minPossible) {
return `${queryFilterKey} >= ${minValue}`
}
if (maxSelected !== maxPossible) {
return `${queryFilterKey} <= ${maxValue}`
}
}
const filterOperator = filterOperators?.[filterKey] || INCLUDE_FILTER_ID
const query = `${queryFilterKey} ${FILTER_OPERATOR_SQL[filterOperator]} (${filterValues
.map((f: string) => `'${f}'`)
.join(', ')})`
if (filterOperator === EXCLUDE_FILTER_ID) {
// workaround as bigquery exludes null values
return `(${queryFilterKey} IS NULL OR ${query})`
}
return query
})

return sqlFilters.length ? sqlFilters.join(' AND ') : ''
}

/**
* Gets list of dataviews and those present in the workspace, and applies any config or datasetConfig
* from it (merges dataview.config and workspace's dataviewConfig and datasetConfig).
Expand Down Expand Up @@ -371,57 +425,12 @@ export function resolveDataviews(
// resolved array filters to url filters
dataviewInstancesResolved = dataviewInstancesResolved.map((dataviewInstance) => {
if (dataviewInstance.config && isFilterableDataviewInstanceGenerator(dataviewInstance)) {
const { filters, filterOperators } = dataviewInstance.config
const { filters } = dataviewInstance.config
if (filters) {
if (filters['vessel-groups']) {
dataviewInstance.config['vessel-groups'] = filters['vessel-groups'].join(',')
}
const sqlFilters = Object.keys(filters)
.filter((key) => key !== 'vessel-groups')
.flatMap((filterKey) => {
if (!filters[filterKey]) return []
const filterValues = Array.isArray(filters[filterKey])
? filters[filterKey]
: [filters[filterKey]]

const dataset = dataviewInstance.datasets?.find(
(d) => getDatasetSchemaItem(d, filterKey) !== undefined
)
const datasetSchema = getDatasetSchemaItem(dataset as Dataset, filterKey)
const isUserDataset = dataviewInstance.category === DataviewCategory.User
const queryFilterKey =
// User context layers requires wrapping the filter key with double quotes
filterKey.includes('_') && isUserDataset ? `"${filterKey}"` : filterKey
if (datasetSchema && datasetSchema.type === 'range') {
const minPossible = Number(datasetSchema?.enum?.[0])
const minSelected = Number(filterValues[0])
const minValue = isUserDataset ? `'${minSelected}'` : minSelected
const maxPossible = Number(datasetSchema?.enum?.[datasetSchema.enum.length - 1])
const maxSelected = Number(filterValues[filterValues.length - 1])
const maxValue = isUserDataset ? `'${maxSelected}'` : maxSelected
if (minSelected !== minPossible && maxSelected !== maxPossible) {
return `${queryFilterKey} >= ${minValue} AND ${queryFilterKey} <= ${maxValue}`
}
if (minSelected !== minPossible) {
return `${queryFilterKey} >= ${minValue}`
}
if (maxSelected !== maxPossible) {
return `${queryFilterKey} <= ${maxValue}`
}
}
const filterOperator = filterOperators?.[filterKey] || INCLUDE_FILTER_ID
const query = `${queryFilterKey} ${FILTER_OPERATOR_SQL[filterOperator]} (${filterValues
.map((f: string) => `'${f}'`)
.join(', ')})`
if (filterOperator === EXCLUDE_FILTER_ID) {
// workaround as bigquery exludes null values
return `(${queryFilterKey} IS NULL OR ${query})`
}
return query
})
if (sqlFilters.length) {
dataviewInstance.config.filter = sqlFilters.join(' AND ')
}
dataviewInstance.config.filter = getDataviewSqlFiltersResolved(dataviewInstance)
}
if (filters?.['vessel-groups']) {
dataviewInstance.config['vessel-groups'] = filters['vessel-groups'].join(',')
}
return dataviewInstance
}
Expand Down
8 changes: 8 additions & 0 deletions libs/layer-composer/src/generators/heatmap/heatmap-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,18 @@ class HeatmapStaticGenerator {
url.searchParams.set('temporal-aggregation', 'true')
url.searchParams.set('format', 'MVT')
url = addURLSearchParams(url, 'datasets', config.datasets)

if (config.filters) {
config.datasets.forEach((_, index) => {
url.searchParams.set(`filters[${index}]`, config.filters)
})
}

return [
{
id: getHeatmapStaticSourceId(config.id),
type: 'vector',
...(config.maxZoom && { maxzoom: parseInt(config.maxZoom.toString()) }),
tiles: [decodeURI(url.toString())],
},
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ const getExtendedFeature = (
const uniqueFeatureInteraction = feature.layer?.metadata?.uniqueFeatureInteraction ?? false
const stopPropagation = feature.layer?.metadata?.stopPropagation ?? false
const properties = feature.properties || {}
let value = properties.value || properties.name || properties.id || properties?.count

let value = properties.value || properties.name || properties?.count || properties.id
const { valueProperties } = feature.layer.metadata || {}
if (valueProperties?.length) {
value =
Expand Down Expand Up @@ -184,7 +185,7 @@ const getExtendedFeature = (
return [
{
...extendedFeature,
value: extendedFeature.value / VALUE_MULTIPLIER,
value: extendedFeature.value,
unit: generatorMetadata.legends[0]?.unit,
},
]
Expand Down

0 comments on commit 2d27e84

Please sign in to comment.