ghettovoice / vuelayers

Web map Vue components with the power of OpenLayers
https://vuelayers.github.io/
MIT License
682 stars 230 forks source link

How to add openlayers feature to vl-layer-vector #476

Closed niklashaa closed 2 years ago

niklashaa commented 2 years ago

Hello How can synchronize an array of openlayers features with the features prop of vl-layer-vector. The following lets Vue exit stating "too much recursion".

<template>
  <vl-map>
    <vl-view ref="view" :zoom.sync="zoom" :center.sync="center" />

    <vl-layer-tile>
      <vl-source-osm
        url="https://cartodb-basemaps-c.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
      ></vl-source-osm>
    </vl-layer-tile>

    <vl-layer-vector>
      <vl-source-vector ref="vectorSource" :features="features" />
    </vl-layer-vector>
  </vl-map>
</template>

<script>
export default {
  data() {
    return {
      zoom: 6,
      center: [0, 0],
      coordinates: [
        [
          [-2.8125000000000004, 5.11282977849946],
          [-3.317871093750001, 6.795535025719516],
          [1.1645507812499996, 6.009459238059563],
          [-2.263183593750001, 4.674979814820247],
          [-2.8125000000000004, 5.11282977849946],
        ],
      ],
      id: "D1E2CE406F3411ECBA294201C0BE0104",
    };
  },
  computed: {
    myFeature() {
      const polygon = new ol.geom.Polygon(this.coordinates);
      const feature = new ol.Feature({
        type: "Polygon",
        id: this.id,
        geometry: polygon,
      });
      return feature;
    },
  },
};
</script>
ghettovoice commented 2 years ago

Hello @niklashaa , you are passing into the vl-source-vector features property, but I don't see it's definition in your code sample. Show me how do you fill this source with features, pls.

niklashaa commented 2 years ago

Hi @ghettovoice I prepared a jsfiddle that reproduces the problem. Depending on the browser it's either "Maximum call stack size exceeded" (Chromium) or "InternalError: too much recursion" (Firefox).

ghettovoice commented 2 years ago

Hi @niklashaa , there is fixed demo https://jsfiddle.net/ghettovoice/okbhs71L/7/. You should not pass OpenLayers instances into Vue reactive props, because they have circular links. Instead you should pass GeoJSON encoded features. Also I have added data-projection="EPSG:4326" because polygon coordinates seems in that projection.

niklashaa commented 2 years ago

Hi @ghettovoice,

thanks a lot for your response! You were mentioning in this comment that using the Openlayers native API can improve performance. Do you happen to have a jsfiddle that demonstrates how to use this API?

niklashaa commented 2 years ago

Ok I just found this comment where OpenLayers features are added in the mounted hook of vl-source-vector. I think this answers my question of how to use the native OpenLayers API. Thanks a lot!