more libraries
This commit is contained in:
198
.venv/lib/python3.12/site-packages/fiona/fio/dump.py
Normal file
198
.venv/lib/python3.12/site-packages/fiona/fio/dump.py
Normal file
@@ -0,0 +1,198 @@
|
||||
"""fio-dump"""
|
||||
|
||||
from functools import partial
|
||||
import json
|
||||
import logging
|
||||
|
||||
import click
|
||||
import cligj
|
||||
|
||||
import fiona
|
||||
from fiona.fio import helpers, options, with_context_env
|
||||
from fiona.model import Feature, ObjectEncoder
|
||||
from fiona.transform import transform_geom
|
||||
|
||||
|
||||
@click.command(short_help="Dump a dataset to GeoJSON.")
|
||||
@click.argument('input', required=True)
|
||||
@click.option('--layer', metavar="INDEX|NAME", callback=options.cb_layer,
|
||||
help="Print information about a specific layer. The first "
|
||||
"layer is used by default. Layers use zero-based "
|
||||
"numbering when accessed by index.")
|
||||
@click.option('--encoding', help="Specify encoding of the input file.")
|
||||
@cligj.precision_opt
|
||||
@cligj.indent_opt
|
||||
@cligj.compact_opt
|
||||
@click.option('--record-buffered/--no-record-buffered', default=False,
|
||||
help="Economical buffering of writes at record, not collection "
|
||||
"(default), level.")
|
||||
@click.option('--ignore-errors/--no-ignore-errors', default=False,
|
||||
help="log errors but do not stop serialization.")
|
||||
@click.option('--with-ld-context/--without-ld-context', default=False,
|
||||
help="add a JSON-LD context to JSON output.")
|
||||
@click.option('--add-ld-context-item', multiple=True,
|
||||
help="map a term to a URI and add it to the output's JSON LD "
|
||||
"context.")
|
||||
@options.open_opt
|
||||
@click.pass_context
|
||||
@with_context_env
|
||||
def dump(
|
||||
ctx,
|
||||
input,
|
||||
encoding,
|
||||
precision,
|
||||
indent,
|
||||
compact,
|
||||
record_buffered,
|
||||
ignore_errors,
|
||||
with_ld_context,
|
||||
add_ld_context_item,
|
||||
layer,
|
||||
open_options,
|
||||
):
|
||||
|
||||
"""Dump a dataset either as a GeoJSON feature collection (the default)
|
||||
or a sequence of GeoJSON features."""
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
sink = click.get_text_stream('stdout')
|
||||
|
||||
dump_kwds = {'sort_keys': True}
|
||||
if indent:
|
||||
dump_kwds['indent'] = indent
|
||||
if compact:
|
||||
dump_kwds['separators'] = (',', ':')
|
||||
item_sep = compact and ',' or ', '
|
||||
|
||||
if encoding:
|
||||
open_options["encoding"] = encoding
|
||||
if layer:
|
||||
open_options["layer"] = layer
|
||||
|
||||
def transformer(crs, feat):
|
||||
tg = partial(
|
||||
transform_geom,
|
||||
crs,
|
||||
"EPSG:4326",
|
||||
antimeridian_cutting=True,
|
||||
precision=precision,
|
||||
)
|
||||
return Feature(
|
||||
id=feat.id, properties=feat.properties, geometry=tg(feat.geometry)
|
||||
)
|
||||
|
||||
with fiona.open(input, **open_options) as source:
|
||||
meta = source.meta
|
||||
meta["fields"] = dict(source.schema["properties"].items())
|
||||
|
||||
if record_buffered:
|
||||
# Buffer GeoJSON data at the feature level for smaller
|
||||
# memory footprint.
|
||||
indented = bool(indent)
|
||||
rec_indent = "\n" + " " * (2 * (indent or 0))
|
||||
|
||||
collection = {
|
||||
"type": "FeatureCollection",
|
||||
"fiona:schema": meta["schema"],
|
||||
"fiona:crs": meta["crs"],
|
||||
"features": [],
|
||||
}
|
||||
if with_ld_context:
|
||||
collection["@context"] = helpers.make_ld_context(add_ld_context_item)
|
||||
|
||||
head, tail = json.dumps(collection, **dump_kwds).split("[]")
|
||||
|
||||
sink.write(head)
|
||||
sink.write("[")
|
||||
|
||||
itr = iter(source)
|
||||
|
||||
# Try the first record.
|
||||
try:
|
||||
i, first = 0, next(itr)
|
||||
first = transformer(first)
|
||||
if with_ld_context:
|
||||
first = helpers.id_record(first)
|
||||
if indented:
|
||||
sink.write(rec_indent)
|
||||
sink.write(
|
||||
json.dumps(first, cls=ObjectEncoder, **dump_kwds).replace(
|
||||
"\n", rec_indent
|
||||
)
|
||||
)
|
||||
except StopIteration:
|
||||
pass
|
||||
except Exception as exc:
|
||||
# Ignoring errors is *not* the default.
|
||||
if ignore_errors:
|
||||
logger.error(
|
||||
"failed to serialize file record %d (%s), " "continuing", i, exc
|
||||
)
|
||||
else:
|
||||
# Log error and close up the GeoJSON, leaving it
|
||||
# more or less valid no matter what happens above.
|
||||
logger.critical(
|
||||
"failed to serialize file record %d (%s), " "quitting", i, exc
|
||||
)
|
||||
sink.write("]")
|
||||
sink.write(tail)
|
||||
if indented:
|
||||
sink.write("\n")
|
||||
raise
|
||||
|
||||
# Because trailing commas aren't valid in JSON arrays
|
||||
# we'll write the item separator before each of the
|
||||
# remaining features.
|
||||
for i, rec in enumerate(itr, 1):
|
||||
rec = transformer(rec)
|
||||
try:
|
||||
if with_ld_context:
|
||||
rec = helpers.id_record(rec)
|
||||
if indented:
|
||||
sink.write(rec_indent)
|
||||
sink.write(item_sep)
|
||||
sink.write(
|
||||
json.dumps(rec, cls=ObjectEncoder, **dump_kwds).replace(
|
||||
"\n", rec_indent
|
||||
)
|
||||
)
|
||||
except Exception as exc:
|
||||
if ignore_errors:
|
||||
logger.error(
|
||||
"failed to serialize file record %d (%s), "
|
||||
"continuing",
|
||||
i, exc)
|
||||
else:
|
||||
logger.critical(
|
||||
"failed to serialize file record %d (%s), "
|
||||
"quitting",
|
||||
i, exc)
|
||||
sink.write("]")
|
||||
sink.write(tail)
|
||||
if indented:
|
||||
sink.write("\n")
|
||||
raise
|
||||
|
||||
# Close up the GeoJSON after writing all features.
|
||||
sink.write("]")
|
||||
sink.write(tail)
|
||||
if indented:
|
||||
sink.write("\n")
|
||||
|
||||
else:
|
||||
# Buffer GeoJSON data at the collection level. The default.
|
||||
collection = {
|
||||
"type": "FeatureCollection",
|
||||
"fiona:schema": meta["schema"],
|
||||
"fiona:crs": meta["crs"].to_string(),
|
||||
}
|
||||
if with_ld_context:
|
||||
collection["@context"] = helpers.make_ld_context(add_ld_context_item)
|
||||
collection["features"] = [
|
||||
helpers.id_record(transformer(rec)) for rec in source
|
||||
]
|
||||
else:
|
||||
collection["features"] = [
|
||||
transformer(source.crs, rec) for rec in source
|
||||
]
|
||||
json.dump(collection, sink, cls=ObjectEncoder, **dump_kwds)
|
||||
Reference in New Issue
Block a user