geo_line_to_s2cells()

Calcola i token di cella S2 che coprono una linea o una multilinea sulla Terra. Questa funzione è uno strumento di join geospaziale utile.

Sintassi

geo_line_to_s2cells(lineString [level[ ,,radius]])

Altre informazioni sulle convenzioni di sintassi.

Parametri

Nome Tipo Obbligatoria Descrizione
Linestring dynamic ✔️ Riga o multilinea nel formato GeoJSON.
level int Definisce il livello di cella richiesto. I valori supportati si trovano nell'intervallo [0, 30]. Se non specificato, viene usato il valore predefinito 11.
Raggio real Raggio del buffer in metri. Se non specificato, viene usato il valore predefinito 0.

Restituisce

Matrice di stringhe di token di cella S2 che coprono una riga o una multilinea. Se il raggio è impostato su un valore positivo, la copertura sarà di forma di input e di tutti i punti all'interno del raggio della geometria di input.

Se una delle seguenti operazioni: riga, livello, raggio non è valido o il numero di celle supera il limite, la query genererà un risultato Null.

Nota

  • La copertura della linea con i token di cella S2 può essere utile nelle coordinate corrispondenti alle linee, quindi trovare punti nelle vicinanze delle righe.
  • I token di copertura linea sono dello stesso livello di cella S2.
  • Il numero massimo di token per riga è 65536.
  • Il datum geodetico usato per misurare la distanza sulla Terra è una sfera. I bordi linea sono geodesici sulla sfera.
  • Se i bordi della linea di input sono linee cartesiane dritte, è consigliabile usare geo_line_densify() per convertire i bordi planari in geodesici.

Scelta del livello di cella S2

  • Idealmente si vuole coprire ogni riga con una o solo poche celle univoche in modo che nessuna due righe condividono la stessa cella.
  • In pratica, provare a coprire con solo poche celle, non più di una dozzina. Copertura con più di 10.000 celle potrebbe non produrre prestazioni ottimali.
  • Il tempo di esecuzione della query e il consumo di memoria potrebbero variare notevolmente a causa di valori di livello di cella S2 diversi.

Suggerimenti per il miglioramento delle prestazioni

  • Se possibile, ridurre le dimensioni della tabella prima del join, raggruppando le coordinate molto vicine tra loro usando clustering geospaziali o filtrando coordinate non necessarie a causa della natura dei dati o delle esigenze aziendali.
  • Se possibile, ridurre il numero di righe a causa della natura dei dati o delle esigenze aziendali. Filtrare le righe non necessarie prima di unire, ambito nell'area di interesse o unificare le righe.
  • In caso di linee molto grandi, ridurre le dimensioni usando geo_line_simplify().
  • La modifica del livello di cella S2 può migliorare le prestazioni e il consumo di memoria.
  • La modifica del tipo di join e l'hint possono migliorare le prestazioni e l'utilizzo della memoria.
  • Nel caso in cui il raggio positivo sia impostato, ripristinare il raggio 0 sulla forma memorizzata nel buffer usando geo_line_buffer() può migliorare le prestazioni.

Esempio

La query seguente individua tutte le stazioni ferroviarie entro 500 metri di strade e aggrega i tubi conteggiati in base al nome della strada.

let radius = 500;
let tube_stations = datatable(tube_station_name:string, lng:real, lat: real)
[
    "St. James' Park",        -0.13451078568013486, 51.49919145858172,
     "London Bridge station", -0.08492752160134387, 51.504876316440914,
     // more points
];
let streets = datatable(street_name:string, line:dynamic)
[
    "Buckingham Palace", dynamic({"type":"LineString","coordinates":[[-0.1399656708283601,51.50190802248855],[-0.14088438832752104,51.50012082761452]]}),
    "London Bridge",    dynamic({"type":"LineString","coordinates":[[-0.087152,51.509596],[-0.088340,51.506110]]}),
    // more lines
];
let join_level = 14;
let lines = materialize(streets | extend id = new_guid());
let res = 
    lines
    | project id, covering = geo_line_to_s2cells(line, join_level, radius)
    | mv-expand covering to typeof(string)
    | join kind=inner hint.strategy=broadcast
    (
        tube_stations
        | extend covering = geo_point_to_s2cell(lng, lat, join_level)
    ) on covering;
res | lookup lines on id
| where geo_distance_point_to_line(lng, lat, line) <= radius
| summarize count = count() by name = street_name
name count
Buckingham Palace 1
Ponte di Londra 1

In caso di riga non valida, verrà restituito un risultato Null.

let line = dynamic({"type":"LineString","coordinates":[[[0,0],[0,0]]]});
print isnull(geo_line_to_s2cells(line))
print_0
True