Title: Draw multiple shapes on a google map using reference of one shape (Using Click only map)
Problem:
A few days back one of our clients encountered a problem with a service we are providing. The problem is related to drawing a shape on the google map which would change its position as time goes by. The shape would have multiple position references and time duration for each reference. As time goes by, its location will be changed from one point to another. This will help users not to draw the same shape multiple times and save lots of time.
I have come up with a solution for this problem. Below is the description of that.
In the following picture you can see there is a shape but in three different positions. This solution will help users to create the same shape without having to draw it multiple times.
Solution:
Step 1:
At first create a div and set the div id name as “map”.
<div id=”map”></div>
Step 2:
Load google map api link into src of the script.
<script src=”https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=&v=weekly"
async >
</script>
Step 3:
After writing the html and css part then go to the JS part. And initialize your google map into map div and set a center also as your wish.
const map = new google.maps.Map(document.getElementById(“map”), {
zoom: 4,
center: { lat: 24.886, lng: -70.268 },
mapTypeId: “terrain”,
});
Step 4:
Now declare your shape using lat,lng. It can be any type of shape such as rectangle, triangle, circle, polygon etc.
Here I draw a triangle (which is also one type of polygon also) and declare it.
const triangleCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
{ lat: 25.774, lng: -80.19 },
];
Step 5:
Draw the first shape into a map using the triangleCoords Data.
const bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: “#FF0000”,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: “#FF0000”,
fillOpacity: 0.35,
});
bermudaTriangle.setMap(map);
Step 6:
Here we draw multiple shapes when I click the map.So at first we need to know the center of any shape, mainly if we calculate the center of any shape we can easily draw those shapes on a map.
So, to calculate the center we need to know the lowest lat long and highest lat long.
Algorithm:
Run through all the points in the polygon. For all the points find;
x1, the lowest x coordinate
y1, the lowest y coordinate
x2, the highest x coordinate
y2, the highest y coordinate
You now have the bounding rectangle, and can work out the center using:
center.x = x1 + ((x2 — x1) / 2);
center.y = y1 + ((y2 — y1) / 2);
So using triangleCoords we get x1,y1,x2,y2;
var x1 = 18.466;
var x2 = 32.321;
var y1 = -80.19;
var y2 = -64.757;
var center = {
lat : x1 + ((x2 — x1) / 2),
lng : y1 + ((y2 — y1) / 2)
};
Step 7:
Then when the user clicks on the map using the mouse then we need to get the new lat,long point where the user clicks. To find it use this code,
map.addListener(“click”, (mapsMouseEvent) => {
const newLatLng = mapsMouseEvent.latLng;
});
Here newLatLng is the click point .
Step 8:
After that we need to set a new center and find the all new lat, long point of the new polygon. So we need to calculate the difference between the click point and center point and add the difference with the previous lat,long point. Then you can easily find the new lat,long point and then push it to the new object and set the map again using the new object.
const newtriangleCoords = [];
triangleCoords.forEach((cord) => {
newtriangleCoords.push({
lat: cord.lat + (newLatLng.lat() — center.lat), lng : cord.lng + ( newLatLng.lng() — center.lng)
});
});
const newbermudaTriangle = new google.maps.Polygon({
paths: newtriangleCoords,
strokeColor: “#FF0000”,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: “#FF0000”,
fillOpacity: 0.35,
editable: true
});
newbermudaTriangle.setMap(map);
By following these steps you can easily draw new shapes also.
Preview:
Before:
After
Follow this link for showing the output: Multiple Shape Draw using reference of one Shape
Html:
<!DOCTYPE html>
<html>
<head>
<title>Polygon Arrays</title>
<script src=”https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<! — jsFiddle will insert css and js →
</head>
<body>
<div id=”map”></div>
<! — Async script executes immediately and must be after any DOM elements used in callback. →
<script
src=”https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=&v=weekly"
async
></script>
</body>
</html>
CSS:
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
JS:
function initMap() {
const map = new google.maps.Map(document.getElementById(“map”), {
zoom: 4,
center: { lat: 24.886, lng: -70.268 },
mapTypeId: “terrain”,
});
const triangleCoords = [
{ lat: 25.774, lng: -80.19 },
{ lat: 18.466, lng: -66.118 },
{ lat: 32.321, lng: -64.757 },
{ lat: 25.774, lng: -80.19 },
];
const bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: “#FF0000”,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: “#FF0000”,
fillOpacity: 0.35,
});
bermudaTriangle.setMap(map);
var x1 = 18.466;
var x2 = 32.321;
var y1 = -80.19;
var y2 = -64.757;
var center = {lat: x1 + ((x2 — x1) / 2), lng: y1 + ((y2 — y1) / 2)};
const myLatlng = { lat: 30.774, lng: -80.19 };
map.addListener(“click”, (mapsMouseEvent) => {
const newLatLng = mapsMouseEvent.latLng;
const newtriangleCoords = [];
triangleCoords.forEach((cord) => {
newtriangleCoords.push({
lat: cord.lat + (newLatLng.lat() — center.lat), lng : cord.lng + ( newLatLng.lng() — center.lng)
});
});
const newbermudaTriangle = new google.maps.Polygon({
paths: newtriangleCoords,
strokeColor: “#FF0000”,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: “#FF0000”,
fillOpacity: 0.35,
editable: true
});
newbermudaTriangle.setMap(map);
});
}