Ability to zoom to an openlayers 6 feature by it's property ID in vue3-openlayers

348 views Asked by At

I have a table of data that contains information pertaining to the different features displayed on the map. When I click on a row in that table, I'd like to zoom to the extent of the line-string geometry. I'm having a hard time figuring out the way to achieve this.

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

    <ol-tile-layer>
      <ol-source-osm />
    </ol-tile-layer>

    <ol-vector-layer>
      <ol-source-vector ref="source">
        <ol-feature v-for="k in applicationState.get_track_keys" :key="k" :properties="{'id':k}" >
          <template v-if="isPoint(k)">
          <ol-geom-point v-if="isPoint(k)" :coordinates="getPointPosition(k)"></ol-geom-point>
            <ol-style>
              <ol-style-circle :radius="radius">
                <ol-style-fill :color="getColor(k)"></ol-style-fill>
                <ol-style-stroke :color="strokeColor" :width="strokeWidth"></ol-style-stroke>
              </ol-style-circle>
            </ol-style>
          </template>
          <template v-else>
            <ol-geom-line-string :coordinates="getLinePositions(k)"></ol-geom-line-string>
            <ol-style>
              <ol-style-stroke :color="getColor(k)" :width="strokeWidth"></ol-style-stroke>
            </ol-style>
          </template>
        </ol-feature>
      </ol-source-vector>
    </ol-vector-layer>

  </ol-map>
</template>

and here is my code:

import {useApplicationState} from "@/stores/applicationState";
import { onMounted, ref, inject } from "vue";

const view = ref();
const source = ref(null);
const center = ref([-160, -160])
const projection = ref('EPSG:4326')
const zoom = ref(2)
const rotation = ref(0)
const currentZoom = ref(zoom.value);
const radius = ref(5)
const strokeWidth = ref(2)
const strokeColor = ref('white')
const fillColor = ref('white')

const extent = inject('ol-extent');
const Feature = inject('ol-feature')
const Geom = inject('ol-geom')

const applicationState = useApplicationState()

applicationState.$subscribe((mutation, state) => {
  flyToFeature(state.selected_feature)
})

const flyToFeature = (feature) => {
  console.log(JSON.stringify(feature));
  console.log(source.value.source.getFeatures());
  debugger
}

const getPointPosition = (key) => {
  let p = applicationState.positions.get(key)[0]
  return [p['long'], p['lat'], 0.0]
}

const isPoint = (key) => {
   if (applicationState.positions.get(key).length == 1) {
     return true;
   }
}

const getLinePositions = (key) => {
  let ret_val = []
  for (const p of applicationState.positions.get(key)) {
    ret_val.push([p['long'], p['lat'], 0.0])
  }
  return ret_val
}

const getColor = (key) => {
  let summary = applicationState.summaries.get(key)
  if(summary == null) {
    return 'yellow'
  }

  let force_type = summary['force_type']
  if(force_type === 'BLUE') {
    return 'blue'
  } else {
    return 'red'
  }
}

onMounted(() => {
  applicationState.loadTrackData();
})

</script>

I can successfully get all the features and see the ID in each one but I'm looking for a way to get one feature based on it's ID and then zoom to it on the map. Any help would be appreciated!! Thanks!

1

There are 1 answers

0
JDun On

I was able to figure it out. For anyone with the same question, here is how you can get a single feature based on the properties id and zoom to it.

const flyToFeature = (feature) => {
  if (feature) {
    let foundFeature = source.value.source.getFeatures().find(function (f) {
      return f.get('id') === feature.track_id
    });
    if (foundFeature) {
      const extent = feature.getGeometry().getExtent()
      view.value.view.fit(extent);
    }
  }
}