以前サンプルノートブックを動かしましたが、理解が表層的でした。なので、きちんと動かして理解したいと思いました。
全部は動かしませんが、主要なところを。
h3_coverash3
h3_coverash3(geographyExpr, resolutionExpr)
入力された線形、領域ジオグラフィを完全にカバーし、指定された解像度の六角形、五角形の最小セットに対応するH3セルID(BIGINT表現)のARRAYを返却します。
分かるような分からないような。なので、目で確認します。可視化はMosaicを使います。
%pip install "databricks-mosaic==0.4.0"
# -- mosaicのセットアップ
import mosaic as mos
mos.enable_mosaic(spark, dbutils)
# -- databricks + spark 関数のインポート
from pyspark.sql import functions as F
from pyspark.sql.functions import col, udf
from pyspark.sql.types import *
# -- その他のインポート
import os
import pathlib
import requests
import warnings
ジオグラフィを用意します。
# ジオグラフィ(ポリゴン)
geography = "POLYGON((-122.4194 37.7749,-118.2437 34.0522,-74.0060 40.7128,-122.4194 37.7749))"
geo_df = spark.sql(
f"SELECT '{geography}' AS polygon"
)
display(geo_df)
これで形状を理解するのは困難なので地図上に表示します。%%mosaic_kepler
マジックコマンドでお手軽にプロットできます。
%%mosaic_kepler
geo_df "polygon" "geometry"
それではh3_coverash3
を使います。二つ目の引数は解像度です。explode
を使っているのはセルIDをレコードに分解するためです。
h3_df = spark.sql(
f"SELECT h3_coverash3('{geography}', 0) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
これも可視化します。
%%mosaic_kepler
h3_df "H3_cells" "h3" 10
分かってきました。まさしく、指定された解像度でジオメトリを完全にカバーするポリゴンのセルIDを返却すると言うことですね。
なので、解像度を上げると…。
h3_df = spark.sql(
f"SELECT h3_coverash3('{geography}', 1) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
これを可視化すると。
%%mosaic_kepler
h3_df "H3_cells" "h3" 10
h3_longlatash3
h3_longlatash3(longitudeExpr, latitudeExpr, resolutionExpr)
これはシンプル。指定された緯度経度に対応するセルIDを返却します。
lon = -122.4783
lat = 37.8199
# ジオメトリ(ポイント)
geometry = f"POINT({lon} {lat})"
geo_df = spark.sql(
f"SELECT '{geometry}' AS point"
)
display(geo_df)
%%mosaic_kepler
geo_df "point" "geometry"
h3_df = spark.sql(
f"SELECT h3_longlatash3({lon}, {lat}, 13) AS H3_cells"
)
display(h3_df)
635714569676958015
%%mosaic_kepler
h3_df "H3_cells" "h3"
h3_pointash3(geographyExpr, resolutionExpr)はジオグラフィ形式で受け取ると言うことで。
h3_polyfillash3
入力領域ジオグラフィに包含される、指定された解像度の六角形、五角形に対応するH3セルID(BIGINT)のARRAYを返却します。
h3_coverash3と若干違います。
# ジオグラフィ(ポリゴン)
geography = "POLYGON((-122.4194 37.7749,-118.2437 34.0522,-74.0060 40.7128,-122.4194 37.7749))"
geo_df = spark.sql(
f"SELECT '{geography}' AS polygon"
)
display(geo_df)
POLYGON((-122.4194 37.7749,-118.2437 34.0522,-74.0060 40.7128,-122.4194 37.7749))
上と同じジオグラフィで。
%%mosaic_kepler
geo_df "polygon" "geometry"
h3_df = spark.sql(
f"SELECT h3_polyfillash3('{geography}', 0) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
クエリー結果が返されませんでした
これも分かってきました。解像度が0なのがミソ。1にします。
h3_df = spark.sql(
f"SELECT h3_polyfillash3('{geography}', 1) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
返ってきました。
581698825698148351
%%mosaic_kepler
h3_df "H3_cells" "h3"
説明の通り、ジオグラフィに内包されるセルを返却すると言うことですね。解像度が低いとセルが大きくてジオグラフィに入りきらなかったのでした。さらに解像度を上げると…。
h3_df = spark.sql(
f"SELECT h3_polyfillash3('{geography}', 2) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
H3_cells
586146350232502271
586147449744130047
586198577034821631
586152397546455039
586199676546449407
586153497058082815
586142501941805055
586201325813891071
%%mosaic_kepler
h3_df "H3_cells" "h3"
h3_df = spark.sql(
f"SELECT h3_polyfillash3('{geography}', 3) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
h3_ischildof
h3_ischildof(h3CellId1Expr, h3CellId2Expr)
最初のH3セルIDが2番目のH3セルIDと同じあるいは子供関係である場合にtrueを返却します。
動作確認します。
%sql
SELECT h3_ischildof(608693241318998015, 599686042433355775)
h3_ischildof(608693241318998015, 599686042433355775)
true
これも目で確認します。
h3_df = spark.sql(
"SELECT col1 AS H3_cells FROM VALUES 608693241318998015, 599686042433355775"
)
display(h3_df)
H3_cells
608693241318998015
599686042433355775
%%mosaic_kepler
h3_df "H3_cells" "h3"
デフォルト表示だと(当然ですが)被ってしまうので、サイドメニューのcoverageを調整します。
h3_hexring
h3_hexring(h3CellIdExpr, kExpr)
オリジンのH3セルを中心とし、オリジンH3セルからkのグリッド距離を持つ空洞六角形リングを形成するH3セルIDの配列を返却します。
これも目で見てみましょう。
cell_id = 599686042433355775
h3_df = spark.sql(
f"SELECT {cell_id} AS H3_cells"
)
display(h3_df)
H3_cells
599686042433355775
%%mosaic_kepler
h3_df "H3_cells" "h3"
h3_df = spark.sql(
f"SELECT h3_hexring({cell_id}, 1) AS H3_cells"
).select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
H3_cells
599686014516068351
599686030622195711
599686044580839423
599686038138388479
599686043507097599
599686015589810175
%%mosaic_kepler
h3_df "H3_cells" "h3"
h3_compact
入力されたH3セルIDのセットを可能な限りコンパクトにします。
h3_df = spark.sql("SELECT col1 AS H3_cells FROM VALUES 599686042433355775,599686030622195711,599686044580839423,599686038138388479,599686043507097599,599686015589810175,599686014516068351,599686034917163007,599686029548453887,599686032769679359,599686198125920255,599686040285872127,599686041359613951,599686039212130303,599686023106002943,599686027400970239,599686013442326527,599686012368584703,599686018811035647")
display(h3_df)
H3_cells
599686042433355775
599686030622195711
599686044580839423
599686038138388479
599686043507097599
599686015589810175
599686014516068351
599686034917163007
599686029548453887
599686032769679359
599686198125920255
599686040285872127
599686041359613951
599686039212130303
599686023106002943
599686027400970239
599686013442326527
599686012368584703
599686018811035647
%%mosaic_kepler
h3_df "H3_cells" "h3"
h3_df = spark.sql("SELECT h3_compact(ARRAY(599686042433355775,599686030622195711,599686044580839423,599686038138388479,599686043507097599,599686015589810175,599686014516068351,599686034917163007,599686029548453887,599686032769679359,599686198125920255,599686040285872127,599686041359613951,599686039212130303,599686023106002943,599686027400970239,599686013442326527,599686012368584703,599686018811035647)) AS H3_cells").select(F.explode(col("H3_cells")).alias("H3_cells"))
display(h3_df)
H3_cells
599686030622195711
599686015589810175
599686014516068351
599686034917163007
599686029548453887
599686032769679359
599686198125920255
599686023106002943
599686027400970239
599686013442326527
599686012368584703
599686018811035647
595182446027210751
%%mosaic_kepler
h3_df "H3_cells" "h3"
H3面白い。