PWA: geoposicionamiento

Creamos unas variables de acceso general (maximumAge indica el tiempo de espera y enableHighAccurancy si queremos posicionamiento preciso):

var geoOptions = { maximumAge: 5 * 60 * 1000, enableHighAccuracy: true };
var lapos = {};

En la pantalla tenemos escondidos un div mensajes y otro cargador. Tenemos un método para manejar el cargador:

function cargadorPos(accion) {
  if(accion === "mostrar") {
    $( "#cargador" ).animate({ opacity: .8 }, { duration: 500, specialEasing: {}, complete: function() {} });
  }else{
    $( "#cargador" ).animate({ opacity: .0 }, { duration: 10, specialEasing: {}, complete: function() {} });
  }
}

Y otro método que maneja los mensajes:

function menPos(dato) {
  // error.code can be: 
  // n: navegador sin geoloacalizacion, 0: unknown error, 1: permission denied, 2: position unavailable (error response from location provider), 3: timed out
  let men = "";
  switch("e"+dato) {
    default: 
      men += '<h2>Lo siento</h2>' + "\n";
      men += '<p>El navegador no acepta la geolocalización</p>' + "\n";
      break;
    case "e1":
      men += '<h2>Error</h2>' + "\n";
      men += '<p>Esta bloqueada la ubicación para el navegador</p>' + "\n";
      men += '<p>Puedes ver como activarlo <a href="https://support.apple.com/es-es/HT207092" target="blank">en esta web</a>.</p>' + "\n";
      break;
    case "e2":
      men += '<h2>Error</h2>' + "\n";
      men += '<p>La posición es ilegible</p>' + "\n";
      break;
    case "e3":
      men += '<h2>Lo siento</h2>' + "\n";
      men += '<p>Tu dispositivo a tardado demasiado en responder.</p>' + "\n";
      men += '<p>Vuelve  a pulsar en el botón para recoger tu ubicación.</p>' + "\n";
      break;
  }
  $("aside").html(men);
  $("aside").css({ display: "block", top: (laH/2) - ($("aside").outerHeight()/2) + "px", left: (laW/2) - ($("aside").outerWidth()/2) + "px" });
}

La llamada a posicionar la hacemos desde un botón que llama al método posiciona:

function posiciona() {
  if (navigator.geolocation) {
    var posTimeoutId = setTimeout(cargadorPos('mostrar'), 5000);
    var geoSuccess = function(position) {
      cargadorPos('esconder');
      clearTimeout(posTimeoutId);
      lapos = position;
      console.log(lapos)
      console.log(lapos.coords.latitude+" : "+lapos.coords.longitude)
      //colocaMarker(map, lapos.coords);
      let markerpos = [lapos.coords.latitude,lapos.coords.longitude];
      let markerpopup = "<p>"+lapos.coords.latitude+" : "+lapos.coords.longitude+"</p>";
      let marker = L.marker(markerpos,{icon: L.icon(iconmap)}).bindPopup(markerpopup,markerpopupstyle).addTo(map);
      map.setView([lapos.coords.latitude,lapos.coords.longitude], configmap.zoomdet);
    }
    var geoError = function(error) { menPos(error.code); }
    navigator.geolocation.getCurrentPosition(geoSuccess, geoError, geoOptions);
  }
  else {
    menPos('n');
  }
}

Obtener la posición del usuario cada vez que ésta cambie

var watch_id = navigator.geolocation.watchPosition(function(objPosition) {
	// Aquí va el código que procesa la posición
}, function(objPositionError) {
	// Aquí va el cópdigo para procesar los errores
}, { maximumAge: 75000, timeout: 15000 });
document.getElementById("stop-button").onclick = function() {
        navigator.geolocation.clearWatch(watch_id);
};

Leer posición

Usamos la propiedad navigator.geolocation y la utilidad promise.

En una función hacemos la llamada a recoger la posición y tras la espera llama a la función respuesta.

getPosition().then(r =>{
    getPositionOk(r);
  }).catch(() => {
    console.log('Algo salió mal');
})

La función getPosition es la que recoge la posición:

function getPosition() {
  return new Promise(function(resolve, reject) {
    navigator.geolocation.getCurrentPosition(
      function(position) { resolve(position); }, 
      function () { reject(); },
      {timeout: 30000, enableHighAccuracy: true, maximumAge: 75000}
    );  
  });
};

La función getPositionOk es la que realiza las acciones una vez tenemos la posición:

function getPositionOk(data) {
  lapos = data;
  $("#conte").html(posicionaBot({latitude:lapos.coords.latitude,longitude:lapos.coords.longitude}));
}

Mostrar un mapa

Usamos la librería leaflet: https://leafletjs.com/

En el html generamos un div en le que cargaremos el mapa:

<div id="map" class="map"></div>

En el css le damos las propiedades:

.map{
	width: 100%;
	display: table;
}

Creamos unas variables de acceso general para el mapa:

var map;
var configmap = { lat: 40.374093, lng: -1.529524, zoom: 3, zoomdet: 12, maxzoom: 18 };
var iconmap = {
  iconUrl: './img/iconpos.png',
  shadowUrl: './img/iconpos_shadow.png',
  iconSize:     [30, 40], // size of the icon
  shadowSize:   [30, 40], // size of the shadow
  iconAnchor:   [15, 40], // point of the icon which will correspond to marker's location
  shadowAnchor: [8, 40],  // the same for the shadow
  popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor
}
var markerpopupstyle = {'maxWidth': '300'};

Si tenemos una cabecera q1ue no queremos tapar, por javascript le damos el alto al mapa para que no se salga de pantalla:

$("#map").css({ top: cabH +0 "px", height: hueco[1] – cabH + "px" });

Colocamos una función para crear el mapa:

map = L.map('map').setView([configmap.lat, configmap.lng], configmap.zoom);
  L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
      maxZoom: configmap.maxzoom
  }).addTo(map);
  map.on('click', function(e) {  });
    marker.bindPopup('<b>'+globals.adtyposiciones[i].momento+'</b>').openPopup();
    latlngs.push([globals.adtyposiciones[i].lat, globals.adtyposiciones[i].lng]);
  }
  // dibujo la linea que une los markers
  let trazado = L.polyline(latlngs, { color: 'red', weight: 3, opacity: 0.5, smoothFactor: 1 }).addTo(map);
  // zoom del mapa a la linea
  map.fitBounds(trazado.getBounds());
}

Si tenemos las coordenadas de una posición, podemos colocar un marcador:

let markerpos = [lapos.coords.latitude,lapos.coords.longitude];
let markerpopup = "<p>"+lapos.coords.latitude+" : "+lapos.coords.longitude+"</p>";
let marker = L.marker(markerpos,{icon: L.icon(iconmap)}).bindPopup(markerpopup,markerpopupstyle).addTo(map);

Centramos el mapa a la marca:

 map.setView([lapos.coords.latitude,lapos.coords.longitude], configmap.zoomdet);

Si tenemos varios puntos podemos unirlos con una linea, para ello hemos guardado la latitud y longitud en un array de arrays, que podemos llamar latlngs:

let trazado = L.polyline(latlngs, { color: 'red', weight: 3, opacity: 0.5, smoothFactor: 1 }).addTo(map)

Si queremos centrar el mapa a un trazado:

map.fitBounds(trazado.getBounds());

Compartir