vue3-openlayers - lineString 上的方向箭头作为单个功能

问题描述 投票:0回答:1

我正在尝试创建一个地图,它采用坐标并在地图上显示一条线,并带有从终点到中间起点的方向箭头。

现在我正在尝试在其中添加交互,因此当用户选择线条或箭头时,应该将其选择为单个功能。

目前我的线条和箭头是单独选择的,因为我实际上将它们用作图层中的不同特征。

如何将线条和箭头作为 vue3-openlayers 中的单个功能?

我的主要目标是使线条和箭头作为单个特征一起选择。 我看过开放层代码的示例,但不知道如何将它们与 vue3-openlayers 一起使用。

任何与我需要学习如何实施它相关的帮助或指导,我们都很感激。

以下是我的模板代码:

<div v-for="(data, index) in [[0.1,0.2], [0.3,0.4]" :key="index">
  <ol-feature>
    <ol-geom-line-string :coordinates="data"> </ol-geom-line-string>
      <ol-style>
        <ol-style-stroke
           color="purple"
           width="4"
        ></ol-style-stroke>
      </ol-style>
  </ol-feature>

  <ol-feature>
    <ol-geom-point
      :coordinates="calculateMidpoint(data)"
    ></ol-geom-point>
    <ol-style>
      <ol-style-icon
        :src="arrowIcon"
        :scale="0.06"
        :color="purple"
        :rotation="calculateRotation(data)"
      ></ol-style-icon>
    </ol-style>
  </ol-feature>
</div>
vuejs3 maps openlayers openlayers-6 vue3-openlayers
1个回答
0
投票

解决方案:

经过大量的尝试和错误,我终于能够弄清楚如何将箭头添加到矢量线上。

因此,线串是单个特征,在其顶部添加箭头作为另一个特征并不是解决方案,因为这使得线和箭头成为两个不同的特征。

如果您使用交互来选择这些功能中的任何一个,那么它们将被单独选择,因为这两个项目都是不同的功能,只是放置在彼此之上。

解决方案是将 LineString 作为一条线,并使用样式在其顶部添加箭头图像。

这是代码:

<template>
  <ol-feature>
    <ol-geom-line-string :coordinates="coordinates"> </ol-geom-line-string>
    <ol-style :overrideStyleFunction="overrideStyleFunction"></ol-style>
  </ol-feature>
</template>

安装脚本

import { pathStyleFunction } from "./map";
import { LineString } from "ol/geom";
import { Style } from "ol/style";
import Feature from "ol/Feature";

const props = defineProps(["strokeColor", "strokeWidth", "coordinates"]);

const overrideStyleFunction = (feature: Feature<LineString>): Style[] => {
  return pathStyleFunction(feature, props.strokeColor, props.strokeWidth);
};

const pathStyleFunction = (
  feature: Feature<LineString>,
  strokeColor: string,
  strokeWidth: number
): Style[] => {
  const geometry = feature.getGeometry();
  const styles = [
    // linestring style
    new Style({
      stroke: new Stroke({
        color: strokeColor,
        width: strokeWidth,
      }),
    }),
  ];

  if (geometry) {
    geometry.forEachSegment((start: Coordinate, end: Coordinate): void => {
      const rotation = calculateRotation(start, end);
      const mid = calculateMidpoint(start, end);

      styles.push(
        // Arrow Icon on top of line with rotation (of icon)
        new Style({
          geometry: new Point(mid),
          image: new Icon({
            src: arrow,
            rotateWithView: true,
            rotation,
            scale: 0.15,
            color: strokeColor,
          }),
        })
      );
    });
  }

  return styles;
};
© www.soinside.com 2019 - 2024. All rights reserved.