First post so bear with me.
I have a google map that displays polylines.
I create the polylines using the following method:
function createPoly(number,path, color, name) {
var g = google.maps;
var poly = new g.Polyline({
path: path,
strokeColor: color,
strokeOpacity: 1,
strokeWeight: 3
});
var label = new Label({ map: map }, poly);
// Add mouse events to poly
g.event.addListener(poly, "mouseover", function() {
label.add_(name);
poly.setOptions({strokeWeight: 6.0,strokeColor: "#0000FF",});
});
g.event.addListener(poly, "mouseout", function() {
label.remove_();
poly.setOptions({strokeWeight: 3.0,strokeColor: "#FF0000",});
});
g.event.addListener(poly, "click", function() {
$('.LORDesc').empty();
$('.LORDesc').append(name);
});
poly.setMap(map);
return poly;
}
The above code works, and every time I want to create a poly on my map I use:
var MyPoly = createPoly(0,SC001, "#FF0000", "SC001 <BR>Poly 1");
which works fine also.
My problem is I want to create Links to the side of my map and allow the user to hover over the link and have the poly change weight and color. Like it does when the user hovers over the poly on the map. Basically to identify the poly as they hover over the links.
I hope this makes sense.
Any help would be appreciated. I have tried various techniques on my own but have failed.
Regards,
Jonny
You can listen for mouseover and mouseout events on link and trigger event for polyline object. For example:
var linkId = document.getElementById('polylink');
google.maps.event.addDomListener(linkId, 'mouseover', function(event) {
google.maps.event.trigger(polyLine, 'mouseover', {
stop: null,
latLng: new google.maps.LatLng(48, 13.5),
edge: 0,
path: 0,
vertex: 0
});
});
google.maps.event.addDomListener(linkId, 'mouseout', function(event) {
google.maps.event.trigger(polyLine, 'mouseout', {
stop: null,
latLng: new google.maps.LatLng(48, 13.5),
edge: 0,
path: 0,
vertex: 0
});
});
See complete example at jsbin.
If you don't provide the 3rd parameter for trigger method you will get the message error in console:
Uncaught TypeError: Cannot read property 'vertex' of undefined
mouseover and mouseout polyline event handler provides google.maps.PolyMouseEvent object. I made it like it was suggested for google.maps.MouseEvent object in question Simulate a click in a Google Map.
I just add {} to third parameter of trigger function and this error don't show again.
Example: google.maps.event.trigger(yourPolygon, 'mouseover', {});
Related
I'm working with google.maps.polygons. The library uses a google.maps.MVCArray element to store the vertices of the polygon where each vertex contains a latitude and longitude variable. So I'm able to create fancy polygons on the fly using user mouse clicks.
var listener1 = google.maps.event.addListener(map, "click", function(e) {
var latLng = e.latLng;
var myMvcArray = new google.maps.MVCArray();
myMvcArray.push(latLng); // First Point
var myPolygon = new google.maps.Polygon({
map: map,
paths: myMvcArray, // one time registration reqd only
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.10,
editable: true,
draggable: false,
clickable: true
});
google.maps.event.removeListener(listener1);
var listener2 = google.maps.event.addListener(map, 'click', function(e) {
latLng = e.latLng;
myMvcArray.push(latLng);
console.log(myMvcArray.getArray());
});
});
My problem is, that console log result is incomprehensible. I've spent a couple of hours trying to figure out how to get clean data from myMvcArray. I need to use the data elsewhere.
So it turns out the trick is this:
console.log(myMvcArray.getArray()[0].lat(), myMvcArray.getArray()[0].lng() );
Which returns: XX.XX2157415679654 -XXX.XX782657623291
A For/Each loop will also work.
myMvcArray.getArray().forEach(function(value, index, array_x) {
console.log(" index: " + index + " value: " + value);
})
Which returns:
index: 0 value: (XX.XX2157415679654, -XXX.XX782657623291)
index: 1 value: (XX.XX209255908967, -XXX.XX77514743805)
Info offered in case anybody else has issues here. Note, too, the code above works pretty well for letting users define a google.maps.polygon on a map easily.
You can use JSON.stringify()
So your code would be
console.log(JSON.stringify(myMvcArray.getArray()))
This works because stringify calls the methods on the MVCArray to get the contents whereas log doesn't.
I have multiple polylines on a Google Map and add a 'click' event handler for each. All these polylines are added via javascript code. However when I click on any polyline on map, the click event for the last added polyline is fired. This makes it difficult to identify the line clicked.
The code that creates the Polylines is:
$.ajax({
type: "GET",
url: "MapData.html",
success: function (json) {
mapData = JSON.parse(json);
var newroad;
for (var i = 0; i < mapData.length; i++) {
newroad = new google.maps.Polyline({
ID: mapData[i].ID,
path: google.maps.geometry.encoding.decodePath(mapData[i].latLngs),
strokeColor: 'blue',
strokeOpacity: 0.75,
strokeWeight: 3
});
newroad.setMap(map);
google.maps.event.addListener(newroad, 'click', function () {
setSelectedRoad(newroad);
});
}
},
error: function () {
alert('Critical Data Failure');
}
});
The data is correctly fetched from the server and all polylines are displayed in blue as expected. The function that gets called when a polyline is clicked is
function setSelectedRoad(road) {
road.strokeColor = 'black';
road.setOptions({ strokeColor: 'black', strokeOpacity: 1.0 });
selectedRoadID = road.ID;
}
However the "selectedRoadID" always turns out to be the last polyline added and the color for that line changes to black, even if any other polyline is clicked.
The confusing part is that if I draw a fresh polyline on the map and set its click event to the same function, then that works properly. I do get proper ID for the polyline clicked. This works for any number of new lines drawn and works properly for clicking them in any order.
The problem is you're doing this in a loop:
newroad = new google.maps.Polyline({ ... });
google.maps.event.addListener(newroad, 'click', function () {
setSelectedRoad(newroad);
});
So you re-create newroad let's say 10 times. Each time you create it, you give the same variable a new event listener, i.e. you're overriding the same event listener 10 times. Not creating 10 separate event listeners, one for each polyline.
When you click on your polyline, you're only therefore executing the very last version of the event listener.
Instead you need to separate out the event listener from the loop. Something like this:
$.ajax({
type: "GET",
url: "MapData.html",
success: function (json) {
mapData = JSON.parse(json);
var newroad;
for (var i = 0; i < mapData.length; i++) {
newroad = new google.maps.Polyline({
ID: mapData[i].ID,
path: google.maps.geometry.encoding.decodePath(mapData[i].latLngs),
strokeColor: 'blue',
strokeOpacity: 0.75,
strokeWeight: 3,
map: map
});
bindEvent(newroad);
}
},
error: function () {
alert('Critical Data Failure');
}
});
function bindEvent(newroad) {
newroad.addListener('click', function () {
setSelectedRoad(this);
});
}
This way you call bindEvent 10 times, each time with a different argument for newroad. So you create 10 separate event listeners with a different value for newroad each time.
I found that changing
newroad.setMap(map);
google.maps.event.addListener(newroad, 'click', function () {
setSelectedRoad(newroad);
});
to
newroad.setMap(map);
google.maps.event.addListener(newroad, 'click', function () {
setSelectedRoad(this);
});
fixed everything.
I know I can make a marker with a tooltip that shows "SOMETHING" like this:
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat,lon),
map: map,
draggable: true,
title:"SOMETHING",
icon: '/public/markers-map/male-2.png'
});
I want to do the same with a circle but title doesn't work.
new google.maps.Circle({
center: new google.maps.LatLng(lat,lon),
radius: 20,
strokeColor: "blue",
strokeOpacity: 1,
title:"SOMETHING",
strokeWeight: 1,
fillColor: "blue",
fillOpacity: 1,
map: map
});
It prints the circle but does not show the message "SOMETHING".
How can I do it? is there another property to get it?
Thanks in advance.
The tooltip is created via the native title-attribute of DOM-elements, but the API doesn't provide any method to access the DOMElement that contains the circle.
A possible workaround may be to use the title-attribute of the map-div instead(set it onmouseover and remove it onmouseout)
//circle is the google.maps.Circle-instance
google.maps.event.addListener(circle,'mouseover',function(){
this.getMap().getDiv().setAttribute('title',this.get('title'));});
google.maps.event.addListener(circle,'mouseout',function(){
this.getMap().getDiv().removeAttribute('title');});
You can also use InfoWindow instead of html title attribute, as the title may not show up always on mouse over. InfoWindow looks pretty good.
var infowindow = new google.maps.InfoWindow({});
var marker = new google.maps.Marker({
map: map
});
Then use same mouseover event mechanism to show the InfoWindow:
google.maps.event.addListener(circle, 'mouseover', function () {
if (typeof this.title !== "undefined") {
marker.setPosition(this.getCenter()); // get circle's center
infowindow.setContent("<b>" + this.title + "</b>"); // set content
infowindow.open(map, marker); // open at marker's location
marker.setVisible(false); // hide the marker
}
});
google.maps.event.addListener(circle, 'mouseout', function () {
infowindow.close();
});
Also we can add event listener direct on google.maps.Circle instance.
Code sample:
//circle is the google.maps.Circle-instance
circle.addListener('mouseover',function(){
this.getMap().getDiv().setAttribute('title',this.get('title'));
});
circle.addListener('mouseout',function(){
this.getMap().getDiv().removeAttribute('title');
});
Just wrote for alternative!
I use a mousemove listener on Google Maps, while I want handle the click event too.
var path = new google.maps.MVCArray;
...
line = new google.maps.Polyline({
map: map,
path: new google.maps.MVCArray([path]),
});
google.maps.event.addListener(map, 'click', function(event) {
path.push(event.latLng);
});
google.maps.event.addListener(map, 'mousemove', function(event) {
if (path.getLength() > 1) path.setAt(path.getLength()-1,event.latLng);
});
I want to follow the mouse with the line, but if the user click on the map, push the polyline's array. But the click event doesn't work...
Any idea?
I think there is a small bug in your code:
On line 5 it should read
path: path,
instead of
path: new google.maps.MVCArray([path]),
Reason:
Your var path is already an MCVArray and the property path of PolylineOptions expects just an MVCArray, but you supply it with an MVCArray inside a normal array inside an MVCArray.
This prevents the code following from pushing the coordinates to the correct array.
I have polygons for various region and states in my application. Markers implement tooltip by taking the title attribute. On mouseover and mouseout over a polygon events can be fired. How do I create a tooltip that looks like the tooltip that is implemented for a marker.
Edit-1: Adding the code used to create the polygon and attach the handlers to show/hide tooltips.
function addPolygon(points) {
var polygon = new google.maps.Polygon({
paths: points,
strokeColor: " #FFFFFF",
strokeOpacity: 0.15,
strokeWeight: 1.5,
fillColor: "#99ff66",
fillOpacity: 0.14
});
var tooltip = document.createElement('div');
tooltip.innerHTML = "Alok";
google.maps.event.addListener(polygon,'mouseover',function(){
tooltip.style.visibility = 'visible';
});
google.maps.event.addListener(polygon,'mouseout',function(){
tooltip.style.visibility = 'hidden';
});
polygon.setMap(map);
}
There's actually a neat trick to work around this (strange) limitation in Google Maps. When moving your mouse over a data item, you can just add a tooltip to the map's <div>. It will be added at the location where your mouse pointer currently is - right over the item!
map.data.addListener('mouseover', mouseOverDataItem);
map.data.addListener('mouseout', mouseOutOfDataItem);
...
function mouseOverDataItem(mouseEvent) {
const titleText = mouseEvent.feature.getProperty('propContainingTooltipText');
if (titleText) {
map.getDiv().setAttribute('title', titleText);
}
}
function mouseOutOfDataItem(mouseEvent) {
map.getDiv().removeAttribute('title');
}
I think you will have to do it yourself.In a page i have implemented i attached a mouse move event to the page so i can record the mouse position.Then when a polygon mouseover event occurs i display a custom div near the mouse position
Hope it helps
This code works for me:
googleShape - is your polygon or circle or rectangle.
titleText - message you need to post on hover of shapes.
google.maps.event.addListener(googleshape, 'mouseover', function() {
this.map.getDiv().setAttribute('title', "`titleText`");
});
google.maps.event.addListener(googleshape, 'mouseout', function() {
this.map.getDiv().removeAttribute('title');
});
You could try the following
//Add a listener for the click event
google.maps.event.addListener('click', showArrays);
infoWindow = new google.maps.InfoWindow;
then when the click event happens call the following function
function showArrays(event) {
var contentString = 'Content here';
// Replace the info window's content and position.
infoWindow.setContent(contentString);
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
}
A nice solution will be to use Google's built in InfoWindow as a tooltip/popup container. Then listen to mouseover and mouseout to show/hide the tooltip.
Notice that by using InfoWindow you can also put HTML markup as the content of the tooltip and not only plain text.
const mapHandler: google.maps.Map = ... // your code here
const polygon: google.maps.Polygon = ... // your colde here
const popUp = new google.maps.InfoWindow({
content: "<span style='color:red'> SOME MESSAGE </span>" // red message
});
polygon.addListener("mouseover", (event) => {
popUp.setPosition(event.latLng);
popUp.open(mapHandler);
});
polygon.addListener("mouseout", (event) => {
popUp.close()
});