Capture Google Maps Polyline On Click (Per Start/End) - javascript

Description
I am currently working with Google Maps V3 for our client and they've asked us to implement a drawing tool that will allow them to create connected stream of lines and calculate the distance. However, it seems the Google Maps V3 Drawing Manager library is very limited in how it allows us to capture the click events for a polyline.
Our Code
google.maps.event.addListener(map, 'click', function(event){
//TODO: Store lat/long of click for distance calculation later
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
//TODO: Display the total distance of the line
});
The Goal
google.maps.event.addListener(drawingManager, 'polylineclick', function(event){
//TODO: Store lat/long of line for distance calculation and display updated distance.
});
As you can see, we want to capture the lat/long as the user is creating the polyline and display the distance as each line is created, not once the entire polyline is completed.
Also, I know we can imitate this by creating custom handlers and doing some magic with the map's click method and drawing lines manually between lat/longs, but it seems weird that the Google Maps API wouldn't have a click method for their Drawing Manager.
Clarification
The end goal is to have functionality so while drawing a polyline, we can display the total length of the polyline dynamically. I.E. I begin by drawing a line, a section appears that says "Total Line is X", I click a second spot to create a second line and the text updates to "x" + "y", I click a third and it updates to "x" + "y" + "z", etc. This is why we were hoping there is an event to handle "lineDrawn" or "polylineClick" to store these lat/longs to we can calculate the length for dynamically created lines without having the user stop drawing lines to see the total length.
Edit: Updated addListener in Our Goal to use drawingManager, not map.
Edit: Addition of Clarification section.

Basically you want to chain the two together like this:
var thePolyLine = new google.maps.Polyline({
polyLineOptions
}).setMap(map).addListener("click", function(event){
//click event
});
============= EDIT =============
Ok, I clearly didn't read the OP's question entirely.
Looks like the markercomplete event returns a marker. I'd create a global Array of marker objects, then you can run a distance check between each on catching that event.
var markers = new Array();
google.maps.event.addListener(theDrawingManager, "markercomplete", function (marker) {
markers.push(marker);
});
Then, you can loop through them, and computeDistanceBetween any or all points.
============= EDIT #2 =============
My Fiddle of the solution! (I updated the code with more comments and fixed an error, made it obvious that distance is in meters):
http://jsfiddle.net/8Xqaw/12/
Right-click the map to add points to measure.
Distance is in meters, btw. It will update distance when you drag points, too. And there is a click function for the polyLine itself.
Clicking the first point again will allow you to connect the final point with the first point to create a polygon, then you can click and drag to move the polygon around (which moves the points as well)...

Try this :3
var PolylineOption = {
strokeColor : "blue",
strokeOpacity : 0.5,
strokeWeight : 5
};
var Display;
var rendererOptions = {
draggable : true,
suppressMarkers : true,
polylineOptions : PolylineOption
};
var Service = new google.maps.DirectionsService();
Display = new google.maps.DirectionsRenderer(this.rendererOptions);
Display.setMap(map);
Service.route(this.request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
Display.setDirections(response);
}
});
google.maps.event.addListener(PolylineOption, 'click', function() {
alert(this.strokeColor);
});

Related

Get Lat Lng when drawing a polygon with Google Maps drawing tool

I got the Google Map and Drawing Tools displayed on the map. I can draw the shapes (circle, polygon, rectangle ...) on the map. For the start I am using the example code from Google Maps JavaScript get started page: https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/drawing-tools
I was able to find a lot of examples on have to draw/make a shape object by providing all the properties and LatLng.
How do I get a LatLng for the shape that I just draw by using one of the drawing tools form Drawing Tools toolbar?
I am planing to make an application which will allow user to draw shapes on the map and save the LatLng in to database (i will be using MySql), so later the shape can be displayed again on the map as per request.
Please help.
There are a few ways to get the coordinates of the shapes you draw on the map. Specifically for polygons you can add an event listener to the map like so. The easiest way is to add an event listener to the map for when a polygon is finished drawing.
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
const coords = polygon.getPath().getArray().map(coord => {
return {
lat: coord.lat(),
lng: coord.lng()
}
});
console.log(JSON.stringify(coords, null, 1));
// SAVE COORDINATES HERE
});
Each type of drawing has a different format for saving so for something like circles you'd do
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
const radius = circle.getRadius();
// Save circle here
});
You also have the option of adding an event to listen for all of the events by listening to the overlaycomplete event but in that case you'd have to handle the different types inside the event.
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
if (event.type == 'circle') {
// Handle Circle using event.overlay
}
if (event.type == 'polygon') {
// Handle Polygon using event.overlay
}
});
Here's an example:
https://jsfiddle.net/juop8q3n/1/
And here's my sources:
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/drawinglayer#drawing_events
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/reference#drawing-on-the-map
EDIT
Another way I've seen people save the data is by adding an event listener to the map to get the GeoJSON data, which is a standard format for saving drawing data.
Link: http://jsfiddle.net/y89rbfLo/

How Can I animate Bing map pushpins based on a live GPS feed

I have looked over the bing maps documentation trying to find an answer to my question. I would prefer to do everything using the bing maps api and not have to add a third party library if possible.
Question: How can I animate a pushpin to make a smooth transition from one set of gps coordinate(longitude/latitude) to another in order to simulate smooth movement of a Pushpin on Bing maps?
Question: can deleting an entire object out of the map.entities array waste enough resources to cause performance issues? If so how can I change the pushpin latitude and longitude properties without deleting the entire object?
Sample code of trying to change the pushpins properties without deleting the object out of the array. This code does not work… I am unsure why it is not working?
map.entities.get(theIndexOfThePushPin)._location.latitude = newLat;
map.entities.get(theIndexOfThePushPin)._location.longitude = newLon;
I create a pushpin like so - This works fine
map.entities.push(new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(lat, lon), {
text: text,
visible: true,
textOffset: new Microsoft.Maps.Point(0, 5)
}));
Pseudo code for my recursive angular $http call
function BusMoveGPSRefresh() {
$http.get(resourceURL)
.then(function (data) {
if ('if pushpins have not been created') {
//create pushpins...
}
} else {
//delete pushpins out of the array and then recreate them
//with updated lon/lat. Or just update existing objects lon/lat properties if possible?
}
}
BusMoveGPSRefresh();//after everything is done then go get more info and start again. recursion...
}, function (reason) {// if fail than do
console.log(reason);
console.log("This Is not Working!!! Dang!!");
});
}
Any insight into the problem would be greatly appreciated! Thanks!
I could not find a simple answer for adding animation. I did find a site that gave a step by step tutorial on a more in-depth answer on how to animate pushpins.
Answer: 1 -- tutorial on how to animate bing map pushpins
https://blogs.bing.com/maps/2014/08/07/bring-your-maps-to-life-creating-animations-with-bing-maps-javascript/
Answer: 2 -- this is how to update the pushpin location without deleting the pushpin object out of the entities array.
Instead of deleting the entire pushpin object find the pushpin index and then use the property "setLocation()" and then add a new location.
//check to make sure that the lat and lon have
//changed if it is still the same location do nothing. else update
if (map.entities.get(indexOfPushpin).getLocation().latitude != lat
|| map.entities.get(indexOfPushpin).getLocation().longitude != lon) {
map.entities.get(indexOfPushpin).setLocation(new Microsoft.Maps.Location(lat, lon));
}

Google Map Marker with custom numbering

I have a Google Maps marker function that successfully creates markers on a map like this:
// A function to create the marker and set up the event window
function createMarker(point,html) {
var marker = new GMarker(point,{title:html});
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
Here is a tinyurl of the exiting code: http://tinyurl.com/b8f9b4l
Using this solution: Google maps: place number in marker?
I've updated this line of code but it is not numbering. What am I doing wrong?
var marker = new GMarker(point,{title:html,icon:'icon: \'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld='+ (position) +'|FF776B|000000',});
The icon property just needs to be the url. You don't need the extra "icon:", and you should drop the extra comma at the end (IE seems to throw an exception when it finds a dangling comma). Also, the parenthesis you don't need - but probably aren't hurting anything.
{
title:html,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=' + position +'|FF776B|000000'
}
I see where you got the idea. Idk why s/he got a point for that. The extra "icon:" messes it up.
Try this as a test, it should make sure you don't have any problems with the variables inside the url.
{
title:html,
icon: 'https://chart.googleapis.com/chart?chst=d_map_pin_letter&chld=4|FF776B|000000'
}

Google Maps API V3 infowindow

While developing this solution, I learned that API V2 was being deprecated. I've since begun work on a version utilizing API V3. This work-in-progress can be found at My New Map. Special thanks are due to David Marland at Hammerspace for accelerating this conversion for me.
I'm down to 3 remaining issues..the first of which I will address in this post.
I am unable to trigger the infowindows I have defined:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.Contains(event.latLng)) {
infowindowInside.open(map,polyline);
} else {
infowindowOutside.open(map,polyline);
}
});
I am attaching them to a polygon..not a marker. The polygon is written:
var path = [
new google.maps.LatLng(35.950079, -84.104977),
new google.maps.LatLng(35.950774, -84.049702),
new google.maps.LatLng(35.946883, -84.047813),
new google.maps.LatLng(35.945354, -84.045067),
new google.maps.LatLng(35.940907, -84.042149),
new google.maps.LatLng(35.930483, -84.037857),
new google.maps.LatLng(35.939656, -84.037857),
new google.maps.LatLng(35.928120, -84.076309),
new google.maps.LatLng(35.938822, -84.066868),
new google.maps.LatLng(35.950079, -84.104977)];
var polyline = new google.maps.Polygon({path:path, strokeColor: "#FF0000", strokeOpacity: 1.0, strokeWeight: 2, clickable:false});
polyline.setMap(map);
I appreciate any guidance you can provide.
Thank you.
** UPDATED *****
I've now modified the code to:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.ContainsLocation(event.latLng, polyline)) {
window.alert('inside');//infowindowInside.open(map,polyline);
} else {
window.alert('outside');//infowindowOutside.open(map,polyline);
}
});
However..still no trigger.
Possibly because Polygon doesn't have a "contains" function. You should look at using the Google Maps API Geometry Library, which has a containsLocation function.
Google maps api v3 does not allow you to add infowindows to polylines or polygons. The solution around this is to grab the lat/lng coordinates of the mouseclick and attach the info window (where the user clicked his/her mouse) to the map like:
google.maps.event.addListener(polyline, 'click', function(event) {
if (polyline.Contains(event.latLng)) {
infowindowInside.open(map);
} else {
infowindowOutside.open(map);
}
});
(note how there isn't a second argument in the .open() method)
otherwise you can figure out the lat/lng of either the center of your polygon or one of its corners and attach the infowindow there (but to the map)
that will allow you to display your infowindow while making it appear as tho it is attached to the polygon.
Edit: Also -- as mano marks had stated about .Contains -- I am not sure if that method exists or not either, so that block of code you have may still not work even after removing the second argument from the .open() method. you may have to take a different approach to your logic if that's the case, but attaching the marker to the map instead of your polygon or polyline will solve your main issue.

Google Maps - Add two markers (directions)

Playing around with Google Maps these days, with some directions.
I have a map that gets the directions and address (reverse-geocoding) when dragging and dropping the markers.
If there is two nodes on the map (http://dev.korebogen.dk/gmap/) the script is working fine (click set directions) - but I need to add a click event so I can place those two markers instead of hard-code the location by hand, but still be able to drag them around - or place new with new click. But I only need A to B markers.
Ive been playing around with some click events, but I can not seem to accomplish what I am looking for - hope to see some help here. Thank you very much.
This code will allow you to click and place two markers, which you can then use to load GDirections, and remove the original markers. Note that you must use this format for the query string: "from: marker#35,-25 to: marker#-20,15".
var markerArray = [];
var listener = GEvent.addListener(map, "click", function(overlay, latlng) {
var marker = new GMarker(latlng, { draggable: true });
map.addOverlay(marker);
markerArray.push(marker);
if (markerArray.length > 1) {
GEvent.removeListener(listener);
var marker1 = markerArray[0];
var marker2 = markerArray[1];
gdir.load("from: marker1#" + marker1.getLatLng() + " to: marker2#" + marker2.getLatLng());
map.removeOverlay(marker1);
map.removeOverlay(marker2);
}
});

Categories