Git Product home page Git Product logo

vue3-openlayers's Introduction

vue3-openlayers

Web map Vue components with the power of OpenLayers

OpenLayers Useful 3rd party libraries https://openlayers.org/3rd-party/

Netlify Status NPM version NPM Minified Size NPM Minzipped Size

Downloads Github Open Issiues Github Closed Issiues GitHub forks GitHub Stars

Open in StackBlitz


Links

6 hours of debugging can save you 5 minutes of reading documentation :) please read the doc :)

Install

# install current vue3-openlayers version
npm install vue3-openlayers
or
yarn add vue3-openlayers

Stargazers repo roster for @MelihAltintas/vue3-openlayers

Overview

vue3-openlayers is components library that brings the powerful OpenLayers API to the Vue3 reactive world. It can display maps with tiled, raster or vector layers loaded from different sources.

Alt Text

Requirements

Run End-to-End Tests with Playwright

# Install browsers for the first run
npx playwright install

# Runs the end-to-end tests
npm run test:e2e

# Runs the end-to-end tests in interactive UI mode (for local development)
npm run test:e2e:ui

# Runs the tests in debug mode
npm run test:e2e:debug

# Runs the tests in trace mode (to time-travel between actions)
npm run test:e2e:trace

# Serve test report (and inspect trace when)
npm run test:e2e:report

# Runs the tests only on Chromium
npm run test:e2e -- --project=chromium
# Runs the tests of a specific file
npm run test:e2e -- tests/example.spec.ts

# Run tests and record new screenshots locally using the same image as in CI env
docker compose run screenshot-update

Screenshots

Please note, when recording screenshots locally the may differ from the platform (linux) in CI. This results in:

  • a: a different file name
  • b: a slightly different screenshot

So tackle this issue, please always record screenshots locally using the docker compose file which will use the same image/platform as in CI.

docker compose run screenshot-update

License

MIT (c) Melih Altıntaş

vue3-openlayers's People

Contributors

aleksmelnyk avatar aocneanu avatar athdemond avatar bmanojlovic avatar chady avatar christophfriedrich avatar d-koppenhagen avatar dominicgebhart avatar fflyingcat avatar josx avatar juzraai avatar karukenert avatar kurbar avatar laddish avatar lisarx avatar lukas-zaugg avatar marktlinn avatar mathiash98 avatar meister-eder avatar melihaltintas avatar mwargan avatar okame avatar persiliao avatar pjreed avatar r3volut1oner avatar schelmo avatar wendellwt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue3-openlayers's Issues

(request) - features parameter for the Modify & Select interaction

I would like to suggest the features parameter for the Modify interaction.

Currently if a feature is selected to enable the Modify interaction, all the features present in an array would be added to the Modify features parameter.

if I understand correctly the features parameter on the Modify interaction allows to select which features can be modified.

In this example, if one country is selected to enable the editEnable, they would all be editable.

      <ol-vector-layer>
        <ol-source-vector :url="'https://openlayers.org/en/latest/examples/data/geojson/countries.geojson'" :format="geoJsonFormat" :projection="data.projection">
          <ol-interaction-modify v-if="editEnable" @modifyend="modifyend" @modifystart="modifystart"> </ol-interaction-modify>
          <ol-interaction-snap v-if="editEnable" />
        </ol-source-vector>
      </ol-vector-layer>
      <ol-interaction-select @select="featureSelected" :condition="selectCondition">
        <ol-style>
          <ol-style-stroke :color="'red'" :width="2"></ol-style-stroke>
          <ol-style-fill :color="`rgba(255, 0, 0, 0.4)`"></ol-style-fill>
        </ol-style>
      </ol-interaction-select>

EDIT:
If possible to add the features parameter on the Select Interaction as well.

How to Save/Recover/Program/Add/Delete Features ?

Not really a bug but I need advice from the developpers because I am completely lost on the logic behind how to deal with feature states

the doc is not clear; at least for me.

I have this template

 <ol-interaction-select @select="featureSelected" :condition="selectCondition" :features="selectedFeatures">
    <ol-style>
      <ol-style-stroke :color="'red'" :width="2"></ol-style-stroke>
      <ol-style-fill :color="`rgba(255, 0, 0, 0.4)`"></ol-style-fill>
    </ol-style>
  </ol-interaction-select>
<ol-source-vector :projection="projection">
   <ol-interaction-modify v-if="modifyEnabled" :features="selectedFeatures" @modifyend="modifyend"></ol-interaction-modify>
   <ol-interaction-draw v-if="drawEnable" :type="drawType" @drawend="drawend"></ol-interaction-draw>
</ol-source-vector>

and the logic:

import {Collection} from "ol"
setup(){
       const selectedFeatures = ref(new Collection())
       let newFeatures = ref([])

       const drawend = (event) => {
          newFeatures.value.push({type:event.target.type_, coordinates:event.target.sketchCoords_})
          modifyEnabled.value = true
          drawEnable.value = false
          emit()
       }
       const modifyend = (event) => {
           // how to know which feature I am editing and how to get the new value ?
           emit()
        }
        function featureSelected(event) {
          const feature = event.target.getFeatures()
          selectedFeatures.value = event.target.getFeatures()
          if(feature.array_ && feature.array_.length) {
             let coordinates = null
             if(feature.array_[0].values_.geometries && feature.array_[0].values_.geometries.length) {
               coordinates = feature.array_[0].values_.geometries[0].flatCoordinates
             } else if(feature.array_[0].values_.geometry) {
               coordinates = feature.array_[0].values_.geometry.flatCoordinates
             }
            console.log(coordinates)
        }
    }
}

when I select I get the new coordinates with featureSelected but that seems cumbersome because I have to dig down into the object and there is no real relation between what I am editing and my data because newFeatures is not being updated.

selectedFeatures and newFeatures have different types so I need to translate one to the other and vice versa ?

Ideally everything should be sharing a single reactive value/format somewhere between the collection and the modified one but they are not linked/bridged ?? Ideally I would just like to put newFeatures in the modify component but I need to track selectedFeature instead and then copy values back to my newFeatures ?

In newFeatures I have a collection of simple data that has no reference to the dom like [{type:'Point',coordinates:[3,2,5]}]
in selectedFeatures I have a complex object so How am I supposed to keep references between both objects?

so I can get new values from console.log(coordinates) but what am I supposed to do with these ? How do I update my newFeatures array? is there no simple feature getter and setters ?

Clearly there must be something I am missing because I can't even extract feature type like LineString, circle, etc... from the modify event object.

in featureSelected I need to do selectedFeatures.value = event.target.getFeatures() and in drawend I have to do selectedFeatures.value.push(event.feature). What is the reason ?

or I could do without newFeatures if there is a way to get all current features from ol-interaction-draw component for export? but in which format to store in database so I can re-edit them later ?

Could you clarify for me? Sorry but I have been on this for 2 days now.

Full code https://gist.github.com/signmeuptwice/c45085e64e09828bc6f3bc81635fdb9e

vue3-openLayers demo template error `undefined is not an object (evaluating 'new format.GeoJSON')`

used the code from the vue3-openlayers example page https://vue3openlayers.github.io/demo/

I only changed path to png imports and imported import OpenLayersMap from 'vue3-openlayers'
I get error undefined is not an object (evaluating 'new format.GeoJSON')

of course if I download the repository and build the app from scratch it works but importing the plugin in my existing project fails

What am I doing wrong ?

here is my full code:

`

  <ol-view ref="view" :center="center" :rotation="rotation" :zoom="zoom" :projection="projection" />

  <ol-swipe-control ref="swipeControl" v-if="layerList.length > 0" :layerList="layerList" />

  <ol-layerswitcherimage-control />

  <ol-tile-layer ref="osmLayer" title="OSM">
    <ol-source-osm />
  </ol-tile-layer>

  <ol-tile-layer ref="jawgLayer" title ="JAWG">
    <ol-source-xyz crossOrigin='anonymous' url="https://c.tile.jawg.io/jawg-dark/{z}/{x}/{y}.png?access-token=87PWIbRaZAGNmYDjlYsLkeTVJpQeCfl2Y61mcHopxXqSdxXExoTLEv7dwqBwSWuJ" />
  </ol-tile-layer>

  <ol-control-bar>
    <ol-control-toggle html="<i class='fas fa-map-marker'></i>" className="edit" title="Point" :onToggle="(active)=>changeDrawType(active,'Point')" />
    <ol-control-toggle html="<i class='fas fa-draw-polygon'></i>" className="edit" title="Polygon" :onToggle="(active)=>changeDrawType(active,'Polygon')" />
    <ol-control-toggle html="<i class='fas fa-circle'></i>" className="edit" title="Circle" :onToggle="(active)=>changeDrawType(active,'Circle')" />
    <ol-control-toggle html="<i class='fas fa-grip-lines'></i>" className="edit" title="LineString" :onToggle="(active)=>changeDrawType(active,'LineString')" />
    <ol-control-videorecorder @stop="videoStopped">

    </ol-control-videorecorder>
    <ol-control-printdialog />
  </ol-control-bar>

  <ol-mouseposition-control />
  <ol-fullscreen-control />
  <ol-overviewmap-control>
    <ol-tile-layer>
      <ol-source-osm />
    </ol-tile-layer>
  </ol-overviewmap-control>

  <ol-scaleline-control />
  <ol-rotate-control />
  <ol-zoom-control />
  <ol-zoomslider-control />
  <ol-zoomtoextent-control :extent="[23.906,42.812,46.934,34.597]" tipLabel="Fit to Turkey" />

  <ol-context-menu :items="contextMenuItems" />

  <ol-interaction-clusterselect @select="featureSelected" :pointRadius="20">
    <ol-style>
      <ol-style-stroke color="green" :width="5"></ol-style-stroke>
      <ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>
      <ol-style-icon :src="markerIcon" :scale="0.05"></ol-style-icon>
    </ol-style>
  </ol-interaction-clusterselect>

  <ol-interaction-select @select="featureSelected" :condition="selectCondition" :filter="selectInteactionFilter" v-if="!drawEnable">
    <ol-style>
      <ol-style-stroke color="green" :width="10"></ol-style-stroke>
      <ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>
      <ol-style-icon :src="markerIcon" :scale="0.05"></ol-style-icon>
    </ol-style>
  </ol-interaction-select>


  <ol-vector-layer title="AIRPORTS" :preview="require('../../../../public/img/map/tr.png')">
    <ol-source-vector ref="cities" url="https://raw.githubusercontent.com/alpers/Turkey-Maps-GeoJSON/master/tr-cities-airports.json" :format="geoJson" :projection="projection" >

      <ol-interaction-modify v-if="drawEnable" @modifyend="modifyend" @modifystart="modifystart">

      </ol-interaction-modify>

      <ol-interaction-draw v-if="drawEnable" :type="drawType" @drawend="drawend" @drawstart="drawstart">

      </ol-interaction-draw>

      <ol-interaction-snap v-if="drawEnable" />

    </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="blue"></ol-style-fill>
      </ol-style-circle>
    </ol-style>
  </ol-vector-layer>

  <ol-vector-layer :updateWhileAnimating="true" :updateWhileInteracting="true" title="STAR" :preview="require('../../../../public/img/map/star.png')">
    <ol-source-vector ref="vectorsource">

      <ol-animation-shake :duration="2000" :repeat="5">
        <ol-feature v-for="index in 20" :key="index">
          <ol-geom-point :coordinates="[getRandomInRange(24,45,3),getRandomInRange(35,41,3)]"></ol-geom-point>

          <ol-style>
            <ol-style-icon :src="starIcon" :scale="0.1"></ol-style-icon>
          </ol-style>
        </ol-feature>
      </ol-animation-shake>

    </ol-source-vector>

  </ol-vector-layer>

  <ol-animated-clusterlayer :animationDuration="500" :distance="40" title="CLUSTER" :preview="require('../../../../public/img/map/cluster.png')">

    <ol-source-vector ref="vectorsource">
      <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-style :overrideStyleFunction="overrideStyleFunction">
      <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="20">
        <ol-style-stroke color="black" :width="15" :lineDash="[]" lineCap="butt"></ol-style-stroke>
        <ol-style-fill color="black"></ol-style-fill>
      </ol-style-circle>

      <ol-style-text>
        <ol-style-fill color="white"></ol-style-fill>
      </ol-style-text>
    </ol-style>

  </ol-animated-clusterlayer>

  <ol-overlay :position="selectedCityPosition" v-if="selectedCityName !='' && !drawEnable">
    <template v-slot="slotProps">
      <div class="overlay-content">
        {{selectedCityName}} {{slotProps}}
      </div>
    </template>
  </ol-overlay>

  <ol-vector-layer>
    <ol-source-vector>
      <ol-feature ref="animationPath">
        <ol-geom-line-string :coordinates="path"></ol-geom-line-string>
        <ol-style>
          <ol-style-stroke color="red" width="7"></ol-style-stroke>
        </ol-style>
      </ol-feature>
      <ol-animation-path v-if="animationPath" :path="animationPath.feature" :duration="4000" :repeat="10">

        <ol-feature>
          <ol-geom-point :coordinates="path[0]"></ol-geom-point>
          <ol-style>
            <ol-style-circle :radius="10">
              <ol-style-fill color="blue"></ol-style-fill>
              <ol-style-stroke color="blue" :width="2"></ol-style-stroke>
            </ol-style-circle>
          </ol-style>

        </ol-feature>
      </ol-animation-path>
    </ol-source-vector>

  </ol-vector-layer>

</ol-map>

</template>

<script>
import OpenLayersMap from 'vue3-openlayers'
import {ref, inject, onMounted} from 'vue'
import markerIcon from '../../../../public/img/map/marker.png'
import starIcon from '../../../../public/img/map/star.png'

export default {
setup() {

const center = ref([34, 39.13])
const projection = ref('EPSG:4326')
const zoom = ref(6)
const rotation = ref(0)

const format = inject('ol-format');

const geoJson = new format.GeoJSON();

const selectConditions = inject('ol-selectconditions')

const selectCondition = selectConditions.pointerMove;

const selectedCityName = ref('')
const selectedCityPosition = ref([])

const extent = inject('ol-extent');

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

const contextMenuItems = ref([])
const vectorsource = ref(null)
const view = ref(null);

const drawEnable = ref(false)
const drawType = ref("Point")


const changeDrawType = (active, draw) => {
  drawEnable.value = active
  drawType.value = draw
}

contextMenuItems.value = [{
  text: 'Center map here',
  classname: 'some-style-class', // add some CSS rules
  callback: (val) => {
    view.value.setCenter(val.coordinate)

  } // `center` is your callback function
},
  {
    text: 'Add a Marker',
    classname: 'some-style-class', // you can add this icon with a CSS class
    // instead of `icon` property (see next line)
    icon: markerIcon, // this can be relative or absolute
    callback: (val) => {
      console.log(val)
      let feature = new Feature({
        geometry: new Geom.Point(val.coordinate),
      });
      vectorsource.value.source.addFeature(feature)
    }
  },
  '-' // this is a separator
]

const featureSelected = (event) => {

  if (event.selected.length == 1) {

    selectedCityPosition.value = extent.getCenter(event.selected[0].getGeometry().extent_)
    selectedCityName.value = event.selected[0].values_.name;
  } else {
    selectedCityName.value = '';
  }

}

const overrideStyleFunction = (feature, style) => {

  let clusteredFeatures = feature.get('features');
  let size = clusteredFeatures.length;

  let color = size > 20 ? "192,0,0" : size > 8 ? "255,128,0" : "0,128,0";
  var radius = Math.max(8, Math.min(size, 20));
  let dash = 2 * Math.PI * radius / 6;
  let calculatedDash = [0, dash, dash, dash, dash, dash, dash];

  style.getImage().getStroke().setLineDash(dash);
  style.getImage().getStroke().setColor("rgba(" + color + ",0.5)");
  style.getImage().getStroke().setLineDash(calculatedDash);
  style.getImage().getFill().setColor("rgba(" + color + ",1)");

  style.getImage().setRadius(radius)

  style.getText().setText(size.toString());

}

const selectInteactionFilter = (feature) => {
  return feature.values_.name != undefined;
};

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)
}

const modifystart = (event) => {
  console.log(event)

}

const modifyend = (event) => {
  console.log(event)
}

const swipeControl = ref(null)
const jawgLayer = ref(null)
const osmLayer = ref(null)
const layerList = ref([])
onMounted(() => {

  layerList.value.push(jawgLayer.value.tileLayer);
  layerList.value.push(osmLayer.value.tileLayer);
  console.log(layerList.value)

});

const path = ref([
  [
    25.6064453125,
    44.73302734375001
  ],
  [
    27.759765625,
    44.75500000000001
  ],
  [
    28.287109375,
    43.32677734375001
  ],
  [
    30.55029296875,
    46.40294921875001
  ],
  [
    31.69287109375,
    43.04113281250001
  ]

])
const animationPath = ref(null);


return {
  center,
  projection,
  zoom,
  rotation,
  geoJson,
  featureSelected,
  selectCondition,
  selectedCityName,
  selectedCityPosition,
  markerIcon,
  overrideStyleFunction,
  getRandomInRange,
  contextMenuItems,
  vectorsource,
  view,
  selectInteactionFilter,
  drawstart,
  drawend,
  modifystart,
  modifyend,
  drawEnable,
  drawType,
  layerList,
  jawgLayer,
  swipeControl,
  osmLayer,
  starIcon,
  changeDrawType,
  path,
  animationPath,
  OpenLayersMap
}
},
}
</script>

`

package.json

"dependencies": { "@tiptap/extension-highlight": "^2.0.0-beta.15", "@tiptap/extension-text-align": "^2.0.0-beta.22", "@tiptap/starter-kit": "^2.0.0-beta.101", "@tiptap/vue-3": "^2.0.0-beta.56", "axios": "*", "elm-pep": "*", "gpx-parser-builder": "*", "moment": "*", "postcss-loader": "*", "raw-loader": "*", "sass": "*", "svg-url-loader": "*", "toastr": "*", "vue": "^3.2.6", "vue-loader": "^16.5.0", "vue-material-design-icons": "*", "vue3-datepicker": "*", "vue3-openlayers": "*", "ol": "*" }

option to HIDE vector layers in ol-layerswitcherimage-control Menu

would be nice to be able to hide Vector layers like drawings from ol-layerswitcherimage-control menu (vectors still displayed of course)

at the moment the menu always shows this extra layer even if no drawings are present

something like
<ol-layerswitcherimage-control :vectorLayers="false" />

Describe alternatives you've considered
removing manually with ol functions but that seems terribly wrong to instantiate something just to remove it

Usage with Nuxt 3

Hi, I'm trying to get your package to work with Nuxt 3.
I tried importing it in my nuxt.config.ts like this:

import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
    buildModules: [
        ['vue3-openlayers', '@pinia/nuxt', '@intlify/nuxt3', '@vueuse/core/nuxt']
    ],
    intlify: {
       // ...
},
    build: {
        // ...
    }
})

Which gives me this error on app startup

ERROR  Cannot start nuxt:  Cannot read property 'webpackJsonpvue3_openlayers' of undefined

  at module.exports.00ee (node_modules/vue3-openlayers/dist/vue3-openlayers.common.js:191:148)
  at node_modules/vue3-openlayers/dist/vue3-openlayers.common.js:203:9
  at g (node_modules/jiti/dist/jiti.js:1:55111)
  at requireModule (node_modules/@nuxt/kit/dist/index.mjs:86:26)
  at installModule (node_modules/@nuxt/kit/dist/index.mjs:1241:50)
  at initNuxt (node_modules/nuxt3/dist/index.mjs:905:11)
  at async load (node_modules/nuxi/dist/chunks/dev.mjs:6713:9)
  at async Object.invoke (node_modules/nuxi/dist/chunks/dev.mjs:6752:5)
  at async _main (node_modules/nuxi/dist/chunks/index.mjs:386:7)

When I place the import at the end of the buildModules array, the error disappears, but upon opening my testpage I receive the following errors:

[Vue warn]: Failed to resolve component: ol-map
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Failed to resolve component: ol-view
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Failed to resolve component: ol-tile-layer
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
[Vue warn]: Failed to resolve component: ol-source-osm
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
Invalid value used as weak map key
  at WeakMap.set (<anonymous>)  
  at normalizePropsOptions (./node_modules/vue/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:2689:11)  
  at createComponentInstance (./node_modules/vue/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:6115:23)  
  at renderComponentVNode (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:197:22)  
  at Module.ssrRenderComponent (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:623:12)  
  at _sfc_ssrRender (file://./.nuxt/dist/server/server.mjs:4813:31)  
  at renderComponentSubTree (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:263:13)  
  at renderComponentVNode (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:214:16)  
  at renderVNode (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:304:22)  
  at renderVNode (./node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:310:17)

Not sure if this is the right place to ask, but I'm stuck.
Thanks in advance!

[Warning] No map visible because the map container's width or height are 0

from doc example, inserting the following component

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

gives error

[Warning] No map visible because the map container's width or height are 0.

I imported

import 'vue3-openlayers/dist/vue3-openlayers.css'

tested in my project and with fresh project from latest source

draw, snap, modify interactions

Awesome project you got going on here and very good job.

If I could suggest some components, it would definitely be the draw, modify and snap interactions. Those would be awesome to have.

After losing connection, random tiles stop updating.

Describe the bug
Map fails to process 'white' tiles if user loses connection mid usage.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://vue3openlayers.netlify.app/componentsguide/map/
  2. Zoom to random spot on map.
  3. Disable internet connection
  4. Move around the map.
  5. White tiles begin to load.
  6. Re-connect, rest of the map starts working again, white tiles remain white.

Expected behavior
White tiles should initiate new call for source img.
Can't reproduce bugs on official openlayers examples.

Screenshots
image

Desktop (please complete the following information):

  • OS: ubuntu
  • Browser: chrome

[Error] Unhandled Promise Rejection: TypeError: null is not an object (evaluating 'currentRenderingInstance.isCE')

Describe the bug
Copying the ol-map sample fires this error

[Error] Unhandled Promise Rejection: TypeError: null is not an object (evaluating 'currentRenderingInstance.isCE')
	logError (runtime-core.esm-bundler.js:6664)
	handleError (runtime-core.esm-bundler.js:305)
	callWithErrorHandling (runtime-core.esm-bundler.js:259)
	flushJobs (runtime-core.esm-bundler.js:483)
	promiseReactionJob

To Reproduce
Steps to reproduce the behavior:

  1. clone my sample repository https://github.com/eltorio/hello-openlayers.git
  2. yarn install && yarn serve
  3. goes to http://127.0.0.1:8080/
  4. See error

Expected behavior
Display a full width map and height 400px

package.json

{
  "name": "hello-openlayers",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@fortawesome/fontawesome-free": "5.15.3",
    "@popperjs/core": "2.9.1",
    "@tailwindcss/forms": "0.2.1",
    "@vue/compiler-sfc": "3.0.7",
    "chart.js": "2.9.4",
    "core-js": "3.9.1",
    "gulp": "4.0.2",
    "gulp-append-prepend": "1.0.8",
    "tailwindcss": "2.0.4",
    "vue": "3.0.7",
    "vue-router": "4.0.5",
    "vue3-openlayers": "^0.1.55"
  },
  "devDependencies": {
    "@babel/core": "7.13.10",
    "@babel/eslint-parser": "7.13.10",
    "@vue/cli-plugin-babel": "5.0.0-alpha.7",
    "@vue/cli-plugin-eslint": "5.0.0-alpha.7",
    "@vue/cli-service": "5.0.0-alpha.7",
    "autoprefixer": "10.2.5",
    "eslint": "7.22.0",
    "eslint-plugin-vue": "7.7.0",
    "postcss": "8.2.8",
    "vue-template-compiler": "2.6.12"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

**Vue **

<template>
<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-map>
</template>
<script>
import {
    ref
} from 'vue'
export default {
    setup() {
        const center = ref([40, 40])
        const projection = ref('EPSG:4326')
        const zoom = ref(8)
        const rotation = ref(0)
        return {
            center,
            projection,
            zoom,
            rotation
        }
    },
}
</script>

main.js

import { createApp } from "vue";
import { createWebHistory, createRouter } from "vue-router";

// styles

import "@fortawesome/fontawesome-free/css/all.min.css";
import "@/assets/styles/tailwind.css";

// mouting point for the whole app

import App from "@/App.vue";

//vue3 openlayers
import OpenLayersMap from 'vue3-openlayers';
import 'vue3-openlayers/dist/vue3-openlayers.css';
import Test from "@/views/OpenLayers.vue";

// routes

const routes = [
  {
    path: "/",
    component: Test,
  },
  { path: "/:pathMatch(.*)*", redirect: "/" },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

const app = createApp(App);

app.use(router);
app.use(OpenLayersMap);
app.mount("#app");

layer name attribute

is it possible for you to add a the prop name to each of the layer types.

This will help with labeling and identifying layers.

Thanks!

Slow zooming when zoom has a reactive variable and zoomChanged is listened

Describe the bug
I detected an odd behavior when I tried to connect a state management system (vuex, pinia...):
Here is my view:
<ol-view ref="view" :center="center" :zoom="appStore.getMapZoomLevel()" @zoomChanged="zoomChanged" />
The only thing the store getter getMapZoomLevel() is just returning the value:
getMapZoomLevel() { return this.mapZoomLevel; },
And the action to set it:
setMapZoomLevel(zoomLevel) { this.mapZoomLevel = zoomLevel; },
I listen to the change event like such:
function zoomChanged(newzoom) { console.log(newzoom); appStore.setMapZoomLevel(newzoom); }
And I see non-integers numbers being dumped on the console and the scroll (using the mouse wheel) is veeery slow. It doesn't move by integers, that's what I mean.

You can reproduce it much simpler without state management system, just a reactive variable in zoom prop. Follow the steps in "To Reproduce" section:

To Reproduce
Steps to reproduce the behavior:

  1. Declare a very simple map with nothing (no need)
  2. Declare const zoom = ref(10) and use zoom in zoom prop (:zoom="zoom")
  3. Listen to the zoomChanged event: @zoomChanged="zoomChanged"
  4. Create zoomChanged function: function zoomChanged(newzoom) { zoom.value = newzoom; }
  5. Scroll back and forth with the mouse wheel and observe what happens... very slow behavior.

Expected behavior
As fast (or normal) as it behaves when there is no reactive variable being used.

Maybe I'm missing something, but with this behavior I wouldn't be able to share the zoom level on a global state and being able to zoom in and zoom out using external components by changing this value, which, I think, should be possible.

Am I missing something and doing it all wrong?
Thank you!
:)

DomException with ol-source-vector, only with KML data

When using an ol-source-vector with the KML data type, the component will not load, and prints this error:

runtime-core.esm-bundler.js:2143 Uncaught (in promise) DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
    at traverse (http://localhost:8080/js/chunk-vendors.js:4620:27)

I've tried to create a standalone example, but in all my attempts the error doesn't happen. I only see it in my large quasar application, so possibly there's some interference there.

My broken Example:

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

    <ol-fullscreen-control />

    <ol-zoom-control />

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

    <ol-vector-layer>
      <ol-source-vector :url="url" :format="kml"> </ol-source-vector>
    </ol-vector-layer>
  </ol-map>
</template>

<script lang="ts">
import { defineComponent, ref, inject } from "vue";

export default defineComponent({
  name: "Map",
  components: {},
  props: {
    kmlData: { type: Object as any }
  },
  setup() {
    const center = ref([-81.51214560283877, 41.07716717533248]);
    const projection = ref("EPSG:4326");
    const zoom = ref(10);
    const rotation = ref(0);

    const url = ref("https://openlayers.org/en/latest/examples/data/kml/2012_Earthquakes_Mag5.kml");
    const format: any = inject("ol-format");
    const kml = new format.KML();

    return {
      center,
      projection,
      zoom,
      rotation,
      kml,
      url
    };
  }
});
</script>

I did get it working though! I had to add some extra settings to my KML config::

const kml = new format.KML({
  extractStyles: false,
  defaultStyle: []
});

This issue is mostly in case someone else has the same problem. Please feel free to close.

Feature properties

How to set properties for "feature"?

Is there some method to setting "properties" to "feature", like:

<ol-source-cluster :distance="40">
    <ol-source-vector>
        <ol-feature
            v-for="{id, coordinates} in markers"
            :key="id"
            @click="clickFeature"
            @setProperties="setProperties(id)">
            <ol-geom-point :coordinates="coordinates"/>
    
            <ol-interaction-modify
                :condition="selectCondition"
                @modifyend="modifyEnd($event, id)"
                @modifystart="modifyStart">
            </ol-interaction-modify>
        </ol-feature>
    
        <ol-interaction-select @select="featureSelectedTwo($event, id)">
        </ol-interaction-select>
    </ol-source-vector>
</ol-source-cluster>

or how I can provide properies and handle them?

Map not visible after v-show

"vue3-openlayers": "0.1.*",

Hiding the map with v-show results in a blank canvas and error message [Warning] No map visible because the map container's width or height are 0. (vue-0eab179a9c5c1648c422.js, line 51744) when show = true

Not sure what to do about this; is this a bug or is there something to do ?

<ol-map
        ref="olMap"
        :key="uid+'-map'"
        class="ol-map-wrapper"
        :default-interactions="interactionOptions"
        style="height: 350px; width: 720px"
        v-on:mousedown="disableUpdate"
        v-on:mouseup="enableUpdate"
    >

calling olMap.value.map.updateSize() solves the visibility issue but I still have the warning

getTileGrid in ol-source-wmts

getTileGrid in ol-source-wmts is a computed value ,but my project has a error 'Unknown TILEMATRIX' , i think if getTileGrid can be a prop

Simplify interactions by events on geometries

Is your feature request related to a problem? Please describe.
Using interactions are super difficult to learn - it does not make sence to use another component, wire it by callback and properties to just make onClick on an geometry. Or specifically, it makes sence only to devs who have OL internals in mind. ;-)

Describe the solution you'd like
Offer set of events, props on geometries or featues itself as it is usual in Vue ecosystem.

<ol-view @click="hoverPlace = false">
...
        <ol-feature v-for="place in places" @hover="hoverPlace = place.id" @click="selectedPlace(place.id)">
          <ol-geom-point :coordinates="fromLonLat(place.lonLat)" />
          <ol-style :z-index="place.type === 'ln_verified' ? 10 : 1">
            <ol-style-icon src="assets/ln_marker.svg" :scale="hoverPlace === place.id ? 0.1 : 0.05" />
          </ol-style>
        </ol-feature>
...
selectedPlace (place) {
  $router.push('/place/' + place)
}

Example form Mapbox: https://v-mapbox.geospoc.io/api/marker.html#events

Describe alternatives you've considered
Use any other library what offers simpler aproach in Vue - used Leaflet and MapboxJS, both are easy to use.

TileGrid Support

Hey all!
Thanks for providing this library, it makes our work with Vue and OL a lot easier!
But - is there any reason that you don't support the TileGrid for SourceXYZ?

We need it for our project and I've already included it in a local version, but it would be cool if you could provide the support officially as well. If you want, I can make a pull request with our local version. :)

v-if in custom ol-control-toggle duplicates all controls

I added custom ol-control-toggle

<ol-control-toggle v-if="selectedFeatures && selectedFeatures.array_ && selectedFeatures.array_.length > 0" html="<i class='fas fa-trash'></i>" className="edit" title="bin" :onToggle="(active)=>deleteSelectedFeature()" />

v-if is default false
All controls are duplicated when v-if becomes true

Source change on modify & stopClick parameter on draw interaction

in the following example using the draw interaction with the my generated features. If I draw a polygon and then click on another polygon to select it and modify it, the drawn one disappears because the source changes.

However when using the :url features if you draw a polygon and then select a country and modify it, the drawn polygon doesn't disappear.

So if I understand correctly, if I want the source to remain the same I must use the :url instead of :features parameter to load features?

Also the stopClick on the parameter on the draw interaction doesn't seem to work, it still fires the click event.

https://codesandbox.io/s/vue3-openlayers-forked-qqrqx?file=/src/App.vue:807-816

Component not found on createApp reload

Reproduction link

codesandbox.io

Steps to reproduce

   function loadEvent(resumeData = null) {
      createApp(eventMainComponent, {resumeData: resumeData}).use(OpenLayersMap).mount("#Vue-events")
    }

What is expected?

Component uses OpenLayersMap

What is actually happening?

Not sure if this is related to OpenLayers or Vue3-OpenLayers or simply Vue3
problem is OpenLayersMap not found inside the created app on a reload
in the sandbox you see the map disappear on reload
My application is not a full vue application
my menu loads vue instances in the website dynamically

for example I click on Events and this will trigger the following code:

    import OpenLayersMap from 'vue3-openlayers'
    createApp(eventMainComponent,{resumeData:resumeData}).use(OpenLayersMap).mount("#Vue-events")

works like a charm the first time but I switch to another page lets say blog

then if I reload Events that will execute the same code above I get

    [Vue warn]: injection "ol-format" not found. which refers to const format = inject('ol-format');

[Vue warn]: Maximum recursive updates exceeded.

in the following example, I get this error when trying to modify a feature from my geojson object. Using the recently added modify & snap interactions components.

Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.

I have tried using reactive, refs, manually creation polygon/features instead of geojson, always end up with the same issue.

Here is the template if you want to test it, I get errors trying to setup a codesandbox using vue3-openlayers.
One thing I noticed is when I use a url to load geojson data, there is no error during the modification. Only when I use my own geojson object, does it show the error.

I have added both options (url and my geojson object you can alternate between both)

<template>
  <ol-map ref="map" :load-tiles-while-animating="true" :load-tiles-while-interacting="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 :style="vectorStyle">
      <ol-source-vector :features="zones">
        <!-- <ol-source-vector :url="'https://openlayers.org/en/latest/examples/data/geojson/countries.geojson'" :format="geoJsonFormat"> -->
        <ol-interaction-modify v-if="modifyEnabled"> </ol-interaction-modify>
        <ol-interaction-snap v-if="modifyEnabled" />
      </ol-source-vector>
    </ol-vector-layer>
    <ol-interaction-select @select="featureSelected" :condition="selectCondition">
      <ol-style>
        <ol-style-stroke :color="'red'" :width="2"></ol-style-stroke>
        <ol-style-fill :color="`rgba(255, 0, 0, 0.4)`"></ol-style-fill>
      </ol-style>
    </ol-interaction-select>
  </ol-map>
</template>

<script>
import { reactive, ref, inject } from 'vue'
import { GeoJSON } from 'ol/format'
import { Fill, Stroke, Style, Text } from 'ol/style'

export default {
  setup() {
    const center = ref([-102.13121, 40.2436])
    const projection = ref('EPSG:4326')
    const zoom = ref(5)
    const rotation = ref(0)
    const modifyEnabled = ref(false)

    const geojsonObject = {
      type: 'FeatureCollection',
      crs: {
        type: 'name',
        properties: {
          name: 'EPSG:4326'
        }
      },
      features: [
        {
          type: 'Feature',
          geometry: {
            type: 'Polygon',
            coordinates: [
              [
                [-103.86923852630616, 43.45599322423934],
                [-103.90891107984544, 39.34240191087722],
                [-98.76630637117387, 39.558687199211114],
                [-98.89435771175386, 43.945405844902986],
                [-103.86923852630616, 43.45599322423934]
              ]
            ]
          }
        },
        {
          type: 'Feature',
          geometry: {
            type: 'Polygon',
            coordinates: [
              [
                [-103.85636392303468, 38.10970692739486],
                [-103.86770698495866, 33.218572724914544],
                [-98.20654544301988, 33.6532810221672],
                [-98.4408283538437, 38.31894739375114],
                [-103.85636392303468, 38.10970692739486]
              ]
            ]
          }
        },
      ]
    }

    const zones = ref([])

    zones.value = new GeoJSON().readFeatures(geojsonObject)
    
    function vectorStyle() {
      const style = new Style({
        stroke: new Stroke({
          color: 'blue',
          width: 3
        }),
        fill: new Fill({
          color: 'rgba(0, 0, 255, 0.4)'
        })
      })
      return style
    }

    const geoJsonFormat = new GeoJSON()
    const selectConditions = inject('ol-selectconditions')
    const selectCondition = selectConditions.click

    function featureSelected(event) {
      if (event.selected.length > 0) {
        modifyEnabled.value = true
      }
      if (event.deselected.length > 0) {
        modifyEnabled.value = false
      }
    }

    return {
      vectorStyle,
      geoJsonFormat,
      featureSelected,
      selectCondition,
      zones,
      center,
      projection,
      zoom,
      rotation,
      modifyEnabled
    }
  }
}
</script>

Usage in a component render function

Hi,

I would like to render the "ol-map" (and its children components) using the h() function. Something like:

h(Map, {
    class: 'q-mt-md',
    loadTilesWhileAnimating: true,
    loadTilesWhileInteracting: true,
    style: 'height:400px'
  }, [ 
      h(View, {
          center: [0, 45],
          rotation: 0,
          zoom: 8,
          projection: 'EPSG:4326'
      }),
      h(FullScreenControl),
      h(TileLayer, null, [ h(SourceOSM) ])
  ])

What is the appropriate import directive that I could use to get access to the component definitions Map, View, FullScreenControl, TileLayer etc. ?

Thanks

Provide a way to register a custom Projection ol.proj.proj4

Dear Melih,

It seems to be a good improvement to provide a way to register new projection.
Only EPSG:3857 and EPSG:4326 are included in openlayers 6,
Creating a projection with ol.proj.Projection(…) is not sufficient because there is so much parameters.
For example in France we use RGF93 (epsg:2154) coordinates so we need to define:

//Proj4 initialization
import proj4 from 'proj4';
import {register} from 'ol/proj/proj4';
proj4.defs("EPSG:2154", "+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
register(proj4);
//if needed
const epsg2154_fullextent = [-357823.2365, 6037008.6939, 1313632.3628, 7230727.3772];

Thanks for your work !

wrong type in overlay Positioning

Describe the bug
https://vue3openlayers.netlify.app/componentsguide/overlay/#positioning
positioning
Type: string
Default: top-left

BUT
:positioning await ARRAY.
working: :positioning="['top-left']" // or const positioning = ref(['top-left'])
not working: :positioning="'top-left'" // or const positioning = ref('top-left')

To Reproduce
just try a component

Expected behavior

expected the right is like not workin

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Smartphone (please complete the following information):

Additional context
https://github.com/MelihAltintas/vue3-openlayers/blob/main/src/components/map/Overlay.vue

...
positioning: {
type: Array
},
...

`Failed to resolve component: ol-view` with basic doc example: How to import locally instead of globally ?

I have this very basic component below that gives me error:

Failed to resolve component: ol-view

I do not understand how to import vue3-openLayers properly. I used code from the official doc. It seems that the global imports are missing but I want to use in my component only. How do I import and reference inside my component.

The doc is not helping from what I can tell.

here is my full component

`

<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-map>

</template>

<script>
import {ref} from 'vue'

export default {
setup() {
  const center = ref([40, 40])
  const projection = ref('EPSG:4326')
  const zoom = ref(8)
  const rotation = ref(0)
  return {
    center,
    projection,
    zoom,
    rotation
  }
  },
 }
 </script>`

TypeError: undefined is not an object (evaluating 'val.toLowerCase')

Describe the bug
Loading my component I get the following error : TypeError: undefined is not an object (evaluating 'val.toLowerCase')

[Vue warn]: Failed to resolve async component: function MapData() { return Promise.all(/*! import() */[__webpack_require__.e("defaultVendors-node_modules_vue3-openlayers_dist_vue3-openlayers_common_js"), __webpack_require__.e("defaultVendors-node_modules_ol_Object_js-node_modules_ol_has_js-node_modules_ol_proj_js"), __webpack_require__.e("defaultVendors-node_modules_vue3-openlayers_dist_vue3-openlayers_css-node_modules_ol_style_Style_js"), __webpack_require__.e("default-src_vue_component_map_map-data_vue-data_image_png_base64_iVBORw0KGgoAAAANSUhEUgAAABIA-d8f71b")]).then(__webpack_require__.bind(__webpack_require__, /*! ../map/map-data.vue */ "./src/vue/component/map/map-data.vue"));

To Reproduce
I just installed vue3-OpenLayers in my project

Expected behavior
no error message

Desktop (please complete the following information):

  • OS: OSX latest
  • Browser: All browsers

Additional context
I just installed vue3-OpenLayers in my project
using webpack 5

here is my component:
gist

select-interaction filter prop

I get this error when passing the filter prop on ol-interaction-select component.

Extraneous non-props attributes (filter) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.

<ol-interaction-select @select="featureSelected" :condition="data.selectCondition" :filter="filterFunc"></ol-interaction-select>

Is it possible to assign style to particular features inside an animated cluster layer?

Is your feature request related to a problem? Please describe.
I'm not sure. I tried to find an example where I can assign individual styles to geo-points regarding some attribute of those points (say you have a map with geo-points and they are color-coded depending if there's an issue in such place), but if they're inside an animated clusterlayer the layer style is defining the style, but the geo point doesn't seem to be able to get it individually.

Describe the solution you'd like
Doing it this way doesn't work:
It will take the styles of the animation layer, but if I remove it and leave only the style in the feature, it won't take any style at all.

<ol-animated-clusterlayer :animationDuration="500" :distance="40">
        <ol-source-vector ref="vectorsource">
          <ol-feature v-for="site in geopoints" :properties="{name: site.name}">
            <ol-geom-point
                :coordinates="fromLonLat(site.coordinates, projection.value)"
            ></ol-geom-point>
            <ol-style v-if="site.id == 8">
              <ol-style-circle :radius="radius">
                <ol-style-fill :color="fillColor"></ol-style-fill>
                <ol-style-stroke :color="strokeColor" :width="strokeWidth"></ol-style-stroke>
              </ol-style-circle>
            </ol-style>
          </ol-feature>
        </ol-source-vector>

        <ol-style :overrideStyleFunction="overrideStyleFunction">
          <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="20">
              <ol-style-stroke color="rgba(255,255,255,0.1)" :width="15" :lineDash="[]" lineCap="butt"></ol-style-stroke>
              <ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>
          </ol-style-circle>

          <ol-style-text>
              <ol-style-fill color="white"></ol-style-fill>
          </ol-style-text>
        </ol-style>
      </ol-animated-clusterlayer>

Describe alternatives you've considered

Additional context

how to get Map and View

i need use openlayers api ,how to get Map and View ?
now,i use ref
map = olMapRef.value.map as Map; view = olViewRef.value.view as View;

Is there a better way?

How to use DragRotateAndZoom interaction of map?

Describe the bug
Upgrade to latest version of 0.1.39, and couldn't find any information about using DragRotateAndZoom interaction of map

To Reproduce
Just run npm run serve in project directory, then use shift key and drag to rotate, the rotation of map never change

Expected behavior
Could change the rotation of map by shift+drag

vue3-Openlayers: Change Feature color according to properties on the fly from template

I have these features

 <ol-vector-layer title="Features" :visible="vectorMenuDisplay" >
    <ol-source-vector ref="sourceVectorNew" :projection="projection" :features="existingFeatures">
      <ol-interaction-modify v-if="!mapLock && modifyEnabled" :features="selectedFeatures" @modifyend="modifyend"></ol-interaction-modify>
      <ol-interaction-draw v-if="!mapLock && drawEnable" :type="drawType" @drawend="drawend"></ol-interaction-draw>
    </ol-source-vector>
    <ol-style>
      <ol-style-stroke color="red" :width="5"></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="green"></ol-style-fill>
        // this color should be from extra data in properties of the feature
      </ol-style-circle>
    </ol-style>
  </ol-vector-layer> 

I would like to change the color="green" dynamically depending on dynamically inserted extra data in properties of the feature

Is it possible ?

How to disable manage user interaction with ol-map?

I have been scouring the doc and internet for options on how to disable all user interactions with the map.

Only reference I could find in doc is view.value.getInteracting()) but this return false
How can this return false when I am clearly interacting with the map ?

then I decided to try something else like suggested on SO but getInteractions() is undefined

this code successfully disables dragpan but with error undefined is not an object (evaluating 'interaction.constructor')

  olMap.value.map.getInteractions().forEach(function(interaction) {
    if (interaction.constructor.name === 'DragPan') {
      olMap.value.map.removeInteraction(interaction);
    }
  }, context);

Before Vue3-openLayers I used to use a Vue2 one called ghettovoice/openlayers and I could just set interactions with a prop on the ol-map component like this:
:default-interactions="interactionOptions"

interactionOptions: {
dragPan: true, // disable move by drag
onFocusOnly:false,
mouseWheelZoom:true,
shiftDragZoom:true,
altShiftDragRotate:true,
doubleClickZoom:true,
keyboard:true,
pinchRotate:true,
pinchZoom:true,
zoomDelta:1,
zoomDuration:1000
},

Flowline or multicolor multi-line-string ? (display elevation)

I cannot see in the doc an example of a multicolor linestring

the closest I fount is the multi-line-string so I tried this

      <ol-feature v-if="waypoints && waypoints.length > 0">
        <ol-geom-multi-line-string :coordinates="waypoints"></ol-geom-multi-line-string>
        <ol-style :overrideStyleFunction="overrideStyleFunction">
          <ol-style-stroke color="green" :width="7"></ol-style-stroke>
        </ol-style>
      </ol-feature>

problem is that my overrideStyleFunction is only triggered once and the line is the same color everywhere
not sure what I am doing wrong

OL has Flowline which could be great to have as a component ?

Uncaught TypeError: Cannot read property 'refs' of null in the production mode

Under the development model, the work is normal, but in the production mode, an error is reported

vendor.1b452b69.js:1 Uncaught TypeError: Cannot read property 'refs' of null
at Pn (vendor.1b452b69.js:1)
at O (vendor.1b452b69.js:1)
at vendor.1b452b69.js:1
at n (vendor.1b452b69.js:1)
at Z (vendor.1b452b69.js:1)
at Y (vendor.1b452b69.js:1)
at z (vendor.1b452b69.js:1)
at U (vendor.1b452b69.js:1)
at O (vendor.1b452b69.js:1)
at vendor.1b452b69.js:1
Pn @ vendor.1b452b69.js:1
O @ vendor.1b452b69.js:1
(anonymous) @ vendor.1b452b69.js:1
n @ vendor.1b452b69.js:1
Z @ vendor.1b452b69.js:1
Y @ vendor.1b452b69.js:1
z @ vendor.1b452b69.js:1
U @ vendor.1b452b69.js:1
O @ vendor.1b452b69.js:1
(anonymous) @ vendor.1b452b69.js:1
n @ vendor.1b452b69.js:1
Z @ vendor.1b452b69.js:1
Y @ vendor.1b452b69.js:1
z @ vendor.1b452b69.js:1
U @ vendor.1b452b69.js:1
O @ vendor.1b452b69.js:1
(anonymous) @ vendor.1b452b69.js:1
n @ vendor.1b452b69.js:1
Z @ vendor.1b452b69.js:1
Y @ vendor.1b452b69.js:1
z @ vendor.1b452b69.js:1
U @ vendor.1b452b69.js:1
O @ vendor.1b452b69.js:1
st @ vendor.1b452b69.js:1
mount @ vendor.1b452b69.js:1
Yr.e.mount @ vendor.1b452b69.js:1
(anonymous) @ index.a10c460a.js:1

ol-layerswitcherimage-control has extra non existent layer and all layers are selected by default

I could not find any documentation on this. If I missed it all my apologies for a useless post

I see that the demo has the exact same behavior; Did you forget props in demo ?

using the <ol-layerswitcherimage-control >

I have an extra layer with image data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAEAAAABA … eJLjLwPul3vj5d0eAAAAAElFTkSuQmCC

then by default all my layers are selected; this is a big performance issue

Can you please let me know how to control this component ?

Beginner question: load ol-source-wmts from geoserver found TileMatrix are missmatch.

Hi ,

I want to load a map from geoserver. I config the tile cache in geoserver and i can get tile image from browser .
http://localhost:28080/geoserver/gwc/service/wmts/rest/test_site:south_sea_release/default/EPSG:4326/EPSG:4326:7/46/200?format=image/png

I use ol-source-wmts to load the tile image:

<ol-tile-layer :zIndex="1001" :center="center">
      <ol-source-wmts
          :url="url"
          :matrixSet="matrixSet"
          :format="format"
          :style="styleName"
          :projection="projection"
          requestEncoding="REST"
      >
      </ol-source-wmts>
    </ol-tile-layer>
    const url = ref('http://localhost:28080/geoserver/gwc/service/wmts/rest/test_site:south_sea_release/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}?format=image/png')
    const layerName = ref('test_site:south_sea_release')
    const matrixSet = ref('EPSG:4326')
    const format = ref('image/png')
    const styleName = ref('default')

I found some error in browser console and the actual request is:
http://localhost:28080/geoserver/gwc/service/wmts/rest/test_site:south_sea_release/default/EPSG:4326/3/2/6?format=image/png

I found the source code to compute matrixIds are

     const getTileGrid = computed(() => {
      
            const resolutions = new Array(14);
            const matrixIds = new Array(14);

            for (var z = 0; z < 14; ++z) {

                resolutions[z] = size.value / Math.pow(2, z);
                matrixIds[z] = z;
            }

            return new WMTSTileGrid({
                origin:origin.value,
                resolutions,
                matrixIds
            });
        });

So i want to know how to add the prefix (e.g. EPSG:4326 in this question).

I'm a beginner to use openlayer and geoserver and not sure if this can be configed in geoserver.

Thanks a lot.
Jeffry

Delete Geometries After Draw Or Any Other Geometries

When implement ol-interaction-draw how i can add feature to user delete the selected shape ,
i'm try from ol-interaction-clusterselect get the featureSelected event and if have a function to delete the current element or something like that or please if have some other way.

Thank you.

Can i use TypeScript?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

openlayer 已经有 @types/ol ,但是 vue3-openlayers不能使用它

现在vue3-openlayers内是通过 provide , inject来获取。但是这样没有类型了
app.provide('ol-feature',feature)
app.provide('ol-geom',geom)
app.provide('ol-animations',animations)
app.provide('ol-format',format)
app.provide('ol-loadingstrategy',loadingstrategy)
app.provide('ol-selectconditions',selectconditions)
app.provide('ol-extent',extent)

我要怎么做才能在const selectConditions = inject('ol-selectconditions') 获取到selectConditions的类型呢

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Issue with the snap interaction & how to automatically select/modify a feature on drawend?

  1. In the following example, when drawing, the snap interaction works only for the first drawn polygon. Or if you first select and modify one of the two polygons and then start drawing a polygon, the snap interaction doesn't work.
    -However the snap interactions works on the modify interaction.

  2. I am having a hard time figuring out how to automatically select / modify a polygon when I finish drawing it on the drawend event.
    Adding the following to the drawend function doesn't quite work and I don't think I am doing it the right way.

selectedFeatures.value = event.feature
modifyEnabled.value = true

https://codesandbox.io/s/vue3-openlayers-forked-qqrqx?file=/src/App.vue

prop "features". Expected Collection, got Object

Thank you for adding the props and for creating a codesandbox.

Trying them out on I get the following warning:

[Vue warn]: Invalid prop: type check failed for prop "features". Expected Collection, got Object

I don't quite understand because I am declaring the selectedFeature as a new Collection() and then when selecting a feature, it add's it to the collection array.

Here is the codesandbox:
https://codesandbox.io/s/vue3-openlayers-forked-jftt9?file=/src/App.vue

Beginner questions: squashed map, drawing circles, displaying circles

Hello there,

Thank you for your awesome library!
I'm not sure whether or not it's the right place to ask for help (maybe it could be relevant to enable the "Discussions" feature on that repository?) but I have a few questions that documentation doesn't answer me.

First of all, on all examples, the maps look "squashed". After further investigation using the EPSG:4326 projection seems to be the guilty, as using the default one fixes it. But then, the whole coordinates system is f*cked up, as you have to translate all coordinates to EPSG:3857, which is really annoying. Is it the right thing to do or did I miss something?
Capture d’écran 2021-10-22 à 14 56 35

Secondly, I managed to draw a circle on the map, but for my use case, I wish that starting to draw a second circle removes the 1st one. Do you have any clue on how to achieve this?

Lastly, when you want to show a circle on the map as described here, zooming in or out doesn't change the size of the circle, which (in my use case of outlining geographical areas) should scale with the zoom, but it remains fixed. I didn't figure out how to handle this, except converting the circle to a polygon then displaying it this way, but that's really overkill / uncomfy. Any ideas?

Thanks!
Ben

Getter / Setter for Features and or entire State

Is your feature request related to a problem? Please describe.
Managing features easily so we can export them in a classic es6 object format to store in database and reuse later
This is basically abstracting OL

we can expand this to a complete object of the map state

Would be super useful for beginners

Describe the solution you'd like
something like
this.$ref.map.getFeatures()
this.$ref.map.removeFeatures()
this.$ref.map.addFeatures()
this.$ref.map.setFeatures()

this.$ref.map.getState()
this.$ref.map.setState()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.