Attiva il geofencing lato client per monitorare gli asset mobile con Nav SDK

Questo documento descrive che cos'è il geofencing lato client, quando utilizzarlo e come applicarlo a casi d'uso in un'applicazione mobile. Mostra inoltre come implementare un esempio su Android utilizzando l'SDK Google Navigation.

SDK Nav con rilevamento del recinto virtuale
SDK Nav con rilevamento del recinto virtuale

Le aziende spesso hanno bisogno di sapere quando un dispositivo mobile entra o esce da una determinata area. Per raggiungere questo obiettivo, mantenere i confini geografici virtuali, o geofence, consentendo al software di attivare eventi quando un dispositivo supera un confine.

Comprendere quando un determinato veicolo oltrepassa un confine è importante per diversi casi d'uso, tra cui:

  • Coinvolgimento dei clienti: le attività possono utilizzare il geofencing per inviare notifiche push agli utenti finali su offerte speciali, eventi o nuovi prodotti.
  • Sicurezza e sicurezza: le attività possono utilizzare il geofencing per creare perimetri virtuali attorno alle aree sensibili, come data center o warehouse, e avvisare il personale addetto alla sicurezza se qualcuno entra o esce dall'area.
  • Trasporti: le attività possono utilizzare il geofencing per monitorare la posizione dei veicoli e ottimizzare percorsi e orari.

Pertanto è importante sapere come rappresentare queste zone (poligoni) all'interno di un'app rivolta al cliente. Questa app dovrebbe monitorare la posizione del dispositivo e verificare se ha violato un determinato recinto virtuale.

Ambito

Questo documento si concentra sull'implementazione lato client del geofencing . Ciò significa che l'app client deve avere:

  1. I poligoni da verificare rispetto ai poligoni da verificare per rilevare eventuali violazioni;
  2. Posizione in tempo reale dell'utente
  3. Funzione logica per verificare se la posizione corrente si trova all'interno o all'esterno di un poligono.

Questa guida include esempi su Android, ma esistono modi equivalenti per raggiungere questo obiettivo su iOS. Il Servizio di geolocalizzazione di Android ha un'implementazione integrata per i recinti virtuali circolari, consultabili qui. Il codice di riferimento e la descrizione riportati di seguito sono un punto di partenza per implementazioni più complesse.

L'SDK di navigazione è una libreria nativa per Android / iOS aggiunta all'app del conducente. È responsabile di:

  • Ottenere posizioni scattate dall'app che la esegue. Questa metrica è più precisa rispetto a FusedLocationProvider (FLP) di Android, in quanto utilizza la rete stradale di Google per agganciare le posizioni al tratto di strada più vicino, rendendo l'orario di arrivo stimato molto più preciso. Altre informazioni provenienti da FLP.
  • Esperienza passo passo che consente ai conducenti di spostarsi in modo efficiente dal punto A al punto B, tenendo conto del traffico in tempo reale e di altre limitazioni del percorso.
  • Attivare gli eventi tramite listener di eventi e callback registrati.

Listener

L'SDK di navigazione offre molti listener che puoi utilizzare. Per citarne alcuni:

  • Modifiche di località tramite il fornitore RoadSnappedLocation.
  • Reindirizza gli eventi (l'utente salta l'inversione a U, la svolta a sinistra e così via e devia dal percorso consigliato) tramite ReroutingListener.
  • Eventi di arrivo (l'utente arriva alla destinazione pianificata) tramite ArrivalListener.
  • Eventi sulla distanza rimanente e sull'orario di arrivo stimato (ricevi una notifica quando il conducente sta per arrivare a destinazione in base ai metri; ricevi una notifica quando il conducente sta per arrivare a destinazione, in base all'orario), entrambi disponibili tramite .RemainingTimeOrDistanceChangedListener

In questa guida vengono utilizzati solo il provider RoadSnappedLocation e il relativo LocationListener.

La soluzione di geofencing lato client

Ora vediamo come creare una funzionalità di geofencing lato client. Nell'esempio riportato di seguito abbiamo l'SDK Navigation che funziona in modalità passo passo e un poligono definito nel percorso che rappresenta il nostro recinto virtuale.

Diagramma funzionale
Diagramma funzionale

  1. I recinti virtuali vengono archiviati in BigQuery ed estratti dal tuo backend.
  2. Il backend invia periodicamente i recinti virtuali alle app di Drive.
  3. Il conducente naviga e l'app del conducente controlla regolarmente i recinti virtuali per verificare se è presente un attivatore.
  4. L'app Driver avvisa il backend di un evento di trigger in modo che possa agire.

Mentre il veicolo si muove lungo il percorso, l'app controlla regolarmente se il poligono è stato violato. Quando l'app rileva di aver oltrepassato un recinto virtuale, nell'interfaccia utente viene visualizzato il messaggio: Il recinto virtuale è stato violato.

Configura le dipendenze per Android-Maps-Utils

Questa soluzione utilizza Android-Maps-Utils, una libreria open source contenente utilità utili per un'ampia gamma di applicazioni che utilizzano l'API Google Maps per Android.

Questa libreria è pubblica e ospitata su GitHub ed è accessibile all'indirizzo:

  • Android: https://github.com/googlemaps/android-maps-utils
  • iOS: https://github.com/googlemaps/google-maps-ios-utils

Per includere questa libreria nella tua app per Android (ambito di questo documento), devi modificare il file build.gradle in modo da includerla. Tieni presente che questo file build.gradle è per il modulo (app) che stai creando, non a livello di progetto.

dependencies {
   ...
   // Utilities for Maps SDK for Android (requires Google Play Services)
   implementation 'com.google.maps.android:android-maps-utils:2.3.0'
}

Quindi, dopo aver sincronizzato Gradle con il tuo ultimo file build.gradle, puoi importare com.google.maps.android.PolyUtil nel tuo file Java:

import com.google.android.gms.maps.model.PolygonOptions;
import com.google.maps.android.PolyUtil;

Definisci i tuoi recinti virtuali

Tieni presente che anche in questo caso PolygonOptions è in corso l'importazione. Il motivo è che questo è ciò che viene utilizzato per rappresentare il poligono:

mPolygonOptions = new PolygonOptions()
       .add(new LatLng(29.4264525,-98.4948758))
       .add(new LatLng(29.4267029,-98.4948758))
       .add(new LatLng(29.4273742,-98.4945822))
       .add(new LatLng(29.4264562,-98.4943592))
       .fillColor(0x0000ff36)
       .strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
       .strokeColor(Color.BLUE)
       .strokeWidth(5);

Come puoi vedere qui sopra, qui definiamo un poligono fisso con coordinate prestabilite (latitudine, longitudine). Tuttavia, in scenari reali, le coordinate e le definizioni di poligoni provengono nella maggior parte dei casi da un endpoint di backend e probabilmente verranno recuperate in remoto. Ciò significa che i poligoni dovranno essere creati in tempo reale dall'app.

Per maggiori dettagli su cosa può essere specificato in PolygonOptions, fai clic qui.

Devi definire i poligoni durante la creazione del frammento o dell'attività. Ad esempio:

protected void onCreate(Bundle savedInstanceState) {
   ...
   mPolygonOptions = new PolygonOptions()
           .add(new LatLng(29.4264525,-98.4948758))
           .add(new LatLng(29.4267029,-98.4948758))
           .add(new LatLng(29.4273742,-98.4945822))
           .add(new LatLng(29.4264562,-98.4943592))
           .fillColor(0x0000ff36)
           .strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
           .strokeColor(Color.BLUE)
           .strokeWidth(5);

   ...// more code here
}

Ascoltare gli aggiornamenti della posizione

Dopo aver definito i tuoi recinti virtuali, devi solo creare un listener di aggiornamenti di posizione per iscriverti al suddetto evento nell'SDK di navigazione chiamato RoadSnappedLocationProvider, che restituirà la posizione più recente del dispositivo.

mLocListener = new RoadSnappedLocationProvider.LocationListener() {
   @Override
   public void onLocationChanged(Location snapped) {
       LatLng snappedL = new LatLng(snapped.getLatitude(), snapped.getLongitude());
       if(PolyUtil.containsLocation(snappedL, mPolygonOptions.getPoints(), true) && !mGeofenceBreached){
           Log.d("Geofence", "Vehicle has breached the polygon");
       }
   }
   @Override
   public void onRawLocationUpdate(Location location) {
   }
};

Con Android-Maps-Utils puoi utilizzare PolyUtil.containsLocation per verificare se la posizione ricevuta si trova all'interno del poligono predefinito. Nell'esempio riportato di seguito, viene utilizzato il poligono predefinito, che rappresenta il recinto virtuale, ma in pratica potresti avere più poligoni e sarebbe necessario creare un loop.

Un approccio alternativo

Questo documento si concentra su un'applicazione rivolta al client che verifica la presenza di una violazione del recinto virtuale (poligono) personalizzata. Esistono però degli scenari in cui potrebbe essere opportuno eseguire questi controlli sul tuo backend.

Ciò significa che l'app segnalerà gli aggiornamenti di posizione a un backend e quest'ultimo controllerà se il veicolo ha violato un determinato poligono, quindi non dipende dall'app del client per eseguire la convalida.

Una possibile soluzione sarebbe la seguente:

[Ambiente di esecuzione] Architettura di geofencing lato server

Un'architettura di esempio che mostra un approccio lato server al geofencing.

Soluzione lato server
Soluzione lato server

  1. L'app del conducente, utilizzando l'SDK Driver, invia aggiornamenti sulla posizione a Fleet Engine. Gli aggiornamenti della posizione e la navigazione in-app avvengono tramite l'SDK di navigazione.
  2. Fleet Engine genera questi aggiornamenti su Cloud Logging o Pub/Sub.
  3. Il backend raccoglie questi indicatori di posizione.
  4. I recinti virtuali vengono archiviati in BigQuery per essere analizzati dal backend.
  5. Quando viene attivato il recinto virtuale, gli avvisi vengono inviati all'app Driver.

In questa architettura vengono utilizzati Driver SDK e Fleet Engine. Fleet Engine può emettere aggiornamenti Pub/Sub e generare voci di log in Cloud Logging. In entrambi i casi, è possibile recuperare la posizione del veicolo.

Il backend potrebbe quindi monitorare la coda PubSub o leggere i log e controllare gli aggiornamenti del veicolo. Ogni volta che si verifica un aggiornamento (oppure a intervalli di pochi secondi, minuti, in base alla sua criticità), il backend potrebbe chiamare le funzioni GIS di BigQuery per determinare se un determinato veicolo si trova all'interno o all'esterno di recinti virtuali. Nel caso in cui siano stati violati uno o più recinti virtuali, il backend può agire e attivare pipeline interne o altri flussi di lavoro pertinenti.

Conclusione

Il geofencing è un potente strumento utilizzabile per vari scopi. Le attività possono utilizzare il geofencing per scegliere come target gli utenti finali con annunci e promozioni pertinenti, fornire servizi basati sulla posizione geografica e migliorare la sicurezza.

L'SDK di navigazione fornisce listener di eventi utili in grado di rilevare molti momenti importanti durante un percorso. Le aziende spesso richiedono recinti virtuali personalizzati per casi d'uso specifici. In questo documento abbiamo mostrato un modo per raggiungere questo obiettivo, ma le possibilità sono infinite. Non vediamo l'ora di conoscere la tua opinione.

Azioni successive

Ulteriori letture suggerite: