Leaflet Map with Custom Rotation , Custom Radius and Draggable

Leaflet Map with Custom Rotation , Custom Radius and Draggable

Scenario:

Want to create leaflet map with following features.

  1. Create Marker on Click
  2. Create a circle with custom radius on the marker point
  3. Create a rectangle polygon around the center of the circle with custom radius and custom angle of rotation.
  4. 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: '&copy; ' + 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/