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

Can I use ol Constructor like this? #234

Closed
kankantian opened this issue Aug 8, 2023 · 12 comments
Closed

Can I use ol Constructor like this? #234

kankantian opened this issue Aug 8, 2023 · 12 comments

Comments

@kankantian
Copy link

const VectorLayer= inject("ol-layer-vector");
const VectorSource= inject("ol-source-vector");
let lineSource = new VectorSource()
let lineLayer = new VectorLayer({
        source: lineSource,
        style: new Style({
            image: new Circle({
                radius: 5,
                fill: new Fill({
                    color: '#F56C6C'
                })
            }),
            stroke: new Stroke({
                color: '#F56C6C',
                width: 4
            })
        })
    })
@kankantian kankantian changed the title Can I use ol Constructor like that? Can I use ol Constructor like this? Aug 8, 2023
@d-koppenhagen
Copy link
Collaborator

Not sure about the goal. Using this lib that way, isn't what it's build for.
The code is more aligned to the direct usage of Openlayers which you can use of course as well.

However: the injects won't provide the direct API from Openlayers. Please have a look at the implementation.

I mean: of course you can go this way (with a little adjustments). But I am wondering why?

The goal of this lib is to provide a reactive declarative API which automatically applied changes on the sources/layers. When implementing features the way you do, you have to keep in mind, that it's not reactive.

@kankantian
Copy link
Author

The reason I go this way is that I want to get the 'Linestring/Polygon' target drawed by 'ol-interaction-draw', and then I can remove it easier by using direct Openlayers APIs.

@d-koppenhagen
Copy link
Collaborator

Not sure if you are going the right way. Can you describe the context a bit more? Probably as kind of a user story? Maybe this helps to understand you use-case better and to point you in the right direction.

@kankantian
Copy link
Author

ok, I drawed a polygon with the demo. how to remove the polygon? I can't find a way.

<template>
  <input type="checkbox" id="checkbox" v-model="drawEnable" />
  <label for="checkbox">Draw Enable</label>

  <select id="type" v-model="drawType">
    <option value="Point">Point</option>
    <option value="LineString">LineString</option>
    <option value="Polygon">Polygon</option>
    <option value="Circle">Circle</option>
  </select>

  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="height: 400px"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />

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

    <ol-vector-layer>
      <ol-source-vector :projection="projection">
        <ol-interaction-draw
          v-if="drawEnable"
          :type="drawType"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style>
            <ol-style-stroke color="blue" :width="2"></ol-style-stroke>
            <ol-style-fill color="rgba(255, 255, 0, 0.4)"></ol-style-fill>
          </ol-style>
        </ol-interaction-draw>
      </ol-source-vector>

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

<script setup>
import { ref } from "vue";

const center = ref([40, 40]);
const projection = ref("EPSG:4326");
const zoom = ref(8);
const rotation = ref(0);

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

const drawstart = (event) => {
  console.log(event);
};

const drawend = (event) => {
  console.log(event);
};
</script>

@d-koppenhagen
Copy link
Collaborator

One way:

move your v-if to the source vector like this:

<ol-source-vector :projection="projection" v-if="drawEnable">

And: set drawEnable to false when calling drawend:

const drawend = (event) => {
  console.log(event);
  drawEnable.value = false;
};

see: https://stackblitz.com/edit/vue3-openlayers-template-xvaghv?file=package.json,src%2Fcomponents%2FTheMap.vue

@kankantian
Copy link
Author

Thanks , it works. But if I add points to the the source vector, when I move‘v-if‘ to the source vector, the points is also hidden. it's another problem.

<template>
  <input type="checkbox" id="checkbox" v-model="drawEnable" />
  <label for="checkbox">Draw Enable</label>

  <select id="type" v-model="drawType">
    <option value="Point">Point</option>
    <option value="LineString">LineString</option>
    <option value="Polygon">Polygon</option>
    <option value="Circle">Circle</option>
  </select>

  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="height: 400px"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />

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

    <ol-vector-layer>
      <ol-source-vector :projection="projection" v-if="drawEnable">
        <ol-feature v-for="index in 500" :key="index">
          <ol-geom-point
            :coordinates="[
              getRandomInRange(24, 45, 3),
              getRandomInRange(35, 41, 3),
            ]"
          ></ol-geom-point>
        </ol-feature>
        <ol-interaction-draw
          :type="drawType"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style>
            <ol-style-stroke color="blue" :width="2"></ol-style-stroke>
            <ol-style-fill color="rgba(255, 255, 0, 0.4)"></ol-style-fill>
          </ol-style>
        </ol-interaction-draw>
      </ol-source-vector>

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

<script setup>
import { ref } from 'vue';

const center = ref([40, 40]);
const projection = ref('EPSG:4326');
const zoom = ref(8);
const rotation = ref(0);

const drawEnable = ref(true);
const drawType = ref('Polygon');

const getRandomInRange = (from, to, fixed) => {
  return (Math.random() * (to - from) + from).toFixed(fixed) * 1;
};

const drawstart = (event) => {
  console.log(event);
};

const drawend = (event) => {
  console.log(event);
  drawEnable.value = false;
};
</script>

@d-koppenhagen
Copy link
Collaborator

What if you place the points in a separate layer with its own source vector?

@kankantian
Copy link
Author

kankantian commented Aug 11, 2023

Thanks , it works. Another question: if it is possible to make the mouse pointer locate to the start point or end point automatically when drawing a line, just like the style implemented by 'ol-interaction-snap'?And how can I get the start point or end point in order to obtain their properties.

@d-koppenhagen
Copy link
Collaborator

Sorry I didn't catch it. Can you describe it a bit more?
When do you want to where do you want to snap? Right after the first click (when starting the line)? At the second click? Something else? Can you describe a concrete example?

About the start/end point: You should receive an event for each point with all points already drawn, the first one and the last one are the relevant ones. Or did I got something wrong?

@kankantian
Copy link
Author

Ok, I add the points in another layer. For example, I draw a line form point A to B, I hope the mouse automatically snaps to point A when approaching point A, snaps to point B when approaching point B.
Also, How to access the attributes of point A or point B when drawing a line.

<ol-vector-layer>
      <ol-source-vector :projection="projection">
        <ol-feature v-for="index in 500" :key="index">
          <ol-geom-point
            :coordinates="[
              getRandomInRange(24, 45, 3),
              getRandomInRange(35, 41, 3),
            ]"
          ></ol-geom-point>
        </ol-feature>
      </ol-source-vector>
</ol-vector-layer>
<ol-vector-layer>
  <ol-source-vector v-if="drawEnable">
        <ol-interaction-draw
          :type="drawType"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style>
            <ol-style-stroke color="blue" :width="2"></ol-style-stroke>
            <ol-style-fill color="rgba(255, 255, 0, 0.4)"></ol-style-fill>
          </ol-style>
        </ol-interaction-draw>
      </ol-source-vector>

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

@d-koppenhagen
Copy link
Collaborator

@kankantian sorry but I am quite busy currently. Can you please open separate issues (snap-problem and attribute access). The original issue here has already been answered, so I will close this issue.

@kankantian
Copy link
Author

ok,thanks for your time

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