Skip to content

Commit 64f6349

Browse files
committed
feat: Allow "single_color" and "none" color modes for rasters
1 parent 2111f27 commit 64f6349

3 files changed

Lines changed: 62 additions & 38 deletions

File tree

uvdat/core/models/styles.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ def save_style_configs(self, style_spec):
6161
color_config.visible = color_spec.get("visible", True)
6262
color_config.use_feature_props = color_spec.get("use_feature_props", True)
6363
single_color = color_spec.get("single_color")
64+
colormap_spec = color_spec.get("colormap")
6465
if single_color is not None:
6566
color_config.single_color = single_color
6667
with contextlib.suppress(ColorConfig.colormap.RelatedObjectDoesNotExist):
6768
color_config.colormap.delete()
68-
else:
69+
elif colormap_spec is not None:
6970
color_config.single_color = ""
70-
colormap_spec = color_spec.get("colormap")
7171
colormap = Colormap.objects.get(id=colormap_spec.get("id"))
7272
map_range = colormap_spec.get("range") or [None, None]
7373
colormap_config_args = {

web/src/components/sidebars/LayerStyle.vue

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ function selectStyle(style: LayerStyle) {
160160
function fetchRasterBands() {
161161
if (!currentStyleSpec.value) return
162162
if (showRasterOptions.value) {
163-
setGroupColorMode('all', 'colormap')
163+
setGroupColorMode('all', 'none')
164164
if (frames.value.length) {
165165
if (currentFrame.value?.raster) {
166166
rasterBands.value = currentFrame.value.raster.metadata.bands;
@@ -209,7 +209,7 @@ function setCurrentColorGroups(different: boolean | null) {
209209
currentStyleSpec.value.colors = availableGroups.value.map((name) => {
210210
return { ...all, visible: true, use_feature_props: true, name }
211211
})
212-
availableGroups.value.forEach((name) => setGroupColorMode(name, 'colormap'))
212+
availableGroups.value.forEach((name) => setGroupColorMode(name, 'none'))
213213
} else if (showVectorOptions.value) {
214214
currentStyleSpec.value.colors = availableGroups.value.map((name) => {
215215
return { ...JSON.parse(JSON.stringify(all)), visible: true, name }
@@ -228,7 +228,7 @@ function setCurrentColorGroups(different: boolean | null) {
228228
} else {
229229
currentStyleSpec.value.colors = [...defaultStyle.colors]
230230
}
231-
if (showRasterOptions.value) setGroupColorMode('all', 'colormap')
231+
if (showRasterOptions.value) setGroupColorMode('all', 'none')
232232
currentGroups.value['color'] = 'all'
233233
}
234234
}
@@ -250,8 +250,10 @@ function setGroupColorMode(groupName: string, colorMode: string) {
250250
},
251251
single_color: undefined,
252252
}
253-
} else if (!c.single_color) {
253+
} else if (colorMode === 'single_color' && !c.single_color) {
254254
return {...c, colormap: undefined, single_color: styleStore.getDefaultColor(props.layer.id)}
255+
} else if (colorMode === 'none') {
256+
return {...c, colormap: undefined, single_color: undefined}
255257
}
256258
}
257259
return c
@@ -523,7 +525,7 @@ onMounted(resetCurrentStyle)
523525
/>
524526
</template>
525527
<v-card v-if="currentStyleSpec" class="layer-style-card mt-5" color="background" width="510">
526-
<div class="px-4 py-2" style="background-color: rgb(var(--v-theme-surface)); height: 40px">
528+
<div class="px-4 py-2" style="background-color: rgb(var(--v-theme-surface)); min-height: 40px">
527529
Edit Style
528530
<span class="secondary-text">(Layer: {{ layer.name }})</span>
529531

@@ -659,6 +661,47 @@ onMounted(resetCurrentStyle)
659661
</td>
660662
</tr>
661663
<tr>
664+
<td><v-label :class="group.visible ? '' : 'helper-text'">Color scheme</v-label></td>
665+
<td>
666+
<div class="d-flex" style="align-items: center;">
667+
<v-btn-toggle
668+
:model-value="group.single_color ? 'single_color' : group.colormap ? 'colormap' : 'none'"
669+
density="compact"
670+
variant="outlined"
671+
divided
672+
mandatory
673+
:disabled="!group.visible"
674+
@update:model-value="(value: string) => setGroupColorMode(group.name, value)"
675+
>
676+
<v-btn :value="'none'">None</v-btn>
677+
<v-btn :value="'single_color'">1 Color</v-btn>
678+
<v-btn :value="'colormap'">Colormap</v-btn>
679+
</v-btn-toggle>
680+
<v-menu
681+
v-if="group.single_color"
682+
:disabled="!group.visible"
683+
:close-on-content-click="false"
684+
open-on-hover
685+
location="end"
686+
>
687+
<template v-slot:activator="{ props }">
688+
<div
689+
v-bind="props"
690+
class="color-square"
691+
:style="{backgroundColor: group.single_color, opacity: group.visible ? 1 : 0.5}"
692+
></div>
693+
</template>
694+
<v-card>
695+
<v-color-picker
696+
v-model:model-value="group.single_color"
697+
mode="rgb"
698+
/>
699+
</v-card>
700+
</v-menu>
701+
</div>
702+
</td>
703+
</tr>
704+
<tr v-if="group.colormap">
662705
<td><v-label :class="group.visible ? '' : 'helper-text'">Colormap</v-label></td>
663706
<td>
664707
<v-select
@@ -722,7 +765,7 @@ onMounted(resetCurrentStyle)
722765
</v-select>
723766
</td>
724767
</tr>
725-
<tr>
768+
<tr v-if="group.colormap">
726769
<td><v-label :class="group.visible && getColormap(group.colormap)?.markers ? '' : 'helper-text'">Colormap class</v-label></td>
727770
<td>
728771
<v-btn-toggle
@@ -739,7 +782,7 @@ onMounted(resetCurrentStyle)
739782
</v-btn-toggle>
740783
</td>
741784
</tr>
742-
<tr>
785+
<tr v-if="group.colormap">
743786
<td><v-label :class="group.visible && getColormap(group.colormap)?.markers && group.colormap?.discrete ? '' : 'helper-text'">No. of colors</v-label></td>
744787
<td>
745788
<SliderNumericInput
@@ -751,7 +794,7 @@ onMounted(resetCurrentStyle)
751794
/>
752795
</td>
753796
</tr>
754-
<tr>
797+
<tr v-if="group.colormap">
755798
<td><v-label :class="group.visible && getColormap(group.colormap)?.markers ? '' : 'helper-text'">Range</v-label></td>
756799
<td>
757800
<SliderNumericInput
@@ -764,7 +807,7 @@ onMounted(resetCurrentStyle)
764807
/>
765808
</td>
766809
</tr>
767-
<tr>
810+
<tr v-if="group.colormap">
768811
<td>
769812
<v-label :class="group.visible && getColormap(group.colormap)?.markers ? '' : 'helper-text'">Clamping</v-label>
770813
<v-icon

web/src/store/style.ts

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,22 @@ function getRasterTilesQuery(styleSpec: StyleSpec, colormaps: Colormap[]) {
115115
(marker) => marker.color
116116
)
117117
}
118+
} else if (colorSpec.single_color) {
119+
colorQuery.palette = colorSpec.single_color
118120
}
119121
if (colorSpec.name === 'all') {
120-
if (colorSpec.colormap && colorSpec.visible) query = colorQuery
122+
if (colorSpec.visible) query = colorQuery
121123
} else {
122124
if (!query.bands) query.bands = []
123125
colorQuery.band = colorSpec.name.replace('Band ', '')
124-
if (colorSpec.colormap && colorSpec.visible) query.bands.push(colorQuery)
126+
if (colorSpec.visible) query.bands.push(colorQuery)
125127
}
126128
})
127129
styleSpec.filters.forEach((f) => {
128130
if (f.apply && f.filter_by && f.include && f.list?.length === 1) {
129131
query[f.filter_by] = f.list[0]
130132
}
131133
})
132-
if (!Object.keys(query).length) return undefined
133134
return query;
134135
}
135136

@@ -336,17 +337,6 @@ export const useStyleStore = defineStore('style', () => {
336337
}
337338

338339
function getDefaultStyleSpec(raster: RasterData | null | undefined, layerId: number): StyleSpec {
339-
let range: [number, number] | undefined;
340-
let absMin: number | undefined, absMax: number | undefined;
341-
if (raster) {
342-
Object.values(raster.metadata.bands).forEach(({ min, max }) => {
343-
if (!absMin || min < absMin) absMin = min;
344-
if (!absMax || max < absMax) absMax = max;
345-
})
346-
}
347-
if (absMin !== undefined && absMax !== undefined) {
348-
range = [Math.floor(absMin), Math.ceil(absMax)] as [number, number];
349-
}
350340
return {
351341
opacity: 1,
352342
default_frame: 0,
@@ -356,13 +346,7 @@ export const useStyleStore = defineStore('style', () => {
356346
visible: true,
357347
use_feature_props: true,
358348
single_color: raster ? undefined : getDefaultColor(layerId),
359-
colormap: raster ? {
360-
range,
361-
color_by: 'value',
362-
discrete: false,
363-
n_colors: 5,
364-
null_color: 'transparent'
365-
} : undefined,
349+
colormap: undefined,
366350
}
367351
],
368352
sizes: [
@@ -476,14 +460,11 @@ export const useStyleStore = defineStore('style', () => {
476460
const source = map.getSource(mapLayer.source) as RasterTileSource;
477461
const sourceURL = mapStore.rasterSourceTileURLs[mapLayer.source];
478462
if (source && sourceURL) {
479-
const oldQuery = new URLSearchParams(sourceURL.split('?')[1]);
480463
const newQueryParams: { projection: string, style?: string } = { projection: 'epsg:3857' };
481-
if (rasterTilesQuery) newQueryParams.style = JSON.stringify(rasterTilesQuery);
464+
newQueryParams.style = JSON.stringify(rasterTilesQuery);
482465
const newQuery = new URLSearchParams(newQueryParams);
483-
if (newQuery.toString() !== oldQuery.toString()) {
484-
tileURL = sourceURL.split('?')[0] + '?' + newQuery.toString();
485-
return { paint, tileURL }
486-
}
466+
tileURL = sourceURL.split('?')[0] + '?' + newQuery.toString();
467+
return { paint, tileURL }
487468
}
488469
}
489470
return { paint };

0 commit comments

Comments
 (0)