I currently have the following code to write a multipolygon Shapely feature to a GeoPackage:
import fiona
myschema = {'geometry': 'MultiPolygon', 'properties': {'id': 'int'}}
with fiona.open(
'/path/to/file.gpkg',
mode='w',
driver='GPKG',
schema=myschema,
crs='EPSG:2056') as m:
m.write({
'geometry': geometry.mapping(shapely_multipolygon_instance),
'properties': {'id': 12},# I can specify properties here time of writing
})
When I open this file in QGIS for example, I can see 2 fields in the attribute table: fid
, which is 1
and id
which is the value I specified, i.e. 12
in that case.
As fiona seems now embedded in the to_file()
method of a GeoDataFrame, I try to directly write my file as follow, but I don't know how could I pass the properties:
import geopandas as gpd
G = gpd.GeoDataFrame(
shapely_multipolyong_instance,
columns=['geometry']).dissolve() # to a unique multipoly
G.set_geometry('geometry', inplace=True, crs='EPSG:2056')
# I removed the 'geometry' from 'myschema' as we're now dealing with a gdf:
myschema = {'properties': {'id': 'int'}}
G.to_file(
'/path/to/file.gpkg',
driver="GPKG",
schema=myschema # when I remove that the file is correctly written but...
)
I get this error message:
Traceback (most recent call last):
File "<ipython-input-142-8bd51132bd01>", line 10, in <module>
schema=myschema
File "/usr/local/lib/python3.6/dist-packages/geopandas/geodataframe.py", line 1086, in to_file
_to_file(self, filename, driver, schema, index, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/geopandas/io/file.py", line 330, in _to_file
colxn.writerecords(df.iterfeatures())
File "/usr/local/lib/python3.6/dist-packages/fiona/collection.py", line 361, in writerecords
self.session.writerecs(records, self)
File "fiona/ogrext.pyx", line 1280, in fiona.ogrext.WritingSession.writerecs
ValueError: Record does not match collection schema: dict_keys([]) != ['id']
And if I simply remove the last schema=myschema
line, the file is correctly written, but it has only one field in the attribute table, namely the fid
which is 1
. The exact same thing happens when I remove the schema=myschema
line but add instead properties={'id': 12}
. And if I put both, I end up on the same error as before.
So...
I probably don't understand correctly how to interpret this sentence in the doc:
The extra keyword arguments **kwargs are passed to fiona.open and can be used to write to multi-layer data, store data within archives (zip files), etc.
Therefore, how could I also set my id
and its value in the attribute table of the written GeoPackage file?
This is the help of the method (if he could include an example using a schema, it would be helpful I think):
$ help(G.to_file)
Help on method to_file in module geopandas.geodataframe:
to_file(filename, driver='ESRI Shapefile', schema=None, index=None, **kwargs)
method of geopandas.geodataframe.GeoDataFrame instance
Write the ``GeoDataFrame`` to a file.
By default, an ESRI shapefile is written, but any OGR data source
supported by Fiona can be written. A dictionary of supported OGR
providers is available via:
import fiona
fiona.supported_drivers # doctest: +SKIP
Parameters
----------
filename : string
File path or file handle to write to.
driver : string, default: 'ESRI Shapefile'
The OGR format driver used to write the vector file.
schema : dict, default: None
If specified, the schema dictionary is passed to Fiona to
better control how the file is written.
index : bool, default None
If True, write index into one or more columns (for MultiIndex).
Default None writes the index into one or more columns only if
the index is named, is a MultiIndex, or has a non-integer data
type. If False, no index is written.
.. versionadded:: 0.7
Previously the index was not written.
Notes
-----
The extra keyword arguments ``**kwargs`` are passed to fiona.open and
can be used to write to multi-layer data, store data within archives
(zip files), etc.
The format drivers will attempt to detect the encoding of your data, but
may fail. In this case, the proper encoding can be specified explicitly
by using the encoding keyword parameter, e.g. ``encoding='utf-8'``.
See Also
--------
GeoSeries.to_file
GeoDataFrame.to_postgis : write GeoDataFrame to PostGIS database
GeoDataFrame.to_parquet : write GeoDataFrame to parquet
GeoDataFrame.to_feather : write GeoDataFrame to feather
Examples
--------
gdf.to_file('dataframe.shp') # doctest: +SKIP
gdf.to_file('dataframe.gpkg', driver='GPKG', layer='name') # doctest: +SKIP
gdf.to_file('dataframe.geojson', driver='GeoJSON') # doctest: +SKIP
With selected drivers you can also append to a file with `mode="a"`:
gdf.to_file('dataframe.shp', mode="a") # doctest: +SKIP