I have created a nice Google map form that gets clients data from the database ( with a jQuery post call to php) and loads it into the clients_details. if clients_details[]['location'] which is Latlng is provided in the database all works well and marker gets displayed as expected. Problem is that when clients_details[]['location'] is not provided then I use the address from clients_details[]['address'] and try to get position of the marker by using geocoder.geocode. However surprisingly every time the code gets to the geocoder it jumps from it and comes back to it after it initialized the map ! so markers wont get added to the map !
I am assuming it has something to do with JavaScript function priorities but not sure how
<script>
var clients_details // getting this from database;
var infowindow =[];
var geocoder;
var map;
function showMarkers(clients_details)
{
var marker = [];
for (var i = 0; i < clients_details.length; i++)
{
content = 'Test Content' ;
infowindow[i] = new google.maps.InfoWindow({
content: content,
maxWidth: 350
});
var client_location;
if (clients_details[i]['location'] !== null)
{
// Geting Lat and Lng from the database string
LatLng = clients_details[i]['location'];
client_location = new google.maps.LatLng (LatLng);
}
else
{
client_address = clients_details[i]['address'];
geocoder.geocode(
{ 'address': client_address},
function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
client_location = results[0].geometry.location;
}
else
alert('Geocode was not successful for the following\n\
reason: ' + clients_details[i]['name']+'\n' + status);
});
}
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
// Add 'click' event listener to the marker
addListenerMarkerList(infowindow[i], map, marker[i]);
}// for
}// function
The
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
Code should be inside the callback in the geocoder.geocode call.
Because in your code the client_location is computed after the marker[i].
What you could do is:
compute the client_location and when the client_locolation is computed
then compute the marker[i]
So your code could be like this:
// ... your code as is
geocoder.geocode(
{ 'address': client_address},
function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
client_location = results[0].geometry.location;
// closure needed, for the marker[i] to work correctly,
// because we are in a loop on i
(function (i) {
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
})(i);
}
else
{
alert('Geocode was not successful for the following\n\
reason: ' + clients_details[i]['name']+'\n' + status);
}
}
);
// .... your code as is
You need to bind your call back function to the right event. Bind the initialize of the map to window load. Inside that function then call the rest of the marker/geocoder logic. As extracted from their documentation:
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(-25.363882, 131.044922)
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title: 'Click to zoom'
});
google.maps.event.addListener(map, 'center_changed', function() {
// 3 seconds after the center of the map has changed, pan back to the
// marker.
window.setTimeout(function() {
map.panTo(marker.getPosition());
}, 3000);
});
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
map.setCenter(marker.getPosition());
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Related
I have a nearby search map, in every open of this map page, it returns the current position, now When I get the current position by coordinates, I want to reverse geocode it into an address name, the problem is I modified my code from this source: https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/geocoding-reverse
with
<script>
function getPosition() {
navigator.geolocation.getCurrentPosition(position => {
currentLatLon = [position.coords.latitude, position.coords.longitude];
infowindow = new google.maps.InfoWindow();
map = new google.maps.Map(
document.getElementById('map'), {
center: new google.maps.LatLng(...currentLatLon),
zoom: 20
});
var geocoder = new google.maps.Geocoder();
service = new google.maps.places.PlacesService(map);
document.getElementById("curr").innerHTML=currentLatLon;
document.getElementById("address").value=currentLatLon;
geocodeLatLng(geocoder,map,infowindow);
});
}
function geocodeLatLng(geocoder, map, infowindow) {
var input = document.getElementById('curr').value;
var latlngStr = input.split(',');
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[0]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map
});
infowindow.setContent(results[0].formatted_address);
infowindow.open(map, marker);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
</script>
this should return the place name in the map which is like the source code I copied from above
https://developers-dot-devsite-v2-prod.appspot.com/maps/documentation/javascript/examples/geocoding-reverse, what could be wrong in my modification? I have an error in the console when I run my modified code, error in the console
Here's my full code without the api key: https://pastebin.com/BhEqRsq0
You set the lat/lng coordinates to the <p> element's innerHTML, not to its (unsupported) value which is why it returns undefined:
document.getElementById("curr").innerHTML = currentLatLon;
So change this code:
var input = document.getElementById('curr').value;
to the following:
var input = document.getElementById('curr').innerHTML;
I just ran your web app on my end and reverse geocoding works fine after the above fix. So hope this helps!
I try to get back the adress of the point where the "user" clicks on the "google map" I have implemented on my website.
I copied the source code form developers.google.com and made a view adaptations. In the source from google, you get the "latlng" by an input field. I get it by a "event".
In my "geocode-function" I sum my "lat" and "lng" parameters together to what they would have looked like if they came out of the input field.
Here is the code:
// Set variables
var clicklat;
var clicklng;
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow;
// Listen for click on map
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
clicklat = parseFloat(event.latLng.lat());
clicklng = parseFloat(event.latLng.lng());
geocodeLatLng(geocoder, map, infowindow);
});
// Geocode function
function geocodeLatLng(geocoder, map, infowindow) {
var input = "#{clicklat},#{clicklng}"
var latlngStr = input.split(',', 2);
var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === 'OK') {
if (results[1]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: latlng,
map: map
});
infowindow.setContent(results[1].formatted_address);
infowindow.open(map, marker);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
Now, the problem I have is that console.log(input); gives back: #{clicklat},#{clicklng}. Why, the heck, my variables get not implemented there?
It looks like you are trying to usea "jade" and is not working?
Anyway Here is a way to make it work:
// Set variables
//var clicklat;
//var clicklng;
var geocoder = new google.maps.Geocoder();
var infowindow = new google.maps.InfoWindow;
// Listen for click on map
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
//clicklat = parseFloat(event.latLng.lat());
//clicklng = parseFloat(event.latLng.lng());
geocodeLatLng(geocoder, map, infowindow, event.latLng); //I add this as a parameter
});
// Geocode function
function geocodeLatLng(geocoder, map, infowindow, thelocation) {
// var input = "#{clicklat},#{clicklng}"
// var latlngStr = input.split(',', 2);
// var latlng = {lat: parseFloat(latlngStr[0]), lng: parseFloat(latlngStr[1])};
geocoder.geocode({'location': thelocation}, function(results, status) {
if (status === 'OK') {
if (results[1]) {
map.setZoom(11);
var marker = new google.maps.Marker({
position: results[1].geometry.location,
map: map
});
infowindow.setContent(results[1].formatted_address);
infowindow.open(map, marker);
} else {
window.alert('No results found');
}
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
I am creating a google map that has a list of locations and then I want the user to be able to enter their(any) address into the map. Once they enter their address, a new marker must show and the bounds of the map need to update to include the new location.
I've successfully been able to set the new location as a cookie and redraw the bounds of the map on load, however when I try and do this on the geocode input click, the new marker loads, but the bounds seem to only redraw around the new location.
How can I get the bounds to redraw on the input?
Dev site link: http://rosemontdev.com/google-maps-api/
Here is my code:
var locations = [
['Dripping Springs', 30.194826, -97.99839],
['Steiner Ranch', 30.381754, -97.884735],
['Central Austin', 30.30497, -97.744086],
['Pflugerville', 30.450049, -97.639163],
['North Austin', 30.41637, -97.704623],
];
var currentLocationMarker = "http://rosemontdev.com/google-maps-api/wp-content/themes/rm-theme/images/current.png";
var locationMarker = "http://rosemontdev.com/google-maps-api/wp-content/themes/rm-theme/images/pin.png";
function initMap() {
window.map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infoWindow = new google.maps.InfoWindow();
var bounds = new google.maps.LatLngBounds();
var geocoder = new google.maps.Geocoder();
document.getElementById('submit').addEventListener('click', function() {
geocodeAddress(geocoder, map);
});
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map,
icon: locationMarker,
});
var circle = new google.maps.Circle({
map: map,
radius: 3000,
fillColor: '#2B98B0',
fillOpacity: 0.2,
strokeOpacity: 0.25,
});
circle.bindTo('center', marker, 'position');
bounds.extend(marker.position);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infoWindow.setContent(locations[i][0]);
infoWindow.open(map, marker);
}
})(marker, i));
} //closing for locations loop
var locationValue = Cookies.get('rmLocationCookie-Place');
var longValue = Cookies.get('rmLocationCookie-Long');
var latValue = Cookies.get('rmLocationCookie-Lat');
currentLocationNewMarker = new google.maps.Marker({
position: new google.maps.LatLng(longValue, latValue),
map: map,
icon: currentLocationMarker,
});
bounds.extend(currentLocationNewMarker.position);
map.fitBounds(bounds);
} //closing initMap
function geocodeAddress(geocoder, resultsMap) {
var address = document.getElementById('address').value;
var infoWindow = new google.maps.InfoWindow();
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
var currentLocationData = [];
var bounds = new google.maps.LatLngBounds();
var currentLocationName = 'Current Location';
var currentLocationLong = results[0]['geometry']['bounds']['f']['b'];
var currentLocationLat = results[0]['geometry']['bounds']['b']['b'];
currentLocationData.push(currentLocationName, currentLocationLong, currentLocationLat);
//Location Value Entered
Cookies.set('rmLocationCookie-Place', address);
//Geocoded Long
Cookies.set('rmLocationCookie-Long', currentLocationLong);
//Geocoded Lat
Cookies.set('rmLocationCookie-Lat', currentLocationLat);
var locationValue = Cookies.get('rmLocationCookie-Place');
if(locationValue === undefined){
console.log('no cookie set');
$('#cookie-notice').html('Your location is not saved.');
}
else{
$('#cookie-notice').html('Your location is saved as ' + locationValue +'');
}
updatedCurrentLocationMarker = new google.maps.Marker({
position: new google.maps.LatLng(currentLocationLong, currentLocationLat),
map: map,
icon: currentLocationMarker,
});
bounds.extend(updatedCurrentLocationMarker.position);
map.fitBounds(bounds);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
Try this:
Keep track of the original bounds before each geocode.
Then once the geocode completes pan to the marker and get the new map bounds the.
The idea is then to union the old and new bounds together using the. Union method then use the result as tour new map boundary.
originalbounds.union(newbounds)
Trying to get Google Places API to notice my location and apply the functions below. Very new to this and not sure what I am doing wrong below as the API and all the functions works initially, but after I'm asked for my location, it shows where I am but nothing else works/aren't working together.
Cordova Geolocation plugin I added to my ionic app:
cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git
App.js
app.controller("MapController", function($scope, $ionicLoading) {
var map;
var infowindow;
var request;
var service;
var markers = [];
google.maps.event.addDomListener(window, 'load', function() {
var center = new google.maps.LatLng(42.3625441, -71.0864435);
var mapOptions = {
center:center,
zoom:16
};
map = new google.maps.Map(document.getElementById('map'), mapOptions);
navigator.geolocation.getCurrentPosition(function(pos) {
map.setCenter(new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude));
var myLocation = new google.maps.Marker({
position: new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude),
map: map,
title: "My Location"
});
});
$scope.map = map;
request = {
location: center,
radius: 1650,
types: ['bakery', 'bar']
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
function callback (results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place){
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function(){
infowindow.setContent(place.name);
infowindow.open(map,this);
});
}
});
});
When you get the position, you update the map's location, but you don't run a new Nearby Search.
So I think you want to call service.nearbySearch(...) in the getCurrentPosition callback.
You may also want to have your nearbySearch callback keep an array of the markers created via createMarker, so you can remove them when you run a new search (e.g. by calling marker.setMap(null) on each old marker).
I have edited my code below and put the full JS. I am trying to extract a list of places near a given zipcode or city. My first step would be to take the zipcode or city name and get the latlng coordinates and then get the list of places. I am getting the following errors "Cannot call method 'geocode' of undefined " & " Cannot read property 'offsetWidth' of null" Any help will be greatly appreciated.
var placesList;
var geocoder;
var map;
function initialize() {
map = new google.maps.Map(document.getElementById('map'));
geocoder = new google.maps.Geocoder();
}
function getLatLng(address, callback) {
geocoder.geocode({
address: address
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
var location = new google.maps.LatLng(result.lat(), result.lng());
map.setCenter(location);
var marker = new google.maps.Marker({
map: map,
position: location
});
callback(location);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
getLatLng('14235', function (latLngLocation) {
var pyrmont = latLngLocation;
var request = {
location: pyrmont,
radius: 5000,
types: ['park', 'zoo']
};
placesList = document.getElementById('places');
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
var request1 = {
reference: place.reference
};
service.getDetails(request1, createMarkers);
function callback(results, status, pagination) {
if (status != google.maps.places.PlacesServiceStatus.OK) {
return;
} else {
for (var i = 0; i < results.length; i++) {
var markerPlace = results[i];
createMarkers(markerPlace, status);
}
if (pagination.hasNextPage) {
var moreButton = document.getElementById('more');
moreButton.disabled = false;
google.maps.event.addDomListenerOnce(moreButton, 'click',
function () {
moreButton.disabled = true;
pagination.nextPage();
});
}
}
}
function createMarkers(place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var bounds = new google.maps.LatLngBounds();
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
});
placesList.innerHTML += '<li>' + place.name + '<br>' +
(place.formatted_address ? place.formatted_address : place.vicinity) + '</li>';
bounds.extend(place.geometry.location);
map.fitBounds(bounds);
}
}
});
google.maps.event.addDomListener(window, 'load', initialize);
Your address is not a string, it is a number:
var address = 14235;
The API expects the "address" in the GeocoderRequest to be a string that looks like a postal address. If you want it to be a string, enclose it in quotes (although I'm not sure what you expect the geocoder to return for a single number):
var address = "14235";
If you give the geocoder something that looks more like a complete address, it will work better.
You also have a problem with the asynchronous nature of the geocoder (a FAQ), you can't return the result of an asynchronous function, you need to use it in the callback function.
What you have to understand is that the geocode API is asynchronous; you're trying to assign the results variable to pyrmont before it's ready. To achieve what you want you're going to need to use a callback. Plus there's some other things wrong with how you're dealing with latLng attributions. Anyway, here's how I think your code should look:
var map, geocoder; // global vars
// retain your initialize function
function initialize() {
map = new google.maps.Map(document.getElementById('map'), options);
geocoder = new google.maps.Geocoder();
}
// but separate out your code into a new function that accepts an address
// and a callback function.
function getLatLng(address, callback) {
geocoder.geocode({ address: address }, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
// assign a new Google latLng object to `location`
var location = new google.maps.LatLng(result.lat(), result.lng();
// set the center of the map and position using the latlng object
map.setCenter(location);
var marker = new google.maps.Marker({
map: map,
position: location;
});
// call the callback with the latlng object as a parameter.
callback(location);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
// call the `getLatLng` function with an address and a callback function
getLatLng('14235', function (latLngLocation) {
var pyrmont = latLngLocation;
});