Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to override the selection with a given feature #417

Open
iboates opened this issue Mar 11, 2025 · 2 comments
Open

How to override the selection with a given feature #417

iboates opened this issue Mar 11, 2025 · 2 comments

Comments

@iboates
Copy link

iboates commented Mar 11, 2025

I'm trying to force the selection of a specified feature by one of its properties but I am coming up empty on how to do this. The closest thing I could find was this issue, which I have tried to replicate, but it does not seem to work.

I've tried to make a minimal example here. In the above issue, this code snippet is what seems to make it work:

  customInteraction.value.select.getFeatures().clear()
  customInteraction.value.select.getFeatures().push(vectorLayer.value.layer.features.find((f) => {
    return f.getProperties().features[0].values_.devaddr === val.values_.devaddr;
  }));
  customInteraction.value.select.getFeatures().forEach(function (feature) {
    feature.setStyle(selectedStyle);

I have added refs to my <ol-interaction-select> and <ol-source-vector> components, and gotten them in the script via useTemplateRef. It seems though, that vectorLayer.value.layer.features does not exist:

Image

Here is a minimal version of the code that I am using. How can I look up the feature I want from the existing vector layer and then force it to be the selected one?

<template>
  
    <ol-map style="height: 100%">
      <ol-view
        ref="view"
        :center="center"
        :rotation="rotation"
        :zoom="zoom"
        :projection="projection"
      />

    <!-- Wind farm site features layer -->
    <ol-vector-layer>

      <ol-source-vector :projection="projection" ref="vectorLayer">
        <ol-feature
          v-for="(windFarmSiteFeature, index) in windFarmSiteFeatures"
          :key="index"
          :properties="windFarmSiteFeature.properties"
          :ref="'windFarmOlFeature_' + windFarmSiteFeature.properties.windFarmSiteId"
        >
          <ol-geom-polygon :coordinates="windFarmSiteFeature.geometry.coordinates" />
        </ol-feature>
      </ol-source-vector>

      <ol-style>
        <ol-style-stroke color="blue" :width="2"></ol-style-stroke>
        <ol-style-fill color="rgba(0,255,0,0.1)"></ol-style-fill>
        <ol-style-circle :radius="7">
          <ol-style-fill color="yellow"></ol-style-fill>
        </ol-style-circle>
      </ol-style>
    </ol-vector-layer>

    <ol-interaction-select ref="customInteraction" @select="handleSelect">
      <ol-style>
        <ol-style-stroke color="red" :width="2"></ol-style-stroke>
        <ol-style-fill color="rgba(255, 255, 0, 0.4)"></ol-style-fill>
      </ol-style>
    </ol-interaction-select>

    </ol-map>

  </template>
  
  <script setup>
  import { ref, inject, defineExpose, useTemplateRef } from "vue";

  const windFarmSiteFeatures = inject("windFarmSiteFeatures");
  const selectedWindFarmSiteForm = inject("selectedWindFarmSiteForm");
  
  const center = ref([40, 40]);
  const projection = ref("EPSG:3857");
  const zoom = ref(8);
  const rotation = ref(0);

  const drawEnable = ref(false);
  const drawType = ref("Polygon");

  const handleSelect = (event) => {
    if (event.selected.length === 0) {
      // Deselection
      selectedWindFarmSiteForm.value = {};
    } else {
      selectedWindFarmSiteForm.value = event.selected[0].get("owcatForm")
    }
  };

  // Method to force-override selected features
  const customInteraction = useTemplateRef("customInteraction")
  const vectorLayer = useTemplateRef("vectorLayer")
  const overrideSelectedFeatures = (windFarmSiteId) => {
    console.log("vectorLayer.value:")
    console.log(vectorLayer.value)
    console.log("vectorLayer.value.layer:")
    console.log(vectorLayer.value.layer)
    console.log("vectorLayer.value.layer.features:")
    console.log(vectorLayer.value.layer.features)
  };
  defineExpose({ overrideSelectedFeatures });

</script>
  
<style scoped>
</style>
@d-koppenhagen
Copy link
Collaborator

Can you replace / add some dummy data for the both injected values windFarmSiteFeatures / selectedWindFarmSiteForm?

@iboates
Copy link
Author

iboates commented Mar 11, 2025

I just got some help from my colleagues and we were able to get it to work after all, this is the method we used:

  const selectInteractionTemplateRef = useTemplateRef("selectInteractionTemplateRef")
  const vectorLayerTemplateRef = useTemplateRef("vectorLayerTemplateRef")
  const overrideSelectedFeatures = (windFarmSiteId) => {
    const foundFeature = vectorLayerTemplateRef.value.source.getFeatures().find((f) => {
      return f.getProperties().windFarmSiteId == windFarmSiteId
    });
    selectInteractionTemplateRef.value.select.getFeatures().clear();
    selectInteractionTemplateRef.value.select.getFeatures().push(foundFeature);
    selectedWindFarmSiteForm.value = foundFeature.get("inputForm")
  };
  defineExpose({ overrideSelectedFeatures });

This is working on the assumption that selectInteractionTemplateRef and vectorLayerTemplateRef are the ref values for the <ol-interaction-select> and the <ol-vector-layer> components, respectively.

It seems that the solution posted by the user in the previous issue that I mentioned in my post is not correct, at least for my case. They were using:

vectorLayer.value.layer.features.find(...)

But this is what worked for me:

vectorLayer.value.source.getFeatures().find(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants