다음을 통해 공유


geo_polygon_to_s2cells()

적용 대상: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

지구의 다각형 또는 다각형을 포함하는 S2 셀 토큰을 계산합니다. 이 함수는 유용한 지리 공간적 조인 도구입니다.

S2 셀 계층 구조에 대해 자세히 알아보세요.

구문

geo_polygon_to_s2cells(polygon [, level[, radius]])

구문 규칙에 대해 자세히 알아봅니다.

매개 변수

이름 Type 필수 설명
다각형 dynamic ✔️ GeoJSON 형식다각형 또는 다각형입니다.
level int 요청된 셀 수준을 정의합니다. 지원되는 값은 [0, 30] 범위에 있습니다. 지정하지 않으면 기본값 11 이 사용됩니다.
반지름 real 버퍼 반경(미터)입니다. 지정하지 않으면 기본값 0 이 사용됩니다.

반품

다각형 또는 다각형을 포함하는 S2 셀 토큰 문자열의 배열입니다. 반지름이 양수 값으로 설정된 경우 입력 도형 외에 입력 기하 도형의 반지름 내에 있는 모든 점의 덮개가 됩니다. 다각형, 수준, 반경이 잘못되었거나 셀 수가 제한을 초과하면 쿼리에서 null 결과를 생성합니다.

참고 항목

  • 다각형을 S2 셀 토큰으로 덮는 것은 이러한 좌표를 포함할 수 있는 다각형에 좌표를 일치시키고 다각형과 다각형을 일치시키는 데 유용할 수 있습니다.
  • 다각형 덮개 토큰은 동일한 S2 셀 수준입니다.
  • 다각형당 최대 토큰 수는 65536개입니다.
  • 지구 측정에 사용되는 측지 데이텀은 구입니다. 다각형 가장자리는 구의 측지식 입니다.
  • 입력 다각형 가장자리가 직선 카티전 선인 경우 평면 가장자리를 측지로 변환하기 위해 geo_polygon_densify()를 사용하는 것이 좋습니다.

S2 셀 토큰을 사용하여 다각형을 포함하는 동기 부여

이 함수가 없으면 좌표를 이러한 좌표가 포함된 다각형으로 분류하기 위해 수행할 수 있는 한 가지 방법이 있습니다.

let Polygons = 
    datatable(description:string, polygon:dynamic)
    [  
      "New York",  dynamic({"type":"Polygon","coordinates":[[[-73.85009765625,40.85744791303121],[-74.16046142578125,40.84290487729676],[-74.190673828125,40.59935608796518],[-73.83087158203125,40.61812224225511],[-73.85009765625,40.85744791303121]]]}),
      "Seattle",   dynamic({"type":"Polygon","coordinates":[[[-122.200927734375,47.68573021131587],[-122.4591064453125,47.68573021131587],[-122.4755859375,47.468949677672484],[-122.17620849609374,47.47266286861342],[-122.200927734375,47.68573021131587]]]}),
      "Las Vegas", dynamic({"type":"Polygon","coordinates":[[[-114.9,36.36],[-115.4498291015625,36.33282808737917],[-115.4498291015625,35.84453450421662],[-114.949951171875,35.902399875143615],[-114.9,36.36]]]}),
    ];
let Coordinates = 
    datatable(longitude:real, latitude:real)
    [
      real(-73.95),  real(40.75), // New York
      real(-122.3),  real(47.6),  // Seattle
      real(-115.18), real(36.16)  // Las Vegas
    ];
Polygons | extend dummy=1
| join kind=inner (Coordinates | extend dummy=1) on dummy
| where geo_point_in_polygon(longitude, latitude, polygon)
| project longitude, latitude, description

출력

longitude latitude description
-73.95 40.75 뉴욕 시
-122.3 47.6 Seattle
-115.18 36.16 라스베이거스

이 메서드는 경우에 따라 작동하지만 비효율적입니다. 이 메서드는 교차 조인을 수행합니다. 즉, 모든 다각형을 모든 지점과 일치시키려고 합니다. 이 프로세스는 많은 양의 메모리와 컴퓨팅 리소스를 사용합니다. 대신, 모든 다각형을 포함 성공 확률이 높은 지점에 일치시키고 다른 점을 필터링하려고 합니다.

이 일치는 다음 프로세스에서 수행할 수 있습니다.

  1. 다각형을 수준 k의 S2 셀로 변환
  2. 점을 동일한 S2 셀 수준 k로 변환
  3. S2 셀에 조인
  4. geo_point_in_polygon()필터링합니다. 가양성의 양이 정상인 경우 이 단계를 생략할 수 있습니다. 최대 오류는 다각형 경계를 넘어 수준 k의 s2 셀 영역입니다.

S2 셀 수준 선택

  • 두 다각형이 동일한 셀을 공유하지 않도록 모든 다각형을 하나 또는 몇 개의 고유한 셀로 덮는 것이 이상적입니다.
  • 다각형이 서로 가까이 있는 경우 셀 가장자리가 평균 다각형의 가장자리보다 작도록 S2 셀 수준을 선택합니다(4, 8, 12배 작음).
  • 다각형이 서로 멀리 떨어져 있는 경우 셀 가장자리가 평균 다각형의 가장자리보다 비슷하거나 크거나 되도록 S2 셀 수준을 선택합니다.
  • 실제로 10,000개 이상의 셀로 다각형을 덮어도 성능이 좋지 않을 수 있습니다.
  • 샘플 사용 사례:
  • S2 셀 수준 5는 국가/지역을 포괄하는 데 적합할 수 있습니다.
  • S2 셀 수준 16은 밀집되고 상대적으로 작은 맨해튼 (뉴욕) 지역을 커버 할 수 있습니다.
  • S2 셀 수준 11은 호주 교외를 커버하는 데 사용할 수 있습니다.
  • 쿼리 런타임 및 메모리 사용량은 S2 셀 수준 값이 다르기 때문에 크게 다를 수 있습니다.

Warning

작은 영역 셀로 넓은 영역 다각형을 덮는 것은 셀을 덮는 엄청난 양의 이어질 수 있습니다. 결과적으로 쿼리는 null을 반환할 수 있습니다.

참고 항목

성능 향상 제안:

  • 가능하면 지리 공간적 클러스터링을 사용하거나 데이터 또는 비즈니스 요구 사항의 특성으로 인해 중요하지 않은 좌표를 필터링하여 서로 매우 가까운 좌표를 그룹화하여 조인하기 전에 좌표 테이블 크기를 줄입니다.
  • 가능하면 데이터 또는 비즈니스 요구 사항의 특성으로 인해 다각형 수를 줄입니다. 조인하기 전에 불필요한 다각형을 필터링하거나 관심 영역으로 범위를 지정하거나 다각형을 통합합니다.
  • 매우 큰 다각형의 경우 geo_polygon_simplify()를 사용하여 크기를 줄입니다.
  • S2 셀 수준을 변경하면 성능 및 메모리 사용량이 향상될 수 있습니다.
  • 조인 종류 및 힌트를 변경하면 성능 및 메모리 사용량이 향상될 수 있습니다.
  • 양수 반지름이 설정된 경우 geo_polygon_buffer()를 사용하여 버퍼링된 셰이프에서 반지름 0으로 되돌려 성능을 향상시킬 수 있습니다.

예제

다음 예제에서는 좌표를 다각형으로 분류합니다.

let Polygons = 
    datatable(description:string, polygon:dynamic)
    [
        'Greenwich Village', dynamic({"type":"Polygon","coordinates":[[[-73.991460000000131,40.731738000000206],[-73.992854491775518,40.730082566051351],[-73.996772,40.725432000000154],[-73.997634685522883,40.725786309886963],[-74.002855946639244,40.728346630056791],[-74.001413,40.731065000000207],[-73.996796995070824,40.73736378205173],[-73.991724524037934,40.735245208931886],[-73.990703782359589,40.734781896080477],[-73.991460000000131,40.731738000000206]]]}),
        'Upper West Side',   dynamic({"type":"Polygon","coordinates":[[[-73.958357552055688,40.800369095633819],[-73.98143901556422,40.768762584141953],[-73.981548752788598,40.7685590292784],[-73.981565335901905,40.768307084720796],[-73.981754418060945,40.768399727738668],[-73.982038573548124,40.768387823012056],[-73.982268248204349,40.768298621883247],[-73.982384797518051,40.768097213086911],[-73.982320919746599,40.767894461792181],[-73.982155532845766,40.767756204474757],[-73.98238873834039,40.767411004834273],[-73.993650353659021,40.772145571634361],[-73.99415893763998,40.772493009137818],[-73.993831082030937,40.772931787850908],[-73.993891252437052,40.772955194876722],[-73.993962585514595,40.772944653908901],[-73.99401262480508,40.772882846631894],[-73.994122058082397,40.77292405902601],[-73.994136652588594,40.772901870174394],[-73.994301342391154,40.772970028663913],[-73.994281535134448,40.77299380206933],[-73.994376552751078,40.77303955110149],[-73.994294029824005,40.773156243992048],[-73.995023275860802,40.773481196576356],[-73.99508939189289,40.773388475039134],[-73.995013963716758,40.773358035426909],[-73.995050284699261,40.773297153189958],[-73.996240651898916,40.773789791397689],[-73.996195837470992,40.773852356184044],[-73.996098807369748,40.773951805299085],[-73.996179459973888,40.773986954351571],[-73.996095245226442,40.774086186437756],[-73.995572265161172,40.773870731394297],[-73.994017424135961,40.77321375261053],[-73.993935876811335,40.773179512586211],[-73.993861942928888,40.773269531698837],[-73.993822393527211,40.773381758622882],[-73.993767019318497,40.773483981224835],[-73.993698463744295,40.773562141052594],[-73.993358326468751,40.773926888327956],[-73.992622663865575,40.774974056037109],[-73.992577842766124,40.774956016359418],[-73.992527743951555,40.775002110439829],[-73.992469745815342,40.775024159551755],[-73.992403837191887,40.775018140390664],[-73.99226708903538,40.775116033858794],[-73.99217809026365,40.775279293897171],[-73.992059084937338,40.775497598192516],[-73.992125372394938,40.775509075053385],[-73.992226867797001,40.775482211026116],[-73.992329346608813,40.775468900958522],[-73.992361756801131,40.775501899766638],[-73.992386042960277,40.775557180424634],[-73.992087684712729,40.775983970821372],[-73.990927174149746,40.777566878763238],[-73.99039616003671,40.777585065679204],[-73.989461267506471,40.778875124584417],[-73.989175778438053,40.779287524015778],[-73.988868617400072,40.779692922911607],[-73.988871874499793,40.779713738253008],[-73.989219022880576,40.779697895209402],[-73.98927785904425,40.779723439271038],[-73.989409054180143,40.779737706471963],[-73.989498614927044,40.779725044389757],[-73.989596493388234,40.779698146683387],[-73.989679812902509,40.779677568658038],[-73.989752702937935,40.779671244211556],[-73.989842247806507,40.779680752670664],[-73.990040102120489,40.779707677698219],[-73.990137977524839,40.779699769704784],[-73.99033584033225,40.779661794394983],[-73.990430598697046,40.779664973055503],[-73.990622199396725,40.779676064914298],[-73.990745069505479,40.779671328184051],[-73.990872114282197,40.779646007643876],[-73.990961672224358,40.779639683751753],[-73.991057472829539,40.779652352625774],[-73.991157429497036,40.779669775606465],[-73.991242817404469,40.779671367084504],[-73.991255318289745,40.779650782516491],[-73.991294887120119,40.779630209208889],[-73.991321967649895,40.779631796041372],[-73.991359455569423,40.779585883337383],[-73.991551059227476,40.779574821437407],[-73.99141982585985,40.779755280287233],[-73.988886144117032,40.779878898532999],[-73.988939656706265,40.779956178440393],[-73.988926103530844,40.780059292013632],[-73.988911680264692,40.780096037146606],[-73.988919261468567,40.780226094343945],[-73.988381050202634,40.780981074045783],[-73.988232413846987,40.781233144215555],[-73.988210420831663,40.781225482542055],[-73.988140000000143,40.781409000000224],[-73.988041288067166,40.781585961353777],[-73.98810029382463,40.781602878305286],[-73.988076449145055,40.781650935001608],[-73.988018059972219,40.781634188810422],[-73.987960792842145,40.781770987031535],[-73.985465811970457,40.785360700575431],[-73.986172704965611,40.786068452258647],[-73.986455862401996,40.785919219081421],[-73.987072345615601,40.785189638820121],[-73.98711901394276,40.785210319004058],[-73.986497781023601,40.785951202887254],[-73.986164628806279,40.786121882448327],[-73.986128422486075,40.786239001331111],[-73.986071135219746,40.786240706026611],[-73.986027274789123,40.786228964236727],[-73.986097637849426,40.78605822569795],[-73.985429321269592,40.785413942184597],[-73.985081137732209,40.785921935110366],[-73.985198833254501,40.785966552197777],[-73.985170502389906,40.78601333415817],[-73.985216218673656,40.786030501816427],[-73.98525509797993,40.785976205511588],[-73.98524273937646,40.785972572653328],[-73.98524962933017,40.785963139855845],[-73.985281779186749,40.785978620950075],[-73.985240032884533,40.786035858136792],[-73.985683885242182,40.786222123919686],[-73.985717529004575,40.786175994668795],[-73.985765660297687,40.786196274858618],[-73.985682871922691,40.786309786213067],[-73.985636270930442,40.786290150649279],[-73.985670722564691,40.786242911993817],[-73.98520511880038,40.786047669212785],[-73.985211035607492,40.786039554883686],[-73.985162639946992,40.786020999769754],[-73.985131636312062,40.786060297019972],[-73.985016964065125,40.78601423719563],[-73.984655078830457,40.786534741807841],[-73.985743787901043,40.786570082854738],[-73.98589227228328,40.786426529019593],[-73.985942854994988,40.786452847880334],[-73.985949561556794,40.78648711396653],[-73.985812373526713,40.786616865357047],[-73.985135209703174,40.78658761889551],[-73.984619428584324,40.786586016349787],[-73.981952458164173,40.790393724337193],[-73.972823037363767,40.803428052816756],[-73.971036786332192,40.805918478839672],[-73.966701,40.804169000000186],[-73.959647,40.801156000000113],[-73.958508540159471,40.800682279767472],[-73.95853274080838,40.800491362464697],[-73.958357552055688,40.800369095633819]]]}),
        'Upper East Side',   dynamic({"type":"Polygon","coordinates":[[[-73.943592454622546,40.782747908206574],[-73.943648235390199,40.782656161333449],[-73.943870759887162,40.781273026571704],[-73.94345932494096,40.780048275653243],[-73.943213862652243,40.779317588660199],[-73.943004239504688,40.779639495474292],[-73.942716005450905,40.779544169476175],[-73.942712374762181,40.779214856940001],[-73.942535563208608,40.779090956062532],[-73.942893408188027,40.778614093246276],[-73.942438481745029,40.777315235766039],[-73.942244919522594,40.777104088947254],[-73.942074188038887,40.776917846977142],[-73.942002667222781,40.776185317382648],[-73.942620205199006,40.775180871576474],[-73.94285645694552,40.774796600349191],[-73.94293043781397,40.774676268036011],[-73.945870899588215,40.771692257932997],[-73.946618690150586,40.77093339256956],[-73.948664164778933,40.768857624399587],[-73.950069793030679,40.767025088383498],[-73.954418260786071,40.762184104951245],[-73.95650786241211,40.760285256574043],[-73.958787773424007,40.758213471309809],[-73.973015157270069,40.764278692864671],[-73.955760332998182,40.787906554459667],[-73.944023,40.782960000000301],[-73.943592454622546,40.782747908206574]]]}),
    ];
let Coordinates = 
    datatable(longitude:real, latitude:real)
    [
        real(-73.9741), 40.7914, // Upper West Side
        real(-73.9950), 40.7340, // Greenwich Village
        real(-73.9584), 40.7688, // Upper East Side
    ];
let Level = 16;
Polygons
| extend covering = geo_polygon_to_s2cells(polygon, Level) // cover every polygon with s2 cell token array
| mv-expand covering to typeof(string)                     // expand cells array such that every row will have one cell mapped to its polygon
| join kind=inner hint.strategy=broadcast                  // assume that Polygons count is small (In some specific case)
(
    Coordinates
    | extend covering = geo_point_to_s2cell(longitude, latitude, Level) // cover point with cell
) on covering // join on the cell, this filters out rows of point and polygons where the point definitely does not belong to the polygon
| where geo_point_in_polygon(longitude, latitude, polygon) // final filtering for exact result
| project longitude, latitude, description

출력

longitude latitude description
-73.9741 40.7914 어퍼 웨스트 사이드
-73.995 40.734 그리니치 빌리지
-73.9584 40.7688 어퍼 이스트 사이드

위의 쿼리에 대한 향상된 기능은 다음과 같습니다. 미국 주당 폭풍 이벤트 수를 계산합니다. 아래 쿼리는 조인을 통해 다각형을 전달하지 않고 조회 연산자를 사용하기 때문에 매우 효율적인 조인을 수행합니다.

let Level = 6;
let polygons = materialize(
    US_States
    | project StateName = tostring(features.properties.NAME), polygon = features.geometry, id = new_guid());
let tmp = 
    polygons
    | project id, covering = geo_polygon_to_s2cells(polygon, Level) 
    | mv-expand covering to typeof(string)
    | join kind=inner hint.strategy=broadcast
            (
                StormEvents
                | project lng = BeginLon, lat = BeginLat
                | project lng, lat, covering = geo_point_to_s2cell(lng, lat, Level)
            ) on covering
    | project-away covering, covering1;
tmp | lookup polygons on id
| project-away id
| where geo_point_in_polygon(lng, lat, polygon)
| summarize StormEventsCountByState = count() by StateName

출력

StateName StormEventsCountByState
Florida 960
조지아 1,085
... ...

다음 예제에서는 관심 있는 다각형의 영역과 교차하지 않는 다각형을 필터링합니다. 최대 오류는 s2cell 길이의 대각선입니다. 이 예제는 야간 래스터 파일의 다각형 지구를 기반으로 합니다.

let intersection_level_hint = 7;
let area_of_interest = dynamic({"type": "Polygon","coordinates": [[[-73.94966125488281,40.79698248639272],[-73.95841598510742,40.800426144169315],[-73.98124694824219,40.76806170936614],[-73.97283554077148,40.7645513650551],[-73.94966125488281,40.79698248639272]]]});
let area_of_interest_covering = geo_polygon_to_s2cells(area_of_interest, intersection_level_hint);
EarthAtNight
| project value = features.properties.DN, polygon = features.geometry
| extend covering = geo_polygon_to_s2cells(polygon, intersection_level_hint)
| mv-apply c = covering to typeof(string) on
(
    summarize is_intersects = take_anyif(1, array_index_of(area_of_interest_covering, c) != -1)
)
| where is_intersects == 1
| count

출력

Count
83

수준 5의 S2 셀로 일부 다각형을 덮기 위해 필요한 셀의 수입니다.

let polygon = dynamic({"type":"Polygon","coordinates":[[[0,0],[0,50],[100,50],[0,0]]]});
print s2_cell_token_count = array_length(geo_polygon_to_s2cells(polygon, 5));

출력

s2_cell_token_count
286

큰 영역 다각형을 작은 영역 셀로 덮는 경우 null이 반환됩니다.

let polygon = dynamic({"type":"Polygon","coordinates":[[[0,0],[0,50],[100,50],[0,0]]]});
print geo_polygon_to_s2cells(polygon, 30);

출력

print_0

큰 영역 다각형을 작은 영역 셀로 덮는 경우 null이 반환됩니다.

let polygon = dynamic({"type":"Polygon","coordinates":[[[0,0],[0,50],[100,50],[0,0]]]});
print isnull(geo_polygon_to_s2cells(polygon, 30));

출력

print_0
1