I am new here so I know I don't have any credibility. I am an artist and new to programming so I understand if no one will take this on. I am posting this on the off chance that this is an easy question. -S
This is the code (mostly from the google developer site) to create multiple markers. It works fine and creates a custom icon for each marker.
Each marker should play a different audio file when clicked (right now only the last marker created does). I would also like to change the icon when the audio file is playing. I am using javascript and sound manager 2 to play the audio - but what i am interested in is:
how do i reference each marker in the array so that i can play the specific audio file assigned to that specific marker?
I am hoping i csn do this without XML and a database.
-Sabine
Here is the relevant code:
setMarkers(map, beaches);
}
var beaches = [
['Devotion', 40.710431,-73.948432, 0],
['Tester', 40.711223,-73.958416, 1],
];
function setMarkers(map, locations) {
var image = new google.maps.MarkerImage('biker.png',
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(32, 32),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point(0, 32)
);
var newimage = new google.maps.MarkerImage('biker_click.png',
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(32, 32),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point(0, 32)
);
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3],
});
}
function markerClick() {
console.log('click');
}
google.maps.event.addListener(marker, 'click', markerClick);
function markerClick() {
var playing = sm2.toggle('http://mm1.ellieirons.com/wp-content/uploads/2012/03/beeps_bubbles.mp3', true);
if (playing) {
this.setIcon(newimage);
} else {
this.setIcon(image);
}
}
Suppose you have an array of URLs:
var sounds = ["http://mm1.ellieirons.com/wp-content/uploads/2012/03/beeps_bubbles.mp3",
"http://mm1.ellieirons.com/wp-content/uploads/2012/03/beeps_bubbles2.mp3"];
Then you could try something like this:
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3]
});
marker.sound = sounds[i]; //Storing associated sound in marker
google.maps.event.addListener(marker, 'click', markerClick);
}
And modify the handler to this:
function markerClick() {
var playing = sm2.toggle(this.sound, true);
if (playing) {
this.setIcon(newimage);
} else {
this.setIcon(image);
}
}
Something like this..
var beaches = [
['Devotion', 40.710431,-73.948432, 0, 'sound1.mp3'],
['Tester', 40.711223,-73.958416, 1, 'sound2.mp3'],
];
// ...
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
shape: shape,
title: beach[0],
zIndex: beach[3],
});
google.maps.event.addListener(marker, 'click', function() {
playSound(beach[4]);
});
}
Because you define an anonymous function inside your loop, it has access to the loop's variables (it is a "closure"). You add the name of your sound to the data associated with the beaches, then pass it from the closure to the function (I call it playSound) which actually causes it to play.
Hope this helps, it's not a complete recipe.
Related
I want to add, for each of my markers, an event on click to center on this one. I use the lib "MarkerWithLabel" and when I click on a marker, the map is zooming on the last marker each time.
Here is my code :
var map = new google.maps.Map(document.getElementById('map-canvas')),
bounds = new google.maps.LatLngBounds(),
marker = [],
grafxUrl = $('#map-canvas').data('grafx'),
image = {
url : grafxUrl + 'universal/icons/pin_locator.png',
size: new google.maps.Size(24, 31),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(12, 31)
};
for (var i = 0; i < response.length; i++) {
marker = new MarkerWithLabel({
position: new google.maps.LatLng(response[i].fLatitude, response[i].fLongitude),
map: map,
icon : image ,
title : (i+1)+' '+response[i].sName,
labelContent: (i+1),
labelAnchor: new google.maps.Point(3, 25),
labelClass: "markerNum", // the CSS class for the label
});
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(15);
map.setCenter(marker.position);
});
bounds.extend(marker.position);
//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);
}
What is wrong with my script ?
Thanks a lot.
Here is a complete example on how to extend a bounds object to display all markers on the map.
function initialize() {
var southWest = new google.maps.LatLng(40.744656, -74.005966);
var northEast = new google.maps.LatLng(34.052234, -118.243685);
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
var map = new google.maps.Map(document.getElementById("map-canvas"), {
zoom: 12,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Create the bounds object
var bounds = new google.maps.LatLngBounds();
// Create random markers
for (var i = 0; i < 100; i++) {
// Calculate a random position
var position = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(), southWest.lng() + lngSpan * Math.random());
var marker = new google.maps.Marker({
position: position,
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
map.setZoom(5);
map.setCenter(marker.position);
}
})(marker, i));
// Extend the bounds with the last marker position
bounds.extend(position);
}
// Fit map to the extended bounds
map.fitBounds(bounds);
}
initialize();
This creates 100 random markers within the defined bounds (southWest / northEast coords) then extends a bounds object and finally fit the map to this bounds object. See how the marker variable is defined (within the for loop) and how the fitBounds() is called (outside the for loop). The same should apply to your code.
Below is a working demo. Hope this helps!
JSFiddle demo
I have two maps using the Google Maps API and, to set the scene, they are both contained in a FuelUX Wizard, on separate panes.
The map on the first pane works perfectly, however on the second map on the other pane, it displays like this:
This is obviously wrong. However, If I resize the window it pops in to the proper display.
Here is the main Javascript that initializes the maps.
function initialize() {
var markers = [];
var map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 5, center: new google.maps.LatLng(30.2500, -97.7500),
mapTypeId: google.maps.MapTypeId.HYBRID
});
var map2 = new google.maps.Map(document.getElementById('map-canvas-2'), {
zoom: 5, center: new google.maps.LatLng(30.2500, -97.7500),
mapTypeId: google.maps.MapTypeId.HYBRID
});
// Create the search box and link it to the UI element.
var input = /** #type {HTMLInputElement} */(
document.getElementById('pac-input'));
var input2 = /** #type {HTMLInputElement} */(
document.getElementById('pac-input-2'));
var searchBox = new google.maps.places.SearchBox(
/** #type {HTMLInputElement} */(input));
var searchBox2 = new google.maps.places.SearchBox(
/** #type {HTMLInputElement} */(input2));
// Listen for the event fired when the user selects an item from the
// pick list. Retrieve the matching places for that item.
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
// For each place, get the icon, place name, and location.
markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
var marker = new google.maps.Marker({
map: map,
icon: image,
title: place.name,
position: place.geometry.location
});
markers.push(marker);
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
//Map 2
google.maps.event.addListener(searchBox2, 'places_changed', function() {
var places = searchBox2.getPlaces();
if (places.length == 0) {
return;
}
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
// For each place, get the icon, place name, and location.
markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
var marker = new google.maps.Marker({
map2: map2,
icon: image,
title: place.name,
position: place.geometry.location
});
markers.push(marker);
bounds.extend(place.geometry.location);
}
map2.fitBounds(bounds);
});
// Bias the SearchBox results towards places that are within the bounds of the
// current map's viewport.
google.maps.event.addListener(map, 'bounds_changed', function() {
var bounds = map.getBounds();
searchBox.setBounds(bounds);
});
google.maps.event.addListener(map2, 'bounds_changed', function() {
var bounds = map2.getBounds();
searchBox2.setBounds(bounds);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
You need to trigger a map resize when the tab is shown. You have an available event in FuelUX: changed.fu.wizard that fires when the step changes and displays to the user.
$('#myWizard').on('changed.fu.wizard', function () {
// Trigger a map resize
google.maps.event.trigger(map, 'resize');
});
JSFiddle demo
Edit:
To trigger it on tab change, use the shown.bs.tab:
$('a[data-toggle="tab"]').on('shown.bs.tab', function () {
// Trigger a map resize
google.maps.event.trigger(map, 'resize');
});
JSFiddle demo
I'm using a searchBar function that I found on the GoogleMaps documentation which works like a charm for it's purpose, however the reason I'm using it is because I want users to be able to capture that GoogleMap as an image (Which I know how to do using HTML2Canvas)
The issue I'm having is that when I use the SearchBar function for some reason it seems to make the bounds "stick" to the bounds that were applied when the SearchBar is used, so when I try and render the canvas of the Google Map is viewport of the render stays the same as when the SearchBox was used, but the actual rendered image is in the location relative to the SearchBox viewport (You can see what I mean in the images below).
Image after SearchBar use:
Image when rendered near SearchBar viewport (this image was rendered when I was NW of the marker for the PostCode, the bottom-right corner of the area with an image in was the bottom-right of the visible area when starting the render):
As you can see above, the actual viewport of the image is the same in each. This leads me to believe that there is some form of issue with the bounds set in the SearchBox code shown below:
JavaScript:
var map;
var markers = [];
function initialize() {
var mapOptions = {
center: { lat: 54.559322, lng: -4.174804},
zoom: 6,
mapTypeId: google.maps.MapTypeId.HYBRID,
panControl: true,
mapTypeControl: false,
scaleControl: true
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var input = (document.getElementById('pac-input'));
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
var searchBox = new google.maps.places.SearchBox(input);
google.maps.event.addListener(searchBox, 'places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
for (var i = 0, marker; marker = markers[i]; i++) {
marker.setMap(null);
}
markers = [];
var bounds = new google.maps.LatLngBounds();
for (var i = 0, place; place = places[i]; i++) {
var image = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
var marker = new google.maps.Marker({
map: map,
icon: image,
title: place.name,
position: place.geometry.location
});
markers.push(marker);
bounds.extend(place.geometry.location);
}
map.fitBounds(bounds);
});
}
What I think needs to be done is to remove/reset the bound information set in the SearchBox function when I run the render, but any information you can provide will be greatly appreciated!
Regards,
Chris
I'm developing a site for some holiday accommodation (it's my first site development).
I've been working on the location page with google maps api V3 and want to take it further. At the moment I have just two custom markers - but want to extend this so I have around 20, to show various things to do in the area. These will be divided into categories such as 'family' and 'shopping', each category having a different marker icon. So I will need say 5 different icon styles, each style at around 4 different locations. On top of this I will need an info box on each, which will popup when the marker is clicked, and will disappear when another marker is clicked.
I'm brand new to javascript and it still looks very complicated to me, so if anyone can explain how to do this it would be greatly appreciated. Current code below, and how it currently looks is here: http://www.upthorpelodges.co.uk/test/location.html
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.316, 0.901),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
setMarkers(map, lodge);
}
var lodge = [
['Lodges', 52.316, 0.901],
['Other', 52, 1],
];
function setMarkers(map, locations) {
var image = {
url: 'http://s20.postimg.org/kq92v5uqh/homepin.png',
size: new google.maps.Size(32, 45),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(16, 45)
};
var shadow = {
url: 'http://s20.postimg.org/65s00bzrt/homepin_shadow.png',
size: new google.maps.Size(36, 23),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(4, 23)
};
var shape = {
coord: [16, 0, 0, 16, 16, 45, 32 , 16],
type: 'poly'
};
for (var i = 0; i < locations.length; i++) {
var lodge = locations[i];
var myLatLng = new google.maps.LatLng(lodge[1], lodge[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: shadow,
icon: image,
shape: shape,
title: lodge[0],
zIndex: lodge[3]
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You could create a json object of json objects where you keep your custom images. Something like this
customImgObj = {
'family' : {'image' : YOUR_IMAGE_GOES_HERE, 'shadow' : YOUR_SHADOW_GOES_HERE},
'couples' : {'image' : YOUR_IMAGE_GOES_HERE, 'shadow' : YOUR_SHADOW_GOES_HERE},
'other' : {'image' : YOUR_IMAGE_GOES_HERE, 'shadow' : YOUR_SHADOW_GOES_HERE}
};
Then you have your locations array where you keep one extra element, which is the type of marker.
var locations = [
['Lodges', 52.316, 0.901, 'family'],
['Other', 52, 1, 'couples']
];
And you access it like this
for (var i = 0; i < locations.length; i++) {
var lodge = locations[i];
var myLatLng = new google.maps.LatLng(lodge[1], lodge[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
shadow: customImgObj[lodge[3]].shadow,
icon: customImgObj[lodge[3]].image,
shape: shape,
title: lodge[0],
zIndex: lodge[3] //<--- where do you keep this? In your locations array there are only three element (0, 1, 2)
});
}
I played around with creating a list of images object, and added an extra element to each array that names the type of image to load from that list object, I also added the lines of code to add an info box
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-37.7836, 144.580),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
setMarkers(map, lodge);
}
var lodge = [
['First marker', -37.7836, 144.580, 4, 'two'],
['Second marker', -37.8136, 144.590, 5, 'one'],
['Third marker', -37.9456, 144.600, 3, 'three'],
['Fourth marker', -37.9234, 144.580, 2, 'four'],
['Fifth marker', -37.8136, 144.610, 1, 'five']
];
function setMarkers(map, locations) {
var imageList = {};
imageList['one'] = {
url: 'images/number_0.png',
size: new google.maps.Size(32, 37),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
imageList['two'] = {
url: 'images/number_1.png',
size: new google.maps.Size(32, 37),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
imageList['three'] = {
url: 'images/number_2.png',
size: new google.maps.Size(32, 37),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
imageList['four'] = {
url: 'images/number_3.png',
size: new google.maps.Size(32, 37),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
imageList['five'] = {
url: 'images/number_4.png',
size: new google.maps.Size(32, 37),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(0, 32)
};
var shape = {
coord: [16, 0, 0, 16, 16, 45, 32 , 16],
type: 'poly'
};
var contentString = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">Start </h1>'+
'<div id="bodyContent">'+
'<p><b>Editable on hover</b></p>'+
'(last visited June 22, 2009).</p>'+
'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
for (var i = 0; i < locations.length; i++) {
var lodge = locations[i];
var myLatLng = new google.maps.LatLng(lodge[1], lodge[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: imageList[lodge[4]],
shape: shape,
title: lodge[0],
zIndex: lodge[3]
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, this);
});
}
}
</script>
Current I have a google maps that will display some markers on the map from my DB... I would like to add a infowindow when the users click on the marker.
I got it to work, but the problem is that it only display on the last marker that was loaded, why is that?
Here is the code to generate the marker and the infowindow.
<script type="text/javascript">
function initialize() {
var myOptions = {
zoom: 3,
center: new google.maps.LatLng(41.850033, -87.6500523),
disableDefaultUI: true,
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
setMarkers(map, offices);
}
/**
* Data for the markers consisting of a name, a LatLng and a zIndex for
* the order in which these markers should display on top of each
* other.
*/
var offices = [<cfoutput>#officeList#</cfoutput>];
function setMarkers(map, locations) {
// Add markers to the map
// Marker sizes are expressed as a Size of X,Y
// where the origin of the image (0,0) is located
// in the top left of the image.
// Origins, anchor positions and coordinates of the marker
// increase in the X direction to the right and in
// the Y direction down.
var image = new google.maps.MarkerImage('images/pin.png',
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(14, 26),
// The origin for this image is 0,0.
new google.maps.Point(0, 0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point(0, 32));
for (var i = 0; i < locations.length; i++) {
var office = locations[i];
var myLatLng = new google.maps.LatLng(office[1], office[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: office[0],
zIndex: office[3]
});
var contentString = "Hello!!!";
var infowindow = new google.maps.InfoWindow({
content: contentString
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
}
}
</script>
I've also stumbled across this problem.
Here's how I fixed it:
I used a function to bind a marker to an infowindow.
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title: office[0],
zIndex: office[3]
});
var contentString = "Hello!!!";
var infowindow = new google.maps.InfoWindow;
bindInfoW(marker, contentString, infowindow);
}
function bindInfoW(marker, contentString, infowindow)
{
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map, marker);
});
}
http://www.codefx.biz/2011/01/google-maps-api-v3-multiple-infowindows
this way also works!