Removing/Resetting all bounds/markers from searchBar function - javascript

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

Related

Draggable pin not updating coordinates in Google Maps API

I have this code that allows users to insert pins in Google Maps, by clicking on the map. Now I'm trying to make this pin draggable, so I just added draggable:true, in the initialization of the markers. But this is not updating the field with the coordinates. It only works if the user clicks in another place. What am I missing?
// global "map" variable
var map = null;
var marker = null;
// popup window for pin, if in use
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150,50)
});
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
google.maps.event.trigger(marker, 'click');
return marker;
}
function initialize() {
// the location of the initial pin
var myLatlng = new google.maps.LatLng(-19.919131, -43.938637);
// create the map
var myOptions = {
zoom: 15,
center: myLatlng,
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// establish the initial marker/pin
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Property Location",
draggable:true,
icon: {
url: 'https://4.bp.blogspot.com/-nHydF9OdHLw/V8OxZbpJW6I/AAAAAAAAADM/G_QLEm7aScUOc3XwZmc5X8DmMHp7FK3RwCLcB/s1600/BikeSpot-Pin-Logo.png',
// base image is 60x60 px
size: new google.maps.Size(64, 96),
// we want to render # 30x30 logical px (#2x dppx or 'Retina')
scaledSize: new google.maps.Size(32, 48),
// the most top-left point of your marker in the sprite
// (based on scaledSize, not original)
origin: new google.maps.Point(0, 0),
// the "pointer"/anchor coordinates of the marker (again based on scaledSize)
anchor: new google.maps.Point(16, 48)
}
});
// establish the initial div form fields
formlat = myLatlng.lat();
formlng = myLatlng.lng();
document.getElementById("LatLng-Input").value = myLatlng.toUrlValue();
// close popup window
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// removing old markers/pins
google.maps.event.addListener(map, 'click', function(event) {
//call function to create marker
if (marker) {
marker.setMap(null);
marker = null;
}
// Information for popup window if you so chose to have one
/*
marker = createMarker(event.latLng, "name", "<b>Location</b><br>"+event.latLng);
*/
var image = 'https://4.bp.blogspot.com/-nHydF9OdHLw/V8OxZbpJW6I/AAAAAAAAADM/G_QLEm7aScUOc3XwZmc5X8DmMHp7FK3RwCLcB/s1600/BikeSpot-Pin-Logo.png';
var myLatLng = event.latLng ;
/*
var marker = new google.maps.Marker({
by removing the 'var' subsquent pin placement removes the old pin icon
*/
marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
title:"Bicicletario",
icon: {
url: 'https://4.bp.blogspot.com/-nHydF9OdHLw/V8OxZbpJW6I/AAAAAAAAADM/G_QLEm7aScUOc3XwZmc5X8DmMHp7FK3RwCLcB/s1600/BikeSpot-Pin-Logo.png',
// base image is 60x60 px
size: new google.maps.Size(64, 96),
// we want to render # 30x30 logical px (#2x dppx or 'Retina')
scaledSize: new google.maps.Size(32, 48),
// the most top-left point of your marker in the sprite
// (based on scaledSize, not original)
origin: new google.maps.Point(0, 0),
// the "pointer"/anchor coordinates of the marker (again based on scaledSize)
anchor: new google.maps.Point(16, 48)
}
});
// populate the form fields with lat & lng
formlat = event.latLng.lat();
formlng = event.latLng.lng();
document.getElementById("LatLng-Input").value = formlat +", "+formlng
});
}
});
}
The HTML with the input I'm receiving the coordinates is:
<div id='map_canvas'/>
<input id='LatLng-Input' size='20' type='text'/>
It's not updating the coordinates because you don't tell it to do so. You have to add a dragend-handler and update your element, where you display the coordinates when the drag of the marker is finished:
marker.addListener('dragend', function(event){
document.getElementById("LatLng-Input").value = event.latLng.lat() + ", " + event.latLng.lng();
});
If you would have an infowindow you would have to update the content of the infowindow:
marker.addListener('dragend', function(event){
infoWindow.setContent(event.latLng.lat() + ", " + event.latLng.lng());
});
If you want to update the coordinates also while dragging, add another handler with 'drag' instead of 'dragend'.

How to get coordinates of outside element dropped on a google map?

I have a google map and a custom element to use as a marker. When I drop the marker from outside the map on the map I need to get the coordinates of that location. How to do this?
".clue_bottom_left img" is the element used as the marker.
Code for drag and drop using jquery-ui:
$(".clue_bottom_left img").draggable({
containment: 'map',
revert: "invalid",
start: function(evt, ui) {
$('.clue_bottom_left img').fadeTo('fast', 0.6, function() {});
},
stop: function(evt, ui) {
$('.clue_bottom_left img').fadeTo('fast', 1.0, function() {});
// INSERT Point
}
});
$('#map').droppable({
drop: function(e, ui) {
$(ui.draggable).draggable();
}
});
Code for creating the map:
function initAutocomplete() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.9876644, lng: 22.4192234},
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true, // a way to quickly hide all controls
});
// Create the search box and link it to the UI element.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
var markers = [];
// Listen for the event fired when the user selects a prediction and retrieve
// more details for that place.
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
var icon = {
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.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
UPDATE:
This is not a duplicate as someone marked it with another post on how to do something when the marker is dropped on the map. I know how to do that. My marker is not actually a marker. Is a image in a div outside the map. And I wondered how to use that image as a marker using drag and drop with jQuery UI.

Google Map Not Displaying Entirely

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

adding sound to an array of markers - google map javascript

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.

Multiple Google Maps infowindow

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!

Categories

Resources