<leaflet-map></leaflet-map>
Use Leaflet maps with GeoJSON objects as a Web Component
This simple guide will quickly get you started on using <leaflet-map>, including setting up the Web Component and working with GeoJSON objects.
The <leaflet-map>
is using the attributes
flyToBounds
, with a small delay,
customStyle
for a pop-up with
dark background when the point and polygon are clicked, and
allowAddMarker
for adding a marker
using the right button.
To get started you need to do the following steps on your project:
/components/leaflet-map-component/
to your project.
It is only required to keep all the files of the Web Component in the same directory.
Any directory structure can be used.
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<link rel="shortcut icon" type="image/x-icon" href="assets/favicon.ico">
<script type="module" src="./components/leaflet-map-component/leaflet-map.js"></script>
</head>
<leaflet-map>
. An id
is
recommended with multiple maps.
<body>
<leaflet-map id="initial-map" class="small-map"></leaflet-map>
</body>
.small-map {
margin-left: auto;
margin-right: auto;
width: 70%;
}
Let's create a map of the Puerta de Alcalá of Madrid with pretty OpenStreetMap tiles. First we’ll initialize the map and set its view to our chosen geographical coordinates and a zoom level:
<body>
<leaflet-map id="madrid-map"
longitude = "-3.6888136946558996"
latitude = "40.42062134697108"
zoom = "16"
></leaflet-map>
</body>
<leaflet-map>
allows the following attributes:
latitude
;
longitude
;
maxZoom
;
tileCopyright
;
tileServer
;
zoom
and, the specials
allowAddMarker
;
customStyle
;
and fitToBounds
or flyToBounds
.
The special attribute allowAddMarker
triggers
the 'x-leaflet-map:marker-pointed-out' event on
adding a new marker. Nothing is done on the map.
The optional attribute customStyle
defines
the name of a custom class and a style file separated by a colon.
This allows custom styling of elements within the Web Component.
The special attributes fit, without or with animation, the map view to contain all added GeoJSON objects at the hightest possible zoom level.
Defaults are centred on London city using OpenStreetMap tiles:
{
latitude: 51.505,
longitude: -0.09,
maxZoom: 19,
tileCopyright: '© OpenStreetMap',
tileServer: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
zoom: 13
}
For example, to change the background colour of all pop-up, we would include a CSS file
custom-popup-style.css
.custom-leaflet-popup-style .leaflet-popup-content-wrapper {
background: #2c3e50;
color: #fff;
}
.custom-leaflet-popup-style .leaflet-popup-tip {
background: #2c3e50;
}
and the customStyle attribute as following
<body>
<leaflet-map customStyle="custom-leaflet-popup-style:<path to file>/custom-popup-style.css"></leaflet-map>
</body>
Obviously the name of the class custom-leaflet-popup-style is the same as the one that encapsulates the styles in the css file.
Change easily the tile layer on the map using the tileServer
property.
Note that most tile servers require attribution, which you can set using the tileCopyrigth
property.
<leaflet-map id="tiles-map"
longitude = "-3.6888136946558996"
latitude = "40.42062134697108"
zoom = "16"
tileCopyright="Map data: © <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a>" +
" contributors, <a href='http://viewfinderpanoramas.org'>SRTM</a>" +
" | Map style: © <a href='https://opentopomap.org'>OpenTopoMap</a>" +
" (<a href='https://creativecommons.org/licenses/by-sa/3.0/'>CC-BY-SA</a>)"
tileServer="https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png">
</leaflet-map>
Leaflet Provider Demo is a good resource for Leaflet layer providers
GeoJSON is a format for encoding a variety of geographic data structures […]. A GeoJSON object may represent a region of space (a Geometry), a spatially bounded entity (a Feature), or a list of Features (a FeatureCollection). GeoJSON supports the following geometry types: Point; LineString; Polygon; MultiPoint; MultiLineString; MultiPolygon; and, GeometryCollection.
Features in GeoJSON contain a Geometry object and additional properties, and a FeatureCollection contains a list of Features. GeoJSON Specification (RFC 7946)
<leaflet-map>
allows to add GeoJSON features. Among the allowed properties:
style
and popupContent
properties are
optional.coordinates
property is in the form [longitude
,
latitude
].
The Web Component <leaflet-map>
defines two events as actions.
Use it to adding GeoJSON Features and FeatureCollections as they allow you to describe features with a set of properties (samples bellow).
This event requires an object with the property:
geojson
, the GeoJSON object to be addedUse it to removing all GeoJSON features from the map.
This event requires no object.
The <leaflet-map>
on the header is using the
GeoJSON features
point, circle and polygon all added using a
FeatureCollection
as following:
const introductionMap = document.getElementById('initial-map');
const features = {
type: "FeatureCollection",
features: [{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-0.09, 51.5]
},
properties: {
popupContent: "<b>Hello world!</b><br>I am a popup.",
icon: {
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-violet.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
}
}
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [-0.11, 51.508]
},
properties: {
radius: 500,
style: {
color: 'green',
fillColor: 'lightgreen',
fillOpacity: 0.5,
}
}
},
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [[
[-0.08, 51.509], [-0.06, 51.503], [-0.047, 51.51]
]]
},
properties: {
popupContent: "I am a polygon.",
style: {
color: 'black'
}
}
}]
};
introductionMap.dispatchEvent(new CustomEvent('x-leaflet-map-geojson-add', {
detail: {
geojson: features
}
}));
The icon
property for a marker is optional.
The radius
property defines a circle and is the only one required.
The popupContent
and style
properties are always optional for all GeoJSON feature.
A marker allows to be dragged by adding the draggable
property in as follow
const marker = {
type: "Feature",
geometry: {
type: "Point",
coordinates: [-0.09, 51.5]
},
properties: {
...,
draggable: true
}
...
}
const multiPoint = {
type: "Feature",
geometry: {
type: "MultiPoint",
coordinates: [
[-3.682427584343109, 40.4111491873453],
[-3.68192202963495, 40.41365692730523],
[-3.681948851722108, 40.41519059487516]
]
},
properties: {
popupContent: "I am a MultiPoint.",
icon: {
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-green.png',
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
}
}
};
const lineString = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: [
[-3.687652527491114, 40.409744093267946], [-3.682427584343109, 40.4111491873453]
]
},
properties: {
popupContent: "I am a LineString.",
style: {
color: "darkgreen"
}
}
};
const multiLineString = {
type: "Feature",
geometry: {
type: "MultiLineString",
coordinates: [
[[-3.682427584343109, 40.4111491873453],[-3.6826099745492304, 40.411341160113004]],
[[-3.6826099745492304, 40.411341160113004], [-3.6826528899000177, 40.411506583044506]],
[[-3.6826528899000177, 40.411506583044506], [-3.68243831317919853, 40.411606653500144]],
[[-3.68243831317919853, 40.411606653500144], [-3.682108401470939, 40.412278551277]],
[[-3.682108401470939, 40.412278551277], [-3.681923329048269, 40.41250115425148]],
[[-3.681923329048269, 40.41250115425148], [-3.6817275277905215, 40.41301170869761]],
[[-3.6817275277905215, 40.41301170869761], [-3.681829451732911, 40.41325473125318]],
[[-3.681829451732911, 40.41325473125318], [-3.6817870058620503, 40.41364722100761]],
[[-3.6817870058620503, 40.41364722100761], [-3.6819264807305836, 40.41399847689981]],
[[-3.6819264807305836, 40.41399847689981], [-3.681591447371322, 40.41409650736312]],
[[-3.681591447371322, 40.41409650736312], [-3.6818127296148377, 40.41472753715036]],
[[-3.6818127296148377, 40.41472753715036], [-3.6818435750184553, 40.414991996086876]]
]
},
properties: {
popupContent: "I am a MultiLineString.",
style: {
color: "green",
}
}
};
const multiPolygon = {
type: "Feature",
geometry: {
type: "MultiPolygon",
coordinates: [
[[
[-3.6851719536314866, 40.418190942101084], [-3.6836913742578337, 40.41853094304074],
[-3.68269536666569, 40.41612787699837], [-3.684217761317601, 40.415778927180085]
]],
[[
[-3.6818543038540397, 40.41399031407121], [-3.6811368129438007, 40.41413326654296],
[-3.6811247430031844, 40.41355941263011], [-3.6816638670142425, 40.41346649276557]
]]
]
},
properties: {
popupContent: "I am a MultiPolygon.",
style: {
color: "black",
opacity: 0.5,
}
};
const walking = document.getElementById('walk-throught-el-retiro');
const walkThroughtElRetiro = {
type: "FeatureCollection",
features: [multiPoint, lineString, multiLineString, multiPolygon]
};
walking.dispatchEvent(new CustomEvent('x-leaflet-map-geojson-add', {
detail: {
geojson: walkThroughtElRetiro
}
}));
The <leaflet-map>
is using the attribute
fitToBounds
<leaflet-map id="walk-throught-el-retiro"
longitude="-3.6843547932100424"
latitude="40.41411233423414"
fitToBounds></leaflet-map>
Actually adding a marker only triggers the 'x-leaflet-map:marker-pointed-out' event and any action must be performed by whoever uses the web component by adding functionality to that marker. Nothing is done on the map.
Adding a marker to the map could be done clicking with the right button in any point.
This action opens a popup with a button for confirmation. Clicking in it triggers the 'x-leaflet-map:marker-pointed-out' event by exposing the latitude and longitude of the point as follows
x-leaflet-map:marker-pointed-out {
target: leaflet-map,
isTrusted: false,
detail: {
latlng: {
lat: 51.52540664057756,
lng: -0.07201194763183595
}
}
...
}
You can the first map as a small demo using the allowAddMarker
attribute.
Any of the markers added to the map can be deleted by double clicking on it and confirming the deletion.
Web Component <leaflet-map>
triggers
'x-leaflet-map:marker-removed' event
when any marker is removed from map by exposing its GeoJSON as follows
x-leaflet-map:marker-removed {
target: leaflet-map,
isTrusted: false,
detail: {
feature: {
type: "Feature",
geometry: {
type: "Point",
coordinates: [-0.09, 51.5]
},
...
}
}
...
}
You can the first map as a small demo using the flyToBounds
attribute.
As you can see from the previous examples, it is very easy to add multiple maps on a web page.
Take a deeper look at the web component by reading and cloning the code on GitHub.