Funzioni geografiche OData in Ricerca geo.distance cognitiva di Azure e geo.intersects

Ricerca cognitiva di Azure supporta query spaziali geografiche nelle espressioni di filtro OData tramite le geo.distance funzioni e geo.intersects . La geo.distance funzione restituisce la distanza in chilometri tra due punti, un campo o una variabile di intervallo e una costante passata come parte del filtro. La geo.intersects funzione restituisce true se un determinato punto si trova all'interno di un poligono specificato, dove il punto è una variabile di campo o intervallo e il poligono viene specificato come costante passata come parte del filtro.

La geo.distance funzione può essere usata anche nel parametro $orderby per ordinare i risultati della ricerca in base alla distanza da un determinato punto. La sintassi per geo.distance in $orderby è la stessa che in $filter. Quando si usa geo.distance in $orderby, il campo a cui si applica deve essere di tipo Edm.GeographyPoint e deve essere anche ordinabile.

Nota

Quando si usa geo.distance nel parametro $orderby , il campo passato alla funzione deve contenere solo un singolo punto geografico. In altre parole, deve essere di tipo Edm.GeographyPoint e non Collection(Edm.GeographyPoint). Non è possibile ordinare nei campi della raccolta in Ricerca cognitiva di Azure.

Sintassi

Il seguente EBNF (Extended Backus-Naur Form) definisce la grammatica delle geo.distance funzioni e geo.intersects , oltre ai valori geografici su cui operano:

geo_distance_call ::=
    'geo.distance(' variable ',' geo_point ')'
    | 'geo.distance(' geo_point ',' variable ')'

geo_point ::= "geography'POINT(" lon_lat ")'"

lon_lat ::= float_literal ' ' float_literal

geo_intersects_call ::=
    'geo.intersects(' variable ',' geo_polygon ')'

/* You need at least four points to form a polygon, where the first and
last points are the same. */
geo_polygon ::=
    "geography'POLYGON((" lon_lat ',' lon_lat ',' lon_lat ',' lon_lat_list "))'"

lon_lat_list ::= lon_lat(',' lon_lat)*

È disponibile anche un diagramma di sintassi interattiva:

geo.distance

La geo.distance funzione accetta due parametri di tipo Edm.GeographyPoint e restituisce un Edm.Double valore che corrisponde alla distanza tra di essi in chilometri. Ciò è diverso da altri servizi che supportano operazioni geografiche OData, che in genere restituiscono distanze in metri.

Uno dei parametri da geo.distance usare deve essere una costante del punto geografico e l'altro deve essere un percorso di campo (o una variabile di intervallo nel caso di un filtro che esegue l'iterazione su un campo di tipo Collection(Edm.GeographyPoint)). L'ordine di questi parametri non è importante.

La costante del punto geografico è della forma geography'POINT(<longitude> <latitude>)', dove la longitudine e latitudine sono costanti numeriche.

Nota

Quando si usa geo.distance in un filtro, è necessario confrontare la distanza restituita dalla funzione con una costante usando lt, le, gto ge. Gli operatori eq e ne non sono supportati quando si confrontano le distanze. Ad esempio, si tratta di un utilizzo corretto di geo.distance: $filter=geo.distance(location, geography'POINT(-122.131577 47.678581)') le 5.

geo.intersects

La geo.intersects funzione accetta una variabile di tipo Edm.GeographyPoint e una costante Edm.GeographyPolygon e restituisce un setrueEdm.Boolean -- il punto si trova all'interno dei limiti del poligono, false in caso contrario.

Il poligono è una superficie bidimensionale archiviata come sequenza di punti che definiscono un anello di delimitazione (vedere gli esempi seguenti). Il poligono deve essere chiuso, quindi il primo e l'ultimo set di punti devono coincidere. I punti in un poligono devono essere in senso antiorario.

Query spaziali geografiche e poligoni che coprono il 180° meridiano

Per molte librerie di query geo-spaziali che simulano una query che include il 180° meridiano (vicino alla linea di data) è disattivata o richiede una soluzione alternativa, ad esempio suddividendo il poligono in due, uno sul lato del meridiano.

In Ricerca cognitiva di Azure, le query spaziali geografiche che includono la longitudine a 180 gradi funzioneranno come previsto se la forma della query è rettangolare e le coordinate si allineano a un layout di griglia lungo longitudine e latitudine (ad esempio, geo.intersects(location, geography'POLYGON((179 65, 179 66, -179 66, -179 65, 179 65))'). In caso contrario, per le forme non rettangolari o non allineate, considerare l'approccio basato sulla suddivisione del poligono.

Funzioni spaziali geografiche e null

Come tutti gli altri campi non di raccolta in Ricerca cognitiva di Azure, i campi di tipo Edm.GeographyPoint possono contenere null valori. Quando Ricerca cognitiva di Azure valuta geo.intersects per un campo che è null, il risultato sarà falsesempre . Il comportamento di geo.distance in questo caso dipende dal contesto:

  • Nei filtri, geo.distance di un null campo viene restituito .null Ciò significa che il documento non corrisponde perché null rispetto a falsequalsiasi valore non Null restituisce .
  • Quando si ordinano i risultati usando $orderby, geo.distance di un null campo viene restituita la distanza massima possibile. I documenti con tale campo verranno ordinati in basso rispetto a tutti gli altri quando viene usata la direzione asc di ordinamento (impostazione predefinita) e superiore a tutte le altre quando la direzione è desc.

Esempio

Esempi di filtro

Trovare tutti gli alberghi entro 10 chilometri di un determinato punto di riferimento (dove posizione è un campo di tipo Edm.GeographyPoint):

    geo.distance(location, geography'POINT(-122.131577 47.678581)') le 10

Trovare tutti gli alberghi all'interno di un determinato viewport descritto come poligono (dove posizione è un campo di tipo Edm.GeographyPoint). Si noti che il poligono è chiuso (il primo e l'ultimo set di punti devono coincidere) e che i punti devono essere elencati in senso antiorario.

    geo.intersects(location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')

Esempi di order-by

Ordinare gli hotel decrescente in ratingbase a , quindi crescente in base alla distanza dalle coordinate specificate:

    rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc

Ordinare gli hotel in ordine decrescente in search.score base a e rating, quindi in ordine crescente per distanza dalle coordinate specificate in modo che tra due hotel con classificazioni identiche, quello più vicino è elencato prima:

    search.score() desc,rating desc,geo.distance(location, geography'POINT(-122.131577 47.678581)') asc

Passaggi successivi