geo_polygon_to_s2cells()
적용 대상: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft 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 | 라스베이거스 |
이 메서드는 경우에 따라 작동하지만 비효율적입니다. 이 메서드는 교차 조인을 수행합니다. 즉, 모든 다각형을 모든 지점과 일치시키려고 합니다. 이 프로세스는 많은 양의 메모리와 컴퓨팅 리소스를 사용합니다. 대신, 모든 다각형을 포함 성공 확률이 높은 지점에 일치시키고 다른 점을 필터링하려고 합니다.
이 일치는 다음 프로세스에서 수행할 수 있습니다.
- 다각형을 수준 k의 S2 셀로 변환
- 점을 동일한 S2 셀 수준 k로 변환
- S2 셀에 조인
- 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 |