Dela via


geo_line_to_s2cells()

Beräknar S2-celltoken som täcker en linje eller flera linjer på jorden. Den här funktionen är ett användbart geospatialt kopplingsverktyg.

Syntax

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

Läs mer om syntaxkonventioner.

Parametrar

Namn Typ Obligatorisk Beskrivning
lineString dynamic ✔️ Linje eller flera rader i GeoJSON-format.
Nivå int Definierar den begärda cellnivån. Värden som stöds finns i intervallet [0, 30]. Om det är ospecificerat används standardvärdet 11 .
Radie real Buffertradie i meter. Om det är ospecificerat används standardvärdet 0 .

Returer

Matris med S2-celltokensträngar som täcker en linje eller en flerrad. Om radien är inställd på ett positivt värde kommer täcket att vara av både indataformen och alla punkter inom indatageometrins radie.

Om något av följande: rad, nivå, radie är ogiltigt, eller om antalet celler överskrider gränsen, genererar frågan ett null-resultat.

Anteckning

  • Att täcka linjen med S2-celltoken kan vara användbart för att matcha koordinater till linjer och därmed hitta punkter i närheten.
  • Raden som täcker token har samma S2-cellnivå.
  • Det maximala antalet token per rad är 65536.
  • Det geodetiska datum som används för att mäta avståndet på jorden är en sfär. Linjekanter är geodesiker på sfären.
  • Om indatalinjens kanter är raka kartesiska linjer bör du överväga att använda geo_line_densify() för att konvertera planära kanter till geodesik.

Välja S2-cellnivå

  • Helst skulle vi vilja täcka varje rad med en eller bara några unika celler så att inga två rader delar samma cell.
  • I praktiken kan du försöka täcka med bara några celler, inte mer än ett dussin. Att täcka med mer än 10 000 celler kanske inte ger bra prestanda.
  • Frågekörningens tid och minnesförbrukning kan skilja sig mycket på grund av olika värden på S2-cellnivå.

Förslag på prestandaförbättringar

  • Minska om möjligt tabellstorleken för koordinater före koppling genom att gruppera koordinater som är mycket nära varandra med hjälp av geospatial klustring eller genom att filtrera bort onödiga koordinater på grund av typ av data eller affärsbehov.
  • Om möjligt kan du minska antalet rader på grund av data eller affärsbehov. Filtrera bort onödiga rader före koppling, omfång till intresseområde eller förena rader.
  • Vid mycket stora linjer minskar du deras storlek med hjälp av geo_line_simplify().
  • Om du ändrar S2-cellnivå kan prestanda och minnesförbrukning förbättras.
  • Ändring av kopplingstyp och tips kan förbättra prestanda och minnesförbrukning.
  • Om positiv radie anges kan prestanda förbättras om du återgår till radie 0 på buffrad form med hjälp av geo_line_buffer().

Exempel

Följande fråga hittar alla tunnelbanestationer inom 500 meter från gator och aggregerade rör räknas efter gatunamn.

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
London Bridge 1

Om raden är ogiltig returneras ett null-resultat.

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