Skip to content

Commit 4c52753

Browse files
committed
Show popovers over Map directly where the click took place, mark selected features
1 parent 424d351 commit 4c52753

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

src/components/Map.vue

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
<TextControl v-if="empty" :map="map" :text="$t('mapping.nodata')" />
77
<TextControl v-else-if="!hasBasemap" :map="map" :text="$t('mapping.nobasemap')" />
88
</div>
9+
<div ref="target" class="popover-target" />
910
<b-popover
1011
v-if="popover && selectedItems" show placement="left" triggers="manual"
11-
:target="selectedItems.target" container="#stac-browser" :key="selectedItems.key"
12+
:target="selectedItems.target" container="#stac-browser"
1213
>
1314
<section class="popover-items">
1415
<Items :stac="stac" :items="selectedItems.items" />
@@ -28,11 +29,20 @@ import { mapGetters } from 'vuex';
2829
import { BPopover } from 'bootstrap-vue';
2930
import proj4 from 'proj4';
3031
import {register} from 'ol/proj/proj4.js';
32+
import Select from 'ol/interaction/Select';
3133
import StacLayer from 'ol-stac';
3234
import { getStacObjectsForEvent } from 'ol-stac/util.js';
35+
import { Stroke, Style } from 'ol/style.js';
3336
3437
register(proj4); // required to support source reprojection
3538
39+
const selectStyle = new Style({
40+
stroke: new Stroke({
41+
color: '#ff0000',
42+
width: 2,
43+
}),
44+
});
45+
3646
export default {
3747
name: 'Map',
3848
components: {
@@ -70,7 +80,8 @@ export default {
7080
return {
7181
stacLayer: null,
7282
selectedItems: null,
73-
empty: false
83+
empty: false,
84+
selector: null
7485
};
7586
},
7687
computed: {
@@ -97,6 +108,11 @@ export default {
97108
if (empty) {
98109
this.$emit('empty');
99110
}
111+
},
112+
selectedItems(selectedItems) {
113+
if (!selectedItems && this.selector) {
114+
this.selector.getFeatures().clear();
115+
}
100116
}
101117
},
102118
async mounted() {
@@ -128,8 +144,6 @@ export default {
128144
disableMigration: true,
129145
});
130146
this.stacLayer = new StacLayer(options);
131-
console.log(this.stacLayer.getData().getBoundingBoxes());
132-
console.log(JSON.stringify(this.stacLayer.getData().toGeoJSON()));
133147
this.stacLayer.on('error', error => {
134148
console.warn(error);
135149
this.fit();
@@ -142,12 +156,26 @@ export default {
142156
this.map.addLayer(this.stacLayer);
143157
144158
if (this.popover) {
159+
this.selector = new Select({
160+
toggleCondition: () => false, // Only add features manually
161+
condition: () => false, // Only add features manually
162+
style: selectStyle
163+
});
164+
this.map.addInteraction(this.selector);
145165
this.map.on('singleclick', async (event) => {
146-
const objects = await getStacObjectsForEvent(event, this.stacLayer.getData());
166+
// The event doesn't contain a target element for the popover to attach to.
167+
// Thus we move a hidden target element to the click position and attach the popover to it.
168+
// See also https://github.com/bootstrap-vue/bootstrap-vue/issues/5285
169+
this.$refs.target.style.left = event.pixel[0] + 'px';
170+
this.$refs.target.style.top = event.pixel[1] + 'px';
171+
172+
this.selector.getFeatures().clear();
173+
const features = this.selector.getFeatures();
174+
const container = this.stacLayer.getData();
175+
const objects = await getStacObjectsForEvent(event, container, features, 5);
147176
if (objects.length > 0) {
148177
this.selectedItems = {
149-
target: event.originalEvent.srcElement || event.originalEvent.target,
150-
key: event.map.ol_uid,
178+
target: this.$refs.target,
151179
// Map from stac-js object back to STAC Browser STAC class
152180
items: objects.map(obj => this.getStac(obj.getAbsoluteUrl()))
153181
};
@@ -156,6 +184,8 @@ export default {
156184
this.selectedItems = null;
157185
}
158186
});
187+
this.map.on('change', () => this.selectedItems = null);
188+
this.map.on('movestart', () => this.selectedItems = null);
159189
}
160190
},
161191
fit() {
@@ -176,20 +206,31 @@ export default {
176206
<style lang="scss">
177207
@import "../../node_modules/ol/ol.css";
178208
179-
#stac-browser .popover-items {
180-
max-height: 500px;
181-
overflow: auto;
182-
margin-top: -0.5rem;
183-
margin-left: -0.75rem;
184-
margin-right: -0.75rem;
185-
padding: 0.5rem 0.75rem 0 0.75rem;
186-
187-
.items {
188-
margin-bottom: 0 !important;
209+
#stac-browser {
210+
.popover-target {
211+
width: 1px;
212+
height: 1px;
213+
opacity: 0;
214+
position: absolute;
215+
top: -1px;
216+
left: -1px;
189217
}
218+
219+
.popover-items {
220+
max-height: 500px;
221+
overflow: auto;
222+
margin-top: -0.5rem;
223+
margin-left: -0.75rem;
224+
margin-right: -0.75rem;
225+
padding: 0.5rem 0.75rem 0 0.75rem;
226+
227+
.items {
228+
margin-bottom: 0 !important;
229+
}
190230
191-
.card-columns {
192-
column-count: 1;
231+
.card-columns {
232+
column-count: 1;
233+
}
193234
}
194235
}
195236
</style>

0 commit comments

Comments
 (0)