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

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

SDK di navigazione con rilevamento del recinto virtuale
SDK di navigazione con rilevamento del recinto virtuale

Le aziende spesso hanno bisogno di sapere quando un dispositivo mobile entra o esce da un determinato in ogni area. Ciò si ottiene mantenendo i confini geografici virtuali. recinti virtuali, che consentono al software di attivare eventi quando un dispositivo attraversa un confine.

Capire quando un determinato veicolo attraversa un confine è importante per diversi casi d'uso, ad esempio:

  • Coinvolgimento dei clienti: le attività possono utilizzare il geofencing per inviare notifiche push agli utenti finali su offerte speciali, eventi o nuovi prodotti.
  • Sicurezza: le aziende possono utilizzare il geofencing per creare perimetri virtuali intorno ad aree sensibili, come data center o magazzini, e avvisare il personale di 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 ai clienti. Questa app deve monitorare la posizione del dispositivo e verificare se ha violato un determinato recinto virtuale.

Ambito

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

  1. I poligoni con cui verificare la presenza di violazioni;
  2. Posizione in tempo reale dell'utente
  3. La logica per verificare se la posizione corrente si trova all'interno o all'esterno di uno dei poligoni.

Questa guida include esempi su Android, ma esistono metodi equivalenti per farlo su iOS. Il servizio di geolocalizzazione Android ha un'implementazione integrata per i recinti virtuali circolari, che puoi consultare qui. Il codice di riferimento e la descrizione riportati di seguito sono un punto di partenza per implementazioni più complesse.

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

  • Ottenere le posizioni degli scatti stradali dall'app che li esegue. Questa metrica è più precisa rispetto alla soluzione 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, oltre ad altre informazioni provenienti dall'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.
  • Attivazione di eventi tramite listener di eventi e callback registrati.

Listener

L'SDK Navigation ha molti ascoltatori che puoi utilizzare. Ecco alcuni esempi:

  • Modifiche di località tramite il fornitore di RoadSnappedLocation.
  • Reindirizza gli eventi (l'utente manca la svolta 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 relativi all'orario di arrivo stimato e distanza rimanente (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 RoadSnappedLocationProvider e il relativo LocationListener.

La soluzione per la geofencing lato client

Ora vediamo come creare una funzionalità di geofencing lato client. Nell'esempio seguente abbiamo l'SDK Navigation che opera 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 e estratti dal tuo backend.
  2. Il backend invia periodicamente i recinti virtuali alle app di guida.
  3. Il conducente naviga e l'app del conducente controlla regolarmente i recinti virtuali alla ricerca di un trigger.
  4. L'app Driver invia una notifica al backend di un evento di trigger in modo che possa agire.

Mentre il veicolo si sposta lungo il percorso, l'app controlla regolarmente se il poligono è stato violato. Quando l'app rileva di aver superato un recinto virtuale, sulla UI viene visualizzato un messaggio con il messaggio: Recinto virtuale 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 (scopo di questo documento), devi modificare il file build.gradle in modo da includerla. Tieni presente che questo file build.gradle è per il modulo (l'app) che stai compilando, 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'
}

Dopo aver sincronizzato Gradle con il file build.gradle più recente, puoi importare com.google.maps.android.PolyUtil nel file Java:

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

Definire i recinti virtuali

Tieni presente che anche in questo caso l'importazione di PolygonOptions è in corso. Il motivo è che viene utilizzato questo valore 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 sopra, qui stiamo definendo un poligono fisso con coordinate predeterminate, ovvero coppie (latitudine, longitudine). Tuttavia, negli scenari reali, la maggior parte delle volte queste coordinate e definizioni di poligoni provengono da un endpoint di backend e probabilmente verranno recuperate da remoto. Ciò significa che i poligoni dovranno essere creati al volo dall'app.

Per ulteriori dettagli su cosa è possibile specificare in PolygonOptions, fai clic qui.

Devi definire i poligoni durante la creazione di Frammento o 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
}

Ascolta gli aggiornamenti sulla posizione

Dopo aver definito i recinti virtuali, devi solo creare un ascoltatore degli aggiornamenti della posizione per iscriverti all'evento sopra menzionato nell'SDK Navigation 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 seguente viene utilizzato il poligono predefinito che rappresenta il recinto virtuale, ma in pratica potresti avere più poligoni e sarebbe necessario un ciclo.

Un approccio alternativo

Questo documento si concentra su un'applicazione rivolta al client che verifica la presenza di una violazione del recinto virtuale personalizzato (poligono). Tuttavia, in alcuni casi potresti voler eseguire questi controlli sul tuo backend.

Ciò significa che l'app segnalerà gli aggiornamenti della posizione a un backend e questo backend controllerà se il veicolo ha violato un determinato poligono, senza dipendere dall'app client da eseguire la convalida.

Una possibile soluzione è la seguente:

[Ambiente di esecuzione] Architettura del 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, che utilizza l'SDK Driver, invia aggiornamenti sulla posizione a Fleet Engine. Gli aggiornamenti della posizione e la navigazione in-app avvengono tramite l'SDK Navigation.
  2. Fleet Engine invia questi aggiornamenti a Cloud Logging o Pub/Sub.
  3. Il backend raccoglie questi indicatori di posizione.
  4. I recinti virtuali vengono archiviati in BigQuery per l'analisi da parte del backend.
  5. Dopo l'attivazione del recinto virtuale, gli avvisi vengono inviati all'app conducente.

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 Pub/Sub o leggere i log e controllare gli aggiornamenti dei veicoli. Poi, ogni volta che si verifica un aggiornamento (o a intervalli di alcuni secondi o 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. Se uno o più recinti virtuali sono stati violati, il backend può intervenire e attivare pipeline interne o altri flussi di lavoro pertinenti.

Conclusione

Il geofencing è un potente strumento che può essere utilizzato 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 e migliorare la sicurezza.

L'SDK Navigation fornisce ascoltatori di eventi utili che possono rilevare molti momenti importanti durante un viaggio. Le aziende spesso richiedono recinti virtuali personalizzati per casi d'uso specifici. In questo documento abbiamo dimostrato come raggiungere questo obiettivo, ma le possibilità sono infinite. Non vediamo l'ora di scoprire cosa pensi.

Azioni successive

Ulteriori letture suggerite: