1

I am trying to load S-57 file with pyQGIS with code below

self.canvas = QgsMapCanvas()
# self.canvas.useImageToRender(False)
self.canvas.show()
# Lay our widgets out in the main window using a
# vertical box layout
self.layout = QVBoxLayout(self.frame)
self.layout.addWidget(self.canvas)

file = QFileDialog.getOpenFileName(self, "Open S57file", ".", "S57files (*.000)")
fileInfo = QFileInfo(file[0])
# Add the layer
layer = QgsVectorLayer(file[0], fileInfo.fileName(), "ogr")
if not layer.isValid():
    print("Invalid Layer File")
    return

QgsProject.instance().addMapLayer(layer);
self.canvas.setExtent(layer.extent())
self.canvas.setLayers([layer])

But I am getting error

"ERROR 4: S57 Driver doesn't support update." and file is canvas is blank although the layer is valid

I came across this question and also set the system path variable named s57_CSV referring to the required csvs folder but no difference.

  • Does that error mean the layer isn't valid? Using your code, I get a valid layer on a test S57 file I made, and the error is only printed to the console but doesn't stop the layer being valid. – Spacedman Oct 10 '18 at 11:40
  • Does the file load into QGIS using QGIS' menu? That will tell you if its valid or not. – Spacedman Oct 10 '18 at 13:35
  • yes checked it, file is loading fine in qgis so its a problem in the script – user9962595 Oct 10 '18 at 13:54
  • @Spacedman I have updated the question kindly have a look. – user9962595 Oct 12 '18 at 12:33
1

An S57 file is a complex thing that can have multiple layers. I downloaded a sample from https://web.archive.org/web/20130730111701/http://home.gdal.org/projects/s57/index.html for testing.

If you create a layer with just the path, you get a valid layer but it has no geometry - this is a layer that is just a table with some metadata in one row:

>>> path="./US5TX51M.000"
>>> layer_p = QgsVectorLayer(path, "pathonly","ogr")
>>> layer_p.isValid()
True

When added to QGIS this shows as a tabular data layer in the legend, but has no geometry so does not appear on the map.

You can get the geometry type from this:

>>> layer_p.wkbType()
100

and 100 is code for "no geometry".

To get a layer from an S57 file you have to add a layername= parameter when creating the layer:

>>> path="./US5TX51M.000|layername=BRIDGE"
>>> layer_w = QgsVectorLayer(path, "withlayername","ogr")
>>> layer_w.isValid()
True

Now I have a valid layer, and its geometry type is...

>>> layer_w.wkbType()
3

which is a real geometry. Add this to the QGIS legend and you should get something on the map.

So your code needs to iterate over the valid layers and load all or some in depending on user input. This is what QGIS does - a dialog is presented of all 52 layers in the test file and the user can select the ones they want. Note this is not done by QgsVectorLayer - QGIS must be querying the metadata on the file when you ask to open a file in the QGIS application to produce a layer list, then calls QgsVectorLayer on the selected layers with the layername= parameter added. You can see the full layer source URI in the properties dialog of these layers once you've loaded them.

I am not sure how to get a list of layers in a data source given a path - this is a more common operation than just for S57 files. If you point OGR (and hence QGIS) at a folder, and that folder has a load of Shapefiles in it, OGR will consider it as a single data source with multiple layers just like the demo S57 file.

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.