Published
- 2 min read
Draw a polygon from markers in leaflet
 Following up from the previous article about implementing the fog of war in leaflet, I want to add some markers to the map and to create a polygon that joins them.
Let’s see how I manage to do that.
This is part of my series of articles about leaflet:
- Leaflet fog of war
 - Draw a polygon from markers in leaflet
 - Load and display GPX in leaflet
 - Browser storage
 
The user can click the map to generate markers that follow a route, e.g. a road, a trail, etc.. and later join those markers to create a complex polygon. This reflects the fact that you have visited the road, but you only have certain visibility of the environment (maybe 10 meters or so):
Markers
Joined markers into a polygon
Join markers into a polygon
When a new marker is added, it is added to the map and to an internal array:
        onAdd: function (e) {
            const marker = new L.Marker(e.latlng)
            container.markers.push(marker.addTo(map))
        }
When the user click on a button, those markers are processed and joined into a polygon by using the jsts library
const _joinLinesInPolygon = (points) => {
	const pointToGeomCoordinate = (p) => {
		if (p.lat && p.lng) return new jsts.geom.Coordinate(p.lat, p.lng)
		return new jsts.geom.Coordinate(p[0], p[1])
	}
	const toLeafletPoint = (p) => {
		return [p.x, p.y]
	}
	const meters = 40 //the user can selected the width of the generated polygon
	const distance = (meters * 0.0001) / 111.12 //Geometry aproximations
	const geometryFactory = new jsts.geom.GeometryFactory()
	const pathCoords = points.map((p) => pointToGeomCoordinate(p))
	const shell = geometryFactory.createLineString(pathCoords)
	const polygon = shell.buffer(distance)
	const polygonCoords = polygon.getCoordinates()
	return polygonCoords.map((coord) => toLeafletPoint(coord))
}
This method converts the leaflet points into a format the jsts libray can understand and perform the buffer operation in jsts which does all the magic. From the API definition: buffer computes a buffer area around this geometry having the given width.
Later the coordinates are transformed into the leaflet format.
Here you can see it in action: https://www.agalera.eu/leaflet-fogofwar/