Features path
by Vladimir Vershinin
HTML
<script src="https://unpkg.com/vue@latest/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io/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">
<script src="https://unpkg.com/[email protected]/turf.js"></script>
<script src="https://unpkg.com/[email protected]/dist/ol-ext.js"></script>
<div id="app">
<button @click="animate">Animate</button>
<vl-map ref="map" data-projection="EPSG:4326" @singleclick="onClick">
<vl-view ref="mapView" :zoom.sync="zoom" :center.sync="center"></vl-view>
<vl-layer-tile>
<vl-source-osm />
</vl-layer-tile>
<vl-layer-vector ref="vectorLayer">
<vl-source-vector ref="vectorSource" :features="features" />
<vl-style-func :factory="styleFuncFactory" />
</vl-layer-vector>
<vl-overlay v-for="point in selectedPoints" :position="point.geometry.coordinates" :auto-pan="true" :key="point.id" :id="point.id">
<div style="background: #fff">
<p>
Id: {{ point.id }}<br>
Name: {{ point.properties.name }}
</p>
</div>
</vl-overlay>
</vl-map>
</div>
CSS
html, body, #app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
JavaScript
new Vue({
el: '#app',
data() {
return {
zoom: 6,
center: [-4, 6],
paths: [{
id: 1,
points: [{
id: 1,
coordinates: [-5, 6],
name: 'point 1'
}, {
id: 2,
coordinates: [-5, 8],
name: 'point 2'
}, {
id: 3,
coordinates: [-3, 8],
name: 'point 3'
}, {
id: 4,
coordinates: [-3, 6],
name: 'point 4'
}, {
id: 5,
coordinates: [-1, 6],
name: 'point 5'
}, {
id: 6,
coordinates: [-1, 4],
name: 'point 6'
}, {
id: 7,
coordinates: [1, 4],
name: 'point 7'
}],
}],
selectedPoint: null,
}
},
computed: {
features() {
return this.paths.map(p => ({
type: 'Feature',
id: p.id,
geometry: {
type: 'LineString',
coordinates: p.points.map(p => p.coordinates),
},
properties: {
points: p.points.map(p => ({
type: 'Feature',
id: p.id,
properties: {
name: p.name,
},
geometry: {
type: 'Point',
coordinates: p.coordinates,
},
})),
},
}))
},
selectedPoints() {
if (!this.selectedPoint) return []
return [this.selectedPoint]
},
},
methods: {
onClick({
pixel,
coordinate
}) {
const feature = this.$refs.map.$map.forEachFeatureAtPixel(pixel, x => x)
if (!feature) {
if (this.selectedPath) {
this.selectedPath.unset('selected')
this.selectedPath = null
}
this.selectedPoint = null
return
}
this.selectedPath = feature
this.selectedPoint = turf.nearest(
turf.point(coordinate),
turf.featureCollection(feature.get('points')),
)
...