Wc3 Geolocation API accuracy discrepancies/differences when additional apps are running on android - leaflet

I'm running into a discrepancy with accuracy with the geolocation api.
When I run this site locally on the web with wifi I receive ~ 20m accuracy.
I put this site up and access it with my phone just on cell data and I receive about ~ 20m accuracy.
When I turn on another app (e.g. strava) and start using GPS to track myself in strava, I then go back to my web app and the accuracy is ridiculously good. I turn strava tracking off and the accuracy drops again.
So my assumption here is that my web app piggybacks on the fact that strava is getting really good location data.
Is there a way to get the good accuracy without needing to turn on a another app?
Alternatively, does anybody know how to get better accuracy with browser based geolocation from the getgo on cell data?
I have researched the forums and haven't seen this exact question yet. Apologies if the answer is out there and if you have a link I'd appreciate the share!
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""
/>
<style>
body {
margin: 0;
padding: 0;
}
#map {
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
<script
src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""
></script>
<script>
var map_init = L.map("map", {
center: [43.030027, -71.890484],
zoom: 14,
});
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0,
};
var osm = L.tileLayer(
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
attribution:
'© OpenStreetMap contributors',
}
).addTo(map_init);
if (!navigator.geolocation) {
console.log("Your browser doesn't support geolocation feature!");
} else {
setInterval(() => {
navigator.geolocation.getCurrentPosition(getPosition);
});
}
var marker, circle, lat, long, accuracy;
function getPosition(position, options) {
// console.log(position)
lat = position.coords.latitude;
long = position.coords.longitude;
accuracy = position.coords.accuracy;
if (marker) {
map_init.removeLayer(marker);
}
if (circle) {
map_init.removeLayer(circle);
}
marker = L.marker([lat, long]);
circle = L.circle([lat, long], { radius: accuracy });
var featureGroup = L.featureGroup([marker, circle]).addTo(map_init);
map_init.fitBounds(featureGroup.getBounds());
console.log(
"Your coordinate is: Lat: " +
lat +
" Long: " +
long +
" Accuracy: " +
accuracy
);
}
</script>
</body>
</html>

Related

Leaflet: GeoJSON (via fetch url) does not display marker popup

I am trying to display open radioactivity data from the German Agency for Protection of Radiation (https://www.imis.bfs.de/geoportal/).
They have a nice GeoJson API.
I can display the individual markers (points of radioactivity sensors), but cannot display the value feature.properties.value in a popup.
I tried onEachFeature but somehow it did not work. I searched for quite a bit, but could not find a solution
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Radioaktivität</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="map"></div>
<script src="script.js"></script>
</body>
</html>
JavaScript:
let config = {
minZoom: 2,
maxZoom: 18,
};
const zoom = 7;
const lat = 51.7036;
const lng = 10.2166;
const map = L.map("map", config).setView([lat, lng], zoom);
let url = 'https://www.imis.bfs.de/ogc/opendata/ows?service=WFS&version=1.1.0&request=GetFeature&typeName=opendata:odlinfo_odl_1h_latest&outputFormat=application/json';
const response = fetch(url)
.then(response => response.json())
.then(response => {
L.geoJson(response, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.value);
}
}).addTo(map);
});

How to automatically update Mapbox when a website updated

I am looking to add markers to Mapbox. These markers will contain links to other websites and I am looking to automatically plot real-time data on the map when the website updates its articles, with a link to the website + shortened version of whatever is being said on the article. Could anyone share any tips?
Can you please share what you have done so far?
You question is very general. Therefore I can only advise to not update the complete website with each change, but use jQuery and update changes incrementally.
In Mapbox, you can add layers. These layers have data sources. When you update the data sources for the layers (that already have been created), the data displayed will be updated with them.
Pleas see this example that adds a periodically updating layer:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add live realtime data</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.0.0/mapbox-gl.css" rel="stylesheet" />
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = "<Access Token>";
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
zoom: 0
});
var url = 'https://wanderdrone.appspot.com/';
map.on('load', function () {
var request = new XMLHttpRequest();
window.setInterval(function () {
// make a GET request to parse the GeoJSON at the url
request.open('GET', url, true);
request.onload = function () {
if (this.status >= 200 && this.status < 400) {
// retrieve the JSON from the response
var json = JSON.parse(this.response);
// update the drone symbol's location on the map
map.getSource('drone').setData(json);
// fly the map to the drone's current location
map.flyTo({
center: json.geometry.coordinates,
speed: 0.5
});
}
};
request.send();
}, 2000);
map.addSource('drone', { type: 'geojson', data: url });
map.addLayer({
'id': 'drone',
'type': 'symbol',
'source': 'drone',
'layout': {
'icon-image': 'rocket-15'
}
});
});
</script>
</body>
</html>

Using Turf with Leaflet

I've made a leaflet map and was trying to implement turf.
As a quick test, I just wanted to put a buffer around one of my markers. But somehow I can still only see the two markers on my map. I basically followed the steps from this document. https://lib.dr.iastate.edu/gis_tasksheets/3/
I'm not sure where I made a mistake, I hope someone can tell me.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Leaflet Map"</title>
<!-- leaflet.css, leaflet.js, turf.js von externer Quelle einbinden -->
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.4.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.4.0/dist/leaflet.js"></script> <!-- Load Leaflet code library-->
<script src='https://cdnjs.cloudflare.com/ajax/libs/leaflet-omnivore/0.3.4/leaflet-omnivore.min.js'></script> <!-- Load Omnivore to convert CSV to GeoJSON format -->
<script src="http://code.jquery.com/jquery-3.5.1.min.js"></script><!-- Load jQuery and PapaParse to read data from a CSV file -->
<script src="https://cdn.jsdelivr.net/npm/papaparse#5.3.0/papaparse.min.js"></script>
<script src='https://unpkg.com/#turf/turf/turf.min.js'></script>
<script>
var buffered = turf.buffer(point);
</script>
</head>
<body>
<div id='Karte' style='height: 800px; width: 100%;'></div>
<script type='text/javascript'>
var Karte = L.map('Karte').setView([48.896465, 10.996526], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
'attribution': 'Kartendaten © OpenStreetMap Mitwirkende',
'useCache': true
}).addTo(Karte);
var marker1 = L.marker([48.896465, 10.996526]).addTo(Karte);
var marker2 = L.marker([48.892750, 10.990300]).addTo(Karte);
var point = turf.point([48.896465, 10.996526]);
var buffered = turf.buffer(point, 50, {units: 'meter'});
buffer = L.geoJSON(buffered);
buffer.addTo(Karte);
</script>
</body>
</html>
Turf use geojson and geojson has the coordinate format lnglat, leaflet has latlng.
You have to swap your coords in the turf.point function:
var point = turf.point([10.996526,48.896465]);
Update
Remove also following:
<script>
var buffered = turf.buffer(point);
</script>
And change meter to meters
{units: 'meters'}
Demo
Be careful, leaflet works with [lat, lon] coordinates while geoJSON (and turf) is [lon, lat].
var coords1 = [48.896465, 10.996526];
var coords2 = [48.892750, 10.990300];
var marker1 = L.marker(coords1).addTo(Karte);
var marker2 = L.marker(coords2).addTo(Karte);
//add buffers
var point1 = turf.point([coords1[1], coords1[0]]);
var buffered1 = turf.buffer(point1, 50, {units: 'meters'})
L.geoJSON(buffered1).addTo(Karte);
var point2 = turf.point([coords2[1], coords2[0]]);
var buffered2 = turf.buffer(point2, 50, {units: 'meters'})
L.geoJSON(buffered2).addTo(Karte);
Check fiddle: https://jsfiddle.net/rp1320mf/
I would also like to add a note. Working with buffers or doing other distance-related tasks may be very inaccurate in Geographic Coordinate Systems. You should use it only if you dont really care about accuracy.

Microsoft bing maps pushpin (web javascript)

Is it possible to create pushpins from addresses instead of lat/long data?
I guess the pushpin constructor accepts only locations which are a lat/long representation of the location.
new Microsoft.Maps.Pushpin(value)
Is there any solution for creating pushpins from addresses.
Here is a sample code showing you how to find a location by address:
<!DOCTYPE html>
<html>
<head>
<title>searchbyaddressHTML</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<style type='text/css'>body{margin:0;padding:0;overflow:hidden;font-family:'Segoe UI',Helvetica,Arial,Sans-Serif}</style>
</head>
<body>
<div id='printoutPanel'></div>
<div id='myMap' style='width: 100vw; height: 100vh;'></div>
<script type='text/javascript'>
function loadMapScenario() {
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {
/* No need to set credentials if already passed in URL */
center: new Microsoft.Maps.Location(47.624527, -122.355255),
zoom: 8 });
Microsoft.Maps.loadModule('Microsoft.Maps.Search', function () {
var searchManager = new Microsoft.Maps.Search.SearchManager(map);
var requestOptions = {
bounds: map.getBounds(),
where: 'Washington, DC',
callback: function (answer, userData) {
map.setView({ bounds: answer.results[0].bestView });
map.entities.push(new Microsoft.Maps.Pushpin(answer.results[0].location));
}
};
searchManager.geocode(requestOptions);
});
}
</script>
<script type='text/javascript' src='https://www.bing.com/api/maps/mapcontrol?key=YourBingMapsKey&callback=loadMapScenario' async defer></script>
</body>
</html>

Leaflet : remove layer if zoom level greater than 9

I built a heatmap on Leaflet.
My first goal is to see the heatmap when you open the map. The second goal is not to view the heatmap if the zoom level is greater than 9.
I tried this :
if (map.getZoom() >9 {
map.removeLayer (heatmapLayer);
};
But it did not work.
Would you have any suggestions ?
Thanks !
Here is the code :
<!DOCTYPE html>
<html lang="en">
<head>
<title>Application - version 1.0</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.6.3/leaflet.css" />
<link rel="stylesheet" href="style_p.css" />
<style type="text/css">
html, body, #map {
margin: 0;
margin-top: 0%;
width: 100%;
height: 100%;
};
</style>
</head>
<!-- Favicon -->
<link rel="icon" href="california.ico" />
<body>
<div id="map"></div>
<script src="http://cdn.leafletjs.com/leaflet-0.6.3/leaflet-src.js"></script>
<script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
<script src="jquery.js"></script>
<script type="text/javascript" src="heatmap.js"></script>
<script type="text/javascript" src="heatmap-leaflet.js"></script>
<script type="text/javascript" src="sloopjohnb.js"></script>
<script src="google.js"></script>
<script src="leaflet_search.js"></script>
<script type="text/javascript" charset="utf-8">
$(function() {
var osm = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
var base = new L.TileLayer('http://129.206.74.245:8001/tms_r.ashx?x={x}&y={y}&z={z}');
var ggl2 = new L.Google('SATELLITE');
var heatmapLayer;
heatmapLayer = L.TileLayer.heatMap({
radius: 10,
opacity: 0.8,
gradient: {
0.45: "rgb(0,0,255)",
0.55: "rgb(0,255,255)",
0.65: "rgb(0,255,0)",
0.95: "yellow",
1.0: "rgb(255,0,0)"
}
});
var Data1={
max: 1,
data: sloopjohnb
};
heatmapLayer.addData(Data1.data);
var baseMaps = {
"Fond OSM": osm,
"Fond de carte de base": base,
"Photo. aérienne Google" : ggl2
};
var overlayMaps = {
'Heatmap': heatmapLayer
};
map = new L.Map('map', {
minZoom : 1,
maxZoom : 11,
boxZoom : true,
layers: [base, heatmapLayer]
});
var controls = L.control.layers(baseMaps, overlayMaps, {position: 'bottomright'});
controls.addTo(map);
map.addControl(L.control.search());
L.control.scale().addTo(map);
map.attributionControl.addAttribution('Heatmap.js');
map.setView(new L.LatLng(39.291,-5.9765),2);
// Disparition de la heatmap en fct du zoom
map.on('zoomend', function () {
if (map.getZoom() > 9) {
map.removeLayer(heatmapLayer);
}
});
});
</script>
</body>
</html>
Are you sure you are creating the listener correctly?
For example, this seems like it should be called when the user zooms. So something like:
Edited
map.on('zoomend', function () {
if (map.getZoom() > 9 && map.hasLayer(heatmapLayer)) {
map.removeLayer(heatmapLayer);
}
if (map.getZoom() < 9 && map.hasLayer(heatmapLayer) == false)
{
map.addLayer(heatmapLayer);
}
});
If you ONLY want the layer added/removed based on zoom, don't add it to your layer control here:
var controls = L.control.layers(baseMaps, overlayMaps, {position: 'bottomright'});
controls.addTo(map);
You will just have to make sure you are doing your adding/removing when it is necessary. Try messing with this set up a little and see where you get. Also, the Documentation is well written regarding the use of L.tileLayer
You can use the leaflet-zoom-show-hide library to do it. This will automatically show/hide your layers as you zoom.
zsh = new ZoomShowHide(map);
var marker1 = L.marker([50.096, 14.425]);
// minzoom, maxzoom
zsh.addLayer(marker1, 10, 13);
var marker2 = L.marker([50.076, 14.425]);
zsh.addLayer(marker2, 8, null);