summit/backend/venv/lib/python3.12/site-packages/rasterio/rio/gcps.py

112 lines
3.7 KiB
Python

"""Command access to dataset metadata, stats, and more."""
import json
import click
from cligj import (
compact_opt, use_rs_opt, geojson_type_collection_opt,
geojson_type_feature_opt, projection_geographic_opt,
projection_projected_opt, precision_opt, indent_opt)
import rasterio
import rasterio.crs
from rasterio.rio import options
from rasterio.warp import transform_geom
# Feature collection or feature sequence switch, defaulting to the
# latter, the opposite of cligj's default.
sequence_opt = click.option(
'--sequence/--no-sequence',
default=True,
help="Write a LF-delimited sequence of texts containing individual "
"objects or write a single JSON text containing a feature "
"collection object (the default).")
@click.command(short_help="Print ground control points as GeoJSON.")
@options.file_in_arg
@geojson_type_collection_opt()
@geojson_type_feature_opt(default=True)
@projection_geographic_opt
@projection_projected_opt
@precision_opt
@use_rs_opt
@indent_opt
@compact_opt
@click.pass_context
def gcps(ctx, input, geojson_type, projection, precision, use_rs, indent, compact):
"""Print GeoJSON representations of a dataset's control points.
Each ground control point is represented as a GeoJSON feature. The
'properties' member of each feature contains a JSON representation
of the control point with the following items:
\b
row, col:
row (or line) and col (or pixel) coordinates.
x, y, z:
x, y, and z spatial coordinates.
crs:
The coordinate reference system for x, y, and z.
id:
A unique (within the dataset) identifier for the control
point.
info:
A brief description of the control point.
"""
# Handle the invalid combinations of args.
if geojson_type == 'feature' and indent and not use_rs:
raise click.BadParameter(
"Pretty-printing a sequence of Features requires the --rs option")
with ctx.obj['env'], rasterio.open(input) as src:
gcps, crs = src.gcps
proj = crs.to_string()
proj = proj.split('=')[1].upper() if proj.startswith('+init=epsg') else proj
def update_props(data, **kwds):
data['properties'].update(**kwds)
return data
def transform(feat):
dst_crs = 'epsg:4326' if projection == 'geographic' else crs
geom = transform_geom(crs, dst_crs, feat['geometry'],
precision=precision)
feat['geometry'] = geom
return feat
# Specifying --collection overrides --sequence.
if geojson_type == 'collection':
if projection == 'geographic' or precision >= 0:
features = [transform(update_props(p.__geo_interface__, crs=proj)) for p in gcps]
else:
features = [update_props(p.__geo_interface__, crs=proj) for p in gcps]
click.echo(
json.dumps(
{"type": "FeatureCollection", "features": features},
separators=(",", ":") if compact else None,
indent=indent,
)
)
else:
for p in gcps:
if use_rs:
click.echo("\x1e", nl=False)
if projection == "geographic" or precision >= 0:
feat = transform(update_props(p.__geo_interface__, crs=proj))
else:
feat = update_props(p.__geo_interface__, crs=proj)
click.echo(
json.dumps(
feat, separators=(",", ":") if compact else None, indent=indent
)
)