I'm currently trying to implement a simple map using javascript, openstreetmaps and leaflet.
My problem comes way before that, when calling javascripts geolocation, and confirming the information on the browser I keep getting an error. My current code is the following:
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.2.0/dist/leaflet.css"
integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.2.0/dist/leaflet.js"
integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
crossorigin=""></script>
<style>
#mymap {
width: 100%;
height: 400px;
background-color: grey;
margin-top: 15px;
}
</style>
<script language="javascript">
function initmap(initialLat, initialLong)
{
if(!initialLat || !initialLat.length){
initialLat = 38.01693;
}
if(!initialLong || !initialLong.length){
initialLong = -8.69475;
}
var mymap = this.mymap = L.map('mymap',{
center: [initialLat, initialLong],
zoom: 15
});
var osmUrl='http://tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
L.tileLayer(osmUrl, osmAttrib).addTo( mymap );
}
function getMylocation()
{
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(function (position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
mymap.setView(new L.LatLng(lat, long), 15);
}, function (error) {
switch (error.code) {
case error.PERMISSION_DENIED:
output.innerHTML += "<p>User denied the request for Geolocation.</p>";
break;
case error.POSITION_UNAVAILABLE:
output.innerHTML += "<p>Location information is unavailable.</p>";
break;
case error.TIMEOUT:
output.innerHTML += "<p>The request to get user location timed out.</p>";
break;
case error.UNKNOWN_ERROR:
output.innerHTML += "<p>An unknown error occurred.</p>";
break;
}
});
}
}
</script>
</head>
<body onLoad="javascript:initmap();">
<button id="find-near-btn" onClick="getMylocation()">
Find my location
</button>
<div id="mymap"></div>
<div id="output"></div>
</body>
</html>
When calling the getMyLocation() function using the button, I always end up in the
case error.POSITION_UNAVAILABLE:
condition. Any idea on why this might be happening?
Error is called when position information is unavailable. GeoLocation API estimates location on the basis of CELL Towers, Wifi MAC Addresses, GPS (if on mobile). But the information is not available. Your code is correct, try running that on different device.
Related
I'm trying to make a webpage with a button. When the button clicked the webpage has to display the user's current location and the user's timezone.
I'm locating users' latitude & longitude by jquery and for the location name I use reverse geocoding of google geocode API and for timezone google timezone API.
Function for the latitude & longitude and function for the reverse geocoding works well. But the function for the timezone isn't working. The unworking function I wrote for this API is the last function in the JS code. I don't understand how to solve this problem.
I need someones' help with this.
HTML Part
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
<h1>Hello let's trace your location</h1>
<button onClick="getLocation()">Get Location</button>
<div id="output"></div>
<script language="javascript" type="text/javascript" src="java.js">
</script>
</body>
</html>
JS PART
var x = document.getElementById('output');
function getLocation(){
if (navigator.geolocation){
x.innerHTML = "Supporting";
navigator.geolocation.getCurrentPosition(showPosition);
}
else{
x.innerHTML = "Browser not supporting";
}
}
function showPosition(position){
var locAPI = "https://maps.googleapis.com/maps/api/geocode/json?latlng="+position.coords.latitude.toFixed(6)+","+position.coords.longitude.toFixed(6)+"&key=<key>";
//x.innerHTML += locAPI;
$.get({
url: locAPI,
success: function(data){
console.log(data);
var num = data.results.length - data.results.length;
var add1 = data.results[num].address_components.length - 1;
var add2 = data.results[num].address_components.length - 2;
x.innerHTML = num;
x.innerHTML += add1;
x.innerHTML += add2;
x.innerHTML += data.results[num].address_components[add2].long_name;
x.innerHTML += "<br/>";
x.innerHTML += data.results[num].address_components[add1].long_name;
}
});
}
function showPosition(location){
var timeAPI = "https://maps.googleapis.com/maps/api/timezone/json?location="+location.coords.latitude.toFixed(6)+","+location.coords.longitude.toFixed(6)+"×tamp=<key>";
//x.innerHTML += timeAPI;
$.get({
url:timeAPI,
success:function(data){
console.log(data);
}
});
}
}
I have a web service that queries a database and returns JSON data. I also have a HTML page which has AJAX and a Leaflet map. I have to make the map display markers based on the JSON that returns from the web service.
I cannot figure out what I am doing wrong, I have followed the class notes. I think the problem is the request is not sending. Here is my code
HTML
<!DOCTYPE html>
<html>
<head>
<title>Points of Interest</title>
<link rel="stylesheet" type="text/css" href="custom.css">
<link href="https://fonts.googleapis.com/css?family=Raleway" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="skeleton.css">
<link rel='stylesheet' type='text/css' href='/wad/leaflet/leaflet.css' />
<script type="text/javascript" src="map.js"></script>
<script type='text/javascript' src='/wad/leaflet/leaflet.js'></script>
</head>
<body onload='init()'>
<img src="heroxd.jpg" alt="">
<div class="container">
<div class="twelve-columns">
<h1>Welcome to Points of Interest!</h1>
<p>Linking users to interesting areas for 25 years</p>
<p>Enter a region below to search for POIs!</p>
<input type="text" id="region" class="margin-top-30" placeholder="Enter Region" name="region" />
<input type="submit" id="submit" />
</div>
<div id="jsonload">
</div>
<div id="map1" style="width:800px; height:600px">
<div id="info"></div>
</div>
</body>
</html>
JS
var map;
var attrib;
function init()
{
document.getElementById("submit").addEventListener("click", poiMarkers);
map = L.map ("map1");
attrib="Map data copyright OpenStreetMap contributors, Open Database Licence";
L.tileLayer
("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{ attribution: attrib } ).addTo(map);
if(navigator.geolocation)
{
navigator.geolocation.getCurrentPosition (processPosition, handleError,
{enableHighAccuracy:true, maximumAge: 5000 }
);
}
else
{
alert("Sorry, geolocation not supported in this browser");
}
function processPosition(gpspos)
{
var info = 'Lat: ' + gpspos.coords.latitude + ' lon: ' + gpspos.coords.longitude;
document.getElementById('info').innerHTML = info;
map.setView([gpspos.coords.latitude,gpspos.coords.longitude], 14);
}
function handleError(err)
{
alert('An error occurred: ' + err.code);
}
}
function processPosition(gpspos)
{
var info = 'Lat: ' + gpspos.coords.latitude + ' lon: ' + gpspos.coords.longitude;
document.getElementById('info').innerHTML = info;
map.setView([gpspos.coords.latitude,gpspos.coords.longitude], 14);
}
function handleError(err)
{
alert('An error occurred: ' + err.code);
}
function poiMarkers()
{
var a = document.getElementById('region').value;
var ajaxConnection = new XMLHttpRequest();
ajaxConnection.addEventListener ("load",e =>
{
var allPlaces = JSON.parse(e.target.responseText);
var lat = 0;
var lon = 0;
var poiLocation = "";
allPlaces.forEach( curplace =>
{
lat = `${curPlace.lat}`;
lon = `${curPlace.lon}`;
poiLocation = [lat, lon];
L.marker(poiLocation).addTo(map);
} );
});
// Open the connection to a given remote URL.
ajaxConnection.open("GET" , `https://****return_poi.php?region=${a}`);
// Send the request.
ajaxConnection.send();
}
Try like this:
$.ajax({
url: "https://****return_poi.php?region=${a}",
data: data,
type: "GET",
success: success,
dataType: json
});
Reference: https://api.jquery.com/jquery.get/
or
$.get(URL,data,function(data,status,xhr),dataType)
Reference: https://www.w3schools.com/jquery/ajax_get.asp
I am trying to use web worker threads to grab directions between multiple pairs of locations parallelly and store the text in a file in the end. Everything had gone well in the sequential approach. I am using npm live-server to display the page. But the browser just closes the page instantly after it loads and I don't even get to see what rendered or consult the console for errors. If I use 'async defer' for my script tag with the google Api in index.html, I would get the "UncaughtReferenceError: google is not defined" error. Thanks in advance guys!
Here is my index.html:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
#map {
height: 100%;
width: 100%;
}
html, body {
height: 100%;
margin: 0;
padding: 0;
}
panel {
display: block;
}
</style>
</head>
<body>
<panel></panel>
<div id="map"></div>
<script src=locations.js></script>
<script src='main.js'></script>
<script src='worker.js'></script>
<script src="https://maps.googleapis.com/maps/api/js?key=<API-KEY>&callback=initMap"></script>
</body>
</html>
Here is my main.js:
let worker = new Worker('worker.js');
worker.onmessage = function(info) {
output += info.data;
};
const container = document.querySelector('panel');
let output = ""
function initMap() {
locations.forEach( spot => {
worker.postMessage(spot);
});
download("data.txt", output, 'text/plain');
console.log("Output: " + output);
}
function download(name, text, type) {
const file = new Blob([text], {type: type});
const atag = 'Download';
container.insertAdjacentHTML('afterbegin', atag);
}
And, finally the worker.js:
let directionsService;
let directionsDisplay;
let map;
self.addEventListener('message', (e) => {
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
const mapOptions = {
center: {lat: 30, lng: -90},
zoom: 6
}
map = new google.maps.Map(document.getElementById('map'), mapOptions);
directionsDisplay.setMap(map);
let request = {
origin: 'New Orleans, LA',
destination: e.data,
travelMode: 'DRIVING',
provideRouteAlternatives: false,
drivingOptions: {
departureTime: new Date('September 7, 2018 15:00:00'),
trafficModel: 'pessimistic'
},
unitSystem: google.maps.UnitSystem.IMPERIAL
};
directionsService.route(request, (result, status) => {
if (status == 'OVER_QUERY_LIMIT') {
console.log('over');
}
if (status == 'INVALID_REQUEST'){
console.log('other status')
}
if (status == 'OK') {
var data = result["routes"][0].legs[0];
postmessage(e.data + ", " + data["distance"].text + ", " + data["duration"].text + "\n");
directionsDisplay.setDirections(result);
console.log(result);
}
});
self.close();
});
Web workers have their own scope in Javascript. This means any scripts you loaded in the scope of the web page will not be available in the scope of the web worker.
Usually you use the importScripts call to load a script. However this won't work in your case because you also try to access the DOM in the web worker. This is not possible in a web worker for a number of reason (most important would be concurrent access to a data structure which is not thread save).
Looking at your code I don't think you need a web worker to calculate the routes. Most likely the actual routing is done on one of Googles servers anyway. Since this would be async anyway you do not need to worry about blocking the UI of your web page.
I have just added bing maps and API to my in development site however I am needing some help understanding how to have my code accept live updating lat and long coordinates and have my map update the marker in regards to these values.
Currently this is what I have but part of the code was designed for google maps which I replaced the words google with Microsoft hoping for the best.
Please be gentle I am new to coding
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<script type='text/javascript' src='http://www.bing.com/api/maps/mapcontrol?branch=release&callback=loadMapScenario' async defer></script>
</head>
<body>
<div id='printoutPanel'></div>
<div id='myMap' style='width: 400px; height: 400px;'></div>
<script type='text/javascript'>
// Setting boundary and loading map
function loadMapScenario() {
var bounds = Microsoft.Maps.LocationRect.fromLocations(new Microsoft.Maps.Location(29.332823, -81.492279), new Microsoft.Maps.Location(28.435825, -81.622231));
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
credentials: 'Bing Maps Key',
maxBounds: bounds
});
// Highlighting the border of bounds on the map
var boundsBorder = new Microsoft.Maps.Polyline([bounds.getNorthwest(),
new Microsoft.Maps.Location(bounds.getNorthwest().latitude, bounds.getSoutheast().longitude),
bounds.getSoutheast(),
new Microsoft.Maps.Location(bounds.getSoutheast().latitude, bounds.getNorthwest().longitude),
bounds.getNorthwest()], { strokeColor: 'red', strokeThickness: 2 });
map.entities.push(boundsBorder);
}
</script>
<script>
function getReverseGeocodingData(lat, lng) {
var latlng = new Microsoft.maps.LatLng(lat, lng);
// This is making the Geocode request
var geocoder = new Microsoft.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status !== Microsoft.maps.GeocoderStatus.OK) {
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == Microsoft.maps.GeocoderStatus.OK) {
console.log(results);
var address = (results[0].formatted_address);
}
});
}
</script>
The Bing Maps V8 team actually has a documented code sample on how to do exactly this here: https://msdn.microsoft.com/en-us/library/mt712803.aspx
I'm going through Foursquare's tutorial and am getting this error message when I try to load the page:
Connecting failed
This app has a configuration problem and was unable
to connect to your Foursquare account.
Cause of error: Callback uri is not valid for this consumer
The code is the exact same as the sample code with my credentials subbed in. Is my Foursquare Client id not the right thing to use as the apiKey under config?
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>foursquare :: Explore Sample</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript" id="jquery"></script>
<link href="/styles/leaflet.css" type="text/css" rel="stylesheet" />
<link href="/styles/apisamples.css" type="text/css" rel="stylesheet" />
<script src="/scripts/apisamples.js" type="text/javascript"></script>
<script src="/scripts/third_party/jquery.ba-bbq.js" type="text/javascript"></script>
<script src="/scripts/third_party/leaflet.js" type="text/javascript"></script>
<script src="/scripts/third_party/wax.leaf.min.js" type="text/javascript"></script>
<style type="text/css">
html { height: 100%; }
body { height: 100%; margin: 0; padding: 0; }
/* Give our markers a background image */
.leaflet-marker-icon {
background: url(https://foursquare.com/img/pin-blue-transparent.png);
padding: 6px;
padding-bottom: 17px;
top: -6px;
left: -6px;
}
</style>
<script type="text/javascript">
var config = {
apiKey: '[my Foursquare Client id]',
authUrl: 'https://foursquare.com/',
apiUrl: 'https://api.foursquare.com/'
};
//<![CDATA[
/* Attempt to retrieve access token from URL. */
function doAuthRedirect() {
var redirect = window.location.href.replace(window.location.hash, '');
var url = config.authUrl + 'oauth2/authenticate?response_type=token&client_id=' + config.apiKey +
'&redirect_uri=' + encodeURIComponent(redirect) +
'&state=' + encodeURIComponent($.bbq.getState('req') || 'users/self');
window.location.href = url;
};
if ($.bbq.getState('access_token')) {
// If there is a token in the state, consume it
var token = $.bbq.getState('access_token');
$.bbq.pushState({}, 2)
} else if ($.bbq.getState('error')) {
} else {
doAuthRedirect();
}
/* HTML 5 geolocation. */
navigator.geolocation.getCurrentPosition(function(data) {
var lat = data['coords']['latitude'];
var lng = data['coords']['longitude'];
/* Create map. */
var map = new L.Map('map_canvas')
.setView(new L.LatLng(lat, lng), 15);
var mapboxUrl = 'http://a.tiles.mapbox.com/v3/[my Mapbox username].[my map id].jsonp';
wax.tilejson(mapboxUrl, function(tilejson) {
map.addLayer(new wax.leaf.connector(tilejson));
});
/* Query foursquare API for venue recommendations near the current location. */
$.getJSON(config.apiUrl + 'v2/venues/explore?ll=' + lat + ',' + lng + '&oauth_token=' + window.token, {}, function(data) {
venues = data['response']['groups'][0]['items'];
/* Place marker for each venue. */
for (var i = 0; i < venues.length; i++) {
/* Get marker's location */
var latLng = new L.LatLng(
venues[i]['venue']['location']['lat'],
venues[i]['venue']['location']['lng']
);
/* Build icon for each icon */
var leafletIcon = L.Icon.extend({
iconUrl: venues[i]['venue']['categories'][0]['icon'],
shadowUrl: null,
iconSize: new L.Point(32,32),
iconAnchor: new L.Point(16, 41),
popupAnchor: new L.Point(0, -51)
});
var icon = new leafletIcon();
var marker = new L.Marker(latLng, {icon: icon})
.bindPopup(venues[i]['venue']['name'], { closeButton: false })
.on('mouseover', function(e) { this.openPopup(); })
.on('mouseout', function(e) { this.closePopup(); });
map.addLayer(marker);
}
})
})
//]]>
</script>
</head>
<body>
<div style="width: 100%; height: 100%;" id="map_canvas"></div>
</body>
</html>
Cause of error: Callback uri is not valid for this consumer
A callback url is a webpage loaded after your web app has been verified. In this case, you need to specify a page for to send data to after authentication.
Double check your Foursquare credentials and update the callback uri to a valid link. The tutorial your shared uses https://developer.foursquare.com/docs/samples/explore, but you'll need to specify the url where this page is hosted.