mirror of
https://github.com/rasterio/rasterio.git
synced 2025-12-08 17:36:12 +00:00
Merge pull request #228 from mapbox/json-test-sequences
--sequence means write JSON text sequences.
This commit is contained in:
commit
13dc4752d7
@ -44,12 +44,12 @@ def coords(obj):
|
||||
|
||||
|
||||
def write_features(file, collection,
|
||||
agg_mode='obj', expression='feature', use_rs=False,
|
||||
collect=True, expression='feature', use_rs=False,
|
||||
**dump_kwds):
|
||||
"""Read an iterator of (feat, bbox) pairs and write to file using
|
||||
the selected modes."""
|
||||
# Sequence of features expressed as bbox, feature, or collection.
|
||||
if agg_mode == 'seq':
|
||||
if not collect:
|
||||
for feat in collection():
|
||||
xs, ys = zip(*coords(feat))
|
||||
bbox = (min(xs), min(ys), max(xs), max(ys))
|
||||
|
||||
@ -9,7 +9,9 @@ import click
|
||||
import rasterio
|
||||
from rasterio.transform import Affine
|
||||
from rasterio.rio.cli import cli, coords, write_features
|
||||
|
||||
from rasterio.rio.params import (
|
||||
precision_opt, indent_opt, compact_opt, geographic_opt, projected_opt,
|
||||
collection_opt, rs_opt, feature_mode_opt, bbox_mode_opt)
|
||||
|
||||
warnings.simplefilter('default')
|
||||
|
||||
@ -17,39 +19,15 @@ warnings.simplefilter('default')
|
||||
# Shapes command.
|
||||
@cli.command(short_help="Write the shapes of features.")
|
||||
@click.argument('input', type=click.Path(exists=True))
|
||||
# Coordinate precision option.
|
||||
@click.option('--precision', type=int, default=-1,
|
||||
help="Decimal precision of coordinates.")
|
||||
# JSON formatting options.
|
||||
@click.option('--indent', default=None, type=int,
|
||||
help="Indentation level for JSON output")
|
||||
@click.option('--compact/--no-compact', default=False,
|
||||
help="Use compact separators (',', ':').")
|
||||
# Geographic (default) or Mercator switch.
|
||||
@click.option('--geographic', 'projected', flag_value='geographic',
|
||||
default=True,
|
||||
help="Output in geographic coordinates (the default).")
|
||||
@click.option('--projected', 'projected', flag_value='projected',
|
||||
help="Output in projected coordinates.")
|
||||
# JSON object (default) or sequence (experimental) switch.
|
||||
@click.option('--json-obj', 'json_mode', flag_value='obj', default=True,
|
||||
help="Write a single JSON object (the default).")
|
||||
@click.option('--x-json-seq', 'json_mode', flag_value='seq',
|
||||
help="Write a JSON sequence. Experimental.")
|
||||
# Use ASCII RS control code to signal a sequence item (False is default).
|
||||
# See http://tools.ietf.org/html/draft-ietf-json-text-sequence-05.
|
||||
# Experimental.
|
||||
@click.option('--x-json-seq-rs/--x-json-seq-no-rs', default=False,
|
||||
help="Use RS as text separator. Experimental.")
|
||||
# GeoJSON feature (default), bbox, or collection switch. Meaningful only
|
||||
# when --x-json-seq is used.
|
||||
@click.option('--collection', 'output_mode', flag_value='collection',
|
||||
default=True,
|
||||
help="Output as a GeoJSON feature collection (the default).")
|
||||
@click.option('--feature', 'output_mode', flag_value='feature',
|
||||
help="Output as sequence of GeoJSON features.")
|
||||
@click.option('--bbox', 'output_mode', flag_value='bbox',
|
||||
help="Output as a GeoJSON bounding box array.")
|
||||
@precision_opt
|
||||
@indent_opt
|
||||
@compact_opt
|
||||
@geographic_opt
|
||||
@projected_opt
|
||||
@collection_opt
|
||||
@rs_opt
|
||||
@feature_mode_opt(True)
|
||||
@bbox_mode_opt(False)
|
||||
@click.option('--bands/--mask', default=True,
|
||||
help="Extract shapes from one of the dataset bands or from "
|
||||
"its nodata mask")
|
||||
@ -61,17 +39,17 @@ warnings.simplefilter('default')
|
||||
help="Include or do not include (the default) nodata regions.")
|
||||
@click.pass_context
|
||||
def shapes(
|
||||
ctx, input, precision, indent, compact, projected, json_mode,
|
||||
x_json_seq_rs, output_mode, bands, bidx, sampling, with_nodata):
|
||||
ctx, input, precision, indent, compact, projected, collection,
|
||||
use_rs, output_mode, bands, bidx, sampling, with_nodata):
|
||||
"""Writes features of a dataset out as GeoJSON. It's intended for
|
||||
use with single-band rasters and reads from the first band.
|
||||
"""
|
||||
# These import numpy, which we don't want to do unless its needed.
|
||||
# These import numpy, which we don't want to do unless it's needed.
|
||||
import numpy
|
||||
import rasterio.features
|
||||
import rasterio.warp
|
||||
|
||||
verbosity = ctx.obj['verbosity']
|
||||
verbosity = ctx.obj['verbosity'] if ctx.obj else 1
|
||||
logger = logging.getLogger('rio')
|
||||
dump_kwds = {'sort_keys': True}
|
||||
if indent:
|
||||
@ -144,11 +122,14 @@ def shapes(
|
||||
'bbox': [min(xs), min(ys), max(xs), max(ys)],
|
||||
'geometry': g }
|
||||
|
||||
if collection:
|
||||
output_mode = 'collection'
|
||||
|
||||
try:
|
||||
with rasterio.drivers(CPL_DEBUG=verbosity>2):
|
||||
write_features(
|
||||
stdout, Collection(), agg_mode=json_mode,
|
||||
expression=output_mode, use_rs=x_json_seq_rs,
|
||||
stdout, Collection(), collect=collection,
|
||||
expression=output_mode, use_rs=use_rs,
|
||||
**dump_kwds)
|
||||
sys.exit(0)
|
||||
except Exception:
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
# Shared arguments and options.
|
||||
|
||||
import click
|
||||
|
||||
|
||||
# Common arguments.
|
||||
files_arg = click.argument(
|
||||
'files',
|
||||
nargs=-1,
|
||||
@ -8,11 +10,7 @@ files_arg = click.argument(
|
||||
required=True,
|
||||
metavar="INPUTS... OUTPUT")
|
||||
|
||||
format_opt = click.option(
|
||||
'-f', '--format', '--driver',
|
||||
default='GTiff',
|
||||
help="Output format driver")
|
||||
|
||||
# Common options.
|
||||
verbose_opt = click.option(
|
||||
'--verbose', '-v',
|
||||
count=True,
|
||||
@ -22,3 +20,89 @@ quiet_opt = click.option(
|
||||
'--quiet', '-q',
|
||||
count=True,
|
||||
help="Decrease verbosity.")
|
||||
|
||||
# Format driver option.
|
||||
format_opt = click.option(
|
||||
'-f', '--format', '--driver',
|
||||
default='GTiff',
|
||||
help="Output format driver")
|
||||
|
||||
# JSON formatting options.
|
||||
indent_opt = click.option(
|
||||
'--indent',
|
||||
type=int,
|
||||
default=None,
|
||||
help="Indentation level for JSON output")
|
||||
|
||||
compact_opt = click.option(
|
||||
'--compact/--no-compact',
|
||||
default=False,
|
||||
help="Use compact separators (',', ':').")
|
||||
|
||||
# Coordinate precision option.
|
||||
precision_opt = click.option(
|
||||
'--precision',
|
||||
type=int,
|
||||
default=-1,
|
||||
help="Decimal precision of coordinates.")
|
||||
|
||||
# Geographic (default) or Mercator switch.
|
||||
geographic_opt = click.option(
|
||||
'--geographic',
|
||||
'projected',
|
||||
flag_value='geographic',
|
||||
default=True,
|
||||
help="Output in geographic coordinates (the default).")
|
||||
|
||||
projected_opt = click.option(
|
||||
'--projected',
|
||||
'projected',
|
||||
flag_value='projected',
|
||||
help="Output in dataset's own, projected coordinates.")
|
||||
|
||||
mercator_opt = click.option(
|
||||
'--mercator',
|
||||
'projected',
|
||||
flag_value='mercator',
|
||||
help="Output in Web Mercator coordinates.")
|
||||
|
||||
# Feature collection or feature sequence switch.
|
||||
collection_opt = click.option(
|
||||
'--collection/--sequence',
|
||||
default=True,
|
||||
help="Write a single JSON text containing a feature collection object "
|
||||
"(the default) or write a LF-delimited sequence of texts containing "
|
||||
"individual objects.")
|
||||
|
||||
rs_opt = click.option(
|
||||
'--with-rs/--without-rs',
|
||||
'use_rs',
|
||||
default=False,
|
||||
help="Use RS (0x1E) as a prefix for individual texts in a sequence "
|
||||
"as per http://tools.ietf.org/html/draft-ietf-json-text-sequence-13 "
|
||||
"(default is False).")
|
||||
|
||||
# GeoJSON output mode option.
|
||||
def collection_mode_opt(default=False):
|
||||
return click.option(
|
||||
'--collection',
|
||||
'output_mode',
|
||||
flag_value='collection',
|
||||
default=default,
|
||||
help="Output as sequence of GeoJSON feature collections.")
|
||||
|
||||
def feature_mode_opt(default=False):
|
||||
return click.option(
|
||||
'--feature',
|
||||
'output_mode',
|
||||
flag_value='feature',
|
||||
default=default,
|
||||
help="Output as sequence of GeoJSON features.")
|
||||
|
||||
def bbox_mode_opt(default=False):
|
||||
return click.option(
|
||||
'--bbox',
|
||||
'output_mode',
|
||||
flag_value='bbox',
|
||||
default=default,
|
||||
help="Output as a GeoJSON bounding box array.")
|
||||
|
||||
@ -13,7 +13,10 @@ import click
|
||||
import rasterio
|
||||
|
||||
from rasterio.rio.cli import cli, write_features
|
||||
|
||||
from rasterio.rio.params import (
|
||||
precision_opt, indent_opt, compact_opt, geographic_opt, projected_opt,
|
||||
mercator_opt, collection_opt, rs_opt, feature_mode_opt, bbox_mode_opt,
|
||||
collection_mode_opt)
|
||||
|
||||
warnings.simplefilter('default')
|
||||
|
||||
@ -27,7 +30,11 @@ warnings.simplefilter('default')
|
||||
# Insp command.
|
||||
@cli.command(short_help="Open a data file and start an interpreter.")
|
||||
@click.argument('input', type=click.Path(exists=True))
|
||||
@click.option('--mode', type=click.Choice(['r', 'r+']), default='r', help="File mode (default 'r').")
|
||||
@click.option(
|
||||
'--mode',
|
||||
type=click.Choice(['r', 'r+']),
|
||||
default='r',
|
||||
help="File mode (default 'r').")
|
||||
@click.pass_context
|
||||
def insp(ctx, input, mode):
|
||||
import rasterio.tool
|
||||
@ -54,44 +61,20 @@ def insp(ctx, input, mode):
|
||||
# One or more files, the bounds of each are a feature in the collection
|
||||
# object or feature sequence.
|
||||
@click.argument('input', nargs=-1, type=click.Path(exists=True))
|
||||
# Coordinate precision option.
|
||||
@click.option('--precision', type=int, default=-1,
|
||||
help="Decimal precision of coordinates.")
|
||||
# JSON formatting options.
|
||||
@click.option('--indent', default=None, type=int,
|
||||
help="Indentation level for JSON output")
|
||||
@click.option('--compact/--no-compact', default=False,
|
||||
help="Use compact separators (',', ':').")
|
||||
# Geographic (default) or Mercator switch.
|
||||
@click.option('--geographic', 'projected', flag_value='geographic',
|
||||
default=True,
|
||||
help="Output in geographic coordinates (the default).")
|
||||
@click.option('--projected', 'projected', flag_value='projected',
|
||||
help="Output in projected coordinates.")
|
||||
@click.option('--mercator', 'projected', flag_value='mercator',
|
||||
help="Output in Web Mercator coordinates.")
|
||||
# JSON object (default) or sequence (experimental) switch.
|
||||
@click.option('--json-obj', 'json_mode', flag_value='obj', default=True,
|
||||
help="Write a single JSON object (the default).")
|
||||
@click.option('--x-json-seq', 'json_mode', flag_value='seq',
|
||||
help="Write a JSON sequence. Experimental.")
|
||||
# Use ASCII RS control code to signal a sequence item (False is default).
|
||||
# See http://tools.ietf.org/html/draft-ietf-json-text-sequence-05.
|
||||
# Experimental.
|
||||
@click.option('--x-json-seq-rs/--x-json-seq-no-rs', default=False,
|
||||
help="Use RS as text separator. Experimental.")
|
||||
# GeoJSON feature (default), bbox, or collection switch. Meaningful only
|
||||
# when --x-json-seq is used.
|
||||
@click.option('--collection', 'output_mode', flag_value='collection',
|
||||
default=True,
|
||||
help="Output as a GeoJSON feature collection (the default).")
|
||||
@click.option('--feature', 'output_mode', flag_value='feature',
|
||||
help="Output as sequence of GeoJSON features.")
|
||||
@click.option('--bbox', 'output_mode', flag_value='bbox',
|
||||
help="Output as a GeoJSON bounding box array.")
|
||||
@precision_opt
|
||||
@indent_opt
|
||||
@compact_opt
|
||||
@geographic_opt
|
||||
@projected_opt
|
||||
@mercator_opt
|
||||
@collection_opt
|
||||
@rs_opt
|
||||
@collection_mode_opt(True)
|
||||
@feature_mode_opt(False)
|
||||
@bbox_mode_opt(False)
|
||||
@click.pass_context
|
||||
def bounds(ctx, input, precision, indent, compact, projected, json_mode,
|
||||
x_json_seq_rs, output_mode):
|
||||
def bounds(ctx, input, precision, indent, compact, projected, collection,
|
||||
use_rs, output_mode):
|
||||
"""Write bounding boxes to stdout as GeoJSON for use with, e.g.,
|
||||
geojsonio
|
||||
|
||||
@ -153,15 +136,14 @@ def bounds(ctx, input, precision, indent, compact, projected, json_mode,
|
||||
self._xs.extend(bbox[::2])
|
||||
self._ys.extend(bbox[1::2])
|
||||
|
||||
collection = Collection()
|
||||
|
||||
col = Collection()
|
||||
# Use the generator defined above as input to the generic output
|
||||
# writing function.
|
||||
try:
|
||||
with rasterio.drivers(CPL_DEBUG=verbosity>2):
|
||||
write_features(
|
||||
stdout, collection, agg_mode=json_mode,
|
||||
expression=output_mode, use_rs=x_json_seq_rs,
|
||||
stdout, col, collect=collection,
|
||||
expression=output_mode, use_rs=use_rs,
|
||||
**dump_kwds)
|
||||
sys.exit(0)
|
||||
except Exception:
|
||||
@ -174,8 +156,7 @@ def bounds(ctx, input, precision, indent, compact, projected, json_mode,
|
||||
@click.argument('input', default='-', required=False)
|
||||
@click.option('--src_crs', default='EPSG:4326', help="Source CRS.")
|
||||
@click.option('--dst_crs', default='EPSG:4326', help="Destination CRS.")
|
||||
@click.option('--precision', type=int, default=-1,
|
||||
help="Decimal precision of coordinates.")
|
||||
@precision_opt
|
||||
@click.pass_context
|
||||
def transform(ctx, input, src_crs, dst_crs, precision):
|
||||
import rasterio.warp
|
||||
|
||||
@ -1,115 +0,0 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
def test_cli_bounds_obj_bbox():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --bbox --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == '[-78.898133, 23.564991, -76.599438, 25.550874]'
|
||||
|
||||
|
||||
def test_cli_bounds_obj_bbox_mercator():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --bbox --mercator --precision 3',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == '[-8782900.033, 2700489.278, -8527010.472, 2943560.235]'
|
||||
|
||||
|
||||
def test_cli_bounds_obj_feature():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --feature --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}'
|
||||
|
||||
|
||||
def test_cli_bounds_obj_collection():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "features": [{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}], "type": "FeatureCollection"}'
|
||||
|
||||
|
||||
def test_cli_bounds_seq_feature_rs():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --x-json-seq --x-json-seq-rs --feature --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').startswith(u'\x1e')
|
||||
assert result.decode('utf-8').strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}'
|
||||
|
||||
|
||||
def test_cli_bounds_seq_collection():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --x-json-seq --x-json-seq-rs --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').startswith(u'\x1e')
|
||||
assert result.decode('utf-8').strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "features": [{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}], "type": "FeatureCollection"}'
|
||||
|
||||
|
||||
def test_cli_bounds_seq_bbox():
|
||||
result = subprocess.check_output(
|
||||
'rio bounds tests/data/RGB.byte.tif --x-json-seq --x-json-seq-rs --bbox --precision 6',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').startswith(u'\x1e')
|
||||
assert result.decode('utf-8').strip() == '[-78.898133, 23.564991, -76.599438, 25.550874]'
|
||||
|
||||
|
||||
def test_cli_bounds_seq_collection_multi(tmpdir):
|
||||
filename = str(tmpdir.join("test.json"))
|
||||
tmp = open(filename, 'w')
|
||||
|
||||
subprocess.check_call(
|
||||
'rio bounds tests/data/RGB.byte.tif tests/data/RGB.byte.tif --x-json-seq --x-json-seq-rs --precision 6',
|
||||
stdout=tmp,
|
||||
shell=True)
|
||||
|
||||
tmp.close()
|
||||
tmp = open(filename, 'r')
|
||||
json_texts = []
|
||||
text = ""
|
||||
for line in tmp:
|
||||
rs_idx = line.find(u'\x1e')
|
||||
if rs_idx >= 0:
|
||||
if text:
|
||||
text += line[:rs_idx]
|
||||
json_texts.append(text)
|
||||
text = line[rs_idx+1:]
|
||||
else:
|
||||
text += line
|
||||
else:
|
||||
json_texts.append(text)
|
||||
|
||||
assert len(json_texts) == 2
|
||||
assert json_texts[0].strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "features": [{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}], "type": "FeatureCollection"}'
|
||||
assert json_texts[1].strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "features": [{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "1", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}], "type": "FeatureCollection"}'
|
||||
|
||||
|
||||
def test_cli_info_count():
|
||||
result = subprocess.check_output(
|
||||
'if [ `rio info tests/data/RGB.byte.tif --count` -eq 3 ]; '
|
||||
'then echo "True"; fi',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == 'True'
|
||||
|
||||
|
||||
def test_cli_info_nodata():
|
||||
result = subprocess.check_output(
|
||||
'if [ `rio info tests/data/RGB.byte.tif --nodata` = "0.0" ]; '
|
||||
'then echo "True"; fi',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == 'True'
|
||||
|
||||
|
||||
def test_cli_info_dtype():
|
||||
result = subprocess.check_output(
|
||||
'if [ `rio info tests/data/RGB.byte.tif --dtype` = "uint8" ]; '
|
||||
'then echo "True"; fi',
|
||||
shell=True)
|
||||
assert result.decode('utf-8').strip() == 'True'
|
||||
|
||||
|
||||
def test_cli_info_shape():
|
||||
result = subprocess.check_output(
|
||||
'if [[ `rio info tests/data/RGB.byte.tif --shape` == "718 791" ]]; '
|
||||
'then echo "True"; fi',
|
||||
shell=True, executable='/bin/bash')
|
||||
assert result.decode('utf-8').strip() == 'True'
|
||||
@ -88,7 +88,7 @@ def test_bounds_seq():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
rio.bounds,
|
||||
['tests/data/RGB.byte.tif', 'tests/data/RGB.byte.tif', '--x-json-seq', '--bbox', '--precision', '2'])
|
||||
['tests/data/RGB.byte.tif', 'tests/data/RGB.byte.tif', '--sequence', '--bbox', '--precision', '2'])
|
||||
assert result.exit_code == 0
|
||||
assert result.output == '[-78.9, 23.56, -76.6, 25.55]\n[-78.9, 23.56, -76.6, 25.55]\n'
|
||||
assert '\x1e' not in result.output
|
||||
@ -98,21 +98,11 @@ def test_bounds_seq_rs():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
rio.bounds,
|
||||
['tests/data/RGB.byte.tif', 'tests/data/RGB.byte.tif', '--x-json-seq', '--x-json-seq-rs', '--bbox', '--precision', '2'])
|
||||
['tests/data/RGB.byte.tif', 'tests/data/RGB.byte.tif', '--sequence', '--with-rs', '--bbox', '--precision', '2'])
|
||||
assert result.exit_code == 0
|
||||
assert result.output == '\x1e[-78.9, 23.56, -76.6, 25.55]\n\x1e[-78.9, 23.56, -76.6, 25.55]\n'
|
||||
|
||||
|
||||
|
||||
def test_bounds_obj_feature():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
rio.bounds,
|
||||
['tests/data/RGB.byte.tif', '--feature', '--precision', '6'])
|
||||
assert result.exit_code == 0
|
||||
assert result.output.strip() == '{"bbox": [-78.898133, 23.564991, -76.599438, 25.550874], "geometry": {"coordinates": [[[-78.898133, 23.564991], [-76.599438, 23.564991], [-76.599438, 25.550874], [-78.898133, 25.550874], [-78.898133, 23.564991]]], "type": "Polygon"}, "properties": {"id": "0", "title": "tests/data/RGB.byte.tif"}, "type": "Feature"}'
|
||||
|
||||
|
||||
def test_transform_err():
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user