I have an app in which I need the data in the infowindow bubbles to update automatically. I've checked around and I see methods for moving markers, updating marker colors, and the like, but nothing with directly updating infowindow content. I am pulling the value necessary (e.g. building[i][7] ) from a hidden DOM element whose content automatically updates, and I need the infowindow's content to automatically update alongside it.
Here is the code I am using to draw the infowindow bubbles.
infowindow=new google.maps.InfoWindow();
for (i=0;i<buildings.length;i++){
marker=new google.maps.Marker({
position:new google.maps.LatLng(buildings[i][4],buildings[i][5]),
map:map,
shadow:shadow,
icon:greenIcon,
title:buildings[i][0]+" \n"+buildings[i][1],
zIndex:buildings[i][6]
});
}
google.maps.event.addListener(marker,'click',(function(marker,i){
return function(){
infowindow.setContent(
'<h2>'+buildings[i][0]+'</h2>'+
'<p>'+buildings[i][2]+'</p>'+
'<p>'+buildings[i][7]+'</p>'
);infowindow.open(map,marker);
}
})(marker,i));
Any help is greatly appreciated!
There isn't a built-in way in JavaScript to be notified when the content of a DIV changes, but I believe the jQuery.bind() function or the newer (jQuery v1.7) jQuery.on() function provide a way to implement what you are trying to achieve.
on funciton call just run
infowindow.setContent(
'<h2>'+buildings[i][0]+'</h2>'+
'<p>'+buildings[i][2]+'</p>'+
'<p>'+buildings[i][7]+'</p>'
);infowindow.open(map,marker);
Related
Using google-map v1.1.10 against git://github.com/GoogleWebComponents/google-map.git#*
I build up my markers like so:
<template>
<site-data sites="{{sites}}"> </site-data>
<google-map fit-to-markers >
<template is="dom-repeat" items="{{sites}}">
<template is="dom-repeat" items="{{item}}">
<google-map-marker latitude={{item.latitude}}
longitude={{item.longitude}}
title="{{item.project_name}}"
>
<h1>{{item.project_name}}</h1>
<p style="margin: 0;">Location: <b>{{item.town}}, {{item.country}}</b></p>
<p style="margin: 0;">Tech Description: <b>{{item.tech_desc}}</b></p>
</google-map-marker>
</template>
</template>
</google-map>
Upon initial loading of the webapp, things work really well. I can click on a marker and the infowindow shows the content. However, if I change any values in my sites array, I seem to lose the infowindow and/or the click event. I have to refresh the browser to get back to my initial condition (click to show infowindow).
Also, The marker locations will update perfectly if I change lat/long and hovering shows tooltip aka. title, appropriately as well.
I've added a click event which calls a console.log to the click event. It works well until a value is changed in the {{sites}} binding, so it seem I am losing click events when the google-map updates itself?
There are no scripts in this element.
If I can provide more information, please let me know.
Thanks in Advance,
Scott
It looks like there are some problems with GoogleMapMarker. I have some hacks you can try, but you should make an issue ticket so somebody can take a deeper look.
One problem is that the MutationObserver that updates MapMarker is not observing characterData, so it doesn't fire when MapMarker's simple text content changes.
Another problem is that the attach/detach implementations don't seem to be complementary. For example, detach removes the MutationObserver and attach never puts it back.
Lastly, there are cases when the info window become disconnected from the MapMarker.
Here is a JSBin where there are three kinds of mutations of a GoogleMapMarker setup as you described: http://jsbin.com/hobixi/edit?html.
Adding a new map marker seems to work just fine.
Modifying content of an existing marker fails because of the MutationObserver problem I described. I fixed that by monkey patching GoogleMapMarker's _contentChanged method like so:
Example:
marker._contentChanged = function() {
if (this._contentObserver)
this._contentObserver.disconnect();
// Watch for future updates.
this._contentObserver = new MutationObserver( this._contentChanged.bind(this));
this._contentObserver.observe( this, {
childList: true,
subtree: true,
///----------------
// monkey patch
characterData: true
//-----------------
});
...
Lastly, I artificially made an example that removes a marker from DOM and puts it back. This fails as described above, so I monkey patched attached and detached like so:
Example:
marker.detached = function() {
if (this.marker) {
google.maps.event.clearInstanceListeners(this.marker);
this._listeners = {};
this.marker.setMap(null);
///----------------
// monkey patch
this.info = null;
//-----------------
}
if (this._contentObserver)
this._contentObserver.disconnect();
};
marker.attached = function() {
// If element is added back to DOM, put it back on the map.
if (this.marker) {
this.marker.setMap(this.map);
///----------------
// monkey patch
this._contentChanged();
//-----------------
}
};
You didn't specify the nature of the changes you are triggering. The clicking doesn't show the info window problem seems to be what happens when the Marker and the Info become discombobulated, maybe there is an attach/detach happening.
Well played baiting me to look into this. :)
how to have custom image marker on google static map, i need url format:
this is what i have tried, but its having default marker image
http://maps.google.com/maps/api/staticmap?center=25.3176452,82.97391440000001,&zoom=15&markers=25.3176452,82.97391440000001|25.3176452,82.97391440000001&path=color:0x0000FF80|weight:5|25.3176452,82.97391440000001&size=175x175&sensor=TRUE_OR_FALSE
This is what you want:
http://maps.googleapis.com/maps/api/staticmap?zoom=17&size=512x512&maptype=hybrid&markers=icon:http://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico|34.052230,-118.243680
for a custom image, put the icon:url after of markers...
Format
icon:url|lat,lng
Example
icon:http://cdn.sstatic.net/Sites/stackoverflow/img/favicon.ico|34.052230,-118.243680
a result of my example
For more information check google maps api, there are more information like size, markers position, center map, map type... etc.
https://developers.google.com/maps/documentation/static-maps/intro#MapTypes
*If the icon, img, don't appear it will be the size of image, try with another size,less than 64x64 px, format of image, "GIF, JPEG and PNG", the documentation recommend "PNG", if it doesn't appear check permision of image for public request(external request)...
According to the documentation you can specify custom icons like so:
markers=icon:...
e.g. amending your URL:
http://maps.google.com/maps/api/staticmap?center=25.3176452,82.97391440000001,&zoom=15&markers=icon:http://www.megaadresse.com/images/icons/google-maps.png|25.3176452,82.97391440000001&path=color:0x0000FF80|weight:5|25.3176452,82.97391440000001&size=175x175
Gives you:
PS: the sensor parameter is no longer required.
PPS: also you seemed to have specified the same coordinates twice in your markers parameter, so it was actually drawing two markers on the same location.
You can add an image in the marker:
var campaign_map = new google.maps.Map(document.getElementById("campaign_map_canvas"), mapOptions);
var selected_marker = new google.maps.Marker({
position: position,
map: campaign_map,
icon: 'path/to/image'
});
google.maps.event.trigger(campaign_map,'resize');
EDIT
You can use the following:
https://maps.googleapis.com/maps/api/staticmap?size=480x480&markers=icon:path/to/image.png%257C996600%7Carea/you/want/
I checked that there are checkresize() methods from google Map's native API.. but it doesn't seem to work with the refresh function from gmaps.js.
Does anyone has similar problems using AngularJS and gMaps.js? How do you come to solve it?
After i resize the window, the map appears again. So I am thinking is there anyway to check resize on initialization for gMap.js?
ng-cloak did not work for me when I tried it. I think this was because I am using the map in a panel which expands on user interaction instead of being visible on load.
I switched my ng-show to an ng-if and it worked correctly. This is because the map code(I used a directive) will not run until the if condition is true, which allows it to render properly.
*Sorry the fiddle got deleted. I don't remember what I had in it, but it was something like this
<gmap unique="231" center="{{getAddress(item)}}" destination="{{getAddress(item)}}" origin="{{getMyAddress(item)}}" type="roadmap" marker-content="Hello"></gmap>
The important thing is that the google scripts don't start doing their thing until your container element is actually displayed. This is accomplished with the ng-if.
Add the ng-cloak property on your map element or on your directive element.
"The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser"
http://docs.angularjs.org/api/ng.directive:ngCloak
map rendered successfully without resize.
Why resize gives you proper map ?
Because browser paints the view again.
How to fix it?
To get a proper layout of the map in any panel which is triggered lately, map has to be painted after the panel is loaded.This can be achieved by (setTimeout) code as mentioned below.
code objective is to trigger map resize event after 60 milli seconds.
setTimeout(function () {
uiGmapIsReady.promise().then(function (maps) {
google.maps.event.trigger(maps[0].map, 'resize');
lat = -37;
lon = 144;
maps[0].map.panTo(new google.maps.LatLng(lat,lon));
var marker = {
id: Date.now(),
coords: {
latitude: lat,
longitude: lon
}
};
$scope.map.markers = [];
$scope.map.markers.push(marker);
console.log($scope.map.markers);
});
}, 60);
Try to resize the map using this code in the controller:
NgMap.getMap().then(function(map){
google.maps.event.addListener(map, "idle", function(){
google.maps.event.trigger(map, 'resize');
});
});
We are now trying to build a map library like google/bing/yahoo,we will use it offline.
However I found that I have no idea about how to arange the divs in the page,since there are some many different types of divs.
1) the map tiles (small image 256X256)
2)the overlayer(marker/informationwindow/polygon...)
3)the control.
I have to try to read the html source codes of google and bing and etc. But I found it is difficult to understand them.
For exmaple,this frangment is copyed from another online map site of China.
As you can see,it is just a exmaple for how to adding a marker to the map.
But take the code,there are so many nested divs,most of them have the property of "width:0;height:0",I do not know why?
Since in my opinion,the marker is just an icon,just put it in the page.
Why use so many nested divs and even the "map" tag?
But I think they must have the advantages which I can not find.
Any one can give some suggestions?
Typically you insert a div in HTML when you want to create a block element but there is no more semantically-loaded element available with the correct meaning.
I think the answer to your question is to use just as many div elements as you need for your purposes. Do not add more just because you can. Sometimes you don't need any div elements at all - you can use other more meaningful elements such as img, ul, p, etc. You can sometimes avoid inserting a wrapping div by using CSS to change an inline element such as a into a block element.
If you need more later then add them later. Don't worry about what Google/Bing/Yahoo do. Their requirements are probably different to yours.
Have you looked at the Google Maps sample code and demo gallery?
http://code.google.com/apis/maps/documentation/javascript/demogallery.html
http://code.google.com/apis/maps/documentation/javascript/examples/index.html
I'm not sure how you would use this "offline" considering the sample you provided makes a call to the internet to get the map. Also all of these types of maps rely heavily on javascript and ajax calls to constantly update the map. Do you mean these pages would be secured and not public?
How about you just use maybe a 5x5 grid of divs, move them as they are dragged out of view, and then texture them dynamically with AJAX calls.
If I am understanding you correctly, all of the layers can be thrown on top of each other with z-index.
<div id="control" style="z-index:-1;"></div>
<div id="overlay" style="z-index:-2;"></div>
<div id="map" style="z-index:-3;"></div>
Then you can use each of these divs as containers for different parts of your map.
As you drag 1 div off to, say, the right, then it will automatically bump itself to the left side of your grid and retexture itself (background-image) through an ajax call.
That's what I would do, at least.
Use the Google Maps API you can see an example of custom tiles here: http://code.google.com/apis/maps/documentation/javascript/examples/maptype-base.html
You would need to copy all the files to your computer to be exceccible offline. Your javascript would look something like this:
function CoordMapType() {
}
CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 19;
CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
var div = ownerDocument.createElement('DIV');
div.style.backgroundImage=coord+'.js';
return div;
};
CoordMapType.prototype.name = "Tile #s";
CoordMapType.prototype.alt = "Tile Coordinate Map Type";
var map;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);
var coordinateMapType = new CoordMapType();
function initialize() {
var mapOptions = {
zoom: 10,
streetViewControl: false,
mapTypeId: 'coordinate',
mapTypeControlOptions: {}
};
map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
google.maps.event.addListener(map, 'maptypeid_changed', function() {
var showStreetViewControl = map.getMapTypeId() != 'coordinate';
map.setOptions({'streetViewControl': showStreetViewControl});
});
// Now attach the coordinate map type to the map's registry
map.mapTypes.set('coordinate', coordinateMapType);
}
I have a lot of markers on my map, so i implemented marker Clusterer !
But, Strangly..
MarkerClusterer collapses to smaller values 244 > 32 > 4 > 2
But after I click 2 -> I should be able to see both the markers, but its collapsing the last 2.
Everything was working fine untill I made the markers to load via ajax !
Default minimum cluster size for the markerCLusterer is 2. So you should set it to 1 when calling for a new MarkerClusterer;
var CLUSTER_MINIMUM_SIZE = 1;
markerCluster = MarkerClusterer(map, [], { minimumClusterSize: CLUSTER_MINIMUM_SIZE }))
You can find brief explanation for the optional constructor parameters inside the javascript file of the markerclusterer.
I was having the same issue, one marker with a label of "2" that would not collapse all the way, I double checked and the marker was NOT being added twice.
I was able to get the desired behavior by increasing the minimumClusterSize to 3. That is the only way I could find to solve the problem, hope it helps someone.