Scenario:
Want to create leaflet map with following features.
- Create Marker on Click
- Create a circle with custom radius on the marker point
- Create a rectangle polygon around the center of the circle with custom radius and custom angle of rotation.
- Allows Dragging of the Marker and redraw the polygon on Movement.
Solution :
Step1 : Define a Map for Map in HTML
<div id=”map” style=”position: absolute; height: 100%; width: 100%;”></div>
Step 2: Initialize map
var map = L.map('map').setView([24, 54], 12);
mapLink =
'<a href="http://openstreetmap.org">OpenStreetMap</a>';
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© ' + mapLink + ' Contributors',
maxZoom: 18,
autoPan: true
}).addTo(map);
Step 3:
Add a click on event on map to create a marker on clicked point
map.on('click', function (e) {
// e.latlng.lat - Latitude of clicked point
// e.latlng.lng - longitude of clicked point
// call the function with custom radius in meters - 6000 Meters means , 6KM
//cla the function with angle required : here it is 32 degrees
DrawAll(e.latlng.lat, e.latlng.lng, 6000, 32)
});
Step 4 : Now time to create the function
function DrawAll(lat, lng, rad, angles) {
//clear old layers
ExpressLayers.clearLayers();
//create a marker and add to layer group
var marker = L.marker([lat,lng], { draggable: 'true', autoPan: true }).addTo(map);
ExpressLayers.addLayer(marker);
//create a cirle and add to layer group
var circle = L.circle([lat, lng], { color: "white", fillColor: "#f03", fillOpacity: 0.0, radius: rad }).addTo(map);
ExpressLayers.addLayer(circle);
//prepare data for create a square around with defined angle
var centerpoint = [lat, lng];
var retpoint = [];
// var angles = 14; // change this variable for desired angle
retpoint = rotateboundary(centerpoint , circle.getBounds(), angles);
//draw polygon from received coordinates
var polygon = L.polygon([retpoint], { color: 'green' });
polygon.addTo(map);
ExpressLayers.addLayer(polygon);
//create an event to move or redraw in case the marker is dragged to new position
marker.on('dragend', function (event) {
var marker = event.target;
var position = marker.getLatLng();
ExpressLayers.clearLayers();
DrawAll(position.lat, position.lng, 6000, 32) ; // 32 degrees, 60000 radius of 6KM in meters
marker.setLatLng(new L.LatLng(position.lat, position.lng), { draggable: 'true' });
ExpressLayers.addLayer(marker);
//pan the view along with the marker
map.panTo(new L.LatLng(position.lat, position.lng))
});
}
function rotateboundary(CenterPoint, circlebounds, angles) {
var ne_lat = circlebounds._northEast.lat;
var ne_lon = circlebounds._northEast.lng;
var sw_lat = circlebounds._southWest.lat;
var sw_lon = circlebounds._southWest.lng;
var pointlist = [];
var p1 = [sw_lat, ne_lon];
pointlist.push(p1);
var p2 = [ne_lat, ne_lon];
pointlist.push(p2);
var p3 = [ne_lat, sw_lon];
pointlist.push(p3);
var p4 = [sw_lat, sw_lon];
pointlist.push(p4);
const res = []
const centerPoint = map.latLngToLayerPoint(CenterPoint)
const angle = angles * (Math.PI / 180)
for (let i = 0; i < pointlist.length; i++) {
const p = map.latLngToLayerPoint(pointlist[i])
// translate to center
const p2 = new L.Point(p.x - centerPoint.x, p.y - centerPoint.y)
// rotate using matrix rotation
const p3 = new L.Point(Math.cos(angle) * p2.x - Math.sin(angle) * p2.y, Math.sin(angle) * p2.x + Math.cos(angle) * p2.y)
// translate back to center
let p4 = new L.Point(p3.x + centerPoint.x, p3.y + centerPoint.y)
// done with that point
p4 = map.layerPointToLatLng(p4)
res.push(p4)
}
return res;
}
The Final Output of the code will be :

For complete working code of the project refer here : https://github.com/haneefputtur/LeafletRotateCircle/blob/master/leafletrotate.html
Live Demo : https://jsfiddle.net/haneefputtur/vkr1qspe/1/

