Manual source fill

by Vladimir Vershinin

HTML

<script src="https://unpkg.com/[email protected]/lodash.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]/dist/vue.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>
    {{ loadingState }}
  </div>
  <div>
    Selected: {{ selectedFeatures }}
  </div>
  <vl-map data-projection="EPSG:4326">
    <vl-view :zoom.sync="zoom" :center.sync="center"></vl-view>
    
    <vl-layer-tile>
      <vl-source-osm />
    </vl-layer-tile>
    
    <vl-layer-vector id="features" render-mode="image">
      <vl-source-vector ref="featuresSource" :features.sync="features" @mounted="onFeaturesSourceMounted"></vl-source-vector>
    </vl-layer-vector>
    
    <vl-interaction-select :features.sync="selectedFeatures"></vl-interaction-select>
  </vl-map>  
</div>

CSS

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

JavaScript

new Vue({
	el: '#app',
  data () {
  	return {
    	zoom: 2,
      center: [0, 0],
      circles: [],
      loading: false,
      features: [],
      selectedFeatures: [],
    }
  },
  computed: {
	  loadingState () {
    	return this.loading ? 'Loading...' : 'Loaded num: ' + this.circles.length
    },
  },
  methods: {
	  onFeaturesSourceMounted () {
    	this.loadCircles()
    },
  	/**
     * Emulates request to the backend API
     */
    requestPlacesFromAPI () {
    	return new Promise(resolve => {
      	setTimeout(() => {
        	const circles = _.range(0, 100).map(i => {
          	const feature = new ol.Feature({
            	geometry: new ol.geom.Circle([_.random(-5e6, 5e6), _.random(-5e6, 5e6)], _.random(1e5, 5e5)),
            })
            feature.setId('circle-' + i)
            Object.seal(feature)

            return feature
          })
          
          resolve(circles)
        }, 3000)
      })
    },
    loadCircles () {
	    this.circles = []
      this.loading = true
      
    	return this.requestPlacesFromAPI().then(circles => {
      	this.circles = circles
        if (this.$refs.featuresSource.$source) {
        	this.$refs.featuresSource.$source.addFeatures(circles)
        }
        
        this.loading = false
      })
    },
  },
})