2

I have a method that creates a new Shapefile layer and returns the layer. As soon as I try to operate on that layer, I get a Segmentation fault. I verified the code works by pulling all the code out of the method and sticking it in the calling method. Thoughts on why this happens? This is a different problem than I posted that ended up being a PIP/Conda conflict.

def CreateMergedLayer(merged_layer_file_name):

  """
  Initializes an ESRI Shapefile with the fields of two
  layers that will be merged - could be improved by creating
  a set of fields from both (assuming they have the same
  definition if sharing names), but just made purpose-built
  for this function - if i have to do again, i'll refactor

  Parameters
  ----------
  merged_layer_file_name : string
    The full path and file name of the new merged layer

  Returns
  -------
    The pointer to the layer
  """
  print ("About to create shapefile for {}".format(merged_layer_file_name))

  driver = ogr.GetDriverByName("ESRI Shapefile")
  data_source = driver.CreateDataSource(merged_layer_file_name)

  # create the spatial reference, WGS84
  srs = osr.SpatialReference()
  srs.ImportFromEPSG(4326)

  new_layer = data_source.CreateLayer("la_streets_with_block_centroid_connectors", srs, ogr.wkbLineString)

  new_field = ogr.FieldDefn("GeoID", ogr.OFTString)
  new_field.SetWidth(16)
  new_layer.CreateField(new_field)

  new_field = ogr.FieldDefn("FULLNAME", ogr.OFTString)
  new_field.SetWidth(100)
  new_layer.CreateField(new_field)

  return new_layer

Calling this method here:

merged_layer = CreateMergedLayer("/tmp/la_streets_with_block_centroid_connectors.shp")

print ("Created Layer, getting definition: layer: {}".format(merged_layer))
merged_layer_defn = merged_layer.GetLayerDefn()

This outputs the following without getting past the GetLayerDefn() request:

About to create shapefile for /tmp/la_streets_with_block_centroid_connectors.shp
Created Layer, getting definition: layer: <osgeo.ogr.Layer; proxy of <Swig Object of type 'OGRLayerShadow *' at 0x114ad4630> >
Segmentation fault: 11
  • My first thought is that merged_layer_file_name in CreateDataSource is not a full path, therefore it is created in your current working directory (if set), is the file created? My second thought is that you're not telling the function what geometry type to create (see gdal.org/drv_shapefile.html under creation options) but according to the tutorial pcjericks.github.io/py-gdalogr-cookbook/… that is not so - or perhaps the default is point. – Michael Stimson Sep 26 '17 at 1:32
  • Thanks Michael. I think i am passing the full path - in the calling statement, it is /tmp/la_streets_with... and on the geometry type, i believe i am creating a wkbLineString in the CreateLayer statement (i should have shortened the code width so that you don't have to scroll to see this). – Cord Sep 26 '17 at 14:30
  • So you're on a Linux (or Mac) system, I'm totally Windows so the path looked weird to me. It seems your code is congruent with the tutorial linked in the previous comment so the problem must be elsewhere.. unfortunately that is where my experience comes to a screaming halt. – Michael Stimson Sep 26 '17 at 20:49
2

I ran into the same issue while attempting to pass a layer object within a python class. After reviewing the PythonGotchas, it appears that when the function returns, the data source goes out of scope. (see the section on 'Python crashes if you use an object after deleting an object it has a relationship with'). So basically, the layer loses connection with the data source after it is deallocated. In a class, this can be fixed by setting the data source as a class attribute. In the case of the function above, it may be possible to simply pass the data source with the layer.

so something like:

def myfunction():
    drv = ogr.GetDriverByName('ESRI Shapefile')
    ds = drv.CreateDataSource(myshape)
    lyr = ds.CreateLayer(yadayada)

    # add fields, etc....

return ds, lyr
  • You may have motivated me to get back to my project. Thanks for that! – Cord Apr 18 '18 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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