Share via


geo_line_to_s2cells()

Calcule les jetons de cellule S2 qui couvrent une ligne ou multiligne sur Terre. Cette fonction est un outil de jointure géospatiale utile.

Syntax

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

Découvrez les conventions de syntaxe.

Paramètres

Nom Type Obligatoire Description
Linestring dynamic ✔️ Ligne ou multiligne au format GeoJSON.
level int Définit le niveau de cellule demandé. Les valeurs prises en charge se trouvent dans la plage [0, 30]. Si la valeur n’est pas spécifiée, la valeur par défaut 11 est utilisée.
Rayon real Rayon de la mémoire tampon en mètres. Si la valeur n’est pas spécifiée, la valeur par défaut 0 est utilisée.

Retours

Tableau de chaînes de jetons de cellule S2 qui couvrent une ligne ou une ligne multiligne. Si le rayon est défini sur une valeur positive, le recouvrement sera à la fois de la forme d’entrée et de tous les points dans le rayon de la géométrie d’entrée.

Si l’un des éléments suivants : ligne, niveau, rayon n’est pas valide ou si le nombre de cellules dépasse la limite, la requête génère un résultat null.

Notes

  • Couvrir la ligne avec des jetons de cellule S2 peut être utile pour faire correspondre les coordonnées aux lignes, ce qui permet de trouver des points à proximité des lignes.
  • Les jetons de couverture de ligne sont du même niveau de cellule S2.
  • Le nombre maximal de jetons par ligne est de 65536.
  • La donnée géodésique utilisée pour mesurer la distance sur Terre est une sphère. Les bords de ligne sont des géodésiques sur la sphère.
  • Si les bords de ligne d’entrée sont des lignes cartésiennes droites, envisagez d’utiliser geo_line_densify() pour convertir les bords planaires en bords géodésiques.

Choix du niveau de cellule S2

  • Dans l’idéal, nous aimerions couvrir chaque ligne avec une ou seulement quelques cellules uniques de sorte que deux lignes ne partagent pas la même cellule.
  • Dans la pratique, essayez de couvrir avec seulement quelques cellules, pas plus d’une douzaine. Le recouvrement de plus de 10 000 cellules peut ne pas produire de bonnes performances.
  • Le temps d’exécution des requêtes et la consommation de mémoire peuvent différer considérablement en raison de différentes valeurs au niveau de la cellule S2.

Suggestions d’amélioration des performances

  • Si possible, réduisez la taille de la table de coordonnées avant la jointure, en regroupant les coordonnées très proches les unes des autres à l’aide de clustering géospatiales ou en filtrant les coordonnées inutiles en raison de la nature des données ou des besoins métier.
  • Si possible, réduisez le nombre de lignes en raison de la nature des données ou des besoins de l’entreprise. Filtrez les lignes inutiles avant la jointure, limitez la zone d’intérêt ou unifiez les lignes.
  • En cas de très grandes lignes, réduisez leur taille à l’aide de geo_line_simplify().
  • La modification du niveau de la cellule S2 peut améliorer les performances et la consommation de mémoire.
  • La modification du type de jointure et de l’indicateur peut améliorer les performances et la consommation de mémoire.
  • Si le rayon positif est défini, le rétablissement du rayon 0 sur la forme mise en mémoire tampon à l’aide de geo_line_buffer() peut améliorer les performances.

Exemples

La requête suivante recherche toutes les stations de métro à moins de 500 mètres des rues et agrège le nombre de tubes par nom de rue.

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
Palais de Buckingham 1
London Bridge 1

En cas de ligne non valide, un résultat null est retourné.

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