PnX-SI / GeoNature

Application de saisie et de synthèse des observations faune et flore
GNU General Public License v3.0
99 stars 101 forks source link

[Map] Localisation automatique #2338

Closed pierre56 closed 1 year ago

pierre56 commented 1 year ago

[Map] Localisation automatique

Bonjour, Suite a une sortie terrain durant laquelle nous avons fait de la saisie via téléphone et tablette. L'un des gros besoins qui est ressorti est la localisation automatique de l'utilisateur a partir du device, que ce soit via ordinateur ou téléphone.

La barre de recherche via https://nominatim.openstreetmap.org/search est utile pour cibler mais pas suffisamment user-friendly et la recherche a la mano sur la carte peut prendre longtemps quand on connait mal le coin. Je sais qu'il existe l'application mobile occtax qui répond a ce besoin d'application android de terrain, mais le gros besoin est sur un module monitoring (qui il me semble, n'est pas encore géré)

Il y a différents soucis :

Mais cela me semble une fonction essentielle a mettre en place. Ne maitrisant que moyen angular et n'ayant pas le temps de faire du dev spécifique sans savoir la faisabilité technique. Je voulais avoir votre avis sur la partie technique avant de me lancer la-dedans.

scénarios possibles :

1. Button "Find me"

Button qui serait disponible dans occtax et autres modules cartos lors de la saisie. image Il faudrait partir sur la principe d'une extension via un nouveau composant comme le button GPS image

Il faut alors ajouter un marker d'une couleur différente pour indiquer la geoloc sur la carte.

2. Localisation par défaut sur toutes les maps

Modification du component map, pour ajouter un paramètre "auto-track" qui affiche en permanence la geolocalisation de l'user. En complément cela répondrait au besoin de créer une trace lors d'un parcours, en enregistrant la position toutes les x minutes. activation de la function watchPosition option if "auto-track" is true

Cela permettrait de filtrer les données sur la commune et participer a la personnalisation de #2333 Ce qui est intéressant pour soulager le server car les gens sont souvent intéressés par ce qu'il y a autour d'eux.

Idées / Documentation utile

Ajout de la function dans map.component.ts et d'un icone de marker avec un logo de maison ou de loupe dans les ressources.

getCurrentPosition

https://stackoverflow.com/questions/74760973/while-using-navigator-geolocation-getcurrentpositionthis-finuc1-func1-cant-r

Use navigator.geolocation.getCurrentPosition :

  showPosition() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (position) => {
          console.log(position.coords.latitude, position.coords.longitude)
          let g = position.coords.latitude;
          let f = position.coords.longitude;
          this.getData(g, f);
        }
      );
      }
  };

map.locate

map.locate({setView: true, maxZoom: 16});

https://leafletjs.com/examples/mobile/

https://github.com/bluehalo/ngx-leaflet/issues/200

https://www.youtube.com/watch?v=orjkt0VHt1c


Je n'ai pas vu de tickets dédiés a cette question, ni de mention dans les PR de la branche dev. Je suis preneur si des gens ont fait des expérimentations, et si j'ai du temps et des réussites je mettrais a dispo par la suite. En version simple, je vais partir sur le scénario 1 pour la modularité.

Merci et bravo pour votre travail, Pierre Le Dorze de Bretagne Vivante

camillemonchicourt commented 1 year ago

Bonjour, l'application web GeoNature est clairement orientée pour un usage Desktop sur PC. Aucun travail n'a jamais été réalisé pour vraiment adapter les interfaces et formulaires a une saisie sur mobile. Donc ce besoin n'est pas forcément remonté jusque là.

Pour le mobile, on privilégie plutôt Occtax-mobile pour les observations occasionnelles et les inventaires. Pour monitoring, une application mobile dédiée a été souvent évoquée mais encore rien de précis. C'est pour cela que nous avons récemment fait un workshop pour mettre en place la solution mobile générique ODK interfacée avec le module Monitoring de GeoNature : https://geonature.fr/documents/2022-12-PNX-OFB-Workshop-ODK.pdf. Voir aussi l'info faite sur le sujet sur la liste de diffusion GeoNature : https://framalistes.org/sympa/arc/geonature-info/2022-12/msg00000.html

Mais pourquoi pas ajouter un outil sur la carte pour permettre de se recentrer sur la localisation de l'utilisateur. Il est aussi possible d'utiliser directement ce plugin Leaflet pour cela : https://github.com/domoritz/leaflet-locatecontrol

Il serait souhaitable que cet outil de localisation de l'utilisateur soit activable ou non en paramètre, car certains ne voudront pas l'afficher pour ne pas trop alourdir l'interface carto qui dispose déjà de beaucoup (trop ?) de boutons.

Je pense que le sujet d'enregistrement de la trace de l'utilisateur est un autre sujet, à traiter par ailleurs, car il pose d'autres questions. D'autant plus du fait que GeoNature (web) est utilisé quasi exclusivement sur PC.

PS : La recherche Nominatim a pas mal de limites, car elle s'appuie sur une base de données Openstreetmap où il y a de tout dedans, mais c'est un bonus. Par contre, comme elle est internationale, il est fortement conseillé de la limiter aux objets de son pays, possible depuis quelques versions, suite à https://github.com/PnX-SI/GeoNature/pull/2011

pierre56 commented 1 year ago

Bonjour @camillemonchicourt Merci de ce retour très rapide.

L'application web n'est pas très opti pour l'usage mobile, il y a des améliorations possible sur le responsive et les listes déroulantes qui gênent la saisie. Mais après quelques test, en mettant en "mode ordinateur" sur le navigateur mobile et en basculant au format paysage. On arrive a un résultat que je trouve déjà satisfaisant pour de la saisie terrain et immédiatement utilisable pour occtax + suivis protocolés👍

avec tablette terrain, c'est déjà validé niveau usage

La grosse contrainte de ce système étant le manque de réseau dans les réserves. J'ai commencé a explorer des solutions similaires au workshop mais en passant par qgis/qfield que je maitrise mieux. Cela permet aux collègues d'avoir leur projet qgis partagé enregistré sur le server avec leurs rapports et leur données au mm endroit, puis la carto publique via lizmap. Mais je n'ai pas eu le temps de creuser et je me suis arrêté au mapping basique des champs. Je butte sur la gestion générique des nomenclatures et des champs additionnels...

mais cela mériterait un autre ticket

L'option du button me semble la plus pertinente et facile a mettre en oeuvre vu ta réponse. Avoir plus de buttons sur le côté ne me semble pas dérangeant tant qu'ils sont pertinent (et ce button va trouver son public^^) Je vais creuser la question et alimenter ce ticket si des succès 😄

pierre56 commented 1 year ago

Update - Need help

Bonjour @camillemonchicourt , @TheoLechemia , @bouttier j'ai passé un peu de temps sur le dev et j'arrive a faire run le build avec le component. Sauf que je n'arrive pas a faire apparaitre le buton 😞

Pour information dans le cas ou ça a de l'importance, mon server de test est en 2.7.5 et mon server de prod en 2.10.4 (je vais bientôt faire la maj vers la 2.11) J'ai l'impression que la mécanique est toujours la mm, mais on sait jamais si j'ai oublié une subtilité d'évolution.


Voilà les étapes jusqu’à présent, si vous avez des suggestions ou correction, je suis preneur.

Création du répertoire /home/geonatureadmin/geonature/frontend/src/app/GN2CommonModule/map/geolocation

image

image

Création de geolocation.component.ts

import { Component, OnInit, OnChanges, ViewChild, ElementRef } from '@angular/core';
import { Map } from 'leaflet';

import { MapService } from '../map.service';
import { AppConfig } from '@geonature_config/app.config';
import { CommonService } from '../../service/common.service';

import * as L from 'leaflet';

@Component({
  selector: 'pnx-geolocation-button',
  templateUrl: 'geolocation.component.html'
})
export class GeolocationComponent {
  @ViewChild('map') public mapElement: ElementRef;
  map: L.Map;

  constructor(public mapservice: MapService, private _commonService: CommonService) {}

  ngOnInit() {
    this.map = this.mapservice.map;
    this.setMarkerGeolocation();
  }

  setMarkerGeolocation()  {
    // Marker
    const MarkerGeolocation = this.mapservice.addCustomLegend(
      'topleft',
      'markerGeolocation',
      'url(assets/images/location-pointer.png)'
    );
    this.map.addControl(new MarkerGeolocation());
    // custom the marker
    document.getElementById('markerGeolocation').style.backgroundColor = '#edcb44';
    L.DomEvent.disableClickPropagation(document.getElementById('markerGeolocation'));
    document.getElementById('markerGeolocation').onclick = () => {
      this.getCurrentLocation();
    };
  }

  getCurrentLocation() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position => {
        const latitude = position.coords.latitude;
        const longitude = position.coords.longitude;
        console.log(`Latitude : ${latitude}, Longitude : ${longitude}`);
        this.map.setView([latitude, longitude], 15); // zoom sur la localisation
        L.marker([latitude, longitude]).addTo(this.map); // ajout d'un marker
      });
    } else {
      console.error("La géolocalisation n'est pas prise en charge par votre navigateur.");
    }
  }

  ngAfterViewInit() {
    this.map = L.map(this.mapElement.nativeElement).setView([47.21837, -1.55362], 13); // initialisation de la carte
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: 'OpenStreetMap'
    }).addTo(this.map);
  }
}

Création de geolocation.component.html

-> Qui est vide, sur le modèle de marker.component.html ou leaflet-draw.component.html

Ajout des références dans /home/geonatureadmin/geonature/frontend/src/app/GN2CommonModule/GN2Common.module.ts


import { GeolocationComponent } from './map/geolocation/geolocation.component';
...
declarations: [
    GeolocationComponent,
...
exports: [
   GeolocationComponent,

Run Build

Avec ce code, le build se fait mais je ne vois le buton sur aucune des cartes. Il faudrait que ce soit opérationnel pour la synthese et occtax, c'est ce qui me parait pertinent dans l'usage. Dans l'exemple suivant, j'explore pour occtax.

Ajout dans la Config ?

la c'est le moment ou je bute, j'ai repéré dans home\geonatureadmin\geonature\contrib\occtax\frontend\app\gnModule.module.ts

Qu'il y a des appel a "GN2CommonModule" et "MapListService", ou je pense avoir déjà ajouté geolocation. Mais si il faut rajouter je peux.


La 2ème piste, me semble être le fichier de config /home/geonatureadmin/geonature/contrib/occtax/frontend/app/module.config.ts


export const ModuleConfig = {
 "ADD_MEDIA_IN_EXPORT": false,
 "CD_TYPO_HABITAT": null,
 "DATE_FORM_WITH_TODAY": true,
 "DISPLAY_VERNACULAR_NAME": true,
 "ENABLE_GPS_TOOL": true,
 "ENABLE_MEDIAS": true,
 "ENABLE_MY_PLACES": true,
 "ENABLE_SETTINGS_TOOLS": false,
 "ENABLE_UPLOAD_TOOL": true,
 "FRONTEND_PATH": "/home/geonatureadmin/geonature/external_modules/occtax/frontend",

J'imagine qu'il faut rajouter un param

ENABLE_GEOLOCATION": true

mais pour que ce soit fonctionnel, je sens qu'il me manque une étape et je vois pas laquelle.


Si je réussi, je ferais une PR dans une branche spécifique. merci :D

Bonne journée Pierre Le Dorze de Bretagne Vivante

TheoLechemia commented 1 year ago

Bonjour,

Je pense qu'il faut juste ajouter la balise du composant que tu as créé à l'endroit ou tu veux afficher le bouton :

Exemple si tu veux qu'il s'affiche sur la synthese, il faut l'ajouter au composant src/app/syntheseModule/synthese-results/synthese-carte/synthese-carte.component.html :

<pnx-map height="92vh" class="map-card">
  <pnx-leaflet-filelayer
    (onLoad)="onFileLayerLoaded($event)"
    [removeLayer]="currentLeafletDrawCoord"
    [style]="{ color: 'green' }"
  ></pnx-leaflet-filelayer>
  <pnx-leaflet-draw
    [options]="leafletDrawOptions"
    [zoomLevel]="1"
    (layerDrawed)="bindGeojsonForm($event)"
    (layerDeleted)="deleteControlValue()"
  >
  </pnx-leaflet-draw>
 // ICI ->>>>> <pnx-geolocation-button> </pnx-geolocation-button>
</pnx-map>

Propose un pull request avec ton code, même non fonctionnel, ce sera plus facile pour nous pour relire, tester et commenter. Pour la config, elle est désormais gérer côté backend, mais pareil, fais la PR et on completera

pierre56 commented 1 year ago

Code fonctionnel \o/

Sur la synthèse

Demande droit

image

Geoloc

Plutôt précise image

Recherche toujours fonctionnelle

mais le marker reste sur la carto, il faudra que j'ajoute un mécanisme pour désactiver la fonction image

Test Mobile

C'est également fonctionnel via le téléphone image

Il faudra que je test la précision de la géoloc en condition réelle.

Conc

Très content que ce soit fonctionnel, ce sera très pratique pour le terrain. Je fais une PR propre la semaine pro, et je fermerais le ticket quand ce sera merge.

Merci beaucoup @TheoLechemia et @camillemonchicourt ! 👍

camillemonchicourt commented 1 year ago

Je ne pense pas qu'il faille placer un marqueur, du moins dans la Synthèse, car cela porte à confusion avec la localisation d'une observation.

Voir ce qui est fait dans le plugin Leaflet-locate que j'aurai utilisé pour cette fonctionnalité : https://domoritz.github.io/leaflet-locatecontrol/demo/

Idem dans les boutons de la carte, c'est une géolocalisation qu'il faut représenter, pas un marqueur.

camillemonchicourt commented 1 year ago

PS : si tu fais une PR, voir la doc de développement, il faut bien partir de la branche DEVELOP.