Style function refresh

by Vladimir Vershinin

HTML

<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v5.3.0/build/ol.js"></script>
<script src="https://unpkg.com/[email protected]/lib/index.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/lib/style.css">
<div id="app">
  <div class="layers">
    <select v-model="currentBaseLayer">
      <option 
        v-for="layer in baseLayers"
        :key="layer.id"
        :value="layer.id" 
      >
        {{ layer.id }}
      </option>
    </select>
  </div>
  <vl-map ref="map" data-projection="EPSG:4326">
    <vl-view :zoom.sync="zoom" :center.sync="center"></vl-view>
  
    <vl-layer-tile
      v-for="layer in extBaseLayers"
      :id="layer.id"
      :key="layer.id"
      :visible="layer.visible"
    >
      <component
        :is="layer.source.cmp"
        v-bind="layer.source"
      />
    </vl-layer-tile>
    
    <vl-layer-vector
      ref="vectorLayer"
      update-while-animating
      update-while-interacting
    >
      <vl-source-vector :features="features" />
      <vl-style-func :factory="styleFuncFactory" />
    </vl-layer-vector>
  </vl-map>
</div>

CSS

html, body, #app {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.layers {
  position: absolute;
  top: 10px;
  left: 50px;
  z-index: 1;
}

JavaScript

new Vue({
	el: '#app',
  data () {
  	return {
    	zoom: 3,
      center: [0, 0],
      currentBaseLayer: 'osm',
      baseLayers: [
      	{ id: 'osm', source: { cmp: 'vl-source-osm' } },
				{ id: 'stamen', source: { cmp: 'vl-source-stamen', layer: 'watercolor' },  },
      ],
      features: [
      	{
        	type: 'Feature',
          id: 'one',
          properties: {},
          geometry: {
          	type: 'Polygon',
            coordinates: [[
            	[0, 0],
              [10, 0],
              [10, 10],
              [0, 10],
            ]],
          },
        },
      ],
    }
  },
  computed: {
  	extBaseLayers () {
    	return this.baseLayers.map(layer => ({
      	...layer,
        visible: layer.id === this.currentBaseLayer,
      }))
    },
  },
  methods: {
  	styleFuncFactory () {
    	const defStyle = new ol.style.Style({
      	fill: new ol.style.Fill({ color: 'red' }),
        stroke: new ol.style.Stroke({ width: 2, color: 'blue' }),
      })
      const stamenStyle = new ol.style.Style({
      	fill: new ol.style.Fill({ color: 'green' }),
        stroke: new ol.style.Stroke({ width: 2, color: 'cyan' }),
      })
    
    	return feature => {
      	switch (this.currentBaseLayer) {
        	case 'stamen':
          	return stamenStyle
        	case 'osm':
          default:
          	return defStyle
        }
      }
    },
  },
  watch: {
  	currentBaseLayer () {
    	this.$refs.vectorLayer.refresh()
    },
  },
})