10 qtm
Working with QTM in Vgrid DGGS¶
Full Vgrid DGGS documentation is available at vgrid document.
To work with Vgrid DGGS directly in GeoPandas and Pandas, please use vgridpandas. Full Vgridpandas DGGS documentation is available at vgridpandas document.
To work with Vgrid DGGS in QGIS, install the Vgrid Plugin.
To visualize DGGS in Maplibre GL JS, try the vgrid-maplibre library.
For an interactive demo, visit the Vgrid Homepage.
# %pip install vgrid --upgrade
latlon2qtm¶
from vgrid.conversion.latlon2dggs import latlon2qtm
lat = 10.775276
lon = 106.706797
res = 14
qtm_id = latlon2qtm(lat, lon, res)
qtm_id
'42012323131211'
QTM to Polygon¶
from vgrid.conversion.dggs2geo.qtm2geo import qtm2geo
qtm_geo = qtm2geo(qtm_id)
qtm_geo
QTM to GeoJSON¶
from vgrid.conversion.dggs2geo.qtm2geo import qtm2geojson
qtm_geojson = qtm2geojson(qtm_id)
# qtm_geojson
Vector to QTM¶
(Multi)Point to QTM¶
from vgrid.conversion.vector2dggs.vector2qtm import vector2qtm
file_path = "https://raw.githubusercontent.com/opengeoshub/vopendata/main/shape/point.geojson"
point_to_qtm = vector2qtm(
file_path,
# resolution=16,
topology=True,
output_format="gpd",
)
# Visualize the output
point_to_qtm.plot(edgecolor="white")
Processing features: 100%|██████████| 12/12 [00:00<00:00, 781.91it/s]
<Axes: >
(Multi)Polygon to QTM¶
from vgrid.conversion.vector2dggs.vector2qtm import vector2qtm
file_path = "https://raw.githubusercontent.com/opengeoshub/vopendata/main/shape/polygon.geojson"
vector_to_qtm = vector2qtm(
file_path,
resolution=17,
compact=False,
predicate="intersects",
output_format="gpd",
)
# Visualize the output
vector_to_qtm.plot(edgecolor="white")
Processing features: 100%|██████████| 4/4 [00:00<00:00, 101.53it/s]
<Axes: >
QTM Compact¶
from vgrid.conversion.dggscompact import qtmcompact
qtm_compacted = qtmcompact(vector_to_qtm, qtm_id="qtm", output_format="gpd")
qtm_compacted.plot(edgecolor="white")
<Axes: >
QTM Expand¶
from vgrid.conversion.dggscompact import qtmexpand
qtm_expanded = qtmexpand(
vector_to_qtm, resolution=18, qtm_id="qtm", output_format="gpd"
)
qtm_expanded.plot(edgecolor="white")
<Axes: >
QTM Binning¶
from vgrid.binning.qtmbin import qtmbin
dggs_type = "isea9r" # choose one from ['gnosis','isea4r','isea9r','isea3h','isea7h','isea7h_z7',
# 'ivea4r','ivea9r','ivea3h','ivea7h','ivea7h_z7','rtea4r','rtea9r','rtea3h','rtea7h','rtea7h_z7','healpix','rhealpix']
file_path = (
"https://raw.githubusercontent.com/opengeoshub/vopendata/main/csv/housing.csv"
)
stats = "max"
numeric_col="median_house_value"
qtm_bin = qtmbin(
file_path,
resolution=10,
stats=stats,
numeric_col=numeric_col,
# category_col="category",
output_format="gpd",
)
qtm_bin.plot(
column= f"{numeric_col}_{stats}", # numeric column to base the colors on
cmap="Spectral_r", # color scheme (matplotlib colormap)
legend=True,
linewidth=0.2, # boundary width (optional)
)
Generating QTM DGGS: 100%|██████████| 10/10 [00:00<00:00, 14.97it/s]
<Axes: >
Raster to QTM¶
QTM Resampling¶
from vgrid.conversion.dggsresample import dggsresample
qtm_resample = dggsresample(
source_dggs=qtm_bin,
dggs_from="qtm",
dggs_to="a5",
method = "nearest", # area_weighted, nearest
dggs_col="qtm",
resample_col=f"{numeric_col}_{stats}", # column on h3_bin with numbers
fix_antimeridian=None,
split_antimeridian=False,
)
qtm_resample.plot(
column=f"{numeric_col}_{stats}", # numeric column to base the colors on
cmap="Spectral_r", # color scheme (matplotlib colormap)
legend=True,
linewidth=0.2, # boundary width (optional)
)
Generating A5 cells: 100%|██████████| 7709/7709 [00:00<00:00, 17703.10 cells/s] Nearest neighbor resampling: 100%|██████████| 2712/2712 [00:00<00:00, 29344.04 cells/s]
<Axes: >
Download and open raster¶
# %pip install folium
from vgrid.utils.io import download_file
import rasterio
from rasterio.plot import show
raster_url = (
"https://raw.githubusercontent.com/opengeoshub/vopendata/main/raster/rgb.tif"
)
raster_file = download_file(raster_url)
src = rasterio.open(raster_file, "r")
print(src.meta)
show(src)
rgb.tif already exists. Skip downloading. Set overwrite=True to overwrite.
{'driver': 'GTiff', 'dtype': 'uint8', 'nodata': None, 'width': 240, 'height': 147, 'count': 3, 'crs': CRS.from_wkt('GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]'), 'transform': Affine(2.6640125000199077e-06, 0.0, 106.708118755,
0.0, -2.6640136054383103e-06, 10.812568272)}
<Axes: >
Convert raster to QTM¶
from vgrid.conversion.raster2dggs.raster2qtm import raster2qtm
raster_to_qtm = raster2qtm(raster_file, resolution=23,
method = 'binning', # nearest, binning
stats = 'mean', output_format="gpd")
# Visualize the output
import folium
m = folium.Map(tiles="CartoDB positron", max_zoom=28)
qtm_layer = folium.GeoJson(
raster_to_qtm,
style_function=lambda x: {
"fillColor": f"rgb({x['properties']['band_1']}, {x['properties']['band_2']}, {x['properties']['band_3']})",
"fillOpacity": 1,
"color": "black",
"weight": 1,
},
popup=folium.GeoJsonPopup(
fields=["qtm", "band_1", "band_2", "band_3"],
aliases=["QTM ID", "Band 1", "Band 2", "Band 3"],
style="""
background-color: white;
border: 2px solid black;
border-radius: 3px;
box-shadow: 3px;
""",
),
).add_to(m)
m.fit_bounds(qtm_layer.get_bounds())
# Display the map
m
Method: binning Stats: mean
Binning raster blocks to QTM: 0%| | 0/14 [00:00<?, ? block/s]
Binning raster blocks to QTM: 100%|██████████| 14/14 [03:44<00:00, 16.05s/ block] Converting raster to QTM: 100%|██████████| 999/999 [00:00<00:00, 2605.42 cells/s]
QTM Generator¶
from vgrid.generator.qtmgrid import qtmgrid
bbox=[106.699007, 10.762811, 106.717674, 10.778649],
# qtm_grid = qtmgrid(resolution=4, output_format="gpd")
qtm_grid = qtmgrid(resolution=18,
bbox=bbox,
compact = True,
output_format="gpd")
qtm_grid.plot(edgecolor="white")
Generating QTM DGGS: 100%|██████████| 18/18 [00:00<00:00, 106.29it/s] Building QTM cells: 100%|██████████| 138/138 [00:00<00:00, 7818.43 cells/s]
<Axes: >
QTM Inspect¶
from vgrid.stats.qtmstats import qtminspect
resolution = 6
qtm_inspect = qtminspect(resolution)
qtm_inspect.head()
Generating QTM DGGS: 100%|██████████| 6/6 [00:00<00:00, 8.92it/s]
| qtm | resolution | center_lat | center_lon | avg_edge_len | cell_area | cell_perimeter | geometry | crossed | norm_area | ipq | zsc | cvh | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 100000 | 6 | 30.0000 | -135.000000 | 410382.857507 | 7.154394e+10 | 1.231149e+06 | POLYGON ((-135 28.125, -132.61779 30.9375, -13... | False | 1.149044 | 0.593146 | 0.770106 | 1.0 |
| 1 | 100001 | 6 | 31.8750 | -135.000000 | 407835.169754 | 7.046575e+10 | 1.223506e+06 | POLYGON ((-137.38221 30.9375, -132.61779 30.93... | False | 1.131728 | 0.591529 | 0.769056 | 1.0 |
| 2 | 100002 | 6 | 29.0625 | -137.326039 | 405961.346376 | 6.991932e+10 | 1.217884e+06 | POLYGON ((-139.5959 28.125, -135 28.125, -137.... | False | 1.122952 | 0.592373 | 0.769605 | 1.0 |
| 3 | 100003 | 6 | 29.0625 | -132.673961 | 405961.346376 | 6.991932e+10 | 1.217884e+06 | POLYGON ((-135 28.125, -130.4041 28.125, -132.... | False | 1.122952 | 0.592373 | 0.769605 | 1.0 |
| 4 | 100010 | 6 | 26.2500 | -135.000000 | 404706.087490 | 6.957179e+10 | 1.214118e+06 | POLYGON ((-137.23 25.3125, -132.77 25.3125, -1... | False | 1.117370 | 0.593091 | 0.770071 | 1.0 |
qtm_inspect.to_file("qtm_6.geojson")
QTM Normalized Area Histogram¶
from vgrid.stats.qtmstats import qtm_norm_area_hist
qtm_norm_area_hist(qtm_inspect)
Distribution of QTM Area Distortions¶
from vgrid.stats.qtmstats import qtm_norm_area
qtm_norm_area(qtm_inspect)
QTM IPQ Compactness Histogram¶
Isoperimetric Inequality (IPQ) Compactness (suggested by Osserman, 1978):
$$C_{IPQ} = \frac{4 \pi A}{p^2}$$ The range of the IPQ compactness metric is [0,1].
A circle represents the maximum compactness with a value of 1.
As shapes become more irregular or elongated, their compactness decreases toward 0.
from vgrid.stats.qtmstats import qtm_compactness_ipq_hist
qtm_compactness_ipq_hist(qtm_inspect)
Distribution of QTM IPQ Compactness¶
from vgrid.stats.qtmstats import qtm_compactness_ipq
qtm_compactness_ipq(qtm_inspect)
QTM Convex hull Compactness Histogram:¶
$$C_{CVH} = \frac{A}{A_{CVH}}$$
The range of the convex hull compactness metric is [0,1].
As shapes become more concave, their convex hull compactness decreases toward 0.
from vgrid.stats.qtmstats import qtm_compactness_cvh_hist
qtm_compactness_cvh_hist(qtm_inspect)
Distribution of QTM Convex hull Compactness¶
from vgrid.stats.qtmstats import qtm_compactness_cvh
qtm_compactness_cvh(qtm_inspect)
QTM Statistics¶
Characteristic Length Scale (CLS - suggested by Ralph Kahn): the diameter of a spherical cap of the same cell's area
from vgrid.stats import qtmstats
qtmstats("m")
| resolution | number_of_cells | avg_edge_len_m | avg_cell_area_m2 | cls_m | |
|---|---|---|---|---|---|
| 0 | 1 | 8 | 1.213438e+07 | 6.375820e+13 | 9.209090e+06 |
| 1 | 2 | 32 | 6.067192e+06 | 1.593955e+13 | 4.528782e+06 |
| 2 | 3 | 128 | 3.033596e+06 | 3.984888e+12 | 2.255434e+06 |
| 3 | 4 | 512 | 1.516798e+06 | 9.962219e+11 | 1.126613e+06 |
| 4 | 5 | 2048 | 7.583990e+05 | 2.490555e+11 | 5.631686e+05 |
| 5 | 6 | 8192 | 3.791995e+05 | 6.226387e+10 | 2.815671e+05 |
| 6 | 7 | 32768 | 1.895997e+05 | 1.556597e+10 | 1.407814e+05 |
| 7 | 8 | 131072 | 9.479987e+04 | 3.891492e+09 | 7.039044e+04 |
| 8 | 9 | 524288 | 4.739994e+04 | 9.728730e+08 | 3.519519e+04 |
| 9 | 10 | 2097152 | 2.369997e+04 | 2.432182e+08 | 1.759759e+04 |
| 10 | 11 | 8388608 | 1.184998e+04 | 6.080456e+07 | 8.798794e+03 |
| 11 | 12 | 33554432 | 5.924992e+03 | 1.520114e+07 | 4.399397e+03 |
| 12 | 13 | 134217728 | 2.962496e+03 | 3.800285e+06 | 2.199698e+03 |
| 13 | 14 | 536870912 | 1.481248e+03 | 9.500713e+05 | 1.099849e+03 |
| 14 | 15 | 2147483648 | 7.406240e+02 | 2.375178e+05 | 5.499246e+02 |
| 15 | 16 | 8589934592 | 3.703120e+02 | 5.937945e+04 | 2.749623e+02 |
| 16 | 17 | 34359738368 | 1.851560e+02 | 1.484486e+04 | 1.374812e+02 |
| 17 | 18 | 137438953472 | 9.257800e+01 | 3.711216e+03 | 6.874058e+01 |
| 18 | 19 | 549755813888 | 4.628900e+01 | 9.278040e+02 | 3.437029e+01 |
| 19 | 20 | 2199023255552 | 2.314450e+01 | 2.319510e+02 | 1.718514e+01 |
| 20 | 21 | 8796093022208 | 1.157225e+01 | 5.798775e+01 | 8.592572e+00 |
| 21 | 22 | 35184372088832 | 5.786125e+00 | 1.449694e+01 | 4.296286e+00 |
| 22 | 23 | 140737488355328 | 2.893062e+00 | 3.624234e+00 | 2.148143e+00 |
| 23 | 24 | 562949953421312 | 1.446531e+00 | 9.060586e-01 | 1.074071e+00 |