I am trying to get the user location by using HTML5 geolocation. The lat and lng value are received successfully and I can show it on the map. I want to save the user location to use it later so I defined origin variable and I concatenated the lat and lng variables and then I assigned the concatenated value to origin. When I am trying to use the origin value later its value is undifined. Could someone please tell me when the problem is in the code. I guess the problem is very silly but I cannot solve it. I don't think the problem is related to variable scope.
Here is the code:
let map ;
// initialize the map and show it on the dashboard.
function initMap()
{
// Map options.
let options =
{
center :
{
lat : 41.015137,
lng : 28.979530
},
zoom : 12
}
// New map.
map = new google.maps.Map
(
document.getElementById('map'),
options
);
};
$(document).ready
(
function()
{
$("#order_and_show").click
(
function()
{
// Change the text of the title and the button when get order from the user.
$('#order_title').text('Cancel the order right now') ;
$('#order_and_show').text('Cancel Now') ;
// Get user location from browser using HTML geolocation.
let origin ;
// HTML5 geolocation.
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition
(
function(position)
{
let pos =
{
lat: position.coords.latitude,
lng: position.coords.longitude
} ;
origin = position.coords.latitude + ',' + position.coords.longitude ;
// Add marker.
let marker = new google.maps.Marker
(
{
position : pos,
map : map,
}
) ;
// Center the map according to user location.
map.setCenter(pos);
// Add popup window for user location information
let infoWindow = new google.maps.InfoWindow
(
{
content : '<h6>Your Location</h6>'
}
) ;
marker.addListener
(
'click',
() =>
{
infoWindow.open(map, marker) ;
}
) ;
},
function()
{
handleLocationError(true, infoWindow, map.getCenter());
}
);
}
else
{
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
// Handle Geolocation errors.
function handleLocationError(browserHasGeolocation, infoWindow, pos)
{
infoWindow.setPosition(pos);
infoWindow.setContent
(
browserHasGeolocation ? 'Error: The Geolocation service failed.' : 'Error: Your browser does not support geolocation.'
) ;
infoWindow.open(map);
}
console.log(origin) ;
}
) ;
}
) ;
The problem with your current code is that you try to access origin outside of the callback that sets it. The getCurrentPosition callback is probably executed asynchronously, thus when you try to access origin outside of the callback the callback function is not yet executed resulting in a origin value of undefined. You could use promises or async/await to solve this issue. Such a solution might look like this:
$(document).ready(function () {
const map = new google.maps.Map(
document.getElementById("map"),
{ center: { lat: 41.015137, lng: 28.979530 }, zoom: 12 }
);
function handleLocationError(infoWindow, msg) {
infoWindow.setPosition(map.getCenter());
infoWindow.setContent(msg);
infoWindow.open(map);
}
$("#order_and_show").click(async function () {
// notice the async keyword ^
$('#order_title').text('Cancel the order right now');
$('#order_and_show').text('Cancel Now');
let position, origin;
if (navigator.geolocation) {
try {
// await the position before continuing
position = await new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
let pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
origin = position.coords.latitude + ',' + position.coords.longitude;
let marker = new google.maps.Marker({position: pos, map: map});
let infoWindow = new google.maps.InfoWindow({
content: '<h6>Your Location</h6>'
});
map.setCenter(position);
marker.addListener('click', () => infoWindow.open(map, marker));
} catch (error) {
// I'm not sure how you are able to access infoWindow here since it's
// created in the try block after the error is thrown.
handleLocationError(infoWindow, 'Error: The Geolocation service failed.')
}
} else {
// Same here, you don't have access to infoWindow, since it's not created
// yet. However both the above and this are present to mimic the question
// structure.
handleLocationError(infoWindow, 'Error: Your browser does not support geolocation.');
}
// origin should be available unless geolocation isn't supported or
// getCurrentPosisiton failed to execute successfully
console.log(origin);
});
});
For more info about working with asynchronous behaviour I recommend checking out the MDN Using Promises guide.
I am not sure but I think problem seems to be with this line:
let infoWindow = new google.maps.InfoWindow({
content: "<h6>Your Location</h6>"
});
You have declared infoWindow using let keyword which is why I think it is scoped within function(position) { .. } block and which is why infoWindow is being passed to handleLocationError function. The same could be said for let pos variable. declaring your variables globally could solve the problem.
declare pos, marker and infoWindow varibles in the same line let origin; like so:
let origin, pos, marker, infoWindow;
Final Code Should look like this, hope it helps:
let map;
// initialize the map and show it on the dashboard.
function initMap() {
// Map options.
let options = {
center: {
lat: 41.015137,
lng: 28.97953
},
zoom: 12
};
// New map.
map = new google.maps.Map(document.getElementById("map"), options);
}
$(document).ready(function() {
$("#order_and_show").click(function() {
// Change the text of the title and the button when get order from the user.
$("#order_title").text("Cancel the order right now");
$("#order_and_show").text("Cancel Now");
// Get user location from browser using HTML geolocation.
let origin, pos, marker, infoWindow;
// HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
origin = position.coords.latitude + position.coords.longitude;
// Add marker.
marker = new google.maps.Marker({
position: pos,
map: map
});
// Center the map according to user location.
map.setCenter(pos);
// Add popup window for user location information
infoWindow = new google.maps.InfoWindow({
content: "<h6>Your Location</h6>"
});
marker.addListener("click", () => {
infoWindow.open(map, marker);
});
},
function() {
handleLocationError(true, infoWindow, map.getCenter());
}
);
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
// Handle Geolocation errors.
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(
browserHasGeolocation
? "Error: The Geolocation service failed."
: "Error: Your browser does not support geolocation."
);
infoWindow.open(map);
}
console.log(origin);
});
});
Related
My website loads the user's current location using GEO location and displays it on a google map when they then click a button, I want it to store the coordinates in the database.
I have already done the GEO location and displaying the coordinates on the map, I just need to take the values from JS and store them in the database inside the if(isset($_POST['newPost'])) statement
javascript
<script>
var map, infoWindow;
function initMap()
{
map = new google.maps.Map(document.getElementById('map'),
{
center: {lat: -34.397, lng: 150.644},
zoom: 10
});
infoWindow = new google.maps.InfoWindow;
// Try HTML5 geolocation.
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(function(position)
{
var pos =
{
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function()
{
handleLocationError(true, infoWindow, map.getCenter());
});
}
else
{
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos)
{
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
</script>
HTML
<form id="newPost" action="index.php" method="Post">
<textarea id="txtMessage" name="body"></textarea>
<hr/>
<br/>
<br/>
<div id="map" style="width:100%;height:400px;"></div>
<br/>
<button type="submit" id="postButton" name="newPost" class="Button">Post!
</button>
</form>
PHP
if(isset($_POST['newPost']))
{
DB::query('INSERT INTO heatmap(lon, lan) VALUES (:lon, :lan)',
array(':lon'=>$VAL, ':lan'=>$VAL));
}
Any help would be appreciated
Not having a way to test it, I had to make some guesses. I don't see any Markers created, so I assume you're using the map coordinates. Consider the following:
$(function() {
var map, infoWindow;
function initMap() {
map = new google.maps.Map($('#map')[0], {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 10
});
infoWindow = new google.maps.InfoWindow();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
$("#newPost").submit(function(e) {
e.preventDefault();
var pData = {
body: $("#txtMessage").val(),
lng: map.coords.longitude,
lat: map.coords.latitude
};
$.post($(this).attr("action"), pData);
});
});
https://jsfiddle.net/Twisty/wzvpnmh6/21/
This would create POST Data like:
{
body: "Hello World",
lat: -34.397,
lng: 150.644
}
You could also Stringify it and send it as a combined string:
var coords = JSON.Stringify({ lat: c.lat(), lng: c.lng() });
You will then get a string like: {"lat":-34.397,"lng":150.644} that can be added direct to a DB. This is up to you and will be defined by what you need to do with the data. If you need to search for specific Lat or Long, then they will store in their own columns. If you just need the geolocation, then they can be in a single column.
Hope that helps.
References:
Google Maps API function map.getCenter()
https://developers.google.com/maps/documentation/javascript/mysql-to-maps
I have recently developed a website but I haven't been able to show the current location marker on the Google map after the location was found.
You can have a look on https://www.storra.com/listings/
I have added a custom listener to the function.php based on Listify auto-locate function but didn't manage to add the marker to the map. The code is as following,
function listify_custom_autolocation() {
if ( ! ( is_front_page() || listify_is_job_manager_archive() ) ) {
return;
}
?>
<script>
var triggered = false;
jQuery(document).on( 'facetwp-loaded', function() {
if ( ! triggered ) {
var locate = jQuery( '.locate-me' );
locate.trigger( 'click' );
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(
parseFloat(coords[0]),
parseFloat(coords[1])
),
info: new google.maps.InfoWindow({
content: val.title + val.distance
})
});
}
triggered = true;
});
</script>
<?php
}
add_action( 'wp_footer', 'listify_custom_autolocation', 9999 );
Would very much appreciate if someone could guide me out.
Thank you!
You could use this one for your locate function:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var marker = new google.maps.Marker({
position: pos,
map: map,
title: 'Your position'
});
map.setCenter(pos);
}, function() {
//handle location error (i.e. if user disallowed location access manually)
});
} else {
// Browser doesn't support Geolocation
}
The following is the relevant code on the backend. I tried adding the code given by #mxlse but didn't seem to work too.
AutoLocateView.prototype.find = function() {
var cv, error, filters, success;
cv = this.collectionView;
filters = this.filters;
if (!navigator.geolocation) {
return;
}
success = function(position) {
var lat, lng;
lat = position.coords.latitude;
lng = position.coords.longitude;
cv.set({
'lat': lat,
'lng': lng
});
return $('.locate-me').removeClass('loading');
};
error = function() {
$('.locate-me').removeClass('loading');
return filters.startup();
};
navigator.geolocation.getCurrentPosition(success, error);
return this;
};
I am trying to rework a phonegap app to use googlemaps plugin and v2 of google maps API.
I am struggling with updating the marker position, which seems to work perfectly in v3, but not with the plugin.
The issue seems to be when calling setMarkerPosition(), the marker object is not being passed to it so I am getting "cannot call method setPosition of undefined"
I have currentPositionMarker set as a global variable at the top of my script and although I define it in setCurrentPosition() at the start, I have also tried using the callback to define it again, but neither work.
Apologies if its something silly, this is my first JavaScript project so still very patchy understanding of parts of the language, so any pointers greatly appreciated.
Code I am trying...
function initializeMap()
{ map = plugin.google.maps.Map.getMap();
// map = new plugin.google.maps.Map(document.getElementById('map_canvas'), {
// zoom: 13,
// });
}
function initLocationProcedure() {
initializeMap();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
displayAndWatch,
errorCallback_highAccuracy,
{maximumAge:600000, timeout:5000, enableHighAccuracy: true});
} else {
alert("Your Phone does not support Geolocation");
}
}
function displayAndWatch(position) {
// set current position
setCurrentPosition(position);
// watch position
watchCurrentPosition();
}
function errorCallback_highAccuracy(position) {
}
function watchCurrentPosition() {
var positionTimer = navigator.geolocation.watchPosition(
function (position) { setMarkerPosition(currentPositionMarker,position);
}, error, {maximumAge:600000, timeout:5000, enableHighAccuracy: true});
}
function error(){
}
function setMarkerPosition(marker, position) {
marker.setPosition(
new plugin.google.maps.LatLng(
position.coords.latitude,
position.coords.longitude)
);
}
function setCurrentPosition(pos) {
currentPositionMarker = map.addMarker({
'position': new plugin.google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
),
}, function(marker) {
currentPositionMarker = marker;
});
map.setCenter(new plugin.google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
));
}
OK, turns out the marker var is being created, but not in time as setCurrentPosition(), which is setting the marker is being called asynchronously with setMarkerPosition(). Removing displayAndWatch() altogether and then calling setMarkerPosition() from the callback of setCurrentPosition() seems to be the fix.
function setCurrentPosition(pos) {
map.addMarker({
'position': new plugin.google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
),
}, function(marker) {
currentPositionMarker = marker;
watchCurrentPosition();
});
map.setCenter(new plugin.google.maps.LatLng(
pos.coords.latitude,
pos.coords.longitude
));
}
I am using the Google maps API along with the HTML 5 geolocation API to display my position as a marker on a map. Once this marker is displayed I have a simple on marker double-click function that saves a new marker to my current position using indexedDB. Everything goes well until the Object is about to be stored, then I received the message "Uncaught DataCloneError: Failed to execute 'put' on 'IDBObjectStore': An object could not be cloned." in the console. my code is as follows:
function initialize() {
var mapProperties = { // Set the maps properties
center: new google.maps.LatLng(55.8580, -4.2590),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-overview"), mapProperties); //Display the map in the map-overview div
function NogeoLocation(e) { //A function to handle users that do not have Geolocation
if (e) {
var content = 'Error: Unfortunately the Geolocation service failed.';
} else {
var content = 'Error: Sorry, Your web browser doesn\'t support geolocation.';
}
var options = { //Error options
map: map,
position: new google.maps.LatLng(60, 105), //Set new position on Error
content: content //Display error message
};
var infowindow = new google.maps.InfoWindow(options);
map.setCenter(options.position);
}
//Using HTML5 Geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var position = new google.maps.LatLng(position.coords.latitude,
position.coords.longitude);
var contentString = "Here is your current location!" + "<button onclick='myBtn()'>Save</button>"
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: position,
map: map,
title: 'My House'
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
var db;
function indexedDBOk() {
return "indexedDB" in window;
}
google.maps.event.addListener(marker, 'dblclick', function () {
alert("dbl Click");
console.log(position);
if (!indexedDBOk) return;
var openRequest = indexedDB.open("idarticle_people", 1);
openRequest.onupgradeneeded = function (e) {
var thisDB = e.target.result;
if (!thisDB.objectStoreNames.contains("people")) {
thisDB.createObjectStore("people");
}
}
openRequest.onsuccess = function (e) {
console.log("running onsuccess");
db = e.target.result;
var transaction = db.transaction(["people"], "readwrite");
var store = transaction.objectStore("people");
//Define a marker
var marker = {
position: position,
map: map,
title: 'New Marker'
}
console.log(marker);
console.log("about to perform add");
//Perform the add
var request = store.put(marker, 1);
console.log("added");
request.onerror = function (e) {
console.log("Error", e.target.error.name);
//some type of error handler
}
request.onsuccess = function (e) {
console.log("Woot! Did it");
}
}
openRequest.onerror = function (e) {
//Do something for the error
}
});
map.setCenter(position);
}, function () {
NogeoLocation(true); // Refers to NogeoLocation function
});
} else {
// If the user's browser doesn't support Geolocation
NogeoLocation(false);
} //End of HTML5 GeoLocation
} // End of the function that initializes Google Maps
google.maps.event.addDomListener(window, 'load', initialize); //On page load, execute initialize()
marker can't be cloned because the object stored in the map-property contains a reference to a DOMNode(#map-overview), which can't be cloned (see:Things that don't work with structured clones).
Remove the map-property, it will not be re-usable at all because the google.maps.Map-instance will not exist when you retrieve the marker later.
I discovered that the reason for the error was to try to add an object that was not recognized to a cache.
this.storage.set ("page", HomePage);
I switched to a string and it worked
this.storage.set ("page", "HomePage");
I wonder whether someone may be able to help me please.
Because of loading issues, I've moved the map options code to my HTML form, rather than it being in a separate Javascript file.
The problem is that I now can't get the Geocode functionality to work. I've added my code below. I'm sure it must be something simple, but I'm a little perplexed by this. I just wondered whether it would be at all possible please that someone could let me know where I've gone wrong.
Many thanks
function geocode() {
// This is defining the global variables
var geocoder, marker;
// This is making the link with the 'Search For Location' HTML form
var form = document.getElementById('searchforlocationform');
// This is catching the forms submit event
form.onsubmit = function() {
// This is getting the Address from the HTML forms 'Address' text box
var address = document.getElementById('inputaddress').value;
// This is making the Geocoder call
getCoordinates(address);
// This is preventing the form from doing a page submit
return false;
}
}
function geocodePosition(pos) {
geocoder.geocode({
latLng: pos
},
function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
//New Code
function updateMarkerStatus(str) {
document.getElementById('markerStatus').innerHTML = str;
}
//Changed 'address' to 'returnedaddress'
function updateMarkerAddress(str) {
document.getElementById('returnedaddress').value= str;
}
// This creates the function that will return the coordinates for the address
function getCoordinates(address) {
// This checks to see if there is already a geocoded object. If not, it creates one
if(!geocoder){geocoder = new google.maps.Geocoder();}
// This is creating a GeocoderRequest object
var geocoderRequest = {address: address}
// This is making the Geocode request
geocoder.geocode(geocoderRequest, function(results, status) {
// Check if status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
// Center the map on the returned location
map.setCenter(results[0].geometry.location);
// Check to see if we've already got a Marker object
if (!marker) {
map.setZoom(16);
marker = new google.maps.Marker({
map: map, draggable:true
});
}
// Setting the position of the marker to the returned location
marker.setPosition(results[0].geometry.location);
// Add dragging event listeners.
google.maps.event.addListener(marker, function() {
updateMarkerAddress;
});
//This fills out the 'Latitude' and 'Longitude' text boxes on the HTML form
document.getElementById('osgb36lat').value= results[0].geometry.location.lat();
document.getElementById('osgb36lon').value= results[0].geometry.location.lng();
//This allows the marker to be draggable and tells the 'Latitude' and 'Longitude' text boxes on the HTML form to update with the new co-ordinates as the marker is dragged
google.maps.event.addListener(marker,'dragend',
function() {
updateMarkerStatus;
geocodePosition(marker.getPosition());
document.getElementById('osgb36lat').value = marker.position.lat();
document.getElementById('osgb36lon').value = marker.position.lng();
});
// Update current position info.
latLng = [marker.position.lat(), marker.position.lng()].join(', ');
geocodePosition(marker.getPosition());
var point = marker.getPosition();
map.panTo(point);
}
}
)
}
<script type="text/javascript">
(function() {
window.onload = function(){
var latlng = new google.maps.LatLng(54.312195845815246,-4.45948481875007);
var options = {
zoom: 6,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.TOP_RIGHT
},
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.ZOOM_PAN,
position: google.maps.ControlPosition.TOP_LEFT
},
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
}
};
var map = new google.maps.Map(document.getElementById('map'), options);
}
})();
</script>
You seen to be trying to call updateMarkerAddress with updateMarkerAddress; and updateMarkerStatus with updateMarkerStatus;, here you are missing (/*some param*/).
What are the loading issues? Maybe if you show your html someone could help with that too.