4

I want to save some geometry to a shapefile with the python27 module fiona and manually specify the coordinate reference system (CRS).

Here's what I tried:

import fiona
import fiona.crs

outpath = "shape.shp"

schema = {'geometry': 'Point', 'properties': {'place': 'str'}}
point = {u"type": u"Point", u"coordinates": [0.0, 51.4769]}
properties = {'place': 'Greenwich'}
wgs84 = fiona.crs.from_epsg(4326)

with fiona.open(outpath, 'w', crs=wgs84, driver='ESRI Shapefile',
                schema=schema) as layer:
    layer.write({'geometry': point, 'properties': properties})

Unfortunately the shape.prj file that's produced is empty, hence the CRS is not specified in the output file.

A little diagnostics: After running the script, the layer has the CRS specified:

In [10]: layer.crs
Out[10]: {'init': 'epsg:4326', 'no_defs': True}

Any idea what's going wrong there?

I can work around this issue by downloading the .PRJ file from spatialreference.org, placing it in the same folder and renaming it shape.prj. I guess I'll figure out how to do that programmatically if there's no direct solution (should be easy).

4
  • 2
    Worked fine for me. All I did was delete your "import fiona.crs" line and change the output path and the resulting shapefile has a non-empty .prj file that seems to plot correctly in QGIS.
    – Jon
    Commented May 1, 2018 at 18:55
  • You could also change line 2 to from fiona.crs import from_espg and change line 9 to wgs84 = from_epsg(4326).
    – SMiller
    Commented May 1, 2018 at 19:54
  • Jon, if you just leave out import fiona.crs, the crs submodule and hence from_epsg shouldn't be available. I tried the changes suggested by @smiller and they give exactly the same result. Shouldn't from_epsg do the same thing no matter how you import it?
    – Joooeey
    Commented May 2, 2018 at 22:13
  • Since it worked for Jon, I figured something might be off with my Fiona installation. In any case reinstalling didn't help. (conda uninstall fiona and conda install fiona)
    – Joooeey
    Commented May 2, 2018 at 22:30

2 Answers 2

5

I had this issue, and fixed it by setting the GDAL_DATA variable correctly, so that fiona can map the projection strings correctly. For reference, I'm using Anaconda, the Spyder IDE, Fiona 1.8.4, Python 3.6.8, and GDAL 2.3.3.

While Anaconda usually sets the GDAL_DATA variable upon entering the virtual environment, using another IDE like Spyder will not preserve it, and thus causes issues where fiona can't export the CRS correctly.

You can test this fix by trying to printing out a EPSG to WKT transformation before & after setting the GDAL_DATA variable explictly.

Without setting GDAL_DATA:

import os
print('GDAL_DATA' in os.environ)
from osgeo import osr
srs = osr.SpatialReference() # Declare a new SpatialReference 
srs.ImportFromEPSG(3413) # Import the EPSG code into the new object srs
print(srs.ExportToWkt()) # Print the result before transformation to ESRI WKT (prints nothing)

Results in:

False

With setting GDAL_DATA:

import os
os.environ['GDAL_DATA'] = 'D:\\ProgramData\\Anaconda3\\envs\\cfm\\Library\\share\\gdal'
print('GDAL_DATA' in os.environ)
from osgeo import , osr
srs = osr.SpatialReference() # Declare a new SpatialReference 
srs.ImportFromEPSG(3413) # Import the EPSG code into the new object srs
print(srs.ExportToWkt()) # Print the result before transformation to ESRI WKT (prints the EPSG converted to a WKT string)

Results in:

True
PROJCS["WGS 84 / NSIDC Sea Ice Polar Stereographic North",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Polar_Stereographic"],PARAMETER["latitude_of_origin",70],PARAMETER["central_meridian",-45],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",EAST],AXIS["Y",NORTH],AUTHORITY["EPSG","3413"]]
2

You can use GDAL/OGR in your code with fiona:

import fiona

from osgeo import osr              ###
srs = osr.SpatialReference()       ###
srs.SetFromUserInput("EPSG:4326")  ###
wgs84 = srs.ExportToProj4()        ###
# or
# wgs84 = srs.ExportToPrettyWkt()  ###
# or
# wgs84 = srs.ExportToWkt()        ###

outpath  = "shape.shp"

schema = {'geometry': 'Point', 'properties': {'place': 'str'}}
point = {u"type": u"Point", u"coordinates": [0.0, 51.4769]}
properties = {'place': 'Greenwich'}

with fiona.open(outpath, 'w', 
                crs=wgs84,         ###
                # crs_wkt=wgs84,   ### use this line if you use wkt
                driver='ESRI Shapefile',
                schema=schema) as layer:
    layer.write({'geometry': point, 'properties': properties})
3
  • This doesn't work for me either.
    – Joooeey
    Commented Oct 15, 2018 at 16:49
  • It doesn't work for me as well
    – Oalvinegro
    Commented Feb 3, 2022 at 19:55
  • It works for me in Python 3. Thanks. Commented Dec 14, 2022 at 6:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.