MelihAltintas / vue3-openlayers

Web map Vue 3.x components with the power of OpenLayers
https://vue3openlayers.netlify.app/
MIT License
629 stars 120 forks source link

How can I determine which polygon region is being triggered by mouse hover? #327

Closed FerretAngel closed 2 months ago

FerretAngel commented 3 months ago

Polygon regions cannot be bound with an ID, and I have searched through the documentation but have not found a way to add IDs to polygon regions. This means that I cannot accurately determine which polygon is being selected through the map's pointermove event. image image image

FerretAngel commented 3 months ago

My requirement is to map the feature objects with my own data IDs. How can I bind them together?

FerretAngel commented 3 months ago

I have encapsulated a polygon component by adding an id option for polygons myself. The usage is basically the same.

Usage:

<Polygon
    :id="item.id"
    :coordinates="item.lnglats"
    :fill="item.style.fill"
    :stroke="item.style.border"
    />

get id

<script setup lang="ts">
...
/**
 * @description 选择要素
 * @param e
 */
function featureSelected(e: SelectEvent) {
  const { selected } = e;
  const ids = selected.map((feature) => {
    return feature.getId();
  });
  emits("update:selctedFeatureIds", ids);
}
</script>

<template>
  <OlMap>
...
    <!-- 选择交互 -->
    <OlSelectInteraction
      @select="featureSelected"
      :condition="selectCondition"
    >
      <ol-style>
        <ol-style-stroke
          color="skyblue"
          :width="5"
        ></ol-style-stroke>
        <ol-style-fill color="rgba(255, 255, 0, 0.4)"></ol-style-fill>
      </ol-style>
    </OlSelectInteraction>
...
  </OlMap>
</template>

<style scoped lang="less">
....
</style>

component source code:

<script lang="ts" setup>
import { Feature } from "ol";
import type { Vector } from "ol/source";
import type { Coordinate } from "ol/coordinate";
import { Polygon } from "ol/geom";
import { type PropType, inject, onMounted, onUnmounted, type Ref } from "vue";
import { Stroke, Fill, Style } from "ol/style";
const { value: source } = inject("vectorSource") as Ref<Vector>;
const {
  coordinates,
  id,
  stroke: _stroke,
  fill: _fill,
} = defineProps({
  coordinates: {
    type: Array as PropType<Coordinate[]>,
    required: true,
  },
  id: {
    type: Number,
    default: Math.random(),
  },
  stroke: {
    type: Object as unknown as PropType<
      ConstructorParameters<typeof Stroke>[0]
    >,
  },
  fill: {
    type: Object as unknown as PropType<ConstructorParameters<typeof Fill>[0]>,
  },
});
if (!source) throw new Error("source is required");
const polygon = new Polygon([coordinates]);
const feature = new Feature({
  geometry: polygon,
});
feature.setId(id);
const stroke = new Stroke(_stroke);
const fill = new Fill(_fill);
feature.setId(id);
feature.setStyle(new Style({ stroke, fill }));
onMounted(() => {
  source.addFeature(feature);
});
onUnmounted(() => {
  source.removeFeature(feature);
});
</script>

<template></template>
d-koppenhagen commented 2 months ago

Please provide a minimal reproduction example. Ideally, you can fork the Stackblitz starter template for this purpose. From your code, I cannot extract what the polygons are and if they have an id. If you want to somehow iterate over Features of type Polygon, you can store the id in the properties of the Polygon Feature. From the code above, I see also that each Polygon component seems to create a new Map. I think this is not something you want isn't it?

FerretAngel commented 2 months ago

Sorry, just saw your reply now. Looks like there was a translation software glitch. Let me rephrase the issue: I want to assign an ID to each polygon. Why? So I can easily tell which polygon the user has selected. I checked the documentation, but couldn't find any way to assign an ID. I hope I can directly assign an ID to the polygon like this. image Or it could be like this to assign an ID to the feature. image

Please provide a minimal reproduction example. Ideally, you can fork the Stackblitz starter template for this purpose. From your code, I cannot extract what the polygons are and if they have an id. If you want to somehow iterate over Features of type Polygon, you can store the id in the properties of the Polygon Feature. From the code above, I see also that each Polygon component seems to create a new Map. I think this is not something you want isn't it?

d-koppenhagen commented 2 months ago

Hey, there is no ID Attribute but you can pass properties the the feature which could be { id: "my-id-1" }. This properties are assigned to the underlying OpenLayers Feature. You can retrieve the properties later to distinguish from a Feature/FeatureLike like this: feature.getProperties()?.id.

FerretAngel commented 2 months ago

Great. That's what I need. Thank you very much for your patient answer!