I'm trying to figure out of it's possible to detect when two Google Maps circles (around markers) intersect or bump into each other.
What I want to accomplish is, if two circles intersect, I want to raise an event. I'm not sure if this is possible though.
Calculate the distance between the centers of the circles, if it is less than the sum of the radius of the two circles, they intersect.
proof of concept fiddle
(based off of the code in Larry Dukek's answer, but using native Google Maps Javascript API v3 functions from the geometry library)
code snippet:
let map;
function initMap() {
// Create the map.
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 41.081301,
lng: -98.214219
},
zoom: 25
});
var c0 = new google.maps.Circle({
strokeColor: '#0000FF',
strokeOpacity: 1,
strokeWeight: 1,
fillColor: '#0000FF',
fillOpacity: 0.2,
map: map,
center: {
lat: 41.082953,
lng: -98.215285
},
radius: 200
});
var c1 = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 1,
strokeWeight: 1,
fillColor: '#FF0000',
fillOpacity: 0.2,
map: map,
center: {
lat: 41.081070,
lng: -98.214027
},
radius: 34.692866520
});
console.log("c1 & c0 hasIntersections returns:" + hasIntersections(c1, c0));
var c2 = new google.maps.Circle({
strokeColor: '#00FF00',
strokeOpacity: 1,
strokeWeight: 1,
fillColor: '#00FF00',
fillOpacity: 0.2,
map: map,
center: {
lat: 41.083313,
lng: -98.211635
},
radius: 34.692866520
});
console.log("c2 & c0 hasIntersections returns:" + hasIntersections(c2, c0));
}
function hasIntersections(circle0, circle1) {
var center0 = circle0.getCenter();
var center1 = circle1.getCenter();
var maxDist = circle0.getRadius() + circle1.getRadius();
var actualDist = google.maps.geometry.spherical.computeDistanceBetween(center0, center1);
return maxDist >= actualDist;
}
/* 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;
}
<!DOCTYPE html>
<html>
<head>
<title>Circles</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=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=geometry&v=weekly&channel=2" async></script>
</body>
</html>
Here is some JavaScript that will detect if two circles intersect
var e = Math; // shortcut for the mathematical function
var D2R = e.PI/180.0; // value used for converting degrees to radians
Number.prototype.toRadians = function() {
return this * D2R;
};
function distance(lat0,lng0,lat1,lng1){
// convert degrees to radians
var rlat0 = lat0.toRadians();
var rlng0 = lng0.toRadians();
var rlat1 = lat1.toRadians();
var rlng1 = lng1.toRadians();
// calculate the differences for both latitude and longitude (the deltas)
var Δlat=(rlat1-rlat0);
var Δlng=(rlng1-rlng0);
// calculate the great use haversine formula to calculate great-circle distance between two points
var a = e.pow(e.sin(Δlat/2),2) + e.pow(e.sin(Δlng/2),2)*e.cos(rlat0)*e.cos(rlat1);
var c = 2*e.asin(e.sqrt(a));
var d = c * 6378137; // multiply by the radius of the great-circle (average radius of the earth in meters)
return d;
}
function hasIntersections(circle0,circle1){
var center0 = circle0.getCenter();
var center1 = circle1.getCenter();
var maxDist = circle0.getRadius()+circle1.getRadius();
var actualDist = distance(center0.lat(),center0.lng(),center1.lat(),center1.lng());
return maxDist>=actualDist;
}
Just call hasIntersections with the references to your circles. Here is an example that showing two circles almost touching (returning false) and if you change the zero to a one in c1 they will touch (returning true).
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.081301, lng: -98.214219},
zoom: 25
});
var c0 = new google.maps.Circle({
strokeOpacity: .1,
strokeWeight: 1,
fillColor: '#0000FF',
fillOpacity: .2,
map: map,
center: {lat:41.082953, lng: -98.215285},
radius: 200
});
var c1 =new google.maps.Circle({
strokeOpacity: .1,
strokeWeight: 1,
fillColor: '#FF0000',
fillOpacity: .2,
map: map,
center: {lat:41.081070, lng: -98.214027},
radius: 34.692866520
});
console.log(hasIntersections(c1,c0));
Related
I have a script where I apply a search radius within a google map. I can change the radius and have it display dynamically but cannot seem to figure out how to replace the radius instead of just adding a radius. The function uses bindTo marker. I have tried replace and replaceWith but they do not seem to work.
Here is the range input -
<input type="range" class="custom-range" id="customRange1" value="20">
Here is the add marker script and creating the radius and binding it when the range value changes.
var marker = new google.maps.Marker({
map: map,
position: latLng,
title: name,
icon: 'linktoimage'
});
// Add circle overlay and bind to marker
$('#customRange1').change(function(){
var new_rad = $(this).val();
var rad = new_rad * 1609.34;
var circle = new google.maps.Circle({
map: map,
radius:rad,
fillColor: '#555',
strokeColor: '#ffffff',
strokeOpacity: 0.1,
strokeWeight: 3
});
circle.bindTo('center', marker, 'position');
});
So when I change the range value it will add a new radius overlay on top of the old, I would like it to replace the current radius overlay with the new. I am guessing its because I'm using bindTo.
Keep a reference to the circle, if the circle already exists, don't create a new one, change the existing one:
var circle;
// Add circle overlay and bind to marker
$('#customRange1').change(function() {
var new_rad = $(this).val();
var rad = new_rad * 1609.34;
if (!circle || !circle.setRadius) {
circle = new google.maps.Circle({
map: map,
radius: rad,
fillColor: '#555',
strokeColor: '#ffffff',
strokeOpacity: 0.1,
strokeWeight: 3
});
circle.bindTo('center', marker, 'position');
} else circle.setRadius(rad);
});
proof of concept fiddle
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 8
});
var circle;
var marker = new google.maps.Marker({
map: map,
position: map.getCenter(),
title: "name"
});
// Add circle overlay and bind to marker
$('#customRange1').change(function() {
var new_rad = $(this).val();
var rad = new_rad * 1609.34;
if (!circle || !circle.setRadius) {
circle = new google.maps.Circle({
map: map,
radius: rad,
fillColor: '#555',
strokeColor: '#ffffff',
strokeOpacity: 0.1,
strokeWeight: 3
});
circle.bindTo('center', marker, 'position');
} else circle.setRadius(rad);
});
}
html,
body,
#map {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="range" class="custom-range" id="customRange1" value="20">
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
I am studying C# , google map api. and i want to draw click rectangle and calculate rectangle area.
this is my code:
function mode() {
google.maps.event.addListener(map, 'click', function (event) {
var bounds = makeBounds(event.latLng, 200, 100);
placeRec(bounds);
});
}
function placeRec(bounds) {
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
editable: true,
bounds: bounds,
draggable:true
});
}
function makeBounds(nw, metersEast, metersSouth) {
ne = google.maps.geometry.spherical.computeOffset(nw, metersEast, 90);
sw = google.maps.geometry.spherical.computeOffset(nw, metersSouth, 180);
return new google.maps.LatLngBounds(sw, ne);
sowe = bounds.getSouthWest();
noea = bounds.getNorthEast();
}
I succeed draw click Rectangle in google map,
I want to know calculate Rectangle Area.
How do i have to do?
Thank you
Hey there i´m trying to find a way to just increase the length of a line without changing the orientation
i tried this with Polyline
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 37.4419, lng: -122.1419},
zoom: 8
});
var line = new google.maps.Polyline({
path: [new google.maps.LatLng(37.4419, -122.1419), new google.maps.LatLng(37.4519, -122.1519)],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 10,
geodesic: true,
map: map
});
}
and it works as expected
but i rather want it like
or
i only have the two coordinates from first example
it should be geodesic and theoreticaly idealy arround the globe back at same start so it will be like endless
i also tried to find out a way to calculate the some more far coordinates but searching is a mess because everboidy want to be found for caluclating distances.
so having two coordinates following the "line-through orientation" of but have high distance like some thousand kilometers pls let me know
You can use the Google Maps Javascript API Geometry library to compute the heading of the line and extend it an arbitrarily long distance along that heading.
code snippet::
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 37.4419,
lng: -122.1419
},
zoom: 8
});
var line = new google.maps.Polyline({
path: [new google.maps.LatLng(37.4419, -122.1419), new google.maps.LatLng(37.4519, -122.1519)],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 10,
geodesic: true,
map: map
});
// extend line from each end along its existing heading
// pick 20e6 meters as an arbitrary length
var lineHeading = google.maps.geometry.spherical.computeHeading(line.getPath().getAt(0), line.getPath().getAt(1));
var newPt0 = google.maps.geometry.spherical.computeOffset(line.getPath().getAt(0), 20000000, lineHeading);
line.getPath().insertAt(0, newPt0);
var newPt1 = google.maps.geometry.spherical.computeOffset(line.getPath().getAt(1), 20000000, lineHeading + 180);
line.getPath().push(newPt1);
}
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id="map"></div>
var xml = data.responseXML;
var circles = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("location");
var scans = markers[i].getAttribute("scans");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("long")));
var html = name;
var marker = new google.maps.Marker({
center: center,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
radius:1000
});
bindInfoWindow(marker, map, infoWindow, html);
}
Trying to add some data to circle markers.
The circles are already markers for specific locations, but I want to make them vary in size depending on a count that corresponds to that location. I cannot seem to find any code to make markers of variable size, since each marker is most likely going to have a unique number of contacts. Any ideas?
Here's the code I have now for markers. I know its not right, since it's not producing what I want.
https://developers.google.com/maps/documentation/javascript/examples/circle-simple <---This is the effect that I am looking for, but I don't understand how to get the values for size to change based on the data entered in the table.
You can set the marker radius to an integer returned by a function. Or it can be an expression.
Here is a JsFiddle with a working example where the count attribute in the XML is set by an expression.
function initMap() {
var myLatLng = new google.maps.LatLng(47.6685771, -122.2553681),
myOptions = {
zoom: 12,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
},
map = new google.maps.Map(document.getElementById('map'), myOptions);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; ++i) {
var marker = markers[i];
var name = marker.getAttribute("location");
var point = new google.maps.LatLng(
parseFloat(marker.getAttribute("lat")),
parseFloat(marker.getAttribute("long")));
var cityCircle = new google.maps.Circle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center: point,
radius: marker.getAttribute("count") * 75
});
}
}
https://jsfiddle.net/plbogen/ecj8o4uL
I have the following lat/long array, which i can draw it on map with success. My question is how can i have a loop and place a circle with custom Km radius (or standard radius if it's too much pain in the 4ss) for each array coordinates.
var locations = [
['lala', 37.0093833333333,24.7528638888889, 1],
['lala', 35.0093833333333,20.7528638888889, 2]
];
Thank you
var cityCircle
for (elements in your array) {
var populationOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center: your latlng,
radius: your radius here
};
// Add the circle for this city to the map.
cityCircle = new google.maps.Circle(populationOptions);
}
something like this?