pasosdeJesus/sivel2_gen

View on GitHub
app/javascript/controllers/mapaosm_controller.js

Summary

Maintainability
F
4 days
Test Coverage
import { Controller } from "@hotwired/stimulus"

import Msip__Motor from "../msip/motor"


export default class extends Controller {

  connect() {
    console.log("Conexion de controlador Mapa osm");
    const usuarioAutenticado = this.data.get("usuarioAutenticado") === 'true';
    if (!this.constructor.marcadores) {
      this.constructor.marcadores = L.markerClusterGroup();
    }
    if (!this.constructor.mapa) {
      this.constructor.mapa = L.map('mapa-osm',
        {
          zoomControl:
          false,
          minZoom:
          2
        })
      this.constructor.mapa.on('zoomend', this.onMapZoom.bind(this));
    }
    if (!this.constructor.baldosasOsm) {
      this.constructor.baldosasOsm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        {
          attribution:'© Contribuyentes de' +
          '<a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        });
    }
    if (!this.constructor.info) {
      this.constructor.info = L.control();
    }
    if (!this.constructor.agregaCapaDiv) {
      this.constructor.agregaCapaDiv = L.control();
    }
    if (!this.constructor.controlCapas) {
      var capasBase =
        {
          "OpenStreetMap": this.constructor.baldosasOsm,
          "Satelite (ArcGIS)":
          L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'),
          "Oscuro (CartoDB)":
          L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png')
        };

      this.constructor.controlCapas =
        L.control.layers(capasBase,
          this.leerCapasSuperpuestas(),
          {
            position:
            'topleft'
          });
    }
    this.presentarMapaOsm(usuarioAutenticado);
  }

  filtrar(){
    this.constructor.marcadores.clearLayers();
    var usuario_aut_global = true;
    this.agregarCasosOsm(usuario_aut_global);
  }

  filtrar_adicionales() {
    return [];
  }

  agregarFuncionesExternasMapaosm() {
    return null;
  }

  leerCapasSuperpuestas() {
    var capasSuperpuestas = {
      "Transporte (OpenPtmap)": L.tileLayer('http://www.openptmap.org/tiles/{z}/{x}/{y}.png'),
    };
    return capasSuperpuestas;
  }

  presentarMapaOsm(usuario_autenticado) {
    var usuario_aut_global = usuario_autenticado;
    // Borrar clase container y ocultar pie de página
    document.querySelector('.navbar').classList.add('navbarosm');
    document.querySelector('.card-body').classList.add('cardbodyosm');
    document.querySelector('.card').classList.add('cardosm');

    var pageHeader = document.querySelector('.page-header');
    if (pageHeader) {
      pageHeader.remove();
    }

    var container = document.querySelector('.container');
    if (container) {
      container.classList.add('divcontenido');
      container.classList.remove('container');
    }

    var divContenido = document.getElementById('div_contenido');
    if (divContenido) {
      divContenido.style.position = 'relative';
      divContenido.classList.remove('container');
      divContenido.classList.add('container-fluid');
    }

    var piePagina =document.getElementById('pie_pagina');
    if (piePagina) {
      piePagina.style.display
        = 'none';
    }

    var filtro = L.control({
      position: 'topleft'
    });
    filtro.onAdd = function(mapa){
      this._div = document.getElementById('filtro-osm');
      return this._div;
    };

    //Carga funciones externas implementadas en otras aplicaciones que usan este mapa
    this.agregarFuncionesExternasMapaosm();
    if (document.getElementById('agrega-capa')
      !==
      null
      &&
      document.getElementById('descarga-capa')
      !==
      null)
    {
      var descargamapaBtn =L.control({
        position:
        'bottomleft'
      });
      descargamapaBtn.onAdd = function(mapa){
        this._div = document.getElementById('descarga-mapa');
        return this._div;
      };

      var agregaCapaBtn = L.control({
        position:
        'bottomleft'
      });
      agregaCapaBtn.onAdd = function(mapa)
      {
        this._div = document.getElementById('agregaCapa');
        return this._div;
      };

      this.constructor.mapa.addLayer(this.constructor.baldosasOsm)
        .addControl(filtro)
        .addControl(L.control.zoom({
          position:
          'topleft'
        }))
        .setView(["4.6682", "-74.071"],
          6)
        .addControl(this.constructor.controlCapas)
        .addControl(agregaCapaBtn)
        .addControl(descargamapaBtn);
    }
    else
    {
      this.constructor.mapa.addLayer(this.constructor.baldosasOsm)
        .addControl(filtro)
        .addControl(L.control.zoom({
          position:
          'topleft'
        }))
        .setView(["4.6682", "-74.071"], 6)
        .addControl(this.constructor.controlCapas);
    }

    L.control.scale({
      imperial:
      false
    }).addTo(this.constructor.mapa);

    window.setTimeout(() =>
      this.agregarCasosOsm(usuario_autenticado),
      0);
  }

  onMapZoom() {
    this.constructor.info.remove(this.constructor.mapa);
    this.constructor.agregaCapaDiv.remove(this.constructor.mapa);
  }

  mostrarCargador() {
    document.getElementById('cargador').style.display = 'block';
  }

  ocultarCargador() {
    document.getElementById('cargador').style.display = 'none';
  }

  descargarUrl(url, retrollamada) {
    var request = window.ActiveXobject ?
      new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
    request.onreadystatechange = function() {
      if (request.readyState === 4) {
        retrollamada(request);
      }
    };
    request.open('GET', url, true);
    request.send(null);
  }

  // Construye URL para consulta agregando el punto de montaje antes de
  // // ruta_sin_puntoMontaje y los filtros acordes a lo elegido a continuación

  armarRutaConsulta(rutaSinPuntomontaje, usuarioAutenticado) {
    var ruta = window.puntoMontaje + rutaSinPuntomontaje;
    var desde = document.getElementById('campo-desde').value;
    var hasta = document.getElementById('campo-hasta').value;
    var departamento = document.getElementById('departamento').value;
    var prresp = document.getElementById('presponsable').value;
    var tvio = document.getElementById('tvio').value;
    var fechainicial = Date.parse(desde);
    var fechafinal = Date.parse(hasta);
    if (+fechainicial > +fechafinal) {
      alert("La fecha Final debe ser más antigua que la inicial");
      window.location.reload();
      return;
    }
    var urlSolicitud = ruta + '?filtro[q]=' +
      '&filtro[fechaini]=' + desde +
      '&filtro[fechafin]=' + hasta;
    if (departamento !== undefined && departamento !== '0') {
      urlSolicitud += '&filtro[departamento_id]=' + departamento;
    }
    if (prresp !== undefined && prresp !== '0') {
      urlSolicitud += '&filtro[presponsable_id]=' + prresp;
    }
    if (tvio !== undefined && tvio !== '0') {
      urlSolicitud += '&filtro[categoria_id]=' + tvio;
    }
    var filtros_adicionales = this.filtrar_adicionales(usuarioAutenticado);
    for (var fi in filtros_adicionales) {
      if (filtros_adicionales.hasOwnProperty(fi)) {
        urlSolicitud += filtros_adicionales[fi];
      }
    }
    urlSolicitud += '&filtro[inc_fecha]=1&filtro[inc_ubicaciones]=2' +
      '&filtro[disgenera]=reprevista.json' +
      '&idplantilla=reprevista' +
      '&commit=Enviar';
    return urlSolicitud;
  }

  agregarCasosOsm(usuario_autenticado) {
    if (typeof window.formato_fecha === 'undefined') {
      Msip__Mootr.preparaEventosComunes();
    }
    var urlSolicitud = this.armarRutaConsulta('casos.json', usuario_autenticado);
    this.mostrarCargador();
    const self = this;
    this.descargarUrl(urlSolicitud, function(req) {
      var data = req.responseText;
      if (data === null || data.charAt(0) !== '{') {
        document.getElementById('cargador').style.display = 'none';
        document.getElementById('nrcasos').innerHTML = "0";
        window.alert("El URL " + urlSolicitud + " no retornó información JSON.\n\n" + data);
        return;
      }
      var listaMarcadores = [];
      var o = JSON.parse(data);
      var numResultados = 0;
      for (var codigo in o) {
        if (o.hasOwnProperty(codigo)) {
          var lat = o[codigo].latitud;
          var lng = o[codigo].longitud;
          if (!lat || lat === 'NaN' || !lng || lng === 'NaN') {
            continue;
          }
          var latf = parseFloat(lat);
          var lngf = parseFloat(lng);
          numResultados++;
          var punto = new L.LatLng(latf, lngf);
          listaMarcadores.push(self.creaMarcador(punto, codigo));
        }
      }
      //Crea los cúmulos de casos y agrega casos
      self.constructor.marcadores.addLayers(listaMarcadores);
      self.constructor.mapa.addLayer(self.constructor.marcadores);
      document.getElementById('nrcasos').innerHTML = numResultados + ' Casos mostrados';
      self.ocultarCargador();
    });
  }

  creaMarcador(punto, codigo, titulo) {
    // Exportar los casos a formato GeoJson
    var marcadorCaso = new L.Marker(punto);
    // Acción al hacer clic en caso en el mapa
    marcadorCaso.on('click', clicMarcadorCaso);
    const self = this;
    function clicMarcadorCaso() {
      self.mostrarCargador();
      Msip__Motor.arreglarPuntomontaje();
      var ruta = window.puntoMontaje + 'casos/';
      var urlSolicitud = ruta + codigo + ".json";  
      self.descargarUrl(urlSolicitud, function(req) {
        var data = req.responseText;
        if (data == null || data.substr(0, 1) != '{') {
          document.getElementById('cargador').style.display = 'none';
          window.alert("El URL " + urlSolicitud + " no retornó detalles del caso\n " + data);
          return;
        }
        var o = JSON.parse(data);
        var id = (typeof o['caso'].id != 'undefined') ? o['caso'].id : -1;
        var titulo = (typeof o['caso'].titulo != 'undefined') ? o['caso'].titulo : '';
        var hechos = (typeof o['caso'].hechos != 'undefined') ? o['caso'].hechos : '--';
        var fecha = o['caso'].fecha; 
        var hora = o['caso'].hora; 
        var departamento = o['caso'].departamento; 
        var municipio = o['caso'].municipio; 
        var centro_poblado = o['caso'].centro_poblado;
        var lugar = o['caso'].lugar;
        var victimas = o['caso'].victimas;
        var prresp = o['caso'].presponsables;
        var descripcionCont = '<div>' +
          '<h3>' + titulo + '</h3>' + '</div>' + '<div>' + hechos + '</div>';
        var hechosCont = '<div><table>';
        hechosCont += ((typeof fecha != 'undefined') && fecha != "") ? 
          '<tr><td>Fecha:</td><td>' + fecha + '</td></tr>' : '';
        hechosCont += ((typeof hora != 'undefined') && hora != "") ? 
          '<tr><td>Hora:</td><td>' + hora + '</td></tr>' : '';
        hechosCont += ((typeof departamento != 'undefined') && departamento != "") ? 
          '<tr><td>Departamento:</td><td>' + departamento + '</td></tr>' : '';
        hechosCont += ((typeof municipio != 'undefined') && municipio != "") ? 
          '<tr><td>Municipio:</td><td>' + municipio + '</td></tr>' : '';
        hechosCont += ((typeof centro_poblado != 'undefined') && centro_poblado != "") ? 
          '<tr><td>Centro Poblado:</td><td>' + centro_poblado + '</td></tr>' : '';
        hechosCont += ((typeof lugar != 'undefined') && lugar != "") ? 
          '<tr><td>Vereda:</td><td>' + lugar + '</td></tr>' : '';
        hechosCont += ((typeof codigo != 'undefined') && codigo != "") ? 
          '<tr><td>Código:</td><td>' + codigo + '</td></tr>' : '';
        hechosCont += '</table></div>';
        var victimasCont = self.obtener_info_victimas(victimas, prresp, o['caso']);
        self.capaInfo(descripcionCont, hechosCont, victimasCont);
        self.ocultarCargador();
      });
    }
    return marcadorCaso;
  }

  obtener_info_victimas(victimas, prresp, caso) {
    var victimasCont = '<div><table>' +
      '<tr><td>Víctimas:</td><td>';
    for (var cv in victimas) {
      if (victimas.hasOwnProperty(cv)) {
        var victima = victimas[cv];
        victimasCont += ((typeof victima != 'undefined') && victima != "") ? victima + '<br />' : 'SIN INFORMACIÓN';
      }
    }
    victimasCont += '</td></tr><tr>' +
      '<td>Presuntos Responsables:</td><td>';
    for (var cp in prresp) {
      if (prresp.hasOwnProperty(cp)) {
        var prrespel = prresp[cp];
        victimasCont += ((typeof prrespel != 'undefined') && prrespel != "") ? prrespel + '<br />' : 'SIN INFORMACIÓN';
      }
    }
    victimasCont += '</td></tr></table></div>';
    return victimasCont;
  }

  // Variable global donde se carga la capa flotante
  // Capa flotante donde se muestra información al pulsar un marcador

  capaInfo(des, hec, vic) {
    if (this.constructor.info != undefined) { // si ya tenía información se quita primero
      this.constructor.info.remove(this.constructor.mapa); 
    }
    this.constructor.info.onAdd = function (mapa) {
      this._div = L.DomUtil.create('div', 'info card');
      this.update(des, hec, vic);
      return this._div;
    };
    this.constructor.info.update = function (des, hec, vic) {
      this._div.innerHTML = 
        ' <div id="infow" class="card-body">' +
        ' <nav>' +
        ' <div class="nav nav-tabs" id="nav-tab" role="tablist">' +
        ' <button class="nav-link active" id="infodes-tab" data-bs-toggle="tab" data-bs-target="#infodes" type="button" role="tab" aria-controls="infodes" aria-selected="true">Descripción</button>' +
        ' <button class="nav-link" id="infodatos-tab" data-bs-toggle="tab" data-bs-target="#infodatos" type="button" role="tab" aria-controls="infodatos" aria-selected="false">Datos</button>' +
        ' <button class="nav-link" id="infovictima-tab" data-bs-toggle="tab" data-bs-target="#infovictima" type="button" role="tab" aria-controls="infovictima" aria-selected="false">Víctimas</button>' +
        ' <button id="boton-cerrar" type="button" data-action="click->sivel2-gen--mapaosm#cerrarinfo"  class="btn-close close position-absolute top-0 end-0" aria-label="Close"></button>' +
        ' </div>' +
        ' </nav>' +
        ' <div class="tab-content" id="nav-tabContent">' +
        ' <div class="tab-pane fade show active panel-infomapa" id="infodes" role="tabpanel" aria-labelledby="infodes-tab">' + des + '</div>' +
        ' <div class="tab-pane fade panel-infomapa" id="infodatos" role="tabpanel" aria-labelledby="infodatos-tab">' + hec + '</div>' +
        ' <div class="tab-pane fade panel-infomapa" id="infovictima" role="tabpanel" aria-labelledby="infovictima-tab">' + vic + '</div>' +
        ' </div>' +
        '</div>';
    };
    this.constructor.info.addTo(this.constructor.mapa);
  }

  // Cierra la capa flotante desde el botón cerrar

  cerrarinfo(){
    if (this.constructor.info != undefined) {
      this.constructor.info.remove(this.constructor.mapa);
    }
  }


  // Descargar capa de casos

  descargarCapaCasos() {
    var geojson = this.constructor.marcadores.toGeoJSON();
    var dataStr = "data:text/json;charset=utf-8," + 
      encodeURIComponent(JSON.stringify(geojson));
    var descargaGeo = document.getElementById('enlace-descarga');
    descargaGeo.setAttribute("href", dataStr);
    descargaGeo.setAttribute("download", "casos.geojson");
  };

  // Funciones de agregar supercapas


  agregarCapaGeojson() {
    this.agregarCapa();
    var contenidoGeoJson;
    document.getElementById('archivoGeo').addEventListener('change', leerArchivo, false);
    function leerArchivo(e) {
      var archivo = e.target.files[0];
      if (!archivo) {
        return;
      }
      var lector = new FileReader();
      lector.onload = function(e) {
        contenidoGeoJson = e.target.result;
      };
      lector.readAsText(archivo);
    }
    document.getElementById('subirCapa').addEventListener('click', function() {
      var nombreCapanueva = document.getElementById('nombreCapaNueva').value;
      var geoJsonReconocido = JSON.parse(contenidoGeoJson);
      var capaGeoJson = L.geoJSON(geoJsonReconocido);
      this.constructor.mapa.addLayer(capaGeoJson);
      this.constructor.controlCapas.addOverlay(capaGeoJson, nombreCapanueva);
      this.constructor.agregaCapaDiv.remove(this.constructor.mapa);
      alert("Capa agregada con éxito");
    });
  };


  // Botón agregar capas

  agregarCapa() {
    if (this.constructor.agregaCapaDiv != undefined) { // si había información se elimina
      this.constructor.agregaCapaDiv.remove(this.constructor.mapa);
    }
    this.constructor.agregaCapaDiv.onAdd = function(mapa) {
      this._div = L.DomUtil.create('div', 'agregaCapaDiv');
      this.updateAgregaCapaDiv();
      return this._div;
    };

    this.constructor.agregaCapaDiv.updateAgregaCapaDiv = function() {
      this._div.innerHTML = '<div class="card border-primary"> ' +
        '<div class="card-body">' +
        '<button type="button" id="boton-cerrar-ag-capa" data-action="sivel2-gen--mapaosm#cierraCapaDiv"  class="close" aria-label="Close">' +
        '<span aria-hidden="true">&times;</span></button>' +
        '<h5>Agregar capa al mapa</h5>' +
        '<input id="nombreCapaNueva" class="form-group form-control campo-subir" type="text" placeholder="Nombre de la Capa">' +
        '<div class="form-group custom-file campo-subir">' +
        '<input id="archivoGeo" type="file" class="custom-file-input" id="customFileLang" lang="es">' +
        '<label class="custom-file-label" for="customFileLang">Seleccionar archivo GeoJSON</label></div>' +
        '<button id="subirCapa" class="form-group btn btn-primary">Subir</button></div></div>';
    };
    this.constructor.agregaCapaDiv.addTo(this.constructor.mapa);
  }

  // Cierra la capa flotante desde el botón cerrar de agregar capa
  cierraCapaDiv(){
    if (this.constructor.agregaCapaDiv != undefined) {
      this.constructor.agregaCapaDiv.remove(this.constructor.mapa);
    }
  };

}