I have a webpage that uses the google places and google maps API on the same page. A user selects a certain location from google places autocomplete and the google map then centers on that given place.
The logic of this event seems to work fine, however I've noticed that 1.) 'autocomplete' place suggestions become slower and slower with each additional place searched through the search bar, and 2.) the shadow on the place suggestions becomes darker and darker with each additional search (see pictures below).
This problem seems to be 'reset' once the browser cache is cleared, leading me to believe the issue is that the previous search terms in the input box are being stored somewhere and slowing down the google places performance.
I apologize if this is a simple issue, but googling the past few days on this problem has turned up nothing for me. Any help??
View of the search box before any problems:
Search bar after multiple previous searches:
My initMap() function:
function initMap() {
var myLatLng = {lat: 40, lng: -20}; //display the initial main map
map = new google.maps.Map(document.getElementById('bigMainMap'), {
center: myLatLng,
mapTypeControl: false,
zoom: 3
});
var searchTerm = $('#mainAdvSearchBox')[0];
var autoComplete = new google.maps.places.Autocomplete(searchTerm);
var geocoder = new google.maps.Geocoder();
geocoder.geocode( {'address': chosenArea}, function(results, status) { //use google place bounds to appropriately zoom on street/city/country
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
map.fitBounds(results[0].geometry.viewport);
google.maps.event.addListenerOnce(map, 'bounds_changed', setSelectedMarkers);
}
else
setAllMarkers(); //user has directly navigated to adventures page, show world map and all events
});
}
My tag for including the google apis:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initMap" async defer></script>
This issue is caused by a mistake in implementation. This normally happens when
new google.maps.places.Autocomplete
is added inside the input's keyup event listener like this:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.8688, lng: 151.2195},
zoom: 13
});
var input = document.getElementById('pac-input');
// this is where things starts to go wrong
input.addEventListener('keyup', function() {
var autocomplete = new google.maps.places.Autocomplete(input);
});
}
Check out the wrong implementation here: http://jsbin.com/popucap/edit?js,output
The listener part for the input box is unnecessary. This will make your autocomplete go insane. The autocomplete will pile itself on the previous suggestions again and again. because every time you input a character, the autocomplete is being created again.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -33.8688, lng: 151.2195},
zoom: 13
});
var input = document.getElementById('pac-input');
// this is how it should be
var autocomplete = new google.maps.places.Autocomplete(input);
}
Check out the working sample here: http://jsbin.com/cubirod/edit?js,output
If this is not how you're doing it, you should get an idea of how this happens with my samples. Hope it helps!
Related
guys I hope you can help me out with this issue. Bassically I'm trying to achive next goal:
Users fills out form (Buddyform + ACF plugin)-> Automatically post are being created from users submited form information
But there is a problem with that since one if the forms fields is Google Map field (created in ACF).
Transaction from form to post is very nice. But for some reason information about selected address is missing. Meaning that you can see marker on map and you can move map, but you can't see what is exact address.
The idea was to include address in infowindow which would open onclick. But so far I understood just how to include manually written text (content : "text here"). But I want that in infowindow would appear address from Buddyform that user submited.
Is there a way to do so?
You can see my testing here
Since am not really good with coding I use plugins for custom fields creation (ACF plugin) and in order to show custom fields in post (wpView plugin)
OK from what I can see from the documentation link in your comments. You have to add the code from the Helpers section into your page template.
In the add_marker($marker, map) method you can make another api call to get a human readable address of the marker location.
function add_marker( $marker, map ) {
// var
var latlng = new google.maps.LatLng( $marker.attr('data-lat'),
$marker.attr('data-lng') ),
formatAddress = "";
// create marker
var marker = new google.maps.Marker({
position : latlng,
map : map
});
Using the latLng variable to make request to the Geocoding service in order to get a formatted address from the variable's lat/lang coordinates.
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'location': latLng}, function(results, status)
{
if (status == 'OK') {
formatAddress = results[0].formatted_address;
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
// add to array
map.markers.push( marker );
Then you when add the infowindow you can put the formatted address as it's body content.
// if marker contains HTML, add it to an infoWindow
if( $marker.html() )
{
// create info window
var infowindow = new google.maps.InfoWindow({
content : formatAddress
});
// show info window when marker is clicked
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
I am using cordova in building the google map for device platform.
What I am going to ask is that, how to check if the user position is change?
Because the scenario is, when user is away from the specified place, the page will be redirected to logout page.
Here is the working map I have for static map (with no position change yet)
var longitude = position.coords.longitude;
var latitude = position.coords.latitude;
var latLong = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
center: latLong,
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
var marker = new google.maps.Marker({
position: latLong,
map: map,
title: 'my location'
});
So the function to achieve what I want is more or less like this:
var positionMust = x, -y;
if (latLong != positionMust )
{
window.location.href//to logout
}
We need to check this everytime user is moving away.
Can anybody help? Many many thanks in advance.
You can use navigator.geolocation API as exemplified in this post:
Accessing a Google Maps API on pageload with Angular
In particular are of your interest navigator.geolocation.getCurrentPosition() and navigator.geolocation.watchPosition().
and it's also possible to check if a position is within a certain region using Google Geometry Library, see:
Determine if location is within a certain region in Google Map
All the geolocation APIs above mentioned are implemented on devices by the cordova-plugin-geolocation.
I am using the Google Maps api to create a small, stripped down map that shows a geocoded location with a marker. You can see the live code here: http://www.ddbeadworks.com/
It works flawlessly, until someone clicks the Google logo to take themselves to maps.google.com. There, the map is properly zoomed and centered on the location, but the marker isn't being passed to maps.google.com, it seems, as that doesn't appear? I looked through the API, but I can't find anything like "markersToGoogle boolean" or any such variable.
Here is the relevant code section. This is the only place I deal with markers anywhere. JavaScript:
var address = $(this).attr("name");
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
var lat = results[0].geometry.location.lat();
var lng = results[0].geometry.location.lng();
if (status == google.maps.GeocoderStatus.OK)
{
var yourStartLatLng = new google.maps.LatLng(lat, lng);
$('#map_canvas').gmap('addMarker', {'position': yourStartLatLng, 'bounds': true});
$('#map_canvas').gmap('option', 'zoom', 14)
$('#map_canvas').gmap('option', 'disableDefaultUI', true)
}
});//close geocoder
That is what the Google logo links to, the main Google Maps web site, with the same center and zoom as the map it came from.
If you want to make a bigger map with your marker on it, you need to link to a bigger Google Maps API v3 based map (and not expect your user to use the "Google" logo).
I am constructing a pretty massive website that is WP powered , but uses Google maps as a main interface .
I have a page on the admin side, where I want to be bale to select a location by dragging a marker , and then save this data to MySQL (via Php/wp functions)
Problem is - as much as my WP and PHP foundations are pretty solid , my JS or Jquery are quite basic, not to say shaky .
I have "hacked" together a code from reading the Google maps API, tutoials, and examples -
It produces the map correctly, and also the marker to be dragged , and then it passes the value of [Lat,Lng] to a TXT input via jQuery - which then is saved to the DB.
Everything works fine - except for one issue :
when I edit or save the data - the next time I will open this "post" - there is no marker ,and I need to make a new one and save again .
when I tried to get the Values of the input field with simple
var LatPoint = jQuery('[name=LatTxt]').val()
and
placeMarker(new google.maps.LatLng(LatPoint,LngPoint));
the map failed to generate at all.
The second is that the drag marker function does not update the input.
the third (and not less important) is that I KNOW that the code is horrible, and I am SURE there is a better way to achieve this - and whis whole website purpose is also for me to LEARN - I would like someone to revise the code and advise on how to optimize it ..
this is the code I have up to now ..
var map;
var markersArray = [];// to be used later to clear overlay array
jQuery(document).ready(function(){
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_2k"), myOptions);
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
});
var marker;
//Function to extract longitude
function placeMarker(location) {
if ( marker ) {
marker.setPosition(location);
} else {
marker = new google.maps.Marker({
position: location,
draggable: true,
title: 'Drag me',
map: map
});
markersArray.push(marker); // to be used later to clear overlay array
}
}
// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
}
}
//Jquery update HTML input boxes
function updatelonlat() {
jQuery('#LatTxt').val(marker.getPosition().lat());
jQuery('#LonTxt').val(marker.getPosition().lng());
}
// add event click
google.maps.event.addListener(map, 'click', function(event) {
placeMarker(event.latLng);
updatelonlat();
//var lat = parseFloat(document.getElementById('LatTxt').value); - somehow not working
});
//google.maps.event.addListener(marker, 'dragend', function(event) {
//document.getElementById("#LatTxt").value = event.latLng.lat(); - somehow not working
map.setCenter(location);
});
Any help would be greatly appreciated ..
EDIT I
I have set up a JSFIDDLE : http://jsfiddle.net/obmerk99/fSj9F/1/
Obviously I can not simulate the PHP function - but it is not needed .
What I want is when the page loads /refresh / save - it will start with a CENTER and a MARKER with vaalues from the input box...
Also - I just now noticed that the drag action is also not updating , I do not know if it is jsfiddle - or my function ...
I've fixed your code in JSFiddle: http://jsfiddle.net/fSj9F/2/
The problems was:
1) You didn't read the values of your inputs before creating the map, and setting the center.
2) You tried to use map.setCenter(location), but the location variable wasn't set
3) You never called your placeMarker function, so the marker was never placed, before the user clicked the map
4) Even though you didn't use the clearOverlays function, I replaced the for..in loop with a regular for. This way you don't iterate the properties of the array (which isn't just the elements, but also the methods of the Array object), but instead you only iterate over the elements contained in the array.
Notice that your code might've been easier to read if you'd declared your functions out of the "ready" function, and if you didn't use global variables such as marker.
I am using a plugin for Google Maps API V3. I use it to put a marker on the map and allow the user to drag the marker to a spot on the map. I want to get the lat,lng of the marker on click.
goMap Plugin Page:
http://www.pittss.lv/jquery/gomap/index.php
This function that sets up the marker in the first place.
$("#map").goMap({
zoom: 16,
maptype: 'ROADMAP',
navigationControl: false,
mapTypeControl: false,
scrollwheel: true,
disableDoubleClickZoom: false,
markers: [{
draggable:true,
latitude: data.lat,
longitude: data.lng,
icon:'./images/pink.png'
}]
});
I tried calling the native getLat() method on goMap(), but I don't think I was doing that right. Any help is much appreciated.
After a bit of sleuthing, it looks like it uses jQuery's data() function to bind data to the map. You can get to the data through $('#map').data(), which has information on markers.
Each marker has an id, and you can get the marker's id through the array $.goMap.markers. Note that $.goMap.markers only contains strings that are IDs and not the markers themselves.
You'll need to use that array to find the id you want (or you might know it ahead of time) and then call $('#map').data()['MARKER_ID'] to get the marker object. The marker has a few properties, including title, visible, icon, id, and position.
We care about position, which has two properties, wa and ya. wa seems to be latitude, while ya seems to be longitude. So $('#map').data()['MARKER_ID'].position.wa will get you the latitude, for example. It seems some markers have a latitude and longitude property, not sure why that's not always there (from my brief testing at least), but you could try $('#map').data()['MARKER_ID'].latitude instead.
Hope this helps.
I don't know why, but the props names changing often with the time... Seems like the best solution is get the key names and use to know the lat & lng.
So, if you want to get the coords after a drag, for example, you'll use:
$.goMap.createListener({type:'marker', marker:'MARKER_ID'}, 'dragend', function() {
var i_prop = 2;
var map_data_marker = $('#map').data()['MARKER_ID'].position;
var map_data_marker_keys = [];
for (var key in map_data_marker)
{
if (i_prop--)
{
if (map_data_marker.hasOwnProperty(key))
{
map_data_marker_keys.push(key);
}
}
else
{
break;
}
}
var lat_lng = map_data_marker[map_data_marker_keys[0]] + ', ' + map_data_marker[map_data_marker_keys[1]];
});