Fiona地理数据引擎,使用手册

2023-11-05 05:10

本文主要是介绍Fiona地理数据引擎,使用手册,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1   The Fiona User Manual

Author:Sean Gillies, <sean.gillies@gmail.com>
Version:1.4.0
Date:September 22, 2014
Copyright:This work is licensed under a Creative Commons Attribution 3.0 United States License.
Abstract:Fiona is OGR’s neat, nimble, no-nonsense API. This document explains how to use the Fiona package for reading and writing geospatial data files. Python 3 is used in examples. See the README for installation and quick start instructions.

1.1   Introduction

Geographic information systems (GIS) help us plan, react to, and understand changes in our physical, political, economic, and cultural landscapes. A generation ago, GIS was something done only by major institutions like nations and cities, but it’s become ubiquitous today thanks to accurate and inexpensive global positioning systems, commoditization of satellite imagery, and open source software.

The kinds of data in GIS are roughly divided into rasters representing continuous scalar fields (land surface temperature or elevation, for example) and vectors representing discrete entities like roads and administrative boundaries. Fiona is concerned exclusively with the latter. It is a Python wrapper for vector data access functions from the OGR library.  A very simple wrapper for minimalists. It reads data records from files as GeoJSON-like mappings and writes the same kind of mappings as records back to files. That’s it. There are no layers, no cursors, no geometric operations, no transformations between coordinate systems, no remote method calls; all these concerns are left to other Python packages such as Shapely andpyproj and Python language protocols. Why? To eliminate unnecessary complication. Fiona aims to be simple to understand and use, with no gotchas.

Please understand this: Fiona is designed to excel in a certain range of tasks and is less optimal in others. Fiona trades memory and speed for simplicity and reliability. Where OGR’s Python bindings (for example) use C pointers, Fiona copies vector data from the data source to Python objects.  These are simpler and safer to use, but more memory intensive. Fiona’s performance is relatively more slow if you only need access to a single record field – and of course if you just want to reproject or filter data files, nothing beats theogr2ogr program – but Fiona’s performance is much better than OGR’s Python bindings if you want all fields and coordinates of a record. The copying is a constraint, but it simplifies programs. With Fiona, you don’t have to track references to C objects to avoid crashes, and you can work with vector data using familiar Python mapping accessors. Less worry, less time spent reading API documentation.

1.1.1   Rules of Thumb

In what cases would you benefit from using Fiona?

  • If the features of interest are from or destined for a file in a non-text format like ESRI Shapefiles, Mapinfo TAB files, etc.

  • If you’re more interested in the values of many feature properties than in a single property’s value.

  • If you’re more interested in all the coordinate values of a feature’s geometry than in a single value.

  • If your processing system is distributed or not contained to a single process.

In what cases would you not benefit from using Fiona?

  • If your data is in or destined for a JSON document you should use Python’sjson or simplejson modules.

  • If your data is in a RDBMS like PostGIS, use a Python DB package or ORM likeSQLAlchemy or GeoAlchemy. Maybe you’re usingGeoDjango already. If so, carry on.

  • If your data is served via HTTP from CouchDB or CartoDB, etc, use an HTTP package (httplib2, Requests, etc) or the provider’s Python API.

  • If you can use ogr2ogr, do so.

1.1.2   Example

The first example of using Fiona is this: copying records from one file to another, adding two attributes and making sure that all polygons are facing “up”. Orientation of polygons is significant in some applications, extruded polygons in Google Earth for one. No other library (like Shapely) is needed here, which keeps it uncomplicated. There’s a test_uk file in the Fiona repository for use in this and other examples.

import datetimeimport loggingimport sysimport fionalogging.basicConfig(stream=sys.stderr, level=logging.INFO)def signed_area(coords):"""Return the signed area enclosed by a ring using the linear time    algorithm at http://www.cgafaq.info/wiki/Polygon_Area. A value >= 0    indicates a counter-clockwise oriented ring.    """xs, ys = map(list, zip(*coords))xs.append(xs[1])ys.append(ys[1])return sum(xs[i]*(ys[i+1]-ys[i-1]) for i in range(1, len(coords)))/2.0with fiona.open('docs/data/test_uk.shp', 'r') as source:# Copy the source schema and add two new properties.sink_schema = source.schema.copy()sink_schema['properties']['s_area'] = 'float'sink_schema['properties']['timestamp'] = 'datetime'# Create a sink for processed features with the same format and# coordinate reference system as the source.with fiona.open('oriented-ccw.shp', 'w',crs=source.crs,driver=source.driver,schema=sink_schema,) as sink:for f in source:try:# If any feature's polygon is facing "down" (has rings# wound clockwise), its rings will be reordered to flip# it "up".g = f['geometry']assert g['type'] == "Polygon"rings = g['coordinates']sa = sum(signed_area(r) for r in rings)if sa < 0.0:rings = [r[::-1] for r in rings]g['coordinates'] = ringsf['geometry'] = g# Add the signed area of the polygon and a timestamp# to the feature properties map.f['properties'].update(s_area=sa,timestamp=datetime.datetime.now().isoformat() )sink.write(f)except Exception, e:logging.exception("Error processing feature %s:", f['id'])# The sink file is written to disk and closed when its block ends.

1.2   Data Model

Discrete geographic features are usually represented in geographic information systems by records. The characteristics of records and their semantic implications are well known [Kent1978]. Among those most significant for geographic data: records have a single type, all records of that type have the same fields, and a record’s fields concern a single geographic feature. Different systems model records in different ways, but the various models have enough in common that programmers have been able to create useful abstract data models.  The OGR model is one. Its primary entities are Data Sources, Layers, and Features. Features have not fields, but attributes and a Geometry. An OGR Layer contains Features of a single type (“roads” or “wells”, for example). The GeoJSON model is a bit more simple, keeping Features and substitutingFeature Collections for OGR Data Sources and Layers. The term “Feature” is thus overloaded in GIS modeling, denoting entities in both our conceptual and data models.

Various formats for record files exist. The ESRI Shapefile [ESRI1998]has been, at least in the United States, the most significant of these up to about 2005 and remains popular today. It is a binary format. The shape fields are stored in one .shp file and the other fields in another .dbf file. The GeoJSON [GeoJSON] format, from 2008, proposed a human readable text format in which geometry and other attribute fields are encoded together usingJavascript Object Notation [JSON]. In GeoJSON, there’s a uniformity of data access.  Attributes of features are accessed in the same manner as attributes of a feature collection.  Coordinates of a geometry are accessed in the same manner as features of a collection.

The GeoJSON format turns out to be a good model for a Python API. JSON objects and Python dictionaries are semantically and syntactically similar. Replacing object-oriented Layer and Feature APIs with interfaces based on Python mappings provides a uniformity of access to data and reduces the amount of time spent reading documentation. A Python programmer knows how to use a mapping, so why not treat features as dictionaries? Use of existing Python idioms is one of Fiona’s major design principles.

TL;DR

Fiona subscribes to the conventional record model of data, but provides GeoJSON-like access to the data via Python file-like and mapping protocols.

1.3   Reading Vector Data

Reading a GIS vector file begins by opening it in mode 'r' using Fiona’sopen() function. It returns an openedCollection object.

>>> import fiona>>> c = fiona.open('docs/data/test_uk.shp', 'r')>>> c<open Collection 'docs/data/test_uk.shp:test_uk', mode 'r' at 0x...>>>> c.closedFalse

API Change

fiona.collection() is deprecated, but aliased tofiona.open() in version 0.9.

Mode 'r' is the default and will be omitted in following examples.

Fiona’s Collection is like a Pythonfile, but is iterable for records rather than lines.

>>> next(c){'geometry': {'type': 'Polygon', 'coordinates': ...>>> len(list(c))48

Note that list() iterates over the entire collection, effectively emptying it as with a Python file.

>>> next(c)Traceback (most recent call last):...StopIteration>>> len(list(c))0

Seeking the beginning of the file is not supported. You must reopen the collection to get back to the beginning.

>>> c = fiona.open('docs/data/test_uk.shp')>>> len(list(c))48

File Encoding

The format drivers will attempt to detect the encoding of your data, but may fail. In my experience GDAL 1.7.2 (for example) doesn’t detect that the encoding of the Natural Earth dataset is Windows-1252. In this case, the proper encoding can be specified explicitly by using the encodingkeyword parameter of fiona.open(): encoding='Windows-1252'.

New in version 0.9.1.

1.3.1   Collection indexing

Features of a collection may also be accessed by index.

>>> import pprint>>> with fiona.open('docs/data/test_uk.shp') as src:...     pprint.pprint(src[1])...{'geometry': {'coordinates': [[(-4.663611, 51.158333),                               (-4.669168, 51.159439),                               (-4.673334, 51.161385),                               (-4.674445, 51.165276),                               (-4.67139, 51.185272),                               (-4.669445, 51.193054),                               (-4.665556, 51.195),                               (-4.65889, 51.195),                               (-4.656389, 51.192215),                               (-4.646389, 51.164444),                               (-4.646945, 51.160828),                               (-4.651668, 51.159439),                               (-4.663611, 51.158333)]],              'type': 'Polygon'}, 'id': '1', 'properties': OrderedDict([(u'CAT', 232.0), (u'FIPS_CNTRY', u'UK'), (u'CNTRY_NAME', u'United Kingdom'), (u'AREA', 244820.0), (u'POP_CNTRY', 60270708.0)]), 'type': 'Feature'}

1.3.2   Closing Files

A Collection involves external resources. There’s no guarantee that these will be released unless you explicitlyclose() the object or use a with statement. When a Collectionis a context guard, it is closed no matter what happens within the block.

>>> try:...     with fiona.open('docs/data/test_uk.shp') as c:...         print(len(list(c)))...         assert True is False... except:...     print(c.closed)...     raise...48TrueTraceback (most recent call last):...AssertionError

An exception is raised in the with block above, but as you can see from the print statement in the except clause c.__exit__()(and thereby c.close()) has been called.

Important

Always call close() or use with and you’ll never stumble over tied-up external resources, locked files, etc.

1.4   Format Drivers, CRS, Bounds, and Schema

In addition to attributes like those of file(name, mode, closed), a Collection has a read-onlydriver attribute which names theOGR format driver used to open the vector file.

>>> c = fiona.open('docs/data/test_uk.shp')>>> c.driver'ESRI Shapefile'

The coordinate reference system (CRS) of the collection’s vector data is accessed via a read-only crs attribute.

>>> c.crs{'no_defs': True, 'ellps': 'WGS84', 'datum': 'WGS84', 'proj': 'longlat'}

The CRS is represented by a mapping of PROJ.4 parameters.

The fiona.crs module provides 3 functions to assist with these mappings. to_string() converts mappings to PROJ.4 strings:

>>> from fiona.crs import to_string>>> print(to_string(c.crs))+datum=WGS84 +ellps=WGS84 +no_defs +proj=longlat

from_string() does the inverse.

>>> from fiona.crs import from_string>>> from_string("+datum=WGS84 +ellps=WGS84 +no_defs +proj=longlat"){'no_defs': True, 'ellps': 'WGS84', 'datum': 'WGS84', 'proj': 'longlat'}

from_epsg() is a shortcut to CRS mappings from EPSG codes.

>>> from fiona.crs import from_epsg>>> from_epsg(3857){'init': 'epsg:3857', 'no_defs': True}

The number of records in the collection’s file can be obtained via Python’s built in len() function.

>>> len(c)48

The minimum bounding rectangle (MBR) or bounds of the collection’s records is obtained via a read-onlybounds attribute.

>>> c.bounds(-8.621389, 49.911659, 1.749444, 60.844444)

Finally, the schema of its record type (a vector file has a single type of record, remember) is accessed via a read-onlyschema attribute. It has ‘geometry’ and ‘properties’ items. The former is a string and the latter is an ordered dict with items having the same order as the fields in the data file.

>>> import pprint>>> pprint.pprint(c.schema){'geometry': 'Polygon', 'properties': {'CAT': 'float:16',                'FIPS_CNTRY': 'str',                'CNTRY_NAME': 'str',                'AREA': 'float:15.2',                'POP_CNTRY': 'float:15.2'}}

1.4.1   Keeping Schemas Simple

Fiona takes a less is more approach to record types and schemas. Data about record types is structured as closely to data about records as can be done. Modulo a record’s ‘id’ key, the keys of a schema mapping are the same as the keys of the collection’s record mappings.

>>> rec = next(c)>>> set(rec.keys()) - set(c.schema.keys()){'id'}>>> set(rec['properties'].keys()) == set(c.schema['properties'].keys())True

The values of the schema mapping are either additional mappings or field type names like ‘Polygon’, ‘float’, and ‘str’. The corresponding Python types can be found in a dictionary named fiona.FIELD_TYPES_MAP.

>>> pprint.pprint(fiona.FIELD_TYPES_MAP){'date': <class 'fiona.rfc3339.FionaDateType'>, 'datetime': <class 'fiona.rfc3339.FionaDateTimeType'>, 'float': <class 'float'>, 'int': <class 'int'>, 'str': <class 'str'>, 'time': <class 'fiona.rfc3339.FionaTimeType'>}

1.4.2   Field Types

In a nutshell, the types and their names are as near to what you’d expect in Python (or Javascript) as possible. The ‘str’ vs ‘unicode’ muddle is a fact of life in Python < 3.0. Fiona records have Unicode strings, but their field type name is ‘str’ (looking forward to Python 3).

>>> type(rec['properties']['CNTRY_NAME'])<class 'str'>>>> c.schema['properties']['CNTRY_NAME']'str'>>> fiona.FIELD_TYPES_MAP[c.schema['properties']['CNTRY_NAME']]<class 'str'>

String type fields may also indicate their maximum width. A value of ‘str:25’ indicates that all values will be no longer than 25 characters. If this value is used in the schema of a file opened for writing, values of that property will be truncated at 25 characters. The default width is 80 chars, which means ‘str’ and ‘str:80’ are more or less equivalent.

Fiona provides a function to get the width of a property.

>>> from fiona import prop_width>>> prop_width('str:25')25>>> prop_width('str')80

Another function gets the proper Python type of a property.

>>> from fiona import prop_type>>> prop_type('int')<type 'int'>>>> prop_type('float')<type 'float'>>>> prop_type('str:25')<class 'str'>

The example above is for Python 3. With Python 2, the type of ‘str’ properties is ‘unicode’.

>>> prop_type('str:25')<class 'unicode'>

1.4.3   Geometry Types

Fiona supports the geometry types in GeoJSON and their 3D variants. This means that the value of a schema’s geometry item will be one of the following:

  • Point

  • LineString

  • Polygon

  • MultiPoint

  • MultiLineString

  • MultiPolygon

  • GeometryCollection

  • 3D Point

  • 3D LineString

  • 3D Polygon

  • 3D MultiPoint

  • 3D MultiLineString

  • 3D MultiPolygon

  • 3D GeometryCollection

The last seven of these, the 3D types, apply only to collection schema. The geometry types of features are always one of the first seven. A ‘3D Point’ collection, for example, always has features with geometry type ‘Point’. The coordinates of those geometries will be (x, y, z) tuples.

Note that one of the most common vector data formats, Esri’s Shapefile, has no ‘MultiLineString’ or ‘MultiPolygon’ schema geometries. However, a Shapefile that indicates ‘Polygon’ in its schema may yield either ‘Polygon’ or ‘MultiPolygon’ features.

1.5   Records

A record you get from a collection is a Python dict structured exactly like a GeoJSON Feature. Fiona records are self-describing; the names of its fields are contained within the data structure and the values in the fields are typed properly for the type of record. Numeric field values are instances of type int and float, for example, not strings.

>>> pprint.pprint(rec){'geometry': {'coordinates': [[(-4.663611, 51.158333),                               (-4.669168, 51.159439),                               (-4.673334, 51.161385),                               (-4.674445, 51.165276),                               (-4.67139, 51.185272),                               (-4.669445, 51.193054),                               (-4.665556, 51.195),                               (-4.65889, 51.195),                               (-4.656389, 51.192215),                               (-4.646389, 51.164444),                               (-4.646945, 51.160828),                               (-4.651668, 51.159439),                               (-4.663611, 51.158333)]],              'type': 'Polygon'}, 'id': '1', 'properties': {'CAT': 232.0,                'FIPS_CNTRY': 'UK',                'CNTRY_NAME': 'United Kingdom',                'AREA': 244820.0,                'POP_CNTRY': 60270708.0}}

The record data has no references to theCollection from which it originates or to any other external resource. It’s entirely independent and safe to use in any way. Closing the collection does not affect the record at all.

>>> c.close()>>> rec['id']'1'

1.5.1   Record Id

A record has an id key. As in the GeoJSON specification, its corresponding value is a string unique within the data file.

>>> c = fiona.open('docs/data/test_uk.shp')>>> rec = next(c)>>> rec['id']'0'

OGR Details

In the OGR model, feature ids are long integers. Fiona record ids are therefore usually string representations of integer record indexes.

1.5.2   Record Properties

A record has a properties key. Its corresponding value is a mapping: an ordered dict to be precise. The keys of the properties mapping are the same as the keys of the properties mapping in the schema of the collection the record comes from (see above).

>>> pprint.pprint(rec['properties']){'CAT': 232.0, 'FIPS_CNTRY': 'UK', 'CNTRY_NAME': 'United Kingdom', 'AREA': 244820.0, 'POP_CNTRY': 60270708.0}

1.5.3   Record Geometry

A record has a geometry key. Its corresponding value is a mapping withtype and coordinates keys.

>>> pprint.pprint(rec['geometry']){'coordinates': [[(0.899167, 51.357216),                  (0.885278, 51.35833),                  (0.7875, 51.369438),                  (0.781111, 51.370552),                  (0.766111, 51.375832),                  (0.759444, 51.380829),                  (0.745278, 51.39444),                  (0.740833, 51.400276),                  (0.735, 51.408333),                  (0.740556, 51.429718),                  (0.748889, 51.443604),                  (0.760278, 51.444717),                  (0.791111, 51.439995),                  (0.892222, 51.421387),                  (0.904167, 51.418884),                  (0.908889, 51.416939),                  (0.930555, 51.398888),                  (0.936667, 51.393608),                  (0.943889, 51.384995),                  (0.9475, 51.378609),                  (0.947778, 51.374718),                  (0.946944, 51.371109),                  (0.9425, 51.369164),                  (0.904722, 51.358055),                  (0.899167, 51.357216)]], 'type': 'Polygon'}

Since the coordinates are just tuples, or lists of tuples, or lists of lists of tuples, the type tells you how to interpret them.

TypeCoordinates
PointA single (x, y) tuple
LineStringA list of (x, y) tuple vertices
PolygonA list of rings (each a list of (x, y) tuples)
MultiPointA list of points (each a single (x, y) tuple)
MultiLineStringA list of lines (each a list of (x, y) tuples)
MultiPolygonA list of polygons (see above)

Fiona, like the GeoJSON format, has both Northern Hemisphere “North is up” and Cartesian “X-Y” biases. The values within a tuple that denoted as (x, y)above are either (longitude E of the prime meridian, latitude N of the equator) or, for other projected coordinate systems, (easting, northing).

Long-Lat, not Lat-Long

Even though most of us say “lat, long” out loud, Fiona’s x,y is always easting, northing, which means (long, lat). Longitude first and latitude second, consistent with the GeoJSON format specification.

1.5.4   Point Set Theory and Simple Features

In a proper, well-scrubbed vector data file the geometry mappings explained above are representations of geometric objects made up of point sets. The following

{'type': 'LineString', 'coordinates': [(0.0, 0.0), (0.0, 1.0)]}

represents not just two points, but the set of infinitely many points along the line of length 1.0 from (0.0, 0.0) to (0.0, 1.0). In the application of point set theory commonly called Simple Features Access [SFA] two geometric objects are equal if their point sets are equal whether they are equal in the Python sense or not. If you have Shapely (which implements Simple Features Access) installed, you can see this in by verifying the following.

>>> from shapely.geometry import shape>>> l1 = shape(...     {'type': 'LineString', 'coordinates': [(0, 0), (2, 2)]})>>> l2 = shape(...     {'type': 'LineString', 'coordinates': [(0, 0), (1, 1), (2, 2)]})>>> l1 == l2False>>> l1.equals(l2)True

Dirty data

Some files may contain vectors that are invalid from a simple features standpoint due to accident (inadequate quality control on the producer’s end) or intention (“dirty” vectors saved to a file for special treatment). Fiona doesn’t sniff for or attempt to clean dirty data, so make sure you’re getting yours from a clean source.

1.6   Writing Vector Data

A vector file can be opened for writing in mode 'a' (append) or mode'w' (write).

Note

The in situ “update” mode of OGR is quite format dependent and is therefore not supported by Fiona.

1.6.1   Appending Data to Existing Files

Let’s start with the simplest if not most common use case, adding new records to an existing file. The file is copied before modification and a suitable record extracted in the example below.

>>> with fiona.open('docs/data/test_uk.shp') as c:...     rec = next(c)>>> rec['id'] = '-1'>>> rec['properties']['CNTRY_NAME'] = 'Gondor'>>> import os>>> os.system("cp docs/data/test_uk.* /tmp")0

The coordinate reference system. format, and schema of the file are already defined, so it’s opened with just two arguments as for reading, but in 'a'mode. The new record is written to the end of the file using thewrite() method. Accordingly, the length of the file grows from 48 to 49.

>>> with fiona.open('/tmp/test_uk.shp', 'a') as c:...     print(len(c))...     c.write(rec)...     print(len(c))...4849

The record you write must match the file’s schema (because a file contains one type of record, remember). You’ll get a ValueError if it doesn’t.

>>> with fiona.open('/tmp/test_uk.shp', 'a') as c:...     c.write({'properties': {'foo': 'bar'}})...Traceback (most recent call last):...ValueError: Record data not match collection schema

Now, what about record ids? The id of a record written to a file is ignored and replaced by the next value appropriate for the file. If you read the file just appended to above,

>>> with fiona.open('/tmp/test_uk.shp', 'a') as c:...     records = list(c)>>> records[-1]['id']'48'>>> records[-1]['properties']['CNTRY_NAME']'Gondor'

You’ll see that the id of '-1' which the record had when written is replaced by '48'.

The write() method writes a single record to the collection’s file. Its siblingwriterecords() writes a sequence (or iterator) of records.

>>> with fiona.open('/tmp/test_uk.shp', 'a') as c:...     c.writerecords([rec, rec, rec])...     print(len(c))...52

Duplication

Fiona’s collections do not guard against duplication. The code above will write 3 duplicate records to the file, and they will be given unique sequential ids.

Buffering

Fiona’s output is buffered. The records passed to write() andwriterecords() are flushed to disk when the collection is closed. You may also call flush() periodically to write the buffer contents to disk.

1.6.2   Writing New Files

Writing a new file is more complex than appending to an existing file because the file CRS, format, and schema have not yet been defined and must be done so by the programmer. Still, it’s not very complicated. A schema is just a mapping, as described above. A CRS is also just a mapping, and the possible formats are enumerated in the fiona.drivers list.

Copy the parameters of our demo file.

>>> with fiona.open('docs/data/test_uk.shp') as source:...     source_driver = source.driver...     source_crs = source.crs...     source_schema = source.schema...>>> source_driver'ESRI Shapefile'>>> source_crs{'no_defs': True, 'ellps': 'WGS84', 'datum': 'WGS84', 'proj': 'longlat'}>>> pprint.pprint(source_schema){'geometry': 'Polygon', 'properties': {'CAT': 'float:16',                'FIPS_CNTRY': 'str',                'CNTRY_NAME': 'str',                'AREA': 'float:15.2',                'POP_CNTRY': 'float:15.2'}}

And now create a new file using them.

>>> with fiona.open(...         '/tmp/foo.shp',...         'w',...         driver=source_driver,...         crs=source_crs,...         schema=source_schema) as c:...     print(len(c))...     c.write(rec)...     print(len(c))...01>>> c.closedTrue>>> len(c)1

Because the properties of the source schema are ordered and are passed in the same order to the write-mode collection, the written file’s fields have the same order as those of the source file.

$ ogrinfo /tmp/foo.shp foo -soINFO: Open of `/tmp/foo.shp'      using driver `ESRI Shapefile' successful.Layer name: fooGeometry: 3D PolygonFeature Count: 1Extent: (0.735000, 51.357216) - (0.947778, 51.444717)Layer SRS WKT:GEOGCS["GCS_WGS_1984",    DATUM["WGS_1984",        SPHEROID["WGS_84",6378137,298.257223563]],    PRIMEM["Greenwich",0],    UNIT["Degree",0.017453292519943295]]CAT: Real (16.0)FIPS_CNTRY: String (80.0)CNTRY_NAME: String (80.0)AREA: Real (15.2)POP_CNTRY: Real (15.2)

The meta attribute makes duplication of a file’s meta properties even easier.

>>> source = fiona.open('docs/data/test_uk.shp')>>> sink = fiona.open('/tmp/foo.shp', 'w', **source.meta)
1.6.2.1   Ordering Record Fields

Beginning with Fiona 1.0.1, the ‘properties’ item of fiona.open()‘s ‘schema’ keyword argument may be an ordered dict or a list of (key, value) pairs, specifying an ordering that carries into written files. If an ordinary dict is given, the ordering is determined by the output of that dict’sitems() method.

For example, since

>>> {'bar': 'int', 'foo': 'str'}.keys()['foo', 'bar']

a schema of {'properties': {'bar': 'int', 'foo': 'str'}} will produce a shapefile where the first field is ‘foo’ and the second field is ‘bar’. If you want ‘bar’ to be the first field, you must use a list of property items

c = fiona.open('/tmp/file.shp','w',schema={'properties': [('bar', 'int'), ('foo', 'str')], ...},... )

or an ordered dict.

from collections import OrderedDictschema_props = OrderedDict([('bar', 'int'), ('foo', 'str')])c = fiona.open('/tmp/file.shp','w',schema={'properties': schema_props, ...},... )

1.6.3   Coordinates and Geometry Types

If you write 3D coordinates, ones having (x, y, z) tuples, to a 2D file (‘Point’ schema geometry, for example) the z values will be lost.

If you write 2D coordinates, ones having only (x, y) tuples, to a 3D file (‘3D Point’ schema geometry, for example) a default z value of 0 will be provided.

1.7   Advanced Topics

1.7.1   Slicing and masking iterators

With some vector data formats a spatial index accompanies the data file, allowing efficient bounding box searches. A collection’sitems() method returns an iterator over pairs of FIDs and records that intersect a given (minx, miny, maxx, maxy)bounding box or geometry object. The collection’s own coordinate reference system (see below) is used to interpret the box’s values. If you want a list of the iterator’s items, pass it to Python’s builtin list() as shown below.

>>> c = fiona.open('docs/data/test_uk.shp')>>> hits = list(c.items(bbox=(-5.0, 55.0, 0.0, 60.0)))>>> len(hits)7

The iterator method takes the same stop or start, stop[, step]slicing arguments as itertools.islice(). To get just the first two items from that iterator, pass a stop index.

>>> hits = c.items(2, bbox=(-5.0, 55.0, 0.0, 60.0))>>> len(list(hits))2

To get the third through fifth items from that iterator, pass start and stop indexes.

>>> hits = c.items(2, 5, bbox=(-5.0, 55.0, 0.0, 60.0))>>> len(list(hits))3

To filter features by property values, use Python’s builtin filter() andlambda or your own filter function that takes a single feature record and returns True or False.

>>> def pass_positive_area(rec):...     return rec['properties'].get('AREA', 0.0) > 0.0...>>> c = fiona.open('docs/data/test_uk.shp')>>> hits = filter(pass_positive_area, c)>>> len(list(hits))48

1.7.2   Reading Multilayer data

Up to this point, only simple datasets with one thematic layer or feature type per file have been shown and the venerable Esri Shapefile has been the primary example. Other GIS data formats can encode multiple layers or feature types within a single file or directory. Esri’s File Geodatabase is one example of such a format. A more useful example, for the purpose of this manual, is a directory comprising multiple shapefiles. The following three shell commands will create just such a two layered data source from the test data distributed with Fiona.

$ mkdir /tmp/data$ ogr2ogr /tmp/data/ docs/data/test_uk.shp test_uk -nln foo$ ogr2ogr /tmp/data/ docs/data/test_uk.shp test_uk -nln bar

The layers of a data source can be listed using fiona.listlayers(). In the shapefile format case, layer names match base names of the files.

>>> fiona.listlayers('/tmp/data')['bar', 'foo']

Unlike OGR, Fiona has no classes representing layers or data sources. To access the features of a layer, open a collection using the path to the data source and specify the layer by name using thelayerkeyword.

>>> import pprint>>> datasrc_path = '/tmp/data'>>> for name in fiona.listlayers(datasrc_path):...     with fiona.open(datasrc_path, layer=name) as c:...         pprint.pprint(c.schema)...{'geometry': 'Polygon', 'properties': {'CAT': 'float:16',                'FIPS_CNTRY': 'str',                'CNTRY_NAME': 'str',                'AREA': 'float:15.2',                'POP_CNTRY': 'float:15.2'}}{'geometry': 'Polygon', 'properties': {'CAT': 'float:16',                'FIPS_CNTRY': 'str',                'CNTRY_NAME': 'str',                'AREA': 'float:15.2',                'POP_CNTRY': 'float:15.2'}}

Layers may also be specified by their index.

>>> for i, name in enumerate(fiona.listlayers(datasrc_path)):...     with fiona.open(datasrc_path, layer=i) as c:...         print(len(c))...4848

If no layer is specified, fiona.open() returns an open collection using the first layer.

>>> with fiona.open(datasrc_path) as c:...     c.name == fiona.listlayers(datasrc_path)[0]...True

The most general way to open a shapefile for reading, using all of the parameters of fiona.open(), is to treat it as a data source with a named layer.

>>> fiona.open('docs/data/test_uk.shp', 'r', layer='test_uk')

In practice, it is fine to rely on the implicit first layer and default 'r'mode and open a shapefile like this:

>>> fiona.open('docs/data/test_uk.shp')

1.7.3   Writing Multilayer data

To write an entirely new layer to a multilayer data source, simply provide a unique name to thelayerkeyword argument.

>>> 'wah' not in fiona.listlayers(datasrc_path)True>>> with fiona.open(datasrc_path, layer='bar') as c:...     with fiona.open(datasrc_path, 'w', layer='wah', **c.meta) as d:...         d.write(next(c))...>>> fiona.listlayers(datasrc_path)['bar', 'foo', 'wah']

In 'w' mode, existing layers will be overwritten if specified, just as normal files are overwritten by Python’s open() function.

>>> 'wah' in fiona.listlayers(datasrc_path)True>>> with fiona.open(datasrc_path, layer='bar') as c:...     with fiona.open(datasrc_path, 'w', layer='wah', **c.meta) as d:...         # Overwrites the existing layer named 'wah'!

1.7.4   Virtual filesystems

Zip and Tar archives can be treated as virtual filesystems and collections can be made from paths and layers within them. In other words, Fiona lets you read zipped shapefiles. For example, make a Zip archive from the shapefile distributed with Fiona.

$ zip /tmp/zed.zip docs/data/test_uk.*adding: docs/data/test_uk.shp (deflated 48%)adding: docs/data/test_uk.shx (deflated 37%)adding: docs/data/test_uk.dbf (deflated 98%)adding: docs/data/test_uk.prj (deflated 15%)

Thevfskeyword parameter for fiona.listlayers() andfiona.open() may be an Apache Commons VFS style string beginning with “zip://” or “tar://” and followed by an absolute or relative path to the archive file. When this parameter is used, the first argument to must be an absolute path within that archive. The layers in that Zip archive are:

>>> import fiona>>> fiona.listlayers('/docs/data', vfs='zip:///tmp/zed.zip')['test_uk']

The single shapefile may also be accessed like so:

>>> with fiona.open(...         '/docs/data/test_uk.shp',...         vfs='zip:///tmp/zed.zip') as c:...     print(len(c))...48

1.8   Dumpgj

Fiona installs a script named dumpgj. It converts files to GeoJSON with JSON-LD context as an option and is intended to be an upgrade to “ogr2ogr -f GeoJSON”.

$ dumpgj --helpusage: dumpgj [-h] [-d] [-n N] [--compact] [--encoding ENC]              [--record-buffered] [--ignore-errors] [--use-ld-context]              [--add-ld-context-item TERM=URI]              infile [outfile]Serialize a file's records or description to GeoJSONpositional arguments:  infile                input file name  outfile               output file name, defaults to stdout if omittedoptional arguments:  -h, --help            show this help message and exit  -d, --description     serialize file's data description (schema) only  -n N, --indent N      indentation level in N number of chars  --compact             use compact separators (',', ':')  --encoding ENC        Specify encoding of the input file  --record-buffered     Economical buffering of writes at record, not                        collection (default), level  --ignore-errors       log errors but do not stop serialization  --use-ld-context      add a JSON-LD context to JSON output  --add-ld-context-item TERM=URI                        map a term to a URI and add it to the output's JSON LD                        context

1.9   Final Notes

This manual is a work in progress and will grow and improve with Fiona. Questions and suggestions are very welcome. Please feel free to use the issue tracker or email the author directly.

Do see the README for installation instructions and information about supported versions of Python and other software dependencies.

Fiona would not be possible without the contributions of other developers, especially Frank Warmerdam and Even Rouault, the developers of GDAL/OGR; and Mike Weisman, who saved Fiona from neglect and obscurity.

1.10   References

[Kent1978]William Kent, Data and Reality, North Holland, 1978.
[ESRI1998]ESRI Shapefile Technical Description. July 1998. http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
[GeoJSON]http://geojson.org
[JSON]http://www.ietf.org/rfc/rfc4627
[SFA]http://en.wikipedia.org/wiki/Simple_feature_access


转载于:https://my.oschina.net/u/2306127/blog/601354

这篇关于Fiona地理数据引擎,使用手册的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/347622

相关文章

Spring Validation中9个数据校验工具使用指南

《SpringValidation中9个数据校验工具使用指南》SpringValidation作为Spring生态系统的重要组成部分,提供了一套强大而灵活的数据校验机制,本文给大家介绍了Spring... 目录1. Bean Validation基础注解常用注解示例在控制器中应用2. 自定义约束验证器定义自

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结

Redis中的数据一致性问题以及解决方案

《Redis中的数据一致性问题以及解决方案》:本文主要介绍Redis中的数据一致性问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Redis 数据一致性问题的产生1. 单节点环境的一致性问题2. 网络分区和宕机3. 并发写入导致的脏数据4. 持

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

一文教你Python如何快速精准抓取网页数据

《一文教你Python如何快速精准抓取网页数据》这篇文章主要为大家详细介绍了如何利用Python实现快速精准抓取网页数据,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录1. 准备工作2. 基础爬虫实现3. 高级功能扩展3.1 抓取文章详情3.2 保存数据到文件4. 完整示例

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll