Calculate driving distances Google Maps API - javascript

For a website where a user enters his address, I'm trying to find the location closest to him where the user can collect the ordered goods.
Based on the user's address I can narrow down the possible pick up locations to between 2 and 5. So I'd like to calculate the distance between user's address (point A) and the possible pick up locations.
The demo here works fine with just two addresses. I've adapted the code as much as I can to work with more than two addresses. I posted my JS code here since I can't seem to properly format it in SO.
In the code are two alerts. The first alert correctly shows the different pick up locations. But the second alert always shows the LAST pickup location.
Can anyone explain why?
HTML:
<p id="hello">Hello World</p>
JavaScript:
var geocoder, location1, location2, gDir;
function initialize(counter) {
if( counter == 0 ){
geocoder = new GClientGeocoder();
gDir = new GDirections();
}
GEvent.addListener(gDir, "load", function() {
var drivingDistanceMiles = gDir.getDistance().meters / 1609.344;
var drivingDistanceKilometers = gDir.getDistance().meters / 1000;
$("#results").append('<strong>Driving Distance: </strong>' + drivingDistanceKilometers + ' kilometers<br /><br />');
});
}
function getDistance(agency_add, counter) {
initialize(counter);
geocoder.getLocations(agency_add, function (response) {
if (!response || response.Status.code != 200) {
alert("Sorry, we were unable to geocode the address" + agency_add);
}
else {
location1 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
//alert("ONE: "+location1.address);
geocoder.getLocations(document.forms[0].address1.value, function (response) {
//alert("TWO: "+location1.address);
if (!response || response.Status.code != 200) {alert("Sorry, we were unable to geocode the second address");}
else {
location2 = {lat: response.Placemark[0].Point.coordinates[1], lon: response.Placemark[0].Point.coordinates[0], address: response.Placemark[0].address};
gDir.load('from: ' + location1.address + ' to: ' + location2.address);
}
});
}
});
}
$(document).ready(function(){
//put each agency address in an array
var agencies = [];
$(".agency_field").each(function(index) {
agencies.push($(this).val());
});
for (var i = 0; i < agencies.length; i++){
var res = getDistance(agencies[i], i);
}
});

you are calling geocoder.getLocations inside a loop. geocoder.getLocations runs asynchronously. when it receives the 2nd request while still processing the first, it cancels the first request.
If you want to multi-thread geocoder.getLocations you need to create multiple instances of it.

Related

Marker cluster Group

I have this code that gets the data from postgis and but when launching my page my markers won't show, even though there is no error in the console. the problem seemes to come from couche.on('data:loaded', function (e) since apparently it's not able to get the loaded data and because when i do couche.addTo(maCarte) directly the markers show. And i tried it in a another example with var couche = new L.GeoJSON.AJAX("data/markers.geojson", { and it works.
Another problem is when i enter a variable to select a specefic marker i always get the same error Uncaught SyntaxError: Unexpected token < in JSON at position 2 even though i checked my php file and it's fine and show the results when i launched directly Exécution du script PHP it happens in this code only when i add a variable and when there is none and the variable is null, the data is downloaded without any problem, so i don't know where the problem is coming from.
Can anyone please help me find a solution ?
function loadData() {
console.log('php/lecture.php?var=' + variable )
$.ajax({url:'php/lecture.php?var=' + variable ,
success: function(response){
data = JSON.parse(response)
console.log(data)
console.log('Données téléchargées : ' + response.length / 1000000 + 'Mo')
drawEntities(data)
maCarte.fitBounds(couche.getBounds())
}
})
}
couche = new L.GeoJSON(data.features, {
onEachFeature: function (feature, layer) {
layer.bindPopup('<h4>date_debut: ' + feature.properties.date_debut+
'</h4>')
},
pointToLayer: createCircleMarker
});
couche.on('data:loaded', function (e){
function makeGroup(color) {
return new L.MarkerClusterGroup({
iconCreateFunction: function(cluster) {
return new L.DivIcon({
iconSize: [20, 20],
html: '<div style="text-align:center;background:'+color + '">' +
cluster.getChildCount() + '</div>'
});
}
}).addTo(maCarte);
}
var groups = {
TR: makeGroup('red'),
DE: makeGroup('green'),
CA: makeGroup('orange'),
CO: makeGroup('blue')
};
e.target.eachLayer(function(layer) {
groups[layer.feature.properties.type].addLayer(layer);
});
});
}

How do i access a filemaker script with javascript in Web Viewer using Apple Mapkit?

I have Filemaker 18 with a Web Viewer using Apple Maps. When I move a pin on the map I want to send the coordinates to a filemaker script that writes to 2 fields. The problem is I can not trigger the script. The database is hosted on a FM Server 18. I have tried these 3 approaches but I am not even able to run a simple "Hello" script. The database name is WEBMAP.fmp12 . Here is how I have tried to run the script. I get no response:
1)
var theURL = "fmp://$/" & Get ( FileName ) & "?script=Hello&param=" + lat +"|"+ long;
window.location = theURL;
2)
var theURL ="fmnet://ip_address_of_server/WEBMAP.fmp12?script=Hello&param=" + lat +"|"+ long;
window.location = theURL;
3)
var theURL = "window.location = "fmp://$/WEBMAP.fmp12?script=Hello&param=" + lat +"|"+ long;
window.location = theURL;
In fact I notice that when I have anything after showing a popup (then I want to run the script) the map is blank whatever I add like "alert("hello").
Here is my js file in Filemaker 18:
var message = document.getElementById("message");
var center = new mapkit.Coordinate(x,y); //
mapkit.init({
authorizationCallback: done => {
done(
"<<$$JWT.TOKEN>>"
);
}
}); //alert("<<$$JWT.TOKEN>>");
var map = new mapkit.Map("map", {
showsScale: mapkit.FeatureVisibility.Visible,
center: center
});
var marker = new mapkit.MarkerAnnotation(map.center, {
draggable: true,
selected: true,
title: "Dra meg og slipp!"
});
marker.addEventListener("drag-start", function(event) {
// No need to show "Drag me" message once user has dragged
// event.target.title = "";
// Hide message
message.style.display = "none";
});
marker.addEventListener("drag-end", function() {
// center map to marker when moved
map.setCenterAnimated(marker.coordinate);
// hide message after seconds
window.setTimeout(function () {
message.style.display = "none";
}, 3550);
// message to show after move
var lat = marker.coordinate.latitude;
var long = marker.coordinate.longitude;
var message = document.getElementById('message');
message.innerHTML = "<p>Vi har lagret posisjonen</p>Latitude: " + lat + " <br />Longitude: " + long;
message.style.display = "block";
//alert("Hello"); ** this alert works!! **
//var test = ‘Hello World!’; alert(test); ** this line gives me a blank map just adding a "var statement" **
var theURL = "fmp://$/" & Get ( FileName ) & "?script=Testaccess&param=" + lat +"|"+ long;
window.location = theURL;
// alert(theURL) here gives me blank map
}); // END drag-end
map.addAnnotation(marker);
var lat = marker.coordinate.latitude;
var long = marker.coordinate.longitude;
var borchbio = new mapkit.CoordinateRegion(
new mapkit.Coordinate(lat,long),
new mapkit.CoordinateSpan(0.002, 0.002)
);
map.region = mymap;
map.mapType = "hybrid";map.setCenterAnimated(new mapkit.Coordinate(x,y), true);
The solution was to set "fmurlscript" rights. Thanks to #michael.hor257k and more detailed help from #paul_tuckey at the Claris Community. His answer here.
File-->Manage-->Security-->Advanced Settings-->Extended Privileges,
Select fmurlscript
Click Edit,
Add the Privilege set that is aligned to your Account Name to the selected fmurlscript
With this code I am able to run a FM script from javascript. Here is the code that triggers the script. Notice that when my database is "WEBMAP.fmp12" I only use "WEBMAP" as the name. I am sending the lat and long to the script that does stuff with it (converts it and writes to the post). The "fmp18://" targets specific version 18.
var theURL = "fmp18://$/WEBMAP?script=My_FM_Script_Name&param=" + lat +"|"+ long;
window.location = theURL;

Changing input value via Javascript before form submission? PHP

Been through a number of questions and nothing seems to work for my case.
Okay so, I have a form with a single input (search) field and a submit button. When the user enters a value (an address in this case) and hits submit, that address value needs to be sent to a JavaScript function which converts it into Longitude and Latitude values, and then these coordinates need to be sent to the destination page instead of the address they input.
Here is my code so far:
HTML
<form name="searchform" action="required/results.php" method="get" id="searchbar" onsubmit="convertToCoords()">
<input type="text" name="input" id="address" placeholder="Search an address or suburb...">
<input type="submit" class="searchbtn" value="Search">
</form>
JS
function convertToCoords() {
var address = document.getElementById("address").value; // Get the input address from the textbox
/* Address to Coordinates conversion (Disregard) */
geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Get the Lat. and Long.
var searchedLat = results[0].geometry.location.lat();
var searchedLong = results[0].geometry.location.lng();
// Set address input value to coordinates, then submit form
document.getElementById('address').value = searchedLat + ',' + searchedLong;
document.getElementById('searchbar').submit();
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
PHP on destination page (for testing)
<?php
if (isset($_GET['input'])) {
echo $_GET['input']; // get value of search input
}
?>
So at the moment what is happening is it is just echoing the address they input, no conversion happens.
I don't know (or care) when the conversion should happen, e.g. whether it should happen before submission or after.
Thanks for any feedback!
I made a basic example of how it could work, please see the JSFiddle here: http://jsfiddle.net/5mMtm/1/
The principle is:
capture the form's submit
do an ajax call to an API (in your case geocoder) with the data entered
change form input value and send/submit to own endpoint
I'm using jQuery in the example:
$(function(){
var $form = $('#my-form'), // the form
$adrInput = $form.find('[name=address]'), // the address input field
isSearching = false; // a flag to prevent multiple submits
// on form submit event
$form.on('submit', function(e){
// Prevent submit event
e.preventDefault();
// Don't start another search while
// other is still going
if( isSearching ){ return; }
isSearching = true;
// Start query to google
getAddressFromGoogle();
});
function getAddressFromGoogle(){
var address = $adrInput.val();
// Get lat/lng value and then do something with it
getLatLng( address, function( lat, lng ){
$adrInput.val( lat + ',' + lng );
});
}
// this function takes two parameters
// the address as a string from the input field
// and a callback it will invoke with the results
// when it's done
function getLatLng( address, callback ){
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': address }, function( results, status ){
if( status == google.maps.GeocoderStatus.OK ){
// Get the Lat. and Long.
var lat = results[0].geometry.location.lat(),
lng = results[0].geometry.location.lng();
// Pass latLng to callback function
if( typeof callback === 'function' ){
callback.apply( null, [ lat, lng ]);
}
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
});
You have to do an event.preventDefault() at the begining. It will prevent the submit made by the "browser" ... so you will be able to do your own submit.
Here is a simplified version of your code:
Javascript:
var convertToCoords = function() {
event.preventDefault();
document.getElementById('address').value = "test";
document.getElementById('searchbar').submit();
};
Html:
<form name="searchform" action="required/results.php" method="get" id="searchbar" onsubmit="convertToCoords()">
<input type="text" name="input" id="address" placeholder="Search an address or suburb...">
<input type="submit" class="searchbtn" value="Search">
</form>

Undefined variable when passing javascript variable to PHP with AJAX

I am trying to build a simple mobile app that checks database and gives user the correct venue based on their location. Essentially, I have two files: one with geolocation, JavaScript and AJAX call, and another one with php that checks the database and sends the correct result back. Everything on its own is working perfectly fine, but when I try to send geolocation coordinates to PHP it returns undefined. Why does it not pick up the coordinates (they pop up in a separate window)? How can I fix it?
Here is my geolocation and AJAX code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$( document ).ready(function() {
var latitude;
var longitude;
if (navigator.geolocation) {
var timeoutVal = 10 * 1000 * 1000;
navigator.geolocation.getCurrentPosition(
displayPosition,
displayError,
{ enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
);
}
else {
alert("Geolocation is not supported by this browser");
}
function displayPosition(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude);
}
function displayError(error) {
var errors = {
1: 'Permission denied',
2: 'Position unavailable',
3: 'Request timeout'
};
alert("Error: " + errors[error.code]);
}
var request = $.ajax({
url: "http://cs11ks.icsnewmedia.net/mobilemedia/ajax.php?latitude=" + latitude + "&longitude=" + longitude,
type: "GET",
dataType: "html"
});
request.done(function(msg) {
$("#ajax").html(msg);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
});
</script>
And here is the bit of PHP that handles these variables:
if (isset($_GET['latitude']) && isset($_GET['longitude'])) {
$latitude = $_GET['latitude'];
$longitude = $_GET['longitude'];
echo "Geolocation seems to work...";
echo $latitude;
echo $longitude;
//continue here
}else{
echo "Hello. I am your geolocation and I am not working.";
}
What I get is "Geolocation seems to work...undefinedundefined"
The Geolocation API is asynchronous, so you have to wait for the result to return
function displayPosition(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
$.ajax({
url : "http://cs11ks.icsnewmedia.net/mobilemedia/ajax.php",
data : {latitude : latitude, longitude : longitude},
type : "GET",
dataType : "html"
}).done(function(msg) {
$("#ajax").html(msg);
}).fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
function displayPosition(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
alert("Latitude: " + position.coords.latitude + ", Longitude: " + position.coords.longitude);
}
remove var in both variable. Those two are not visible outside displayPosition. When you use the $.ajax call you're using latitude and longitude declared right under the $(document).raedy() but you never assign nothing to them so they're undefined.
Hope this solve your issue.
P.S. You se the values in the alert because you're using ones from position, not from your variables.
Do not use var inside your displayPosition function. You do not want to declare new variables inside the scope of the function, you want to assign values to the existing variables you declared in the global scope earlier.

JS: How to make a dynamic Google Maps Polyline?

I am working on a Google Map which needs to show:
a KML (floor-plan)
a Polyline which should take its coordinates from a GET response, each 5 seconds.
I would like the polyline to update itself with the new coordinates that arrives from the RESTful API.
This is the code [updated]:
var FlightPath1 = []
$(document).ready(function() {
var BASE_URL = "https://its.navizon.com/api/v1/sites/" //Do not change this
SITE_ID = "1001" // Your site ID here
MAC_add = "00:1E:8F:92:D0:56" //Mac address of the device to track
USERNAME = "demo#navizon.com" // Your username
PASSWORD = "" // Your password
var Path1=new google.maps.Polyline({
path:FlightPath1,
strokeColor:"#F020FF",
strokeOpacity:0.8,
strokeWeight:2
});
// Send the request
jQuery.support.cors = true; // Enable cross-site scripting
function makeCall() {
$.ajax({
type: "GET",
url: BASE_URL + SITE_ID + "/stations/" + MAC_add + "/",
beforeSend: function(jqXHR) {
jqXHR.setRequestHeader("Authorization", "Basic " + Base64.encode(USERNAME + ":" + PASSWORD));
},
success: function(jimmi) {
// Output the results
if (typeof jimmi === "string") {
jimmi = JSON.parse(jimmi);
}
//Display the results
FlightPath1.push("new google.maps.LatLng(" + jimmi.loc.lat + "," + jimmi.loc.lng + "),");
var mapOptions = {
zoom: 19,
center: new google.maps.LatLng(jimmi.loc.lat,jimmi.loc.lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var SanDiegoKML = new google.maps.KmlLayer({
url: 'https://s3.amazonaws.com/navizon.its.fp/1001/05w0kyw829_a.kml'
});
SanDiegoKML.setMap(map);
google.maps.event.addDomListener(window, 'load', jimmi);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error');
}
});
window.setTimeout(makeCall, 5000); //run the script each 5000 milliseconds
}
makeCall();
})
But I nothing happens. And I get no errors neither.
Could some one help me?
Thanks..
Two issues:
The necessary var, Path1 is internal and private to initialize(), therefore out of scope with regard to the ajax success function which is in an entirely different scope.
The ajax success function does nothing other than to push a string derived from the response onto an array. Doing so will not, in itself, affect the polyline.
Fix (1) first, then (2).

Categories