Skip to content

DGGS Statistics

Statistics module for vgrid.

This module provides functions to calculate and display statistics for various discrete global grid systems (DGGS), including cell counts, areas, and edge lengths.

a5inspect(resolution, options={'segments': 100}, split_antimeridian=False)

Generate comprehensive inspection data for A5 DGGS cells at a given resolution.

This function creates a detailed analysis of A5 cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

A5 resolution level (0-29)

required
options

Optional dictionary of options for grid generation

{'segments': 100}
split_antimeridian bool

When True, apply antimeridian splitting to the resulting polygons. Defaults to False when None or omitted.

False

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing A5 cell inspection data with columns: - a5: A5 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/a5stats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
def a5inspect(resolution: int, options={"segments": 100}, split_antimeridian: bool = False):
    """
    Generate comprehensive inspection data for A5 DGGS cells at a given resolution.

    This function creates a detailed analysis of A5 cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: A5 resolution level (0-29)
        options: Optional dictionary of options for grid generation
        split_antimeridian: When True, apply antimeridian splitting to the resulting polygons.
            Defaults to False when None or omitted.

    Returns:
        geopandas.GeoDataFrame: DataFrame containing A5 cell inspection data with columns:
            - a5: A5 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    a5_gdf = a5grid(
        resolution, output_format="gpd", options=options, split_antimeridian=split_antimeridian
    )
    a5_gdf["crossed"] = a5_gdf["geometry"].apply(check_crossing_geom)
    a5_gdf = a5_gdf[~a5_gdf["crossed"]]  # remove cells that cross the Antimeridian

    mean_area = a5_gdf["cell_area"].mean()
    # Calculate normalized area
    a5_gdf["norm_area"] = a5_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    a5_gdf["ipq"] = 4 * np.pi * a5_gdf["cell_area"] / (a5_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    a5_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * a5_gdf["cell_area"]
            - np.power(a5_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / a5_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = a5_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    a5_gdf_lambert = get_cells_area(a5_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    a5_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        a5_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    a5_gdf["cvh"] = a5_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return a5_gdf

a5inspect_cli()

Command-line interface for A5 cell inspection.

CLI options

-r, --resolution: A5 resolution level (0-29) -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)

Source code in vgrid/stats/a5stats.py
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
def a5inspect_cli():
    """
    Command-line interface for A5 cell inspection.

    CLI options:
      -r, --resolution: A5 resolution level (0-29)
      -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-split",
        "--split_antimeridian",
        action="store_true",
        default=False,  # default is False to avoid splitting the Antimeridian by default
        help="Enable antimeridian splitting",
    )
    parser.add_argument(
        "-options",
        "--options",
        type=str,
        default=None,
        help="JSON string of options to pass to a52geo. "
             "Example: '{\"segments\": 1000}'",
    )
    args = parser.parse_args()
    resolution = args.resolution

    # Parse options JSON if provided
    options = None
    if args.options:
        try:
            options = json.loads(args.options)
        except json.JSONDecodeError as e:
            print(f"Error: Invalid JSON in options: {str(e)}")
            return

    print(a5inspect(resolution, options=options, split_antimeridian=args.split_antimeridian))

a5stats_cli()

Command-line interface for generating A5 DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/a5stats.py
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def a5stats_cli():
    """
    Command-line interface for generating A5 DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()
    unit = args.unit
    # Get the DataFrame
    df = a5stats(unit=unit)
    # Display the DataFrame
    print(df)

dggalinspect(dggs_type, resolution, split_antimeridian=False)

Generate detailed inspection data for a DGGAL DGGS type at a given resolution.

Parameters:

Name Type Description Default
dggs_type str

DGGS type supported by DGGAL

required
resolution int

Resolution level

required
split_antimeridian bool

When True, apply antimeridian splitting to the resulting polygons. Defaults to True when None or omitted.

False

Returns:

Type Description
GeoDataFrame

geopandas.GeoDataFrame with columns: - ZoneID (as provided by DGGAL output; no renaming is performed) - resolution - geometry - cell_area (m^2) - cell_perimeter (m) - crossed (bool) - norm_area (area/mean_area) - ipq (4πA/P²) - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a

Source code in vgrid/stats/dggalstats.py
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def dggalinspect(
    dggs_type: str, resolution: int, split_antimeridian: bool = False
) -> gpd.GeoDataFrame:
    """
    Generate detailed inspection data for a DGGAL DGGS type at a given resolution.

    Args:
        dggs_type: DGGS type supported by DGGAL
        resolution: Resolution level
        split_antimeridian: When True, apply antimeridian splitting to the resulting polygons.
            Defaults to True when None or omitted.

    Returns:
        geopandas.GeoDataFrame with columns:
          - ZoneID (as provided by DGGAL output; no renaming is performed)
          - resolution
          - geometry
          - cell_area (m^2)
          - cell_perimeter (m)
          - crossed (bool)
          - norm_area (area/mean_area)
          - ipq (4πA/P²)
          - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a
    """
    dggal_gdf = dggalgen(
        dggs_type,
        resolution,
        output_format="gpd",
        split_antimeridian=split_antimeridian,
    )

    # Determine whether current CRS is geographic; compute metrics accordingly
    if dggal_gdf.crs.is_geographic:
        dggal_gdf["cell_area"] = dggal_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[0])
        )
        dggal_gdf["cell_perimeter"] = dggal_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[1])
        )
        dggal_gdf["crossed"] = dggal_gdf.geometry.apply(check_crossing_geom)
    else:
        dggal_gdf["cell_area"] = dggal_gdf.geometry.area
        dggal_gdf["cell_perimeter"] = dggal_gdf.geometry.length
        dggal_gdf["crossed"] = False

    dggal_gdf = dggal_gdf[~dggal_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = dggal_gdf["cell_area"].mean()
    dggal_gdf["norm_area"] = (
        dggal_gdf["cell_area"] / mean_area if mean_area and mean_area != 0 else np.nan
    )
    # Robust formulas avoiding division by zero
    dggal_gdf["ipq"] = (
        4 * np.pi * dggal_gdf["cell_area"] / (dggal_gdf["cell_perimeter"] ** 2)
    )

    dggal_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * dggal_gdf["cell_area"]
            - np.power(dggal_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / dggal_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = dggal_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    dggal_gdf_lambert = get_cells_area(dggal_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    dggal_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        dggal_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    dggal_gdf["cvh"] = dggal_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return dggal_gdf

dggalinspect_cli()

Command-line interface for DGGAL cell inspection.

CLI options

-t, --dggs_type -r, --resolution -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)

Source code in vgrid/stats/dggalstats.py
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
def dggalinspect_cli():
    """
    Command-line interface for DGGAL cell inspection.

    CLI options:
      -t, --dggs_type
      -r, --resolution
      -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-t", "--dggs_type", dest="dggs_type", choices=DGGAL_TYPES.keys(), required=True
    )
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-split",
        "--split_antimeridian",
        action="store_true",
        default=False,  # default is False to avoid splitting the Antimeridian by default
        help="Enable antimeridian splitting",
    )
    args = parser.parse_args()
    dggs_type = args.dggs_type
    resolution = args.resolution
    print(
        dggalinspect(
            dggs_type, resolution, split_antimeridian=args.split_antimeridian
        )
    )

dggalstats_cli()

Command-line interface for generating DGGAL DGGS statistics.

CLI options

-dggs, --dggs_type {gnosis, isea3h, isea9r, ivea3h, ivea9r, rtea3h, rtea9r, rhealpix} -unit, --unit {m,km} --minres, --maxres

Source code in vgrid/stats/dggalstats.py
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
def dggalstats_cli():
    """
    Command-line interface for generating DGGAL DGGS statistics.

    CLI options:
      -dggs, --dggs_type {gnosis, isea3h, isea9r, ivea3h, ivea9r, rtea3h, rtea9r, rhealpix}
      -unit, --unit {m,km}
      --minres, --maxres
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-dggs", "--dggs_type", dest="dggs_type", choices=DGGAL_TYPES.keys()
    )
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()

    dggs_type = args.dggs_type
    unit = args.unit

    result = dggalstats(dggs_type, unit)
    if result is not None:
        print(result)

dggridinspect(dggrid_instance, dggs_type, resolution, split_antimeridian=False, aggregate=False, options={'densification': 30})

Generate detailed inspection data for a DGGRID DGGS type at a given resolution.

Parameters:

Name Type Description Default
dggrid_instance

DGGRID instance for grid operations

required
dggs_type str

DGGS type supported by DGGRID (see dggs_types)

required
resolution int

Resolution level

required
split_antimeridian bool

When True, apply antimeridian fixing to the resulting polygons.

False
aggregate bool

When True, aggregate the resulting polygons. Defaults to False to avoid aggregation by default.

False
options dict

Options to pass to grid_cell_polygons_for_extent. For example: {"densification": 2} to add densification points. Defaults to None.

{'densification': 30}
Source code in vgrid/stats/dggridstats.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
def dggridinspect(
    dggrid_instance,
    dggs_type: str,
    resolution: int,
    split_antimeridian: bool = False,
    aggregate: bool = False,
    options={"densification": 30},
) -> gpd.GeoDataFrame:
    """
    Generate detailed inspection data for a DGGRID DGGS type at a given resolution.

    Args:
        dggrid_instance: DGGRID instance for grid operations
        dggs_type: DGGS type supported by DGGRID (see dggs_types)
        resolution: Resolution level
        split_antimeridian: When True, apply antimeridian fixing to the resulting polygons.
        Defaults to False to avoid splitting the Antimeridian by default.
        aggregate: When True, aggregate the resulting polygons. Defaults to False to avoid aggregation by default.
        options (dict, optional): Options to pass to grid_cell_polygons_for_extent. 
            For example: {"densification": 2} to add densification points.
            Defaults to None.
    Returns:
        geopandas.GeoDataFrame: DataFrame containing inspection data with columns:
          - name (cell identifier from DGGRID)
          - resolution
          - geometry
          - cell_area (m^2)
          - cell_perimeter (m)
          - crossed (bool)
          - norm_area (area/mean_area)
          - ipq (4πA/P²)
          - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a
    """

    # Generate grid using dggridgen
    dggrid_gdf = dggridgen(
        dggrid_instance,
        dggs_type,
        resolution,
        output_format="gpd",
        split_antimeridian=split_antimeridian,
        aggregate=aggregate,
        options=options,
    )

    # Remove cells with null or invalid geometry
    dggrid_gdf = dggrid_gdf.dropna(subset=["geometry"])
    dggrid_gdf = dggrid_gdf[dggrid_gdf.geometry.is_valid]

    # Add dggs_type column
    dggrid_gdf["dggs_type"] = f"dggrid_{dggs_type.lower()}"

    # Rename global_id to cell_id
    if "global_id" in dggrid_gdf.columns:
        dggrid_gdf = dggrid_gdf.rename(columns={"global_id": "cell_id"})

    # Determine whether current CRS is geographic; compute metrics accordingly
    if dggrid_gdf.crs.is_geographic:
        dggrid_gdf["cell_area"] = dggrid_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[0])
        )
        dggrid_gdf["cell_perimeter"] = dggrid_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[1])
        )
        dggrid_gdf["crossed"] = dggrid_gdf.geometry.apply(check_crossing_geom)
    else:
        dggrid_gdf["cell_area"] = dggrid_gdf.geometry.area
        dggrid_gdf["cell_perimeter"] = dggrid_gdf.geometry.length
        dggrid_gdf["crossed"] = False

    # Add resolution column
    dggrid_gdf["resolution"] = resolution

    dggrid_gdf = dggrid_gdf[~dggrid_gdf["crossed"]]  # remove cells that cross the Antimeridian
    # Calculate normalized area
    mean_area = dggrid_gdf["cell_area"].mean()
    dggrid_gdf["norm_area"] = (
        dggrid_gdf["cell_area"] / mean_area if mean_area and mean_area != 0 else np.nan
    )

    # Calculate compactness metrics (robust formulas avoiding division by zero)
    dggrid_gdf["ipq"] = (
        4 * np.pi * dggrid_gdf["cell_area"] / (dggrid_gdf["cell_perimeter"] ** 2)
    )
    dggrid_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * dggrid_gdf["cell_area"]
            - np.power(dggrid_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / dggrid_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = dggrid_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    dggrid_gdf_lambert = get_cells_area(dggrid_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    dggrid_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        dggrid_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    dggrid_gdf["cvh"] = dggrid_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return dggrid_gdf

dggridinspect_cli()

Command-line interface for DGGRID cell inspection.

CLI options

-dggs, --dggs_type: DGGS type from dggs_types -r, --resolution: Resolution level --no-split_antimeridian: Disable antimeridian fixing (default: enabled) --no-aggregate: Disable aggregation (default: enabled)

Source code in vgrid/stats/dggridstats.py
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
def dggridinspect_cli():
    """
    Command-line interface for DGGRID cell inspection.

    CLI options:
      -dggs, --dggs_type: DGGS type from dggs_types
      -r, --resolution: Resolution level
      --no-split_antimeridian: Disable antimeridian fixing (default: enabled)
      --no-aggregate: Disable aggregation (default: enabled)
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-dggs", "--dggs_type", dest="dggs_type", choices=dggs_types, required=True
    )
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-split",
        "--split_antimeridian",
        action="store_true",
        default=False,  # default is False to avoid splitting the Antimeridian by default
        help="Enable antimeridian fixing",
    )
    parser.add_argument(
        "-aggregate",
        "--aggregate",
        action="store_true",
        default=False,  # default is False to avoid aggregation by default
        help="Enable aggregation",
    )
    parser.add_argument(
        "-options",
        "--options",
        type=str,
        default=None,
        help="JSON string of options to pass to grid_cell_polygons_for_extent. "
             "Example: '{\"densification\": 2}'",
    )
    args = parser.parse_args()
    dggrid_instance = create_dggrid_instance()
    dggs_type = args.dggs_type
    resolution = args.resolution

    # Parse options JSON if provided
    options = None
    if args.options:
        try:
            options = json.loads(args.options)
        except json.JSONDecodeError as e:
            print(f"Error: Invalid JSON in options: {str(e)}")
            return

    print(
        dggridinspect(
            dggrid_instance,
            dggs_type,
            resolution,
            split_antimeridian=args.split_antimeridian,
            aggregate=args.aggregate,
            options=options,
        )
    )

dggridstats_cli()

Command-line interface for generating DGGAL DGGS statistics.

CLI options

-dggs, --dggs_type {gnosis, isea3h, isea9r, ivea3h, ivea9r, rtea3h, rtea9r, rhealpix} -unit, --unit {m,km} --minres, --maxres

Source code in vgrid/stats/dggridstats.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
def dggridstats_cli():
    """
    Command-line interface for generating DGGAL DGGS statistics.

    CLI options:
      -dggs, --dggs_type {gnosis, isea3h, isea9r, ivea3h, ivea9r, rtea3h, rtea9r, rhealpix}
      -unit, --unit {m,km}
      --minres, --maxres
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-dggs", "--dggs_type", dest="dggs_type", choices=DGGRID_TYPES.keys()
    )
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()

    dggs_type = args.dggs_type
    unit = args.unit

    dggrid_instance = create_dggrid_instance()
    result = dggridstats(dggrid_instance, dggs_type, unit)
    if result is not None:
        print(result)

digipininspect(resolution)

Generate comprehensive inspection data for DIGIPIN DGGS cells at a given resolution.

This function creates a detailed analysis of DIGIPIN cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution

DIGIPIN resolution level (1-10)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing DIGIPIN cell inspection data with columns: - digipin: DIGIPIN cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness - cvh: Convex Hull compactness

Source code in vgrid/stats/digipinstats.py
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def digipininspect(resolution):
    """
    Generate comprehensive inspection data for DIGIPIN DGGS cells at a given resolution.

    This function creates a detailed analysis of DIGIPIN cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: DIGIPIN resolution level (1-10)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing DIGIPIN cell inspection data with columns:
            - digipin: DIGIPIN cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
            - cvh: Convex Hull compactness
    """
    resolution = validate_digipin_resolution(resolution)
    digipin_gdf = digipingrid(resolution, output_format="gpd")
    digipin_gdf["crossed"] = digipin_gdf["geometry"].apply(check_crossing_geom)
    mean_area = digipin_gdf["cell_area"].mean()
    # Calculate normalized area
    digipin_gdf["norm_area"] = digipin_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    digipin_gdf["ipq"] = (
        4 * np.pi * digipin_gdf["cell_area"] / (digipin_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    digipin_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * digipin_gdf["cell_area"]
            - np.power(digipin_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / digipin_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = digipin_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    digipin_gdf_lambert = get_cells_area(digipin_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    digipin_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        digipin_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    digipin_gdf["cvh"] = digipin_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return digipin_gdf

digipininspect_cli()

Command-line interface for DIGIPIN cell inspection.

CLI options

-r, --resolution: DIGIPIN resolution level (1-10)

Source code in vgrid/stats/digipinstats.py
534
535
536
537
538
539
540
541
542
543
544
545
def digipininspect_cli():
    """
    Command-line interface for DIGIPIN cell inspection.

    CLI options:
      -r, --resolution: DIGIPIN resolution level (1-10)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=1)
    args, _ = parser.parse_known_args()  # type: ignore
    resolution = args.resolution
    print(digipininspect(resolution))

digipinstats_cli()

Command-line interface for generating DIGIPIN DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/digipinstats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
def digipinstats_cli():
    """
    Command-line interface for generating DIGIPIN DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args, _ = parser.parse_known_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = digipinstats(unit=unit)

    # Display the DataFrame
    print(df)

easeinspect(resolution)

Generate comprehensive inspection data for EASE-DGGS cells at a given resolution.

This function creates a detailed analysis of EASE cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

EASE-DGGS resolution level (0-6)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing EASE cell inspection data with columns: - ease: EASE cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/easestats.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def easeinspect(resolution: int):  # length unit is m, area unit is m2
    """
    Generate comprehensive inspection data for EASE-DGGS cells at a given resolution.

    This function creates a detailed analysis of EASE cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: EASE-DGGS resolution level (0-6)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing EASE cell inspection data with columns:
            - ease: EASE cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    ease_gdf = easegrid(resolution, output_format="gpd")    
    ease_gdf["crossed"] = ease_gdf["geometry"].apply(check_crossing_geom)
    # ease_gdf = ease_gdf[~ease_gdf["crossed"]]  # remove cells that cross the Antimeridian

    mean_area = ease_gdf["cell_area"].mean()
    # Calculate normalized area
    ease_gdf["norm_area"] = ease_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    ease_gdf["ipq"] = (
        4 * np.pi * ease_gdf["cell_area"] / (ease_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    ease_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * ease_gdf["cell_area"]
            - np.power(ease_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / ease_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = ease_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    ease_gdf_lambert = get_cells_area(ease_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    ease_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        ease_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    ease_gdf["cvh"] = ease_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return ease_gdf

easeinspect_cli()

Command-line interface for EASE cell inspection.

CLI options

-r, --resolution: EASE resolution level (0-6)

Source code in vgrid/stats/easestats.py
495
496
497
498
499
500
501
502
503
504
505
506
def easeinspect_cli():
    """
    Command-line interface for EASE cell inspection.

    CLI options:
      -r, --resolution: EASE resolution level (0-6)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    print(easeinspect(resolution))

easestats_cli()

Command-line interface for generating EASE-DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/easestats.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def easestats_cli():
    """
    Command-line interface for generating EASE-DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )

    args = parser.parse_args()  # type: ignore
    unit = args.unit

    # Get the DataFrame
    df = easestats(unit=unit)

    # Display the DataFrame
    print(df)

garsinspect(resolution)

Generate comprehensive inspection data for GARS DGGS cells at a given resolution.

This function creates a detailed analysis of GARS cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

GARS resolution level (0-4)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing GARS cell inspection data with columns: - gars: GARS cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/garsstats.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def garsinspect(resolution: int):  # length unit is km, area unit is km2
    """
    Generate comprehensive inspection data for GARS DGGS cells at a given resolution.

    This function creates a detailed analysis of GARS cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: GARS resolution level (0-4)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing GARS cell inspection data with columns:
            - gars: GARS cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    gars_gdf = garsgrid(resolution, output_format="gpd")        
    gars_gdf["crossed"] = gars_gdf["geometry"].apply(check_crossing_geom)
    mean_area = gars_gdf["cell_area"].mean()
    # Calculate normalized area
    gars_gdf["norm_area"] = gars_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    gars_gdf["ipq"] = (
        4 * np.pi * gars_gdf["cell_area"] / (gars_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    gars_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * gars_gdf["cell_area"]
            - np.power(gars_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / gars_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = gars_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    gars_gdf_lambert = get_cells_area(gars_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    gars_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        gars_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    gars_gdf["cvh"] = gars_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return gars_gdf

garsinspect_cli()

Command-line interface for GARS cell inspection.

CLI options

-r, --resolution: GARS resolution level (0-4)

Source code in vgrid/stats/garsstats.py
499
500
501
502
503
504
505
506
507
508
509
510
def garsinspect_cli():
    """
    Command-line interface for GARS cell inspection.

    CLI options:
      -r, --resolution: GARS resolution level (0-4)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    print(garsinspect(resolution))

garsstats_cli()

Command-line interface for generating GARS DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/garsstats.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def garsstats_cli():
    """
    Command-line interface for generating GARS DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()

    unit = args.unit

    # Get the DataFrame
    df = garsstats(unit=unit)

    # Display the DataFrame
    print(df)

geohashinspect(resolution)

Generate comprehensive inspection data for Geohash DGGS cells at a given resolution.

This function creates a detailed analysis of Geohash cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

Geohash resolution level (0-12)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Geohash cell inspection data with columns: - geohash: Geohash cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/geohashstats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def geohashinspect(resolution: int):
    """
    Generate comprehensive inspection data for Geohash DGGS cells at a given resolution.

    This function creates a detailed analysis of Geohash cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: Geohash resolution level (0-12)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Geohash cell inspection data with columns:
            - geohash: Geohash cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    geohash_gdf = geohashgrid(resolution, output_format="gpd")
    geohash_gdf["crossed"] = geohash_gdf["geometry"].apply(check_crossing_geom)
    mean_area = geohash_gdf["cell_area"].mean()
    # Calculate normalized area
    geohash_gdf["norm_area"] = geohash_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    geohash_gdf["ipq"] = (
        4 * np.pi * geohash_gdf["cell_area"] / (geohash_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    geohash_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * geohash_gdf["cell_area"]
            - np.power(geohash_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / geohash_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = geohash_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    geohash_gdf_lambert = get_cells_area(geohash_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    geohash_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        geohash_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    geohash_gdf["cvh"] = geohash_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return geohash_gdf

geohashinspect_cli()

Command-line interface for Geohash cell inspection.

CLI options

-r, --resolution: Geohash resolution level (0-12)

Source code in vgrid/stats/geohashstats.py
505
506
507
508
509
510
511
512
513
514
515
516
def geohashinspect_cli():
    """
    Command-line interface for Geohash cell inspection.

    CLI options:
      -r, --resolution: Geohash resolution level (0-12)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()
    resolution = args.resolution
    print(geohashinspect(resolution))

geohashstats_cli()

Command-line interface for generating Geohash DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/geohashstats.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def geohashstats_cli():
    """
    Command-line interface for generating Geohash DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()

    unit = args.unit

    # Get the DataFrame
    df = geohashstats(unit=unit)

    # Display the DataFrame
    print(df)

georefinspect(resolution)

Generate comprehensive inspection data for GEOREF DGGS cells at a given resolution.

This function creates a detailed analysis of GEOREF cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

GEOREF resolution level (0-10)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing GEOREF cell inspection data with columns: - georef: GEOREF cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/georefstats.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def georefinspect(resolution: int):
    """
    Generate comprehensive inspection data for GEOREF DGGS cells at a given resolution.

    This function creates a detailed analysis of GEOREF cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: GEOREF resolution level (0-10)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing GEOREF cell inspection data with columns:
            - georef: GEOREF cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    georef_gdf = georefgrid(resolution, output_format="gpd")
    georef_gdf["crossed"] = georef_gdf["geometry"].apply(check_crossing_geom)
    mean_area = georef_gdf["cell_area"].mean()
    # Calculate normalized area
    georef_gdf["norm_area"] = georef_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    georef_gdf["ipq"] = (
        4 * np.pi * georef_gdf["cell_area"] / (georef_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    georef_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * georef_gdf["cell_area"]
            - np.power(georef_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / georef_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = georef_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    georef_gdf_lambert = get_cells_area(georef_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    georef_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        georef_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    georef_gdf["cvh"] = georef_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return georef_gdf

georefinspect_cli()

Command-line interface for GEOREF cell inspection.

CLI options

-r, --resolution: GEOREF resolution level (0-10)

Source code in vgrid/stats/georefstats.py
506
507
508
509
510
511
512
513
514
515
516
517
def georefinspect_cli():
    """
    Command-line interface for GEOREF cell inspection.

    CLI options:
      -r, --resolution: GEOREF resolution level (0-10)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    print(georefinspect(resolution))

georefstats_cli()

Command-line interface for generating GEOREF DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/georefstats.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
def georefstats_cli():
    """
    Command-line interface for generating GEOREF DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = georefstats(unit=unit)

    # Display the DataFrame
    print(df)

h3inspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for H3 DGGS cells at a given resolution.

This function creates a detailed analysis of H3 cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

H3 resolution level (0-15)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing H3 cell inspection data with columns: - h3: H3 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - is_pentagon: Whether cell is a pentagon - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/h3stats.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
def h3inspect(resolution: int, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for H3 DGGS cells at a given resolution.

    This function creates a detailed analysis of H3 cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: H3 resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

    Returns:
        geopandas.GeoDataFrame: DataFrame containing H3 cell inspection data with columns:
            - h3: H3 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - is_pentagon: Whether cell is a pentagon
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    h3_gdf = h3grid(resolution, output_format="gpd", fix_antimeridian=fix_antimeridian)
    h3_gdf["crossed"] = h3_gdf["geometry"].apply(check_crossing_geom)
    h3_gdf = h3_gdf[~h3_gdf["crossed"]]  # remove cells that cross the Antimeridian
    h3_gdf["is_pentagon"] = h3_gdf["h3"].apply(h3.is_pentagon)
    mean_area = h3_gdf["cell_area"].mean()
    # Calculate normalized area
    h3_gdf["norm_area"] = h3_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    h3_gdf["ipq"] = 4 * np.pi * h3_gdf["cell_area"] / (h3_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    h3_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * h3_gdf["cell_area"]
            - np.power(h3_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / h3_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = h3_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    h3_gdf_lambert = get_cells_area(h3_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    h3_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        h3_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    h3_gdf["cvh"] = h3_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return h3_gdf

h3inspect_cli()

Command-line interface for H3 cell inspection.

CLI options

-r, --resolution: H3 resolution level (0-15) -split, --split_antimeridian: Apply antimeridian fixing to the resulting polygons

Source code in vgrid/stats/h3stats.py
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
def h3inspect_cli():
    """
    Command-line interface for H3 cell inspection.

    CLI options:
      -r, --resolution: H3 resolution level (0-15)
      -split, --split_antimeridian: Apply antimeridian fixing to the resulting polygons
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-fix--fix_antimeridian",
        type=str,
        choices=[
            "shift",
            "shift_balanced",
            "shift_west",
            "shift_east",
            "split",
            "none",
        ],
        default=None,
        help="Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none",
    )
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    print(h3inspect(resolution, fix_antimeridian=args.fix_antimeridian))

h3stats_cli()

Command-line interface for generating H3 DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/h3stats.py
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def h3stats_cli():
    """
    Command-line interface for generating H3 DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    df = h3stats(unit=unit)
    df["number_of_cells"] = df["number_of_cells"].apply(lambda x: "{:,.0f}".format(x))
    print(df)

isea3hinspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for ISEA3H DGGS cells at a given resolution.

This function creates a detailed analysis of ISEA3H cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

ISEA3H resolution level (0-40)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/isea3hstats.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def isea3hinspect(resolution: int, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for ISEA3H DGGS cells at a given resolution.

    This function creates a detailed analysis of ISEA3H cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: ISEA3H resolution level (0-40)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
    Returns:
        geopandas.GeoDataFrame: DataFrame containing ISEA3H cell inspection data with columns:
            - isea3h: ISEA3H cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    # Allow running on all platforms

    isea3h_gdf = isea3hgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )  # remove cells that cross the Antimeridian
    isea3h_gdf["crossed"] = isea3h_gdf["geometry"].apply(check_crossing_geom)
    isea3h_gdf = isea3h_gdf[~isea3h_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = isea3h_gdf["cell_area"].mean()
    # Calculate normalized area
    isea3h_gdf["norm_area"] = isea3h_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    isea3h_gdf["ipq"] = (
        4 * np.pi * isea3h_gdf["cell_area"] / (isea3h_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    isea3h_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * isea3h_gdf["cell_area"]
            - np.power(isea3h_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / isea3h_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = isea3h_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    isea3h_gdf_lambert = get_cells_area(isea3h_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    isea3h_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        isea3h_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    isea3h_gdf["cvh"] = isea3h_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return isea3h_gdf

isea3hinspect_cli()

Command-line interface for ISEA3H cell inspection.

CLI options

-r, --resolution: ISEA3H resolution level (0-40) -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)

Source code in vgrid/stats/isea3hstats.py
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
def isea3hinspect_cli():
    """
    Command-line interface for ISEA3H cell inspection.

    CLI options:
      -r, --resolution: ISEA3H resolution level (0-40)
      -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)
    """

    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-split",
        "--split_antimeridian",
        action="store_true",
        default=False,  # default is False to avoid splitting the Antimeridian by default
        help="Enable antimeridian splitting",
    )
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    split_antimeridian = args.split_antimeridian
    print(isea3hinspect(resolution, split_antimeridian=split_antimeridian))

isea3hstats_cli()

Command-line interface for generating ISEA3H DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/isea3hstats.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def isea3hstats_cli():
    """
    Command-line interface for generating ISEA3H DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = isea3hstats(unit=unit)

    # Display the DataFrame
    print(df)

isea4tinspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for ISEA4T DGGS cells at a given resolution.

This function creates a detailed analysis of ISEA4T cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution

ISEA4T resolution level (0-15)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/isea4tstats.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def isea4tinspect(resolution, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for ISEA4T DGGS cells at a given resolution.

    This function creates a detailed analysis of ISEA4T cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: ISEA4T resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
    Returns:
        geopandas.GeoDataFrame: DataFrame containing ISEA4T cell inspection data with columns:
            - isea4t: ISEA4T cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    # Allow running on all platforms
    resolution = validate_isea4t_resolution(resolution)
    isea4t_gdf = isea4tgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )
    isea4t_gdf["crossed"] = isea4t_gdf["geometry"].apply(check_crossing_geom)
    isea4t_gdf = isea4t_gdf[~isea4t_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = isea4t_gdf["cell_area"].mean()
    # Calculate normalized area
    isea4t_gdf["norm_area"] = isea4t_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    isea4t_gdf["ipq"] = (
        4 * np.pi * isea4t_gdf["cell_area"] / (isea4t_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    isea4t_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * isea4t_gdf["cell_area"]
            - np.power(isea4t_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / isea4t_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = isea4t_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    isea4t_gdf_lambert = get_cells_area(isea4t_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    isea4t_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        isea4t_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    isea4t_gdf["cvh"] = isea4t_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return isea4t_gdf

isea4tinspect_cli()

Command-line interface for ISEA4T cell inspection.

CLI options

-r, --resolution: ISEA4T resolution level (0-15)

-fix, --fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

Source code in vgrid/stats/isea4tstats.py
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
def isea4tinspect_cli():
    """
    Command-line interface for ISEA4T cell inspection.

    CLI options:
      -r, --resolution: ISEA4T resolution level (0-15)
    -fix, --fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-fix",
        "--fix_antimeridian",
        type=str,
        choices=[
            "shift",
            "shift_balanced",
            "shift_west",
            "shift_east",
            "split",
            "none",
        ],
        default=None,
        help="Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none",
    )
    args = parser.parse_args()
    resolution = args.resolution
    fix_antimeridian = args.fix_antimeridian
    print(isea4tinspect(resolution, fix_antimeridian=fix_antimeridian))

isea4tstats_cli()

Command-line interface for generating ISEA4T DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/isea4tstats.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def isea4tstats_cli():
    """
    Command-line interface for generating ISEA4T DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args, _ = parser.parse_known_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = isea4tstats(unit=unit)

    # Display the DataFrame
    print(df)

maidenheadinspect(resolution)

Generate comprehensive inspection data for Maidenhead DGGS cells at a given resolution.

This function creates a detailed analysis of Maidenhead cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Maidenhead resolution level (1-4)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Maidenhead cell inspection data with columns: - maidenhead: Maidenhead cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/maidenheadstats.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def maidenheadinspect(resolution: int):
    """
    Generate comprehensive inspection data for Maidenhead DGGS cells at a given resolution.

    This function creates a detailed analysis of Maidenhead cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Maidenhead resolution level (1-4)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Maidenhead cell inspection data with columns:
            - maidenhead: Maidenhead cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    resolution = validate_maidenhead_resolution(resolution)
    maidenhead_gdf = maidenheadgrid(resolution, output_format="gpd")    
    maidenhead_gdf["crossed"] = maidenhead_gdf["geometry"].apply(check_crossing_geom)
    mean_area = maidenhead_gdf["cell_area"].mean()
    # Calculate normalized area
    maidenhead_gdf["norm_area"] = maidenhead_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    maidenhead_gdf["ipq"] = (
        4
        * np.pi
        * maidenhead_gdf["cell_area"]
        / (maidenhead_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    maidenhead_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * maidenhead_gdf["cell_area"]
            - np.power(maidenhead_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / maidenhead_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = maidenhead_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    maidenhead_gdf_lambert = get_cells_area(maidenhead_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    maidenhead_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        maidenhead_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    maidenhead_gdf["cvh"] = maidenhead_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return maidenhead_gdf

maidenheadinspect_cli()

Command-line interface for Maidenhead cell inspection.

CLI options

-r, --resolution: Maidenhead resolution level (1-4)

Source code in vgrid/stats/maidenheadstats.py
515
516
517
518
519
520
521
522
523
524
525
526
def maidenheadinspect_cli():
    """
    Command-line interface for Maidenhead cell inspection.

    CLI options:
      -r, --resolution: Maidenhead resolution level (1-4)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args, _ = parser.parse_known_args()  # type: ignore
    resolution = args.resolution
    print(maidenheadinspect(resolution))

maidenheadstats_cli()

Command-line interface for generating Maidenhead DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/maidenheadstats.py
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def maidenheadstats_cli():
    """
    Command-line interface for generating Maidenhead DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args, _ = parser.parse_known_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = maidenheadstats(unit=unit)

    # Display the DataFrame
    print(df)

mgrsstats_cli()

Command-line interface for generating MGRS DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/mgrsstats.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
def mgrsstats_cli():
    """
    Command-line interface for generating MGRS DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    print("Resolution 0: 100 x 100 km")
    print("Resolution 1: 10 x 10 km")
    print("2 <= Resolution <= 5 = Finer subdivisions (1 x 1 km, 0.1 x 0.11 km, etc.)")

    # Get the DataFrame
    df = mgrsstats(unit=unit)

    # Display the DataFrame
    print(df)

olcinspect(resolution)

Generate comprehensive inspection data for OLC DGGS cells at a given resolution.

This function creates a detailed analysis of OLC cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

OLC resolution level (2-15)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing OLC cell inspection data with columns: - olc: OLC cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/olcstats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
def olcinspect(resolution: int):
    """
    Generate comprehensive inspection data for OLC DGGS cells at a given resolution.

    This function creates a detailed analysis of OLC cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: OLC resolution level (2-15)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing OLC cell inspection data with columns:
            - olc: OLC cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    olc_gdf = olcgrid(resolution, output_format="gpd")          
    olc_gdf["crossed"] = olc_gdf["geometry"].apply(check_crossing_geom)
    mean_area = olc_gdf["cell_area"].mean()
    # Calculate normalized area
    olc_gdf["norm_area"] = olc_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    olc_gdf["ipq"] = 4 * np.pi * olc_gdf["cell_area"] / (olc_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    olc_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * olc_gdf["cell_area"]
            - np.power(olc_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / olc_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = olc_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    olc_gdf_lambert = get_cells_area(olc_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    olc_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        olc_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    olc_gdf["cvh"] = olc_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return olc_gdf

olcinspect_cli()

Command-line interface for OLC cell inspection.

CLI options

-r, --resolution: OLC resolution level (2-15)

Source code in vgrid/stats/olcstats.py
491
492
493
494
495
496
497
498
499
500
501
502
def olcinspect_cli():
    """
    Command-line interface for OLC cell inspection.

    CLI options:
      -r, --resolution: OLC resolution level (2-15)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args, _ = parser.parse_known_args()  # type: ignore
    resolution = args.resolution
    print(olcinspect(resolution))

olcstats_cli()

Command-line interface for generating OLC DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/olcstats.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def olcstats_cli():
    """
    Command-line interface for generating OLC DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args, _ = parser.parse_known_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = olcstats(unit=unit)

    # Display the DataFrame
    print(df)

qtminspect(resolution)

Generate comprehensive inspection data for QTM DGGS cells at a given resolution.

This function creates a detailed analysis of QTM cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

QTM resolution level (1-24)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing QTM cell inspection data with columns: - qtm: QTM cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/qtmstats.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
def qtminspect(resolution: int):
    """
    Generate comprehensive inspection data for QTM DGGS cells at a given resolution.

    This function creates a detailed analysis of QTM cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: QTM resolution level (1-24)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing QTM cell inspection data with columns:
            - qtm: QTM cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    qtm_gdf = qtm_grid(resolution)
    qtm_gdf["crossed"] = qtm_gdf["geometry"].apply(check_crossing_geom)
    qtm_gdf = qtm_gdf[~qtm_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = qtm_gdf["cell_area"].mean()
    # Calculate normalized area
    qtm_gdf["norm_area"] = qtm_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    qtm_gdf["ipq"] = 4 * np.pi * qtm_gdf["cell_area"] / (qtm_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    qtm_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * qtm_gdf["cell_area"]
            - np.power(qtm_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / qtm_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = qtm_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    qtm_gdf_lambert = get_cells_area(qtm_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    qtm_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        qtm_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    qtm_gdf["cvh"] = qtm_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return qtm_gdf

qtminspect_cli()

Command-line interface for QTM cell inspection.

CLI options

-r, --resolution: QTM resolution level (1-24)

Source code in vgrid/stats/qtmstats.py
488
489
490
491
492
493
494
495
496
497
498
499
def qtminspect_cli():
    """
    Command-line interface for QTM cell inspection.

    CLI options:
      -r, --resolution: QTM resolution level (1-24)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()
    resolution = args.resolution
    print(qtminspect(resolution))

qtmstats_cli()

Command-line interface for generating QTM DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/qtmstats.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def qtmstats_cli():
    """
    Command-line interface for generating QTM DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()
    unit = args.unit
    # Get the DataFrame
    df = qtmstats(unit=unit)
    # Display the DataFrame
    print(df)

quadkeyinspect(resolution)

Generate comprehensive inspection data for Quadkey DGGS cells at a given resolution.

This function creates a detailed analysis of Quadkey cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Quadkey resolution level (0-29)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Quadkey cell inspection data with columns: - quadkey: Quadkey cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/quadkeystats.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
def quadkeyinspect(resolution: int):
    """
    Generate comprehensive inspection data for Quadkey DGGS cells at a given resolution.

    This function creates a detailed analysis of Quadkey cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Quadkey resolution level (0-29)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Quadkey cell inspection data with columns:
            - quadkey: Quadkey cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    quadkey_gdf = quadkeygrid(resolution, output_format="gpd")
    quadkey_gdf["crossed"] = quadkey_gdf["geometry"].apply(check_crossing_geom)
    mean_area = quadkey_gdf["cell_area"].mean()
    # Calculate normalized area
    quadkey_gdf["norm_area"] = quadkey_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    quadkey_gdf["ipq"] = (
        4 * np.pi * quadkey_gdf["cell_area"] / (quadkey_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    quadkey_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * quadkey_gdf["cell_area"]
            - np.power(quadkey_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / quadkey_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = quadkey_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    quadkey_gdf_lambert = get_cells_area(quadkey_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    quadkey_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        quadkey_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    quadkey_gdf["cvh"] = quadkey_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return quadkey_gdf

quadkeyinspect_cli()

Command-line interface for Quadkey cell inspection.

CLI options

-r, --resolution: Quadkey resolution level (0-29)

Source code in vgrid/stats/quadkeystats.py
500
501
502
503
504
505
506
507
508
509
510
511
def quadkeyinspect_cli():
    """
    Command-line interface for Quadkey cell inspection.

    CLI options:
      -r, --resolution: Quadkey resolution level (0-29)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=None)
    args, _ = parser.parse_known_args()
    res = args.resolution if args.resolution is not None else 2
    print(quadkeyinspect(res))

quadkeystats_cli()

Command-line interface for generating Quadkey DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/quadkeystats.py
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def quadkeystats_cli():
    """
    Command-line interface for generating Quadkey DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()
    unit = args.unit
    # Get the DataFrame
    df = quadkeystats(unit=unit)
    # Display the DataFrame
    print(df)

rhealpixinspect(resolution=0, fix_antimeridian=None)

Generate comprehensive inspection data for rHEALPix DGGS cells at a given resolution.

This function creates a detailed analysis of rHEALPix cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

rHEALPix resolution level (0-15)

0
fix_antimeridian str

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/rhealpixstats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def rhealpixinspect(resolution: int = 0, fix_antimeridian: str = None):
    """
    Generate comprehensive inspection data for rHEALPix DGGS cells at a given resolution.

    This function creates a detailed analysis of rHEALPix cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: rHEALPix resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
        Defaults to False to avoid splitting the Antimeridian by default.
    Returns:
        geopandas.GeoDataFrame: DataFrame containing rHEALPix cell inspection data with columns:
            - rhealpix: rHEALPix cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
            - cvh: Convex Hull Compactness
    """
    rhealpix_gdf = rhealpixgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )  # type: ignore
    rhealpix_gdf["crossed"] = rhealpix_gdf["geometry"].apply(check_crossing_geom)
    rhealpix_gdf = rhealpix_gdf[~rhealpix_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = rhealpix_gdf["cell_area"].mean()
    # Calculate normalized area
    rhealpix_gdf["norm_area"] = rhealpix_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    rhealpix_gdf["ipq"] = (
        4 * np.pi * rhealpix_gdf["cell_area"] / (rhealpix_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    rhealpix_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * rhealpix_gdf["cell_area"]
            - np.power(rhealpix_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / rhealpix_gdf["cell_perimeter"]
    )
    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = rhealpix_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    rhealpix_gdf_lambert = get_cells_area(rhealpix_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    rhealpix_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        rhealpix_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    rhealpix_gdf["cvh"] = rhealpix_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return rhealpix_gdf

rhealpixinspect_cli()

Command-line interface for rHEALPix cell inspection.

CLI options

-r, --resolution: rHEALPix resolution level (0-15) -fix, --fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none (default: none)

Source code in vgrid/stats/rhealpixstats.py
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
def rhealpixinspect_cli():
    """
    Command-line interface for rHEALPix cell inspection.

    CLI options:
      -r, --resolution: rHEALPix resolution level (0-15)
      -fix, --fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none (default: none)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-fix",
        "--fix_antimeridian",
        type=str,
        choices=[
            "shift",
            "shift_balanced",
            "shift_west",
            "shift_east",
            "split",
            "none",
        ],
        default=None,
        help="Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none (default: none)",
    )
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    fix_antimeridian = args.fix_antimeridian
    print(rhealpixinspect(resolution, fix_antimeridian=fix_antimeridian))

rhealpixstats_cli()

Command-line interface for generating rHEALPix DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/rhealpixstats.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def rhealpixstats_cli():
    """
    Command-line interface for generating rHEALPix DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = rhealpixstats(unit=unit)

    # Display the DataFrame
    print(df)

s2inspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for S2 DGGS cells at a given resolution.

Parameters:

Name Type Description Default
resolution int

S2 resolution level (0-30)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing S2 cell inspection data with columns: - s2: S2 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/s2stats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def s2inspect(resolution: int, fix_antimeridian=None):
    """
    Generate comprehensive inspection data for S2 DGGS cells at a given resolution.

    Args:
        resolution: S2 resolution level (0-30)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing S2 cell inspection data with columns:
            - s2: S2 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    s2_gdf = s2grid(resolution, output_format="gpd", fix_antimeridian=fix_antimeridian)
    s2_gdf["crossed"] = s2_gdf["geometry"].apply(check_crossing_geom)
    s2_gdf = s2_gdf[~s2_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = s2_gdf["cell_area"].mean()
    # Calculate normalized area
    s2_gdf["norm_area"] = s2_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    s2_gdf["ipq"] = 4 * np.pi * s2_gdf["cell_area"] / (s2_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    s2_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * s2_gdf["cell_area"]
            - np.power(s2_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / s2_gdf["cell_perimeter"]
    )
    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = s2_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    s2_gdf_lambert = get_cells_area(s2_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    s2_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        s2_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    s2_gdf["cvh"] = s2_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return s2_gdf

s2inspect_cli()

Command-line interface for S2 cell inspection. CLI options: -r, --resolution: S2 resolution level (0-30) -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)

Source code in vgrid/stats/s2stats.py
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
def s2inspect_cli():
    """
    Command-line interface for S2 cell inspection.
    CLI options:
      -r, --resolution: S2 resolution level (0-30)
      -split, --split_antimeridian: Enable antimeridian splitting (default: enabled)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    parser.add_argument(
        "-fix",
        "--fix_antimeridian",
        type=str,
        choices=[
            "shift",
            "shift_balanced",
            "shift_west",
            "shift_east",
            "split",
            "none",
        ],
        default=None,
        help="Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none",
    )
    args = parser.parse_args()  # type: ignore
    resolution = args.resolution
    fix_antimeridian = args.fix_antimeridian
    print(s2inspect(resolution, fix_antimeridian=fix_antimeridian))

s2stats_cli()

Command-line interface for generating S2 DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/s2stats.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def s2stats_cli():
    """
    Command-line interface for generating S2 DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = s2stats(unit=unit)

    # Display the DataFrame
    print(df)

tilecodeinspect(resolution)

Generate comprehensive inspection data for Tilecode DGGS cells at a given resolution.

This function creates a detailed analysis of Tilecode cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Tilecode resolution level (0-29)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Tilecode cell inspection data with columns: - tilecode: Tilecode cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/tilecodestats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def tilecodeinspect(resolution: int):
    """
    Generate comprehensive inspection data for Tilecode DGGS cells at a given resolution.

    This function creates a detailed analysis of Tilecode cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Tilecode resolution level (0-29)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Tilecode cell inspection data with columns:
            - tilecode: Tilecode cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    tilecode_gdf = tilecodegrid(resolution, output_format="gpd")
    tilecode_gdf["crossed"] = tilecode_gdf["geometry"].apply(check_crossing_geom)
    mean_area = tilecode_gdf["cell_area"].mean()
    # Calculate normalized area
    tilecode_gdf["norm_area"] = tilecode_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    tilecode_gdf["ipq"] = (
        4 * np.pi * tilecode_gdf["cell_area"] / (tilecode_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    tilecode_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * tilecode_gdf["cell_area"]
            - np.power(tilecode_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / tilecode_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = tilecode_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    tilecode_gdf_lambert = get_cells_area(tilecode_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    tilecode_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        tilecode_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    tilecode_gdf["cvh"] = tilecode_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return tilecode_gdf

tilecodeinspect_cli()

Command-line interface for Tilecode cell inspection.

CLI options

-r, --resolution: Tilecode resolution level (0-30)

Source code in vgrid/stats/tilecodestats.py
503
504
505
506
507
508
509
510
511
512
513
514
def tilecodeinspect_cli():
    """
    Command-line interface for Tilecode cell inspection.

    CLI options:
      -r, --resolution: Tilecode resolution level (0-30)
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-r", "--resolution", dest="resolution", type=int, default=0)
    args = parser.parse_args()
    resolution = args.resolution
    print(tilecodeinspect(resolution))

tilecodestats_cli()

Command-line interface for generating Tilecode DGGS statistics.

CLI options

-unit, --unit {m,km}

Source code in vgrid/stats/tilecodestats.py
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def tilecodestats_cli():
    """
    Command-line interface for generating Tilecode DGGS statistics.

    CLI options:
      -unit, --unit {m,km}
    """
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument(
        "-unit", "--unit", dest="unit", choices=["m", "km"], default="m"
    )
    args = parser.parse_known_args()  # type: ignore

    unit = args.unit

    # Get the DataFrame
    df = tilecodestats(unit=unit)

    # Display the DataFrame
    print(df)

This module provides functions for generating statistics for H3 DGGS cells.

h3stats(unit='m')

Generate comprehensive statistics for H3 DGGS cells.

This function combines basic H3 statistics (number of cells, edge lengths, areas) with area extrema analysis (min/max areas and ratios).

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing comprehensive H3 DGGS statistics with columns: - resolution: Resolution level (0-15) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_area_{unit}2: Average cell area in the squared unit - min_area_{unit}2: Minimum pentagon area - max_area_{unit}2: Maximum hexagon area - max_min_ratio: Ratio of max hexagon area to min pentagon area

Source code in vgrid/stats/h3stats.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
def h3stats(unit: str = "m"):
    """
    Generate comprehensive statistics for H3 DGGS cells.

    This function combines basic H3 statistics (number of cells, edge lengths, areas)
    with area extrema analysis (min/max areas and ratios).

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing comprehensive H3 DGGS statistics with columns:
            - resolution: Resolution level (0-15)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_area_{unit}2: Average cell area in the squared unit
            - min_area_{unit}2: Minimum pentagon area
            - max_area_{unit}2: Maximum hexagon area
            - max_min_ratio: Ratio of max hexagon area to min pentagon area
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_areas = []
    min_areas = []
    max_areas = []
    max_min_ratios = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        # Get comprehensive metrics
        metrics_data = h3_metrics(res, unit=unit)  # length unit is km, area unit is km2

        resolutions.append(res)
        num_cells_list.append(metrics_data["number_of_cells"])
        avg_edge_lens.append(metrics_data["avg_edge_len"])
        avg_areas.append(metrics_data["avg_area"])
        min_areas.append(metrics_data["min_area"])
        max_areas.append(metrics_data["max_area"])
        max_min_ratios.append(metrics_data["max_min_ratio"])
        cls_list.append(metrics_data["cls"])
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    avg_area = f"avg_area_{unit}"
    min_area = f"min_area_{unit}"
    max_area = f"max_area_{unit}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_area: avg_areas,
            min_area: min_areas,
            max_area: max_areas,
            "max_min_ratio": max_min_ratios,
            cls_label: cls_list,
        }
    )

    return df

h3inspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for H3 DGGS cells at a given resolution.

This function creates a detailed analysis of H3 cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

H3 resolution level (0-15)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing H3 cell inspection data with columns: - h3: H3 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - is_pentagon: Whether cell is a pentagon - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/h3stats.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
def h3inspect(resolution: int, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for H3 DGGS cells at a given resolution.

    This function creates a detailed analysis of H3 cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: H3 resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

    Returns:
        geopandas.GeoDataFrame: DataFrame containing H3 cell inspection data with columns:
            - h3: H3 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - is_pentagon: Whether cell is a pentagon
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    h3_gdf = h3grid(resolution, output_format="gpd", fix_antimeridian=fix_antimeridian)
    h3_gdf["crossed"] = h3_gdf["geometry"].apply(check_crossing_geom)
    h3_gdf = h3_gdf[~h3_gdf["crossed"]]  # remove cells that cross the Antimeridian
    h3_gdf["is_pentagon"] = h3_gdf["h3"].apply(h3.is_pentagon)
    mean_area = h3_gdf["cell_area"].mean()
    # Calculate normalized area
    h3_gdf["norm_area"] = h3_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    h3_gdf["ipq"] = 4 * np.pi * h3_gdf["cell_area"] / (h3_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    h3_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * h3_gdf["cell_area"]
            - np.power(h3_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / h3_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = h3_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    h3_gdf_lambert = get_cells_area(h3_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    h3_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        h3_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    h3_gdf["cvh"] = h3_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return h3_gdf

This module provides functions for generating statistics for S2 DGGS cells.

s2stats(unit='m')

Generate statistics for S2 DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing S2 DGGS statistics with columns: - Resolution: Resolution level (0-30) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/s2stats.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def s2stats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for S2 DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing S2 DGGS statistics with columns:
            - Resolution: Resolution level (0-30)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = s2_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

s2inspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for S2 DGGS cells at a given resolution.

Parameters:

Name Type Description Default
resolution int

S2 resolution level (0-30)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing S2 cell inspection data with columns: - s2: S2 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/s2stats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
def s2inspect(resolution: int, fix_antimeridian=None):
    """
    Generate comprehensive inspection data for S2 DGGS cells at a given resolution.

    Args:
        resolution: S2 resolution level (0-30)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing S2 cell inspection data with columns:
            - s2: S2 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    s2_gdf = s2grid(resolution, output_format="gpd", fix_antimeridian=fix_antimeridian)
    s2_gdf["crossed"] = s2_gdf["geometry"].apply(check_crossing_geom)
    s2_gdf = s2_gdf[~s2_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = s2_gdf["cell_area"].mean()
    # Calculate normalized area
    s2_gdf["norm_area"] = s2_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    s2_gdf["ipq"] = 4 * np.pi * s2_gdf["cell_area"] / (s2_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    s2_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * s2_gdf["cell_area"]
            - np.power(s2_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / s2_gdf["cell_perimeter"]
    )
    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = s2_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    s2_gdf_lambert = get_cells_area(s2_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    s2_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        s2_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    s2_gdf["cvh"] = s2_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return s2_gdf

This module provides functions for generating statistics for A5 DGGS cells.

a5stats(unit='m')

Generate statistics for A5 DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing A5 DGGS statistics with columns: - Resolution: Resolution level (0-29) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - CLS: Characteristic length scale in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/a5stats.py
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def a5stats(unit: str = "m"):
    """
    Generate statistics for A5 DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing A5 DGGS statistics with columns:
            - Resolution: Resolution level (0-29)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - CLS: Characteristic length scale in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Derive bounds from central constants registry

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = a5_metrics(
            res, unit=unit
        )  # length unit is m, area unit is m2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)

    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    cls_label = f"cls_{unit}"
    avg_cell_area = f"avg_cell_area_{unit_area_label}"

    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        },
        index=None,
    )

    return df

a5inspect(resolution, options={'segments': 100}, split_antimeridian=False)

Generate comprehensive inspection data for A5 DGGS cells at a given resolution.

This function creates a detailed analysis of A5 cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

A5 resolution level (0-29)

required
options

Optional dictionary of options for grid generation

{'segments': 100}
split_antimeridian bool

When True, apply antimeridian splitting to the resulting polygons. Defaults to False when None or omitted.

False

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing A5 cell inspection data with columns: - a5: A5 cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/a5stats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
def a5inspect(resolution: int, options={"segments": 100}, split_antimeridian: bool = False):
    """
    Generate comprehensive inspection data for A5 DGGS cells at a given resolution.

    This function creates a detailed analysis of A5 cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: A5 resolution level (0-29)
        options: Optional dictionary of options for grid generation
        split_antimeridian: When True, apply antimeridian splitting to the resulting polygons.
            Defaults to False when None or omitted.

    Returns:
        geopandas.GeoDataFrame: DataFrame containing A5 cell inspection data with columns:
            - a5: A5 cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    a5_gdf = a5grid(
        resolution, output_format="gpd", options=options, split_antimeridian=split_antimeridian
    )
    a5_gdf["crossed"] = a5_gdf["geometry"].apply(check_crossing_geom)
    a5_gdf = a5_gdf[~a5_gdf["crossed"]]  # remove cells that cross the Antimeridian

    mean_area = a5_gdf["cell_area"].mean()
    # Calculate normalized area
    a5_gdf["norm_area"] = a5_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    a5_gdf["ipq"] = 4 * np.pi * a5_gdf["cell_area"] / (a5_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    a5_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * a5_gdf["cell_area"]
            - np.power(a5_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / a5_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = a5_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    a5_gdf_lambert = get_cells_area(a5_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    a5_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        a5_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    a5_gdf["cvh"] = a5_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return a5_gdf

This module provides functions for generating statistics for rHEALPix DGGS cells.

rhealpixstats(unit='m')

Generate statistics for rHEALPix DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing rHEALPix DGGS statistics with columns: - Resolution: Resolution level (0-30) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/rhealpixstats.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def rhealpixstats(unit: str = "m"):
    """
    Generate statistics for rHEALPix DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing rHEALPix DGGS statistics with columns:
            - Resolution: Resolution level (0-30)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = rhealpix_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

rhealpixinspect(resolution=0, fix_antimeridian=None)

Generate comprehensive inspection data for rHEALPix DGGS cells at a given resolution.

This function creates a detailed analysis of rHEALPix cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

rHEALPix resolution level (0-15)

0
fix_antimeridian str

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/rhealpixstats.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def rhealpixinspect(resolution: int = 0, fix_antimeridian: str = None):
    """
    Generate comprehensive inspection data for rHEALPix DGGS cells at a given resolution.

    This function creates a detailed analysis of rHEALPix cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: rHEALPix resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
        Defaults to False to avoid splitting the Antimeridian by default.
    Returns:
        geopandas.GeoDataFrame: DataFrame containing rHEALPix cell inspection data with columns:
            - rhealpix: rHEALPix cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
            - cvh: Convex Hull Compactness
    """
    rhealpix_gdf = rhealpixgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )  # type: ignore
    rhealpix_gdf["crossed"] = rhealpix_gdf["geometry"].apply(check_crossing_geom)
    rhealpix_gdf = rhealpix_gdf[~rhealpix_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = rhealpix_gdf["cell_area"].mean()
    # Calculate normalized area
    rhealpix_gdf["norm_area"] = rhealpix_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    rhealpix_gdf["ipq"] = (
        4 * np.pi * rhealpix_gdf["cell_area"] / (rhealpix_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    rhealpix_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * rhealpix_gdf["cell_area"]
            - np.power(rhealpix_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / rhealpix_gdf["cell_perimeter"]
    )
    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = rhealpix_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    rhealpix_gdf_lambert = get_cells_area(rhealpix_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    rhealpix_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        rhealpix_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    rhealpix_gdf["cvh"] = rhealpix_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return rhealpix_gdf

This module provides lightweight wrappers for DGGAL using the external dgg CLI directly.

Per request, dggalstats simply returns the direct output from dgg <dggs_type> level without computing any additional metrics.

dggalstats(dggs_type, unit='m')

Compute and return a DataFrame of DGGAL metrics per resolution for the given type.

Parameters:

Name Type Description Default
dggs_type str

DGGS type supported by DGGAL (see vgrid.utils.constants.DGGAL_TYPES)

required
unit str

'm' or 'km' for length; area columns will reflect the squared unit

'm'

Returns:

Type Description
DataFrame | None

pandas DataFrame with columns for resolution, number of cells, average edge length,

DataFrame | None

and average cell area in the requested units.

Source code in vgrid/stats/dggalstats.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
def dggalstats(
    dggs_type: str, unit: str = "m"
) -> pd.DataFrame | None:  # length unit is km, area unit is km2
    """
    Compute and return a DataFrame of DGGAL metrics per resolution for the given type.

    Args:
            dggs_type: DGGS type supported by DGGAL (see vgrid.utils.constants.DGGAL_TYPES)
            unit: 'm' or 'km' for length; area columns will reflect the squared unit

    Returns:
            pandas DataFrame with columns for resolution, number of cells, average edge length,
            and average cell area in the requested units.
    """
    dggs_type = validate_dggal_type(dggs_type)
    min_res = int(DGGAL_TYPES[dggs_type]["min_res"])
    max_res = int(DGGAL_TYPES[dggs_type]["max_res"])

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = dggal_metrics(
            dggs_type, res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Build column labels with unit awareness
    avg_edge_len_col = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area_col = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len_col: avg_edge_lens,
            avg_cell_area_col: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

dggalinspect(dggs_type, resolution, split_antimeridian=False)

Generate detailed inspection data for a DGGAL DGGS type at a given resolution.

Parameters:

Name Type Description Default
dggs_type str

DGGS type supported by DGGAL

required
resolution int

Resolution level

required
split_antimeridian bool

When True, apply antimeridian splitting to the resulting polygons. Defaults to True when None or omitted.

False

Returns:

Type Description
GeoDataFrame

geopandas.GeoDataFrame with columns: - ZoneID (as provided by DGGAL output; no renaming is performed) - resolution - geometry - cell_area (m^2) - cell_perimeter (m) - crossed (bool) - norm_area (area/mean_area) - ipq (4πA/P²) - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a

Source code in vgrid/stats/dggalstats.py
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
def dggalinspect(
    dggs_type: str, resolution: int, split_antimeridian: bool = False
) -> gpd.GeoDataFrame:
    """
    Generate detailed inspection data for a DGGAL DGGS type at a given resolution.

    Args:
        dggs_type: DGGS type supported by DGGAL
        resolution: Resolution level
        split_antimeridian: When True, apply antimeridian splitting to the resulting polygons.
            Defaults to True when None or omitted.

    Returns:
        geopandas.GeoDataFrame with columns:
          - ZoneID (as provided by DGGAL output; no renaming is performed)
          - resolution
          - geometry
          - cell_area (m^2)
          - cell_perimeter (m)
          - crossed (bool)
          - norm_area (area/mean_area)
          - ipq (4πA/P²)
          - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a
    """
    dggal_gdf = dggalgen(
        dggs_type,
        resolution,
        output_format="gpd",
        split_antimeridian=split_antimeridian,
    )

    # Determine whether current CRS is geographic; compute metrics accordingly
    if dggal_gdf.crs.is_geographic:
        dggal_gdf["cell_area"] = dggal_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[0])
        )
        dggal_gdf["cell_perimeter"] = dggal_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[1])
        )
        dggal_gdf["crossed"] = dggal_gdf.geometry.apply(check_crossing_geom)
    else:
        dggal_gdf["cell_area"] = dggal_gdf.geometry.area
        dggal_gdf["cell_perimeter"] = dggal_gdf.geometry.length
        dggal_gdf["crossed"] = False

    dggal_gdf = dggal_gdf[~dggal_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = dggal_gdf["cell_area"].mean()
    dggal_gdf["norm_area"] = (
        dggal_gdf["cell_area"] / mean_area if mean_area and mean_area != 0 else np.nan
    )
    # Robust formulas avoiding division by zero
    dggal_gdf["ipq"] = (
        4 * np.pi * dggal_gdf["cell_area"] / (dggal_gdf["cell_perimeter"] ** 2)
    )

    dggal_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * dggal_gdf["cell_area"]
            - np.power(dggal_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / dggal_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = dggal_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    dggal_gdf_lambert = get_cells_area(dggal_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    dggal_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        dggal_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    dggal_gdf["cvh"] = dggal_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return dggal_gdf

DGGRID Statistics Module

This module provides functions to calculate and display statistics for DGGRID Discrete Global Grid System (DGGS) types. It supports both command-line interface and direct function calls.

Key Functions: - dggrid_stats: Calculate and display statistics for a given DGGRID DGGS type and resolution - dggridinspect: Generate detailed inspection data for a given DGGRID DGGS type and resolution - main: Command-line interface for dggrid_stats

dggridstats(dggrid_instance, dggs_type, unit='m')

length unit is m, area unit is m2 Return a DataFrame of DGGRID stats per resolution.

'km' or 'm' for length columns; area is squared unit.

DGGRID native output is km^2 for area and km for CLS.

Columns include avg_edge_len_{unit}, derived from mean cell area and topology (hex vs quad).

Source code in vgrid/stats/dggridstats.py
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def dggridstats(
    dggrid_instance, dggs_type: str, unit: str = "m"
) -> pd.DataFrame:  # length unit is km, area unit is km2
    """length unit is m, area unit is m2
    Return a DataFrame of DGGRID stats per resolution.

    unit: 'km' or 'm' for length columns; area is squared unit.
          DGGRID native output is km^2 for area and km for CLS.

    Columns include ``avg_edge_len_{unit}``, derived from mean cell area
    and topology (hex vs quad).
    """
    dggs_type = validate_dggrid_type(dggs_type)
    unit_norm = unit.strip().lower()

    if unit_norm not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    max_res = int(DGGRID_TYPES[dggs_type]["max_res"])

    dggrid_stats_table = dggrid_instance.grid_stats_table(dggs_type, max_res)
    # Characteristic Length Scale (CLS): the diameter of a spherical cap of the same area as a cell of the specified res
    if isinstance(dggrid_stats_table, pd.DataFrame):
        rename_map = {
            "Resolution": "resolution",
            "Cells": "number_of_cells",
            "Area (km^2)": "area_km2",
            "CLS (km)": "cls_km",
        }
        dggrid_stats = dggrid_stats_table.rename(columns=rename_map).copy()
    else:
        dggrid_stats = pd.DataFrame(
            dggrid_stats_table,
            columns=["resolution", "number_of_cells", "area_km2", "cls_km"],
        )

    if unit_norm == "m":
        dggrid_stats = dggrid_stats.rename(
            columns={"area_km2": "area_m2", "cls_km": "cls_m"}
        )
        dggrid_stats["area_m2"] = dggrid_stats["area_m2"] * (10**6)
        dggrid_stats["cls_m"] = dggrid_stats["cls_m"] * (10**3)

    area_col = "area_m2" if unit_norm == "m" else "area_km2"
    avg_edge_len_col = f"avg_edge_len_{unit_norm}"
    areas = dggrid_stats[area_col]
    if dggrid_num_edges(dggs_type) == 6:
        dggrid_stats[avg_edge_len_col] = np.sqrt(
            (2 * areas) / (3 * math.sqrt(3))
        )
    else:
        dggrid_stats[avg_edge_len_col] = np.sqrt(areas)

    if unit_norm == "m":
        col_order = [
            "resolution",
            "number_of_cells",
            avg_edge_len_col,
            "area_m2",
            "cls_m",
        ]
    else:
        col_order = [
            "resolution",
            "number_of_cells",
            avg_edge_len_col,
            "area_km2",
            "cls_km",
        ]
    return dggrid_stats[col_order]

dggridinspect(dggrid_instance, dggs_type, resolution, split_antimeridian=False, aggregate=False, options={'densification': 30})

Generate detailed inspection data for a DGGRID DGGS type at a given resolution.

Parameters:

Name Type Description Default
dggrid_instance

DGGRID instance for grid operations

required
dggs_type str

DGGS type supported by DGGRID (see dggs_types)

required
resolution int

Resolution level

required
split_antimeridian bool

When True, apply antimeridian fixing to the resulting polygons.

False
aggregate bool

When True, aggregate the resulting polygons. Defaults to False to avoid aggregation by default.

False
options dict

Options to pass to grid_cell_polygons_for_extent. For example: {"densification": 2} to add densification points. Defaults to None.

{'densification': 30}
Source code in vgrid/stats/dggridstats.py
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
def dggridinspect(
    dggrid_instance,
    dggs_type: str,
    resolution: int,
    split_antimeridian: bool = False,
    aggregate: bool = False,
    options={"densification": 30},
) -> gpd.GeoDataFrame:
    """
    Generate detailed inspection data for a DGGRID DGGS type at a given resolution.

    Args:
        dggrid_instance: DGGRID instance for grid operations
        dggs_type: DGGS type supported by DGGRID (see dggs_types)
        resolution: Resolution level
        split_antimeridian: When True, apply antimeridian fixing to the resulting polygons.
        Defaults to False to avoid splitting the Antimeridian by default.
        aggregate: When True, aggregate the resulting polygons. Defaults to False to avoid aggregation by default.
        options (dict, optional): Options to pass to grid_cell_polygons_for_extent. 
            For example: {"densification": 2} to add densification points.
            Defaults to None.
    Returns:
        geopandas.GeoDataFrame: DataFrame containing inspection data with columns:
          - name (cell identifier from DGGRID)
          - resolution
          - geometry
          - cell_area (m^2)
          - cell_perimeter (m)
          - crossed (bool)
          - norm_area (area/mean_area)
          - ipq (4πA/P²)
          - zsc (sqrt(4πA - A²/R²)/P), with R=WGS84 a
    """

    # Generate grid using dggridgen
    dggrid_gdf = dggridgen(
        dggrid_instance,
        dggs_type,
        resolution,
        output_format="gpd",
        split_antimeridian=split_antimeridian,
        aggregate=aggregate,
        options=options,
    )

    # Remove cells with null or invalid geometry
    dggrid_gdf = dggrid_gdf.dropna(subset=["geometry"])
    dggrid_gdf = dggrid_gdf[dggrid_gdf.geometry.is_valid]

    # Add dggs_type column
    dggrid_gdf["dggs_type"] = f"dggrid_{dggs_type.lower()}"

    # Rename global_id to cell_id
    if "global_id" in dggrid_gdf.columns:
        dggrid_gdf = dggrid_gdf.rename(columns={"global_id": "cell_id"})

    # Determine whether current CRS is geographic; compute metrics accordingly
    if dggrid_gdf.crs.is_geographic:
        dggrid_gdf["cell_area"] = dggrid_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[0])
        )
        dggrid_gdf["cell_perimeter"] = dggrid_gdf.geometry.apply(
            lambda g: abs(geod.geometry_area_perimeter(g)[1])
        )
        dggrid_gdf["crossed"] = dggrid_gdf.geometry.apply(check_crossing_geom)
    else:
        dggrid_gdf["cell_area"] = dggrid_gdf.geometry.area
        dggrid_gdf["cell_perimeter"] = dggrid_gdf.geometry.length
        dggrid_gdf["crossed"] = False

    # Add resolution column
    dggrid_gdf["resolution"] = resolution

    dggrid_gdf = dggrid_gdf[~dggrid_gdf["crossed"]]  # remove cells that cross the Antimeridian
    # Calculate normalized area
    mean_area = dggrid_gdf["cell_area"].mean()
    dggrid_gdf["norm_area"] = (
        dggrid_gdf["cell_area"] / mean_area if mean_area and mean_area != 0 else np.nan
    )

    # Calculate compactness metrics (robust formulas avoiding division by zero)
    dggrid_gdf["ipq"] = (
        4 * np.pi * dggrid_gdf["cell_area"] / (dggrid_gdf["cell_perimeter"] ** 2)
    )
    dggrid_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * dggrid_gdf["cell_area"]
            - np.power(dggrid_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / dggrid_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = dggrid_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    dggrid_gdf_lambert = get_cells_area(dggrid_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    dggrid_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        dggrid_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    dggrid_gdf["cvh"] = dggrid_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return dggrid_gdf

This module provides functions for generating statistics for ISEA4T DGGS cells.

isea4tstats(unit='m')

Generate statistics for ISEA4T DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing ISEA4T DGGS statistics with columns: - Resolution: Resolution level (0-39) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/isea4tstats.py
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def isea4tstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for ISEA4T DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing ISEA4T DGGS statistics with columns:
            - Resolution: Resolution level (0-39)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = isea4t_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

isea4tinspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for ISEA4T DGGS cells at a given resolution.

This function creates a detailed analysis of ISEA4T cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution

ISEA4T resolution level (0-15)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/isea4tstats.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
def isea4tinspect(resolution, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for ISEA4T DGGS cells at a given resolution.

    This function creates a detailed analysis of ISEA4T cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: ISEA4T resolution level (0-15)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
    Returns:
        geopandas.GeoDataFrame: DataFrame containing ISEA4T cell inspection data with columns:
            - isea4t: ISEA4T cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    # Allow running on all platforms
    resolution = validate_isea4t_resolution(resolution)
    isea4t_gdf = isea4tgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )
    isea4t_gdf["crossed"] = isea4t_gdf["geometry"].apply(check_crossing_geom)
    isea4t_gdf = isea4t_gdf[~isea4t_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = isea4t_gdf["cell_area"].mean()
    # Calculate normalized area
    isea4t_gdf["norm_area"] = isea4t_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    isea4t_gdf["ipq"] = (
        4 * np.pi * isea4t_gdf["cell_area"] / (isea4t_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    isea4t_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * isea4t_gdf["cell_area"]
            - np.power(isea4t_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / isea4t_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = isea4t_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    isea4t_gdf_lambert = get_cells_area(isea4t_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    isea4t_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        isea4t_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    isea4t_gdf["cvh"] = isea4t_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return isea4t_gdf

This module provides functions for generating statistics for ISEA3H DGGS cells.

isea3hstats(unit='m')

Generate statistics for ISEA3H DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing ISEA3H DGGS statistics with columns: - Resolution: Resolution level (0-40) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/isea3hstats.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def isea3hstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for ISEA3H DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing ISEA3H DGGS statistics with columns:
            - Resolution: Resolution level (0-40)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = isea3h_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

isea3hinspect(resolution, fix_antimeridian=None)

Generate comprehensive inspection data for ISEA3H DGGS cells at a given resolution.

This function creates a detailed analysis of ISEA3H cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

ISEA3H resolution level (0-40)

required
fix_antimeridian None

Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none

None
Source code in vgrid/stats/isea3hstats.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
def isea3hinspect(resolution: int, fix_antimeridian: None = None):
    """
    Generate comprehensive inspection data for ISEA3H DGGS cells at a given resolution.

    This function creates a detailed analysis of ISEA3H cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: ISEA3H resolution level (0-40)
        fix_antimeridian: Antimeridian fixing method: shift, shift_balanced, shift_west, shift_east, split, none
    Returns:
        geopandas.GeoDataFrame: DataFrame containing ISEA3H cell inspection data with columns:
            - isea3h: ISEA3H cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    # Allow running on all platforms

    isea3h_gdf = isea3hgrid(
        resolution, output_format="gpd", fix_antimeridian=fix_antimeridian
    )  # remove cells that cross the Antimeridian
    isea3h_gdf["crossed"] = isea3h_gdf["geometry"].apply(check_crossing_geom)
    isea3h_gdf = isea3h_gdf[~isea3h_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = isea3h_gdf["cell_area"].mean()
    # Calculate normalized area
    isea3h_gdf["norm_area"] = isea3h_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    isea3h_gdf["ipq"] = (
        4 * np.pi * isea3h_gdf["cell_area"] / (isea3h_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    isea3h_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * isea3h_gdf["cell_area"]
            - np.power(isea3h_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / isea3h_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = isea3h_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    isea3h_gdf_lambert = get_cells_area(isea3h_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    isea3h_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        isea3h_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    isea3h_gdf["cvh"] = isea3h_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return isea3h_gdf

This module provides functions for generating statistics for EASE-DGGS cells.

easestats(unit='m')

Generate statistics for EASE-DGGS cells. length unit is m, area unit is m2 Args: unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

Returns:

Type Description

pandas.DataFrame: DataFrame containing EASE-DGGS statistics with columns: - Resolution: Resolution level (0-6) - Number_of_Cells: Number of cells at each resolution - Avg_Edge_Length_{unit}: Average edge length in the given unit - Avg_Cell_Area_{unit}2: Average cell area in the squared unit - CLS_{unit}: Characteristic Length Scale in the given unit

Source code in vgrid/stats/easestats.py
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def easestats(unit: str = "m"):  # length unit is m, area unit is m2
    """
    Generate statistics for EASE-DGGS cells.
    length unit is m, area unit is m2
    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing EASE-DGGS statistics with columns:
            - Resolution: Resolution level (0-6)
            - Number_of_Cells: Number of cells at each resolution
            - Avg_Edge_Length_{unit}: Average edge length in the given unit
            - Avg_Cell_Area_{unit}2: Average cell area in the squared unit
            - CLS_{unit}: Characteristic Length Scale in the given unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells_at_res, avg_edge_length, cell_area, cls = ease_metrics(res, unit)
        resolutions.append(res)
        num_cells_list.append(num_cells_at_res)
        avg_edge_lens.append(avg_edge_length)
        avg_cell_areas.append(cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

easeinspect(resolution)

Generate comprehensive inspection data for EASE-DGGS cells at a given resolution.

This function creates a detailed analysis of EASE cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

EASE-DGGS resolution level (0-6)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing EASE cell inspection data with columns: - ease: EASE cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/easestats.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def easeinspect(resolution: int):  # length unit is m, area unit is m2
    """
    Generate comprehensive inspection data for EASE-DGGS cells at a given resolution.

    This function creates a detailed analysis of EASE cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: EASE-DGGS resolution level (0-6)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing EASE cell inspection data with columns:
            - ease: EASE cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    ease_gdf = easegrid(resolution, output_format="gpd")    
    ease_gdf["crossed"] = ease_gdf["geometry"].apply(check_crossing_geom)
    # ease_gdf = ease_gdf[~ease_gdf["crossed"]]  # remove cells that cross the Antimeridian

    mean_area = ease_gdf["cell_area"].mean()
    # Calculate normalized area
    ease_gdf["norm_area"] = ease_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    ease_gdf["ipq"] = (
        4 * np.pi * ease_gdf["cell_area"] / (ease_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    ease_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * ease_gdf["cell_area"]
            - np.power(ease_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / ease_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = ease_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    ease_gdf_lambert = get_cells_area(ease_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    ease_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        ease_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    ease_gdf["cvh"] = ease_gdf["cvh"].replace([np.inf, -np.inf], np.nan)
    return ease_gdf

This module provides functions for generating statistics for QTM DGGS cells.

qtmstats(unit='m')

Generate statistics for QTM DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing QTM DGGS statistics with columns: - resolution: Resolution level (1-24) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/qtmstats.py
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
def qtmstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for QTM DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing QTM DGGS statistics with columns:
            - resolution: Resolution level (1-24)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = qtm_metrics(res, unit=unit)
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

qtminspect(resolution)

Generate comprehensive inspection data for QTM DGGS cells at a given resolution.

This function creates a detailed analysis of QTM cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

QTM resolution level (1-24)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing QTM cell inspection data with columns: - qtm: QTM cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/qtmstats.py
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
def qtminspect(resolution: int):
    """
    Generate comprehensive inspection data for QTM DGGS cells at a given resolution.

    This function creates a detailed analysis of QTM cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: QTM resolution level (1-24)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing QTM cell inspection data with columns:
            - qtm: QTM cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    qtm_gdf = qtm_grid(resolution)
    qtm_gdf["crossed"] = qtm_gdf["geometry"].apply(check_crossing_geom)
    qtm_gdf = qtm_gdf[~qtm_gdf["crossed"]]  # remove cells that cross the Antimeridian
    mean_area = qtm_gdf["cell_area"].mean()
    # Calculate normalized area
    qtm_gdf["norm_area"] = qtm_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    qtm_gdf["ipq"] = 4 * np.pi * qtm_gdf["cell_area"] / (qtm_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    qtm_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * qtm_gdf["cell_area"]
            - np.power(qtm_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / qtm_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = qtm_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    qtm_gdf_lambert = get_cells_area(qtm_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    qtm_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        qtm_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    qtm_gdf["cvh"] = qtm_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return qtm_gdf

This module provides functions for generating statistics for OLC DGGS cells.

olcstats(unit='m')

Generate statistics for OLC DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing OLC DGGS statistics with columns: - resolution: Resolution level (2,4,6,8,10,11,12,13,14,15) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/olcstats.py
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def olcstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for OLC DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing OLC DGGS statistics with columns:
            - resolution: Resolution level (2,4,6,8,10,11,12,13,14,15)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Only specific resolutions are supported

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in olc_resolutions:
        num_cells, avg_edge_len, avg_cell_area, cls = olc_metrics(res, unit=unit)
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

olcinspect(resolution)

Generate comprehensive inspection data for OLC DGGS cells at a given resolution.

This function creates a detailed analysis of OLC cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

OLC resolution level (2-15)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing OLC cell inspection data with columns: - olc: OLC cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/olcstats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
def olcinspect(resolution: int):
    """
    Generate comprehensive inspection data for OLC DGGS cells at a given resolution.

    This function creates a detailed analysis of OLC cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: OLC resolution level (2-15)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing OLC cell inspection data with columns:
            - olc: OLC cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    olc_gdf = olcgrid(resolution, output_format="gpd")          
    olc_gdf["crossed"] = olc_gdf["geometry"].apply(check_crossing_geom)
    mean_area = olc_gdf["cell_area"].mean()
    # Calculate normalized area
    olc_gdf["norm_area"] = olc_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    olc_gdf["ipq"] = 4 * np.pi * olc_gdf["cell_area"] / (olc_gdf["cell_perimeter"] ** 2)
    # Calculate zonal standardized compactness
    olc_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * olc_gdf["cell_area"]
            - np.power(olc_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / olc_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = olc_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    olc_gdf_lambert = get_cells_area(olc_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    olc_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        olc_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    olc_gdf["cvh"] = olc_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return olc_gdf

This module provides functions for generating statistics for Geohash DGGS cells.

geohashstats(unit='m')

Generate statistics for Geohash DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing Geohash DGGS statistics with columns: - resolution: Resolution level (0-12) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/geohashstats.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def geohashstats(unit: str = "m"):
    """
    Generate statistics for Geohash DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing Geohash DGGS statistics with columns:
            - resolution: Resolution level (0-12)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = geohash_metrics(res, unit=unit)
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

geohashinspect(resolution)

Generate comprehensive inspection data for Geohash DGGS cells at a given resolution.

This function creates a detailed analysis of Geohash cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

Geohash resolution level (0-12)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Geohash cell inspection data with columns: - geohash: Geohash cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/geohashstats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def geohashinspect(resolution: int):
    """
    Generate comprehensive inspection data for Geohash DGGS cells at a given resolution.

    This function creates a detailed analysis of Geohash cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: Geohash resolution level (0-12)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Geohash cell inspection data with columns:
            - geohash: Geohash cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    geohash_gdf = geohashgrid(resolution, output_format="gpd")
    geohash_gdf["crossed"] = geohash_gdf["geometry"].apply(check_crossing_geom)
    mean_area = geohash_gdf["cell_area"].mean()
    # Calculate normalized area
    geohash_gdf["norm_area"] = geohash_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    geohash_gdf["ipq"] = (
        4 * np.pi * geohash_gdf["cell_area"] / (geohash_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    geohash_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * geohash_gdf["cell_area"]
            - np.power(geohash_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / geohash_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = geohash_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    geohash_gdf_lambert = get_cells_area(geohash_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    geohash_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        geohash_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    geohash_gdf["cvh"] = geohash_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return geohash_gdf

This module provides functions for generating statistics for GEOREF DGGS cells.

georefstats(unit='m')

Generate statistics for GEOREF DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing GEOREF DGGS statistics with columns: - resolution: Resolution level (0-7) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/georefstats.py
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def georefstats(unit: str = "m"):
    """
    Generate statistics for GEOREF DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing GEOREF DGGS statistics with columns:
            - resolution: Resolution level (0-7)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = georef_metrics(res, unit=unit)
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    length_col = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    area_col = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            length_col: avg_edge_lens,
            area_col: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

georefinspect(resolution)

Generate comprehensive inspection data for GEOREF DGGS cells at a given resolution.

This function creates a detailed analysis of GEOREF cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

GEOREF resolution level (0-10)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing GEOREF cell inspection data with columns: - georef: GEOREF cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/georefstats.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def georefinspect(resolution: int):
    """
    Generate comprehensive inspection data for GEOREF DGGS cells at a given resolution.

    This function creates a detailed analysis of GEOREF cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: GEOREF resolution level (0-10)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing GEOREF cell inspection data with columns:
            - georef: GEOREF cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    georef_gdf = georefgrid(resolution, output_format="gpd")
    georef_gdf["crossed"] = georef_gdf["geometry"].apply(check_crossing_geom)
    mean_area = georef_gdf["cell_area"].mean()
    # Calculate normalized area
    georef_gdf["norm_area"] = georef_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    georef_gdf["ipq"] = (
        4 * np.pi * georef_gdf["cell_area"] / (georef_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    georef_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * georef_gdf["cell_area"]
            - np.power(georef_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / georef_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = georef_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    georef_gdf_lambert = get_cells_area(georef_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    georef_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        georef_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    georef_gdf["cvh"] = georef_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return georef_gdf

This module provides functions for generating statistics for MGRS DGGS cells.

mgrsstats(unit='m')

Generate statistics for MGRS DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing MGRS DGGS statistics with columns: - resolution: Resolution level (0-5) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/mgrsstats.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def mgrsstats(unit: str = "m"):
    """
    Generate statistics for MGRS DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing MGRS DGGS statistics with columns:
            - resolution: Resolution level (0-5)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for resolution in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = mgrs_metrics(resolution, unit=unit)
        resolutions.append(resolution)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

This module provides functions for generating statistics for Tilecode DGGS cells.

tilecodestats(unit='m')

Generate statistics for Tilecode DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing Tilecode DGGS statistics with columns: - resolution: Resolution level (0-30) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/tilecodestats.py
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def tilecodestats(unit: str = "m"):
    """
    Generate statistics for Tilecode DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing Tilecode DGGS statistics with columns:
            - resolution: Resolution level (0-30)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = tilecode_metrics(res, unit=unit)
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

tilecodeinspect(resolution)

Generate comprehensive inspection data for Tilecode DGGS cells at a given resolution.

This function creates a detailed analysis of Tilecode cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Tilecode resolution level (0-29)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Tilecode cell inspection data with columns: - tilecode: Tilecode cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/tilecodestats.py
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def tilecodeinspect(resolution: int):
    """
    Generate comprehensive inspection data for Tilecode DGGS cells at a given resolution.

    This function creates a detailed analysis of Tilecode cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Tilecode resolution level (0-29)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Tilecode cell inspection data with columns:
            - tilecode: Tilecode cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    tilecode_gdf = tilecodegrid(resolution, output_format="gpd")
    tilecode_gdf["crossed"] = tilecode_gdf["geometry"].apply(check_crossing_geom)
    mean_area = tilecode_gdf["cell_area"].mean()
    # Calculate normalized area
    tilecode_gdf["norm_area"] = tilecode_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    tilecode_gdf["ipq"] = (
        4 * np.pi * tilecode_gdf["cell_area"] / (tilecode_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    tilecode_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * tilecode_gdf["cell_area"]
            - np.power(tilecode_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / tilecode_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = tilecode_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    tilecode_gdf_lambert = get_cells_area(tilecode_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    tilecode_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        tilecode_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    tilecode_gdf["cvh"] = tilecode_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return tilecode_gdf

This module provides functions for generating statistics for Quadkey DGGS cells.

quadkeystats(unit='m')

Generate statistics for Quadkey DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing Quadkey DGGS statistics with columns: - resolution: Resolution level (0-30) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/quadkeystats.py
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
def quadkeystats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for Quadkey DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing Quadkey DGGS statistics with columns:
            - resolution: Resolution level (0-30)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = quadkey_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

quadkeyinspect(resolution)

Generate comprehensive inspection data for Quadkey DGGS cells at a given resolution.

This function creates a detailed analysis of Quadkey cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Quadkey resolution level (0-29)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Quadkey cell inspection data with columns: - quadkey: Quadkey cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/quadkeystats.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
def quadkeyinspect(resolution: int):
    """
    Generate comprehensive inspection data for Quadkey DGGS cells at a given resolution.

    This function creates a detailed analysis of Quadkey cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Quadkey resolution level (0-29)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Quadkey cell inspection data with columns:
            - quadkey: Quadkey cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    quadkey_gdf = quadkeygrid(resolution, output_format="gpd")
    quadkey_gdf["crossed"] = quadkey_gdf["geometry"].apply(check_crossing_geom)
    mean_area = quadkey_gdf["cell_area"].mean()
    # Calculate normalized area
    quadkey_gdf["norm_area"] = quadkey_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    quadkey_gdf["ipq"] = (
        4 * np.pi * quadkey_gdf["cell_area"] / (quadkey_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    quadkey_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * quadkey_gdf["cell_area"]
            - np.power(quadkey_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / quadkey_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = quadkey_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    quadkey_gdf_lambert = get_cells_area(quadkey_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    quadkey_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        quadkey_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    quadkey_gdf["cvh"] = quadkey_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return quadkey_gdf

This module provides functions for generating statistics for Maidenhead DGGS cells.

maidenheadstats(unit='m')

Generate statistics for Maidenhead DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing Maidenhead DGGS statistics with columns: - resolution: Resolution level (0-4) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/maidenheadstats.py
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def maidenheadstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for Maidenhead DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing Maidenhead DGGS statistics with columns:
            - resolution: Resolution level (0-4)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = maidenhead_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

maidenheadinspect(resolution)

Generate comprehensive inspection data for Maidenhead DGGS cells at a given resolution.

This function creates a detailed analysis of Maidenhead cells including area variations, compactness measures, and dateline crossing detection.

Parameters:

Name Type Description Default
resolution int

Maidenhead resolution level (1-4)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing Maidenhead cell inspection data with columns: - maidenhead: Maidenhead cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the dateline - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/maidenheadstats.py
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def maidenheadinspect(resolution: int):
    """
    Generate comprehensive inspection data for Maidenhead DGGS cells at a given resolution.

    This function creates a detailed analysis of Maidenhead cells including area variations,
    compactness measures, and dateline crossing detection.

    Args:
        resolution: Maidenhead resolution level (1-4)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing Maidenhead cell inspection data with columns:
            - maidenhead: Maidenhead cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the dateline
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    resolution = validate_maidenhead_resolution(resolution)
    maidenhead_gdf = maidenheadgrid(resolution, output_format="gpd")    
    maidenhead_gdf["crossed"] = maidenhead_gdf["geometry"].apply(check_crossing_geom)
    mean_area = maidenhead_gdf["cell_area"].mean()
    # Calculate normalized area
    maidenhead_gdf["norm_area"] = maidenhead_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    maidenhead_gdf["ipq"] = (
        4
        * np.pi
        * maidenhead_gdf["cell_area"]
        / (maidenhead_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    maidenhead_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * maidenhead_gdf["cell_area"]
            - np.power(maidenhead_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / maidenhead_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = maidenhead_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    maidenhead_gdf_lambert = get_cells_area(maidenhead_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    maidenhead_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        maidenhead_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    maidenhead_gdf["cvh"] = maidenhead_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return maidenhead_gdf

This module provides functions for generating statistics for GARS DGGS cells.

garsstats(unit='m')

Generate statistics for GARS DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing GARS DGGS statistics with columns: - resolution: Resolution level (0-4) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit

Source code in vgrid/stats/garsstats.py
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
def garsstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for GARS DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing GARS DGGS statistics with columns:
            - resolution: Resolution level (0-4)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = gars_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

garsinspect(resolution)

Generate comprehensive inspection data for GARS DGGS cells at a given resolution.

This function creates a detailed analysis of GARS cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution int

GARS resolution level (0-4)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing GARS cell inspection data with columns: - gars: GARS cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness

Source code in vgrid/stats/garsstats.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def garsinspect(resolution: int):  # length unit is km, area unit is km2
    """
    Generate comprehensive inspection data for GARS DGGS cells at a given resolution.

    This function creates a detailed analysis of GARS cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: GARS resolution level (0-4)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing GARS cell inspection data with columns:
            - gars: GARS cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
    """
    gars_gdf = garsgrid(resolution, output_format="gpd")        
    gars_gdf["crossed"] = gars_gdf["geometry"].apply(check_crossing_geom)
    mean_area = gars_gdf["cell_area"].mean()
    # Calculate normalized area
    gars_gdf["norm_area"] = gars_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    gars_gdf["ipq"] = (
        4 * np.pi * gars_gdf["cell_area"] / (gars_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    gars_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * gars_gdf["cell_area"]
            - np.power(gars_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / gars_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = gars_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    gars_gdf_lambert = get_cells_area(gars_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    gars_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        gars_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    gars_gdf["cvh"] = gars_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return gars_gdf

This module provides functions for generating statistics for DIGIPIN DGGS cells.

digipinstats(unit='m')

Generate statistics for DIGIPIN DGGS cells.

Parameters:

Name Type Description Default
unit str

'm' or 'km' for length; area will be 'm^2' or 'km^2'

'm'

Returns:

Type Description

pandas.DataFrame: DataFrame containing DIGIPIN DGGS statistics with columns: - resolution: Resolution level (1-10) - number_of_cells: Number of cells at each resolution - avg_edge_len_{unit}: Average edge length in the given unit - avg_cell_area_{unit}2: Average cell area in the squared unit - cls_{unit}: Characteristic length scale in the given unit

Source code in vgrid/stats/digipinstats.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def digipinstats(unit: str = "m"):  # length unit is km, area unit is km2
    """
    Generate statistics for DIGIPIN DGGS cells.

    Args:
        unit: 'm' or 'km' for length; area will be 'm^2' or 'km^2'

    Returns:
        pandas.DataFrame: DataFrame containing DIGIPIN DGGS statistics with columns:
            - resolution: Resolution level (1-10)
            - number_of_cells: Number of cells at each resolution
            - avg_edge_len_{unit}: Average edge length in the given unit
            - avg_cell_area_{unit}2: Average cell area in the squared unit
            - cls_{unit}: Characteristic length scale in the given unit
    """
    # normalize and validate unit
    unit = unit.strip().lower()
    if unit not in {"m", "km"}:
        raise ValueError("unit must be one of {'m','km'}")

    # Initialize lists to store data
    resolutions = []
    num_cells_list = []
    avg_edge_lens = []
    avg_cell_areas = []
    cls_list = []
    for res in range(min_res, max_res + 1):
        num_cells, avg_edge_len, avg_cell_area, cls = digipin_metrics(
            res, unit=unit
        )  # length unit is km, area unit is km2
        resolutions.append(res)
        num_cells_list.append(num_cells)
        avg_edge_lens.append(avg_edge_len)
        avg_cell_areas.append(avg_cell_area)
        cls_list.append(cls)
    # Create DataFrame
    # Build column labels with unit awareness (lower case)
    avg_edge_len = f"avg_edge_len_{unit}"
    unit_area_label = {"m": "m2", "km": "km2"}[unit]
    avg_cell_area = f"avg_cell_area_{unit_area_label}"
    cls_label = f"cls_{unit}"
    df = pd.DataFrame(
        {
            "resolution": resolutions,
            "number_of_cells": num_cells_list,
            avg_edge_len: avg_edge_lens,
            avg_cell_area: avg_cell_areas,
            cls_label: cls_list,
        }
    )

    return df

digipininspect(resolution)

Generate comprehensive inspection data for DIGIPIN DGGS cells at a given resolution.

This function creates a detailed analysis of DIGIPIN cells including area variations, compactness measures, and Antimeridian crossing detection.

Parameters:

Name Type Description Default
resolution

DIGIPIN resolution level (1-10)

required

Returns:

Type Description

geopandas.GeoDataFrame: DataFrame containing DIGIPIN cell inspection data with columns: - digipin: DIGIPIN cell ID - resolution: Resolution level - geometry: Cell geometry - cell_area: Cell area in square meters - cell_perimeter: Cell perimeter in meters - crossed: Whether cell crosses the Antimeridian - norm_area: Normalized area (cell_area / mean_area) - ipq: Isoperimetric Quotient compactness - zsc: Zonal Standardized Compactness - cvh: Convex Hull compactness

Source code in vgrid/stats/digipinstats.py
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def digipininspect(resolution):
    """
    Generate comprehensive inspection data for DIGIPIN DGGS cells at a given resolution.

    This function creates a detailed analysis of DIGIPIN cells including area variations,
    compactness measures, and Antimeridian crossing detection.

    Args:
        resolution: DIGIPIN resolution level (1-10)

    Returns:
        geopandas.GeoDataFrame: DataFrame containing DIGIPIN cell inspection data with columns:
            - digipin: DIGIPIN cell ID
            - resolution: Resolution level
            - geometry: Cell geometry
            - cell_area: Cell area in square meters
            - cell_perimeter: Cell perimeter in meters
            - crossed: Whether cell crosses the Antimeridian
            - norm_area: Normalized area (cell_area / mean_area)
            - ipq: Isoperimetric Quotient compactness
            - zsc: Zonal Standardized Compactness
            - cvh: Convex Hull compactness
    """
    resolution = validate_digipin_resolution(resolution)
    digipin_gdf = digipingrid(resolution, output_format="gpd")
    digipin_gdf["crossed"] = digipin_gdf["geometry"].apply(check_crossing_geom)
    mean_area = digipin_gdf["cell_area"].mean()
    # Calculate normalized area
    digipin_gdf["norm_area"] = digipin_gdf["cell_area"] / mean_area
    # Calculate IPQ compactness using the standard formula: CI = 4πA/P²
    digipin_gdf["ipq"] = (
        4 * np.pi * digipin_gdf["cell_area"] / (digipin_gdf["cell_perimeter"] ** 2)
    )
    # Calculate zonal standardized compactness
    digipin_gdf["zsc"] = (
        np.sqrt(
            4 * np.pi * digipin_gdf["cell_area"]
            - np.power(digipin_gdf["cell_area"], 2) / np.power(6378137, 2)
        )
        / digipin_gdf["cell_perimeter"]
    )

    # Compute convex hull using Lambert Azimuthal Equal Area projection
    convex_hull = digipin_gdf["geometry"].apply(convexhull_from_lambert)
    # Calculate convex hull area using Lambert projection
    convex_hull_area = convex_hull.apply(
        lambda g: get_area_perimeter_from_lambert(g)[0] if g is not None else np.nan
    )
    # Calculate cell area using Lambert projection for consistent cvh calculation
    digipin_gdf_lambert = get_cells_area(digipin_gdf.copy(), 'LAEA')
    # Compute CVH safely; set to NaN where convex hull area is non-positive or invalid
    digipin_gdf["cvh"] = np.where(
        (convex_hull_area > 0) & np.isfinite(convex_hull_area),
        digipin_gdf_lambert["area"] / convex_hull_area,
        np.nan,
    )
    # Replace any accidental inf values with NaN
    digipin_gdf["cvh"] = digipin_gdf["cvh"].replace([np.inf, -np.inf], np.nan)

    return digipin_gdf