Geographic Information Systems Asked by larry chambers on February 28, 2021
I have an app working in node.js that locates a user and plots their location on a leaflet map. When others connect it shows them too. It keeps their marker live as long as they move the mouse.
I would like to change a couple of things but not sure where to start:
I know I can use the watch feature but not sure where to add it.I will include the application.js code with is where the map locate and placing the marker code is.
The application.js
$(function() {
// generate unique user id
var userId = Math.random().toString(16).substring(2,15);
var socket = io.connect('/');
socket.emit('little_newbie', username);
var map;
var info = $('#infobox');
var doc = $(document);
// custom marker's icon styles
var tinyIcon = L.Icon.extend({
options: {
shadowUrl: '../assets/marker-shadow.png',
iconSize: [25, 39],
iconAnchor: [12, 36],
shadowSize: [41, 41],
shadowAnchor: [12, 38],
popupAnchor: [0, -30]
}
});
var redIcon = new tinyIcon({ iconUrl: '../assets/marker-red.png' });
var yellowIcon = new tinyIcon({ iconUrl: '../assets/marker-yellow.png' });
var sentData = {};
var connects = {};
var markers = {};
var active = false;
socket.on('load:coords', function(data) {
if (!(data.id in connects)) {
setMarker(data);
}
connects[data.id] = data;
connects[data.id].updated = $.now();
});
// check whether browser supports geolocation api
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(positionSuccess, positionError, { enableHighAccuracy: true });
} else {
$('.map').text('Your browser is out of fashion, there's no geolocation!');
}
function positionSuccess(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
var acr = position.coords.accuracy;
// mark user's position
var userMarker = L.marker([lat, lng], {
icon: redIcon
});
// uncomment for static debug
// userMarker = L.marker([51.45, 30.050], { icon: redIcon });
// load leaflet map
map = L.map('map').fitWorld();
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
userMarker.addTo(map);
userMarker.bindPopup('<p>You are here ' + username + '</p>').openPopup();
var emit = $.now();
// send coords on when user is active
doc.on('mousemove', function() {
active = true;
sentData = {
id: userId,
active: active,
coords: [{
lat: lat,
lng: lng,
acr: acr,
name: username
}]
};
if ($.now() - emit > 1) {
socket.emit('send:coords', sentData);
emit = $.now();
}
});
}
doc.bind('mouseup mouseleave', function() {
active = false;
});
// showing markers for connections
function setMarker(data) {
for (var i = 0; i < data.coords.length; i++) {
var num = +$("#count").text() + 1;
$("#count").text(num);
var marker = L.marker([data.coords[i].lat, data.coords[i].lng], { icon: yellowIcon }).addTo(map);
marker.bindPopup('<p>One more external user is here!</p>' + data.coords[i].name);
markers[data.id] = marker;
}
}
// handle geolocation api errors
function positionError(error) {
var errors = {
1: 'Authorization fails', // permission denied
2: 'Can't detect your location', //position unavailable
3: 'Connection timeout' // timeout
};
showError('Error:' + errors[error.code]);
}
function showError(msg) {
info.addClass('error').text(msg);
doc.click(function() {
info.removeClass('error');
});
}
// delete inactive users every 15 sec
setInterval(function() {
for (var ident in connects){
if ($.now() - connects[ident].updated > 200000) {
var num = +$("#count").text() - 1;
$("#count").text(num);
delete connects[ident];
map.removeLayer(markers[ident]);
}
}
}, 15000);
});
Fully working, rewritten. Just adding it to show how it should of been done from the start and to help anyone else that wants to do something similar
server.js
var http = require('http');
var Static = require('node-static');
var app = http.createServer(handler);
var io = require('socket.io').listen(app);
var port = 8080;
var active = false;
var update = false;
var users = [];
var files = new Static.Server('./public');
function handler(request, response) {
request.on('end', function() {
files.serve(request, response);
}).resume();
}
io.on('connection', (socket) => {
var addedUser = false;
socket.on('add user', (username) => {
if (addedUser) return;
socket.username = username;
var new_count = users.length;
console.log(new_count);
var new_user = {
username: username,
active: active,
lat: null,
lng: null,
update: false
};
users.push(new_user);
console.log(users);
});
socket.on('new_coords', (data) => {
var New_Details = {
username: data.username,
active: data.active,
lat: data.new_lat,
lng: data.new_lng,
update: true
};
var checkuser = data.username;
result = users.map(obj => obj.username).indexOf(checkuser) >= 0;
if (result === true) {
objIndex = users.findIndex((obj => obj.username == data.username));
users[objIndex].lat = data.new_lat;
users[objIndex].lng = data.new_lng;
users[objIndex].active = data.active;
users[objIndex].update = true;
var to_send = {
username: data.username,
active: true,
lat: data.new_lat,
lng: data.new_lng,
update: true
};
console.log(data.username + ' has just updated their location');
var new_count = users.length;
console.log(new_count);
console.log(users);
socket.broadcast.emit('updatecoords', to_send);
objIndex = users.findIndex((obj => obj.username == data.username));
users[objIndex].update = false;
}
});
socket.on('load_init', (data) => {
socket.emit('load_init', users);
})
socket.on('disconnect', () => {
for (var i = 0; i < users.length; i++)
if (users[i].username === socket.username) {
socket.broadcast.emit('remove_marker', {
username: users[i].username
});
users.splice(i, 1);
break;
}
var new_count = users.length;
console.log(new_count);
console.log('remove marker');
});
});
app.listen(port);
console.log('Your server goes on localhost:' + port);
and viewer.html
<!DOCTYPE html>
<html>
<head>
<title>Multiple user tracker</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var username = prompt('What's your username?');
var tinyIcon = L.Icon.extend({
options: {
shadowUrl: '../assets/marker-shadow.png',
iconSize: [25, 39],
iconAnchor: [12, 36],
shadowSize: [41, 41],
shadowAnchor: [12, 38],
popupAnchor: [0, -30]
}
});
var redIcon = new tinyIcon({
iconUrl: '../assets/marker-red.png'
});
var yellowIcon = new tinyIcon({
iconUrl: '../assets/marker-yellow.png'
});
socket = io.connect('/');
socket.emit('add user', username);
</script>
<style>
body {
padding: 0;
margin: 0;
}
html,
body,
#map {
height: 100vh;
width: 100vw;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
function initializeMapAndLocator() {
var markers = {};
var mymarker;
var map = L.map('map');
googleStreets = L.tileLayer('https://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 18,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3']
}).addTo(map);
map.locate({
setView: true,
maxZoom: 20
});
function onLocationFound(e) {
var radius = e.accuracy / 2;
map.locate({
setView: false,
timeout: 60000,
enableHighAccuracy: true
});
var newlatlng = e.latlng;
const new_lat = newlatlng.lat;
const new_lng = newlatlng.lng;
var Details = {
username: username,
active: true,
new_lat: new_lat,
new_lng: new_lng,
update: true
};
socket.emit('new_coords', Details);
if (map.hasLayer(mymarker)) {
map.removeLayer(mymarker);
}
mymarker = new L.Marker(e.latlng, {
icon: yellowIcon,
draggable: true
});
map.addLayer(mymarker);
mymarker.bindPopup('<p>You are here ' + username + '</p>').openPopup();
}
map.on('locationfound', onLocationFound);
socket.on('load_init', function(data) {
for (var i = 0; i < data.length; i++) {
if (data[i].lat != null) {
markers[data[i].username] = new L.marker([data[i].lat, data[i].lng], {
draggable: true,
icon: redIcon
});
map.addLayer(markers[data[i].username]);
markers[data[i].username].bindPopup('Online :' + data[i].username);
}
}
});
socket.on('updatecoords', function(data) {
if (map.hasLayer(markers[data.username])) {
map.removeLayer(markers[data.username]);
}
markers[data.username] = new L.marker([data.lat, data.lng], {
draggable: true,
icon: redIcon
});
map.addLayer(markers[data.username]);
markers[data.username].bindPopup(data.username + ' is on the move').openPopup();
});
socket.on('remove_marker', function(data) {
map.removeLayer(markers[data.username]);
});
}
socket.emit('load_init');
initializeMapAndLocator();
</script>
</body>
</html>
Answered by larry chambers on February 28, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP