GithubHelp home page GithubHelp logo

vem's Introduction

VEM

Vuejs Easy Maps

Easy but powerful maps for Vuejs2+ with OpenLayers.

Minimal Example

import Vue from 'vue'
import VEM from 'vem'

Vue.use(VEM)

new Vue({
  el: '#app',
  template: '<vem-map><tile-layer /></vem-map>'
})

This creates a map with default controls and an OSM layer.

GeoJSON

The following Vue SFC renders GeoJSON data on top of an OSM layer.

<template>
  <vem-map>
    <tile-layer />
    <vector-layer :source="jsonData" :format="GeoJSON" :fitMapToThisLayer="true" />
  </vem-map>
</template>

<script>
import GeoJSON from 'ol/format/geojson'
import jsonData from './src/assets/data.json'

export default {
  data () {
    return { jsonData }
  }
}
</script>

Notice the fitMapToThisLayer attribute. This sets the center and zoom of the map to exactly fit the extent of the given data in. It should (obviously) only be used once and is only supported on layers with an actual size. VEM tries to nicely abstract away the difference between TileLayer and VectorLayer by automatically deciding which type is needed depending on the given source. Only VectorLayers have an actual size ('extent'), which VEM can automatically fit into the viewport for you.

Raw vs OpenLayers data objects

If a raw data source is given, the format needs to be set via the format attribute. This attribute is not necessary if the object given via source is already an OpenLayers format object:

<template>
  <vem-map>
    <tile-layer />
    <vector-layer :source="features" :fitMapToThisLayer="true" />
  </vem-map>
</template>

<script>
import GeoJSON from 'ol/format/geojson'
import jsonData from './src/assets/data.json'

export default {
  data () {
    return {
      // this might give strange results if your data isn't EPSG:4326 projected
      features: new GeoJSON().readFeatures(jsonData)
    }
  }
}
</script>

It is usually more convenient to use the format parameter because VEM handles the projection for you. If your data is not EPSG:3857 (aka WSG84, aka what you usually have on web-based maps) projected, you can tell VEM using the projection attribute. The default should work in most cases though.

Map click

The map component emits click events:

<template>
  <vem-map @click="onMapClick">
    <tile-layer />
    <vector-layer :source="jsonData" :format="GeoJSON" :fitMapToThisLayer="true" />
  </vem-map>
</template>

<script>
import GeoJSON from 'ol/format/geojson'
import jsonData from './src/assets/data.json'

export default {
  data () {
    return { jsonData }
  },
  methods: {
    onMapClick (ev) {
      console.log('clicked on map', ev)
    }
  }
}
</script>

The emitted object has the following form:

{
  pixel: Array,  // pixel coordinates of click, eg [23.5, 42]
  lonlat: Array, // map coordinates of click, eg [13.5, 52.45]
  pointerEvent: ol.pointer.PointerEvent, // original PointerEvent from OpenLayers
  originalEvent: ol.MapBrowserPointerEvent, // originally emitted event
  feature: ol.Feature // clicked map feature (on vector maps)
}

Zoom state

The map component also supports a temporary zoom state. It is possible to set the zoomToExtent or zoomToFeature attributes to define the area to zoom to. Typical usage would be to zoom on a clicked feature:

<template>
  <vem-map @click="onMapClick" :zoomToFeature="highlightedFeature">
    <tile-layer />
    <vector-layer :source="jsonData" :format="GeoJSON" :fitMapToThisLayer="true" />
  </vem-map>
</template>

<script>
import GeoJSON from 'ol/format/geojson'
import jsonData from './src/assets/data.json'

export default {
  data () {
    return {
      jsonData,
      highlightedFeature: null
    }
  },
  methods: {
    onMapClick (ev) {
      console.log('clicked on map', ev)
      
      if (this.highlightedFeature === ev.feature) {
        this.highlightedFeature = null
      } else {
        this.highlightedFeature = ev.feature
      }
    }
  }
}
</script>

Markers

Markers can be added to the map, using the <map-marker /> component:

<template>
  <vem-map>
    <tile-layer />
    <map-marker name="somewhere-in-berlin" :lon="13.5" :lat="52.5" />
  </vem-map>
</template>

<script>
export default {
  data () {
    return {
    }
  }
}
</script>

All fields are optional. name defaults to "Marker" and the coordinates default to 0.0, 0.0.

Markers are static and not draggable by default, but this can be changed easily:

<template>
  <vem-map>
    <tile-layer />
    <map-marker :lon.sync="longitude" :lat.sync="latitude" :draggable="true" />
  </vem-map>
</template>

<script>
export default {
  data () {
    return {
      // will be kept in sync with the marker position
      longitude: 13.5,
      latitude: 52.5
    }
  }
}
</script>

Resolution boundaries

Markers and VectorLayers can be set to be invisible outside certain resolution or zoom level boundaries:

<template>
  <vem-map>
    <tile-layer />
    <map-marker name="somewhere-in-berlin" :lon="13.5" :lat="52.5" :maxResolution="100" />
  </vem-map>
</template>

<script>
export default {
  data () {
    return {
    }
  }
}
</script>

This marker only becomes visible when the map is zoomed pretty close to Berlin already, somewhere between zoom level 10 and 11.

Because resolution values might not be very obvious. It is also possible to use the zoom value:

<template>
  <vem-map>
    <tile-layer />
    <map-marker name="somewhere-in-berlin" :lon="13.5" :lat="52.5" :minZoom="11" />
  </vem-map>
</template>

<script>
export default {
  data () {
    return {
    }
  }
}
</script>

This hides the marker at zoom levels smaller than 11.

To see this in action, run npm run dev in the source folder and go to http://localhost:4000 .

vem's People

Contributors

nkoehring avatar

Stargazers

Jinghao Hu avatar Hotuns avatar Stefano Giraldi avatar Thomas Gratier avatar Peter Leonov avatar Straussn avatar Arjanski avatar Braunson Yager avatar Jurica Železnjak avatar Byron Ferguson avatar Kevin Peters avatar

Watchers

 avatar James Cloos avatar  avatar

Forkers

limujinshan

vem's Issues

Using vem?

1> pulling vem from npm is version 0.0.2 while the github version is 0.0.3

2> I have tried to use vem in two different ways.
the first way is to put the import of vem in the main.js file and the second is to put the import into the component I want to use it in.

import Vue from 'vue'
import VEM from 'vem'
Vue.use(VEM)

but when I try to use it is undefined

        <vem-map>
          <tile-layer />
        </vem-map>

I am using @vue/cli 3.0.1 and vuetify 1.2.0 and ol 5.2.0

In the source I see importing four components, but how do you get those imported in a upper level component?

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.