Im working on a google maps plugin (there's always room for another right?) and I'm drawing a preview of the map my users will be inserting into their content. Im able to draw everything I set out to, custom content in the info window, setting the location (through places.Autocomplete) etc. The one thing that is escaping me is custom map icon isn't being drawn.
My goal is to have the default icon drawn on first load, and then update it when it changes
Im not getting any 404 or errors in the console, and I've checked my event handlers and they are all working. Can anyone tell me where I've going astray?
Here is what I have so far:
//Initilize the map
google.maps.event.addDomListener(window, 'load', initialize);
function initialize(infowindow) {
var init_center = new google.maps.LatLng(43.703793, -72.326187);
mapOptions = {
center: init_center,
zoom: parseFloat(mapZoomReturn),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel : false,
};
var input = document.getElementById('mapAddress');
var autocomplete = new google.maps.places.Autocomplete(input);
var infowindow = new google.maps.InfoWindow();
//var marker = new google.maps.Marker({
// position: init_center,
// map: map,
// icon: mapMarkerImageReturn
//});
// Draw the map
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
// marker needs to be set after the map
var marker = new google.maps.Marker({
position: init_center,
map: map,
icon: mapMarkerImageReturn
});
// Set up event listeners
// Info window DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapInfoWindow'),
'change', function() {
mapInfoWindowReturn = escape(jQuery('#mapInfoWindow').val());
// get the extra content from feild, by this time the place_changed even will have fired at least once, so we have these values
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn); // returns formatted markup for info bubble
infowindow.setContent(infowindowPlace);
});
// Marker dropdown selection DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarker'), 'change', update_maker);
// Custom marker text field DOM->MAP
google.maps.event.addDomListener(document.getElementById('mapMarkerImage'), 'change', update_maker );
function update_maker(){
//update the marker imge - (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
}
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.close();
if (mapMarkerImageReturn !=='' || mapMarkerImageReturn !== false) marker.setVisible(false);
input.className = '';
locPlace = autocomplete.getPlace();
if (!locPlace.geometry) {
// Inform the user that the place was not found and return.
input.className = 'notfound';
return;
}
// If the place has a geometry, then present it on a map.
if (locPlace.geometry.viewport) {
map.fitBounds(locPlace.geometry.viewport);
mapCurrCenter = map.getCenter();
} else {
map.setCenter(locPlace.geometry.location);
map.setZoom(parseFloat(mapZoomReturn));
mapCurrCenter = map.getCenter();
}
// Set the marker image (not working)
markerImage = get_marker_image(); // returns URL as string
marker.setIcon(markerImage);
marker.setPosition(locPlace.geometry.location);
marker.setMap(map);
// get the location values for the info bubble
if (locPlace.address_components) {
//console.log(locPlace.address_components);
// Populate values for info bubble
locName = locPlace.name;
locIcon = locPlace.icon;
locAddress = locPlace.formatted_address;
locPhone = locPlace.formatted_phone_number;
locWeb = locPlace.website;
}
infowindowPlace = get_info_bubble(locIcon, locName, locAddress, locPhone, locWeb, mapInfoWindowReturn);
infowindow.setContent(infowindowPlace);
infowindow.open(map, marker);
});
}
Related
I am trying to use Google Maps API service to allow my site visitors to type in their address in a box. Once he/she selects a matching address, I want to obtain the latitude and longitude info about the provided address.
Using the code in the API documentation, I got a map and a text box on my site. However, once Google finds a matching address I need to get the latitude and longitude info for the selected address only.
Here is the function that initialize the map
function initMap() {
var mapElement = document.getElementById('map');
var map = new google.maps.Map(mapElement, {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 6
});
// 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);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map
});
// 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();
console.log(places);
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) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
/*
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
}));
//coords.latitude
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
console.log(latitude, longitude);
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
The following lines of code gave me the info that I am looking for. However, it seems that it display's it more that once (possibly it is displaying the info for multiple addresses). How can I get the latitude and longitude info only one address?
var latitude = place.geometry.location.lat();
var longitude = place.geometry.location.lng();
I tried adding a click listener where I Can grab the info one the lick event like this
map.addListener("click", function (event) {
var lat = event.latLng.lat();
var lng = event.latLng.lng();
console.log(lat, lng);
});
However, this gives me the latitude and longitude of the place where I click on the map, not the address that I selected from the text box after the autocomplete suggested the matching addresses
I'm sure there is an easier way but I use maps.google.com and right-click wherever I want to find the coordinates for and choose what's here?, then the longitude and latitude will appear at the bottom of the map.
Using the Google's API you can just send an AJAX request, you don't need a map on your page to get coordinates. Check this out!
https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY
var responseAsObject;
$("#div").load( "url", function( response, status, xhr ) {
responseAsObject = $.parseJSON(response);
});
var long = responseAsObject.results.geometry.location.lng;
var lat = responseAsObject.results.geometry.location.lat;
I'm occasionally seeing a javascript error (Uncaught TypeError: Cannot call method 'panTo' of undefined) when loading my website. My website, for reference, is www.nolofo.com. What is supposed to happen when you load that page is to determine your location and move the map to that location. Sometimes this works just fine, other times it does not. I can't seem to figure out the pattern other than when it doesn't work I see this error message in the javascript log. Perhaps something is not being loaded in the correct order?
<script type="text/javascript">
// Check to see if this browser supports geolocation.
if (navigator.geolocation) {
// This is the location marker that we will be using on the map. Let's store a reference to it here so that it can be updated in several places.
var locationMarker = null;
var myLat = null;
var myLng = null;
// Get the location of the user's browser using the native geolocation service.
navigator.geolocation.getCurrentPosition(
function (position) {
// Check to see if there is already a location. There is a bug in FireFox where this gets invoked more than once with a cached result.
if (locationMarker){
return;
}
// Log that this is the initial position.
console.log( "Initial Position Found" );
// Assign coordinates to global variables
myLat = position.coords.latitude;
myLng = position.coords.longitude;
moveToLocation(myLat, myLng);
}
);
}
// Start the Google Maps implementation
var map;
var markersArray = [];
function initialize() {
var mapOptions = {
zoom: 13,
center: new google.maps.LatLng(40.760779, -111.891047),
mapTypeId: google.maps.MapTypeId.TERRAIN,
scaleControl: true
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Add all recent listing markers to map
<?php
foreach ($coordinateArray as $Key => $Value) {
$listingQuery = mysql_query("
SELECT
Listings.Lat,
Listings.Lng,
Listings.Title,
Listings.Type
FROM
Listings
WHERE
Listings.ID='$Key'
");
if (!$listingQuery) {
die('<p>Error executing query (2) with database!<br />'.
'Error: ' . mysql_error() . '</p>');
}
$listingArray = mysql_fetch_array($listingQuery);
$ListingLat = $listingArray["Lat"];
$ListingLng = $listingArray["Lng"];
$ListingTitle = addslashes($listingArray["Title"]);
$ListingType = $listingArray["Type"];
$ListingLatLng = $ListingLat . ", " . $ListingLng;
?>
// Marker
var myLatLng = new google.maps.LatLng(<?=$ListingLatLng?>);
var marker<?=$Key?> = new google.maps.Marker({
position: myLatLng,
map: map,
title: ""
});
iconFile = 'http://maps.google.com/mapfiles/ms/icons/<?=$Value?>-dot.png';
marker<?=$Key?>.setIcon(iconFile);
// Info Window
var infowindow<?=$Key?> = new google.maps.InfoWindow({
content: '<b><?=$ListingType?></b><br /><?=$ListingTitle?>'
});
google.maps.event.addListener(marker<?=$Key?>, 'click', function() {
infowindow<?=$Key?>.open(map, marker<?=$Key?>);
});
<?php } ?>
// Add a click event handler to the map object
google.maps.event.addListener(map, "click", function(event) {
// Place a marker
placeMarker(event.latLng, event.latLng.lat(), event.latLng.lng());
// Display the lat/lng in your form's lat/lng fields
//document.getElementById("lat").value = event.latLng.lat();
//document.getElementById("lng").value = event.latLng.lng();
});
// Add a click event handler to the marker object
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent("Your content here");
infowindow.open(map, this);
});
}
function placeMarker(location, lat, lng) {
// Remove all markers if there are any
deleteOverlays();
var marker = new google.maps.Marker({
position: location,
map: map
});
// Add marker in markers array
markersArray.push(marker);
var contentString = 'New Listing';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
infowindow.open(map,marker);
google.maps.event.addListener(infowindow, "closeclick", function() {
deleteOverlays(); // removes the marker
});
//map.setCenter(location);
}
// Deletes all markers in the array by removing references to them
function deleteOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
}
function moveToLocation(lat, lng) {
var center = new google.maps.LatLng(lat, lng);
map.panTo(center);
}
// The function to trigger the marker click, 'id' is the reference index to the 'markers' array.
function linkClick(id){
google.maps.event.trigger(markersArray[id], 'click');
}
google.maps.event.addDomListener(window, 'load', initialize);
Most likely it's because you're trying to pan the map before the map has been loaded. You run that initial geolocation script as soon as the page is loaded. Sounds like sometimes getCurrentPosition() is faster than the map load, sometimes it's not.
What you can do is run your geolocation stuff after map has been loaded. The very last line in your script is an event listener for when the map has been loaded - you can use it for other bits too.
Wrap the whole first part in a function:
function setupGeoLocator() {
// Check to see if this browser supports geolocation.
if (navigator.geolocation) {
// This is the location marker that we will be using on the map. Let's store a reference to it here so that it can be updated in several places.
var locationMarker = null;
var myLat = null;
var myLng = null;
// Get the location of the user's browser using the native geolocation service.
navigator.geolocation.getCurrentPosition(
function (position) {
// Check to see if there is already a location. There is a bug in FireFox where this gets invoked more than once with a cached result.
if (locationMarker){
return;
}
// Log that this is the initial position.
console.log( "Initial Position Found" );
// Assign coordinates to global variables
myLat = position.coords.latitude;
myLng = position.coords.longitude;
moveToLocation(myLat, myLng);
}
);
}
}
And then call it when the 'load' event fires on the map.
google.maps.event.addDomListener(window, 'load', initialize);
google.maps.event.addDomListener(window, 'load', setupGeoLocator);
I'm wondering if it's possible to open one of the infoWindow objects that are attached to each marker in the code below on page load and not just by clicking on them? As it is now, the user has to click on one of the markers to open an info window.
I tested to create a "stand alone" info window object and that opened fine onload, but it didn't close when I clicked on some of the other markers, because the onClick function was attached to the markers that only could close the info windows attached to that object. Correct med if I'm wrong?
Would this be possible and can I "call" an object by the number or what options do I have? Tips are preciated!
Or if there is possible, that I have tried to open an separate info window onload and be able to close that if I open one of the other info windows!?
var map = null;
var infowindow = new google.maps.InfoWindow();
var iconBase = 'images/mapNumbers/number';
//var zoomLevel = 11;
//var mapPositionLat = 55.678939;
//var mapPositionLng = 12.568359;
function initialize() {
var markerPos = new google.maps.LatLng(55.674196574861895, 12.583808898925781);
var myOptions = {
zoom: 11,
//center: new google.maps.LatLng(55.678939, 12.568359),
center: markerPos,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function () {
infowindow.close();
});
google.maps.event.addListener(map, 'zoom_changed', function () {
infowindow.close();
});
google.maps.event.addDomListener(window, 'resize', function() {
map.setCenter(markerPos);
map.setZoom(zoomLevel);
//var center = map.getCenter();
});
// Add markers to the map
var point;
point = new google.maps.LatLng(55.667093,12.581255); createMarker(point, "<div class='infoWindow'>1</div>");
point = new google.maps.LatLng(55.660794,12.58972); createMarker(point, "<div class='infoWindow'>2</div>");
point = new google.maps.LatLng(55.660491,12.587087); createMarker(point, "<div class='infoWindow'>3</div>");
}
// Create markers
function createMarker(latlng, html, name, number) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
icon: iconBase + number + '.png'
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(html);
infowindow.open(map, marker);
//map.setCenter(marker.getPosition());
map.setCenter(55.678939, 12.568359);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
In order to display InfoWindow when the map loads, make the call to
infowindow.open(map, marker);
outside of the marker listener.
Below is demonstrated createMarker function, where parameter displayInfoWindow defines whether to display InfoWindow when the map loads:
// Create marker
function createMarker(map,markerPos, markerTitle,infoWindowContent,displayInfoWindow) {
var marker = new google.maps.Marker({
position: markerPos,
map: map,
title: markerTitle,
});
var infowindow = new google.maps.InfoWindow({
content: infoWindowContent
});
if(displayInfoWindow) {
infowindow.open(map, marker);
}
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
Example: http://jsbin.com/lusuquwu/1/
It is possible. One possible solution is to save markers to an array and then trigger click event on of one of them using google.maps.event.trigger(). For example:
...
var zoomLevel = 11; // uncommented due to error message
var markers = [];
function initialize() {
...
point = new google.maps.LatLng(55.660491,12.587087); createMarker(point, "<div class='infoWindow'>3</div>");
google.maps.event.trigger(markers[1], 'click');
}
function createMarker(latlng, html, name, number) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
//icon: iconBase + number + '.png'
icon: iconBase
});
// added to collect markers
markers.push(marker);
google.maps.event.addListener(marker, 'click', function () {
console.log('click event listener');
infowindow.setContent(html);
infowindow.open(map, marker);
//map.setCenter(marker.getPosition());
// corrected due to error
map.setCenter(new google.maps.LatLng(55.678939, 12.568359));
});
}
I combined info from this and another site to come up with the below solution as most solutions are for multi-marker maps.
Just a few lines is all you actually need.
// Start with your map
var map = new google.maps.Map(...);
// Now define the info window using HTML. You can insert images etc.
var info = new google.maps.InfoWindow({content: 'YOUR HTML HERE'});
// Now define the marker position on the map
var marker = new google.maps.Marker({map: map, position:{lat: 'YOUR LATITUDE',lng: 'YOUR LONGITUDE'}});
Now we have the variables, just hide the marker, show the info window and set the map zoom and center.
// Set the map zoom
map.setZoom('YOUR ZOOM LEVEL [1 - 20]');
// Set the map center
map.setCenter({lat: 'YOUR LATITUDE',lng: 'YOUR LONGITUDE'});
// Hide the marker that we created
marker.setVisible(false);
// Open the info window with the HTML on the marker position
info.open(map, marker);
For the content, you can create layers and insert images and text as you need. Just make sure you include the full URL to images in your html.
I also recommend adding this to your CSS to hide the close button, which effectively makes this a permanent, info window.
.gm-style-iw + div {display: none;}
I have implemented a google map with multiple markers but what i am failing to do is how to add a unique label for each marker i.e. Each marker needs have a letter:e.g.
Marker 1 needs to display 'A'
Marker 2 needs to display 'B'
Marker 3 needs to display 'C'
Marker 4 needs to display 'D'
...
an example of what i am trying to achieve is: http://www.athenos.com/locator/ --- enter 11205 in the zip search
here is a portion of my map code - my init and add_marker methods:
init : function() {
var self = this;
// set map property
var map = new google.maps.Map(self.dom_element, self.options);
self.map = map;
// set some other shit
new google.maps.Size(95, 77),
new google.maps.Point(0,0),
new google.maps.Point(47, 76);
// creating new bounds
var bounds = new google.maps.LatLngBounds();
// for loop to iterate through locations
for (var i = 0; i < self.locations.length; i++) {
// extend the bounds
bounds.extend(self.locations[i].latlng);
// add the marker
self.add_marker(self.locations[i].latlng, i);
}
// centers the map based on the existing map markers
self.map.fitBounds(bounds);
},
add_marker : function(latlng, marker_index) {
var self = this;
var marker = new google.maps.Marker({
position: latlng,
map: self.map,
icon: self.map_icon,
zIndex: 998,
id: marker_index // give the marker an ID e.g. 0, 1, 2, 3 - use this for indexing the listed venues
});
google.maps.event.addListener(marker, 'mouseover', function(event) {
var this_marker = this;
// executes handler and passes the marker as 'this' and event data as an argument
self.handle_marker_mouseover.call(self, this, event);
this_marker.setZIndex(999);
});
google.maps.event.addListener(marker, 'mouseout', function(event) {
// executes handler and passes the marker as 'this' and event data as an argument
self.handle_marker_mouseout.call(self, this, event);
});
google.maps.event.addListener(marker, 'click', function(event) {
// executes handler and passes the marker as 'this' and event data as an argument
self.handle_marker_click.call(self, this, event);
});
},
...
Please help.
Thanks in advance
just try to locate your icon, in marker's prop, at this url:
http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=7|00FF00|000000
So iterate with letters over the first part of the chld querystring parameter, and don't forget to choose your marker's color (latest two part, pipe separated)
Take a look at the article below. It's very simple. Use a marker with numeric labels or a marker with alphabet label (A,B..)
Multiple marker with labels in google map
for (i = 1; i <= markers.length; i++) {
var letter = String.fromCharCode("A".charCodeAt(0) + i - 1);
var data = markers[i - 1]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
icon: "http://maps.google.com/mapfiles/marker" + letter + ".png"
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
Go to this article for more details
Multiple marker with labels in google map
I have GoogleMaps integrated into my site. I'm having a problem pulling my info from my JSON file into the Info Window when the markers are clicked.
Below is my current code:
/*********** Custom GoogleMaps functions ***********/
if (document.getElementById("events-map")) {
// set json path
var markerFile = '/scripts/json/find-events.json';
// set default map properties
var defaultLatlng = new google.maps.LatLng(41.4925, -99.9018);
// zoom level of the map
var defaultZoom = 4;
// variable for map
var map;
// variable for marker info window
var infowindow;
// List with all marker to check if exist
var markerList = {};
// option for google map object
var myOptions = {
zoom: defaultZoom,
center: defaultLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
/**
* Load Map
*/
function loadMap() {
// create new map make sure a DIV with id myMap exist on page
map = new google.maps.Map(document.getElementById("events-map"), myOptions);
// create new info window for marker detail pop-up
infowindow = new google.maps.InfoWindow();
// load markers
loadMarkers();
}
/**
* Load markers via ajax request from server
*/
function loadMarkers() {
// load marker jSon data
$.getJSON(markerFile, function(data) {
// loop all the markers
$.each(data, function(i, item) {
// add marker to map
loadMarker(item);
});
});
}
/**
* Load marker to map
*/
function loadMarker(makerData) {
// create new marker location
var myLatlng = new google.maps.LatLng(markerData['xCoordinate'], markerData['yCoordinate']);
// create new marker
var marker = new google.maps.Marker({
id: markerData['id'],
map: map,
title: markerData['propertyName'] ,
position: myLatlng
});
// add marker to list used later to get content and additional marker information
markerList[marker.id] = marker;
// add event listener when marker is clicked
// currently the marker data contain a dataurl field this can of course be done different
google.maps.event.addListener(marker, 'click', function() {
// show marker when clicked
showMarker(marker.id);
});
// add event when marker window is closed to reset map location
google.maps.event.addListener(infowindow, 'closeclick', function() {
map.setCenter(defaultLatlng);
map.setZoom(defaultZoom);
});
}
/**
* Show marker info window
*/
function showMarker(markerId) {
// get marker information from marker list
var marker = markerList[markerId];
// check if marker was found
if (marker) {
// get marker detail information from server
$.getJSON(markerFile, function(data) {
// show marker window
infowindow.setContent(data);
infowindow.open(map, marker);
});
} else {
alert('Error marker not found: ' + markerId);
}
}
google.maps.event.addDomListener(window, 'load', loadMap);
}
And here is the info that is contained in my JSON file:
{
"markers":[
{
"id":"1",
"xCoordinate" : 34.048928,
"yCoordinate" : -111.093731,
"propertyName" : "Arizona",
"propertyState" : "AZ",
"propertyPhone" : "777.777.7777",
"propertyEmail" : "test#example.com"
},
{
"id":"2",
"xCoordinate" : 38.582526,
"yCoordinate" : -92.510376,
"propertyName" : "Missouri",
"propertyState" : "MO",
"propertyPhone" : "777.777.7777",
"propertyEmail" : "test#example.com"
}
]
}
In
var marker = ...
$.getJSON(markerFile, function(data) {...marker...}
the function(data) is the callback that is called asynchronously when the result of the respective AJAX call is returned. At that moment the local variable marker is no longer in scope. You should apply a closure over the marker:
$.getJSON(markerFile, function(mapMarker) {
var m = mapMarker; // save the current marker in the closure
return function(data) { // return the required callback ...
// show marker window
infowindow.setContent(data);
infowindow.open(map, m);
} (marker) // ... applied to marker
});
There is a typo in your loadMarker function:
makerData should be markerData