Open street maps Vuejs Integration

shivam jadhav
5 min readJan 2, 2023

--

Shivam Jadhav

2st January 2023
Jadhavshivam0228@gmail.com
https://www.linkedin.com/in/shivam-jadhav-1152921b0/

Introduction

Basic info:

OpenStreetMap (OSM) is a free, open geographic database updated and maintained by a community of volunteers via open collaboration. Contributors collect data from surveys, trace from aerial imagery, and also import from other freely licensed geodata sources.

In order to use openstreet maps and make use of its APIs we will use the leaflet npm package and leverage the basic and advanced features like map layout, adding markers on the map, enabling geo search, and other useful features like creating geofence, polyline, etc

Topics

  1. Setup and Installation
  2. LMAP (Base map)
  3. Marker Component
  4. Implement geosearch
  5. Add polyline
  6. Add Geofence

Please Notice: I have chosen vueJS in order to make a web app and implement some of OSM features through a leaflet npm package to leverage some of the components

Setup and Installation

Step 1:create a vue 2 app using the command vue create project-name

vue create osm-demo

Step 2: add the dependencies

npm install leaflet vue2-leaflet - save

Step 3: add the following links to your index.html file

<link rel="stylesheet" href="//unpkg.com/leaflet/dist/leaflet.css" />
<script src="//unpkg.com/leaflet/dist/leaflet.js"></script>
<script src="//unpkg.com/vue2-leaflet"></script>

Step 4: Import the package and add the register components to the globally in our app in our main.js file

//main.js file
import Vue from 'vue';
import { LMap, LTileLayer, LMarker } from 'vue2-leaflet';
import 'leaflet/dist/leaflet.css';
Vue.component('l-map', LMap);
Vue.component('l-tile-layer', LTileLayer);
Vue.component('l-marker', LMarker);

Step 5: add the css support for the maps by adding css link in our main.js file

import "leaflet/dist/leaflet.css";
Step 6: for icons support add the following in our
import { Icon } from "leaflet";
delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
iconUrl: require("leaflet/dist/images/marker-icon.png"),
shadowUrl: require("leaflet/dist/images/marker-shadow.png"),
});

2. LMAP

Base component, contains and wraps all the other components.

<template>
<l-map style="height: 100em; width: 600px":zoom="zoom":center="center">
<l-tile-layer:url="url":attribution="attribution"></l-tile-layer>
</l-map>
</template>
<script>
export default {
name: "OSMMap",
data() {
return {
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution:
'&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 3,
center: [17.4436222, 78.3519638],
bounds: null,
};
},
};
</script>

LMAP Preview

Marker Component

<template>
<div >
<l-map style="width: 100em; height: 600px":zoom="zoom":center="center">
<l-marker:lat-lng="markerLatLng"></l-marker>
<l-tile-layer:url="url":attribution="attribution"></l-tile-layer>
</l-map>
</div>
</template>
<script>
export default {
name: "MarkerView",
data() {
return {
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution:
'&copy; <a target="_blank"
href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 14,
center: [17.4436222, 78.3519638],
markerLatLng: [17.4436222, 78.3519638],
};
},
};
</script>

Marker Preview

Geo search

In order to implement geo search we have to install a leaflet plugin vue2-leaflet-geosearch which is used to provide an interface. Another library adds leaflet-geosearch support for geocoding (address lookup, a.k.a.
geoseaching) to your (web) application. It comes with controls to be embedded in your Leaflet map such that users can search any address and the location will be updated on the map using an api .

Step 1: install dependencies inorder to implement geosearch

npm install --save vue2-leaflet-geosearch leaflet-geosearch

Step 2:Add the css support to the main.js file

import "leaflet-geosearch/dist/geosearch.css";

step3:Add the css support cdn in index.html file to avoid any css breakdown

<link rel="stylesheet"
href="https://unpkg.com/leaflet-geosearch@2.6.0/assets/css/leaflet.css">

Geosearch component

In order to catch results “latitude”,” longitude” and “address” we need to interact with the “geosearch/showlocation” event. I have added an example for the same.

<template>
<div>
<div v-if="location">
<p>location:{{ location }}</p>
<p>address: {{ address }}</p>
</div>
<l-map
ref=" map" style=" width: 100em; height: 600px"
:zoom="zoom":center="center"
>
7<v-geosearch :options="geosearchOptions"></v-geosearch>
<l-tile-layer :url="url":attribution="attribution"></l-tile-layer>
</l-map>
</div>
</template>
<script>
import { OpenStreetMapProvider } from "leaflet-geosearch";
import VGeosearch from "vue2-leaflet-geosearch";
export default {
name: "GeoSearchView",
data() {
return {
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution:
'&copy; <a target="_blank"
href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 14,
center: [17.4436222, 78.3519638],
address: null,
location: null,
geosearchOptions: {
style: "bar",
provider: new OpenStreetMapProvider(),
showMarker: true,
autoClose: true,
keepResult: true,
searchLabel: "Enter address",
},
};
},
mounted() {
this.$refs.map.mapObject.on("geosearch/showlocation", this.onSearch);
},
methods: {
onSearch(value) {
this.location = { lat: value.location.y, lng: value.location.x };
this.address = value.location.label;
},
},
components: {
"v-geosearch": VGeosearch,
},
};
</script>

Geosearch Preview

Polyline component

Given the latitude and longitude we can draw the polyline on the
maps.

<template>
<div>
<l-map
ref="map"
style="width: 100em; height: 600px"
:zoom="zoom"
:center="center"
>
<l-polyline :lat-lngs="polyline.latlngs" color="green"></l-polyline>
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
</l-map>
</div>
</template>
<script>
import { LPolyline } from "vue2-leaflet";
export default {
name: "PolylineView",
data() {
return {
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution:
'&copy; <a target="_blank"
href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 14,
center: [17.4436222, 78.3519638],
polyline: {
latlngs: [
[17.4436222, 78.3519638],
[17.420637, 78.384465],
[17.401145, 78.41324],
],
color: "green",
},
};
},
components: {
LPolyline,
},
};
</script>

Polyline Preview

GeoCircle component

Draw a path in the shape of a circle around a center
positioned at latLng coordinates

<template>
<div>
<l-map
ref="map"
style="width: 100em; height: 600px"
:zoom="zoom"
:center="center"
>
<l-circle
:lat-lng="circle.center"
:radius="circle.radius"
:color="circle.color"
/>
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
</l-map>
</div>
</template>
<script>
import { LCircle } from "vue2-leaflet";
export default {
name: "PolylineView",
data() {
return {
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution:
'&copy; <a target="_blank"
href="http://osm.org/copyright">OpenStreetMap</a> contributors',
zoom: 14,
center: [17.4436222, 78.3519638],
circle: {
center: [17.4436222, 78.3519638],
radius: 500,
color: "red",
},
12};
},
components:{
LCircle,
},
};
</script>

Geo Circle Preview

Github Repository

References

Check the documentation for more components
https://vue2-leaflet.netlify.app/components/
https://vue2-leaflet.netlify.app/examples/
https://github.com/smeijer/leaflet-geosearch

--

--

shivam jadhav

Full Stack Engineer | R&D | ML Devotee | music admirer | lakers fan