This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Export Shapefile of Network using WaterObjects

I have a WaterObjects application and would like to export the calculated water quality results to a shapefile of my pipe network.  I can do this in WaterCAD by selecting Report->Element Tables -> Pipe, selecting the properties I want to export, and clicking on the export button and selecting ESRI Shapefile as my export format.  Would anybody know if this can be accomplished using WaterObjects?  I don't necessarily need to see the flex table that gets generated, but if it was necessary to generate the flex table in order to export the shapefile then I could deal with that.

Parents
  • Hi Bruce, by searching for "Waterobjects shapefile" in the search bar, I came across this similar discussion from a few years ago:

    communities.bentley.com/.../89113

    This points to a sample we have available on communities that has code that may help you with your shapefile export.


    Regards,

    Jesse Dringoli
    Technical Support Manager, OpenFlows
    Bentley Communities Site Administrator
    Bentley Systems, Inc.

  • Thanks very much for finding this prior post on creating a shapefile. The bits of code in the description were tremendously helpful and I think I know now what needs to be done. Here's the first part of my code.

    Dim dbFields(3) As DBFFieldInfo
    dbFields(0) = New DBFFieldInfo("MonYr", DBFFieldType.String)
    dbFields(0) = New DBFFieldInfo("Id", DBFFieldType.String)
    dbFields(1) = New DBFFieldInfo("conc", DBFFieldType.Double)
    dbFields(2) = New DBFFieldInfo("StrtNd", DBFFieldType.String)
    dbFields(3) = New DBFFieldInfo("EndNd", DBFFieldType.String)
    Dim shpWriter As ShapefileDataSourceWriter = New ShapefileDataSourceWriter()
    shpWriter.CreateDataFile(pathShpFle, dbFields, True, ShapeType.Polyline)

    When I reach the CreateDataFile step in debug mode, it throws a DllNotFoundException with the message "Unable to load DLL 'c4dll.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)". I see from a note in the WaterObjects.Net Samples Guide, that c4dll.dll is a file that comes with WaterGEMS. Since I am using WaterCAD, I don't have this file. Is there any way around this? Can I get the c4dll.dll file withoug purchasing a WaterGEMS license?
  • Bruce, I will check with some of our developers for ideas on why this is happening. In the meantime, it may help to try creating a smaller demo project for the shapefile export and get things working there first.


    Regards,

    Jesse Dringoli
    Technical Support Manager, OpenFlows
    Bentley Communities Site Administrator
    Bentley Systems, Inc.

  • Jesse,

    Your idea of creating a demo project was a good one. I added the following event handler to my existing project to see if I could isolate the problem. I ran it and am still coming up with an dbf file where the fields have been created but their contents are all null.  I've uploaded the project using your Secure File Upload capability. To run the application, the developer will need to change line 923 of WQWorkstationParentForm.vb so that it contains a valid local folder.  Then compile and click on the Create Shapefile button.  That will run the following code.  As I mentioned, the dbf file is created, the fields within the dbf file are there, but the contents of the records within the dbf file are all null.

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim sShapeFileName As String = "shapefile.shp"
    Dim sFolder As String = "C:\Users\Bruce\Documents\HydroAnalysis\J392 - Wilmington 2015\watercad\Final\"
    Dim pathShpFle As String = sFolder + sShapeFileName

    Dim dbFields(4) As DBFFieldInfo
    dbFields(0) = New DBFFieldInfo("MonYr", DBFFieldType.String)
    dbFields(1) = New DBFFieldInfo("Id", DBFFieldType.String)
    dbFields(2) = New DBFFieldInfo("conc", DBFFieldType.Double)
    dbFields(3) = New DBFFieldInfo("StrtNd", DBFFieldType.String)
    dbFields(4) = New DBFFieldInfo("EndNd", DBFFieldType.String)

    Dim shpWriter As ShapefileDataSourceWriter = New ShapefileDataSourceWriter()
    If (shpWriter.CreateDataFile(pathShpFle, dbFields, True, ShapeType.Polyline)) Then
    Dim sMonthYr As String = "jan-74"
    Dim sId As String = "P-1"
    Dim c As Double = 0
    Dim sNd0 As String = "J-1"
    Dim sNd1 As String = "J-2"
    Dim x0 As Double = 0
    Dim y0 As Double = 0
    Dim x1 As Double = 1
    Dim y1 As Double = 1
    Dim geoPt0 As GeometryPoint = New GeometryPoint(x0, y0)
    Dim geoPt1 As GeometryPoint = New GeometryPoint(x1, y1)
    Dim ln() As GeometryPoint = {geoPt0, geoPt1}

    shpWriter.AddRecordBegin()
    shpWriter.WriteFieldData(sMonthYr, "MonYr")
    shpWriter.WriteFieldData(sId, "Id")
    shpWriter.WriteFieldData(c, "conc")
    shpWriter.WriteFieldData(sNd0, "StrtNd")
    shpWriter.WriteFieldData(sNd1, "EndNd")
    shpWriter.WritePolylineGeometry(ln)
    shpWriter.AddRecordEnd()
    shpWriter.Close()
    End If
    End Sub

  • Thanks Bruce, I'll check with a developer.


    Regards,

    Jesse Dringoli
    Technical Support Manager, OpenFlows
    Bentley Communities Site Administrator
    Bentley Systems, Inc.

  • Hi Bruce,

    I took a few minutes and looked at your code. I have some comments.

    I have no tried these ideas so they may or may not work but it's worth a shot.

    VB.Net has the ability to use either 0 or 1-based arrays. The first thing I noticed is that you are using

    Dim dbFields(4) As DBFFieldInfo

    You might want to use using dbFields(5) instead. This way you use indices 0 thru 4. The DBF writer is C# and I'm not sure how would it handle this situation.

    The second thing I noticed is that you are using whole numbers without decimals for assigning your double variables. I recommend, if only for consistency, to use a true double value like 1.0 or 0.0 instead of 1 or 0. I don't know if this would make a difference or not.

    I checked our own code for when we export to Shapefile from a FlexTable and we create the DBFFieldInfo a little bit differently. In addition we add an instance of DBFFieldInfo to an ArrayList and then use ToArray() to create the array. In my example here I'll use a generic list instead. Note that this is C# code, not VB.Net code (you should get the gist of the idea though).

    List<DBFFieldInfo> fields = new List<DBFFieldInfo>();

    DBFFieldInfo field = new DBFFieldInfo();
    field.FieldName = "MonYr";
    field.FieldType = DBFFieldType.String;
    if(field.FieldType == DBFFieldType.String)
    field.FieldLength = DBFFieldType.MaxTextFieldLength; //You were actually missing this setting.
    fields.Add(field);

    You could easily refactor the code above between the creation of the List<> and the Add call into a method. You could pass in the fieldname and type and return the resulting object. Then you could do something like this:

    fields.Add(Newfield("MonYr", DBFFieldType.String));

    Then once your fields are added, you can initialize the writer like this:

    if (shpWriter.CreateDataFile(pathShpFile, fields.ToArray(), true, ShapeType.Polyline))
    ...

    In this case you would know for sure the exact number of elements are in the array when it is passed to the function.

    I hope that helps.

    Kris Culin

    Bentley Software Development

  • I don't think you're right about the Visual Basic arrays. That's actually how they're defined. They have zero based indices, but you indicate the maximum index value when you create the array.

    I took your tip and added assignments for the FieldLength property. I couldn't find that DBFFieldType had a MaxTextFieldLength property, but I arbitrarily assigned it the length 12 and everything's good now.

    I also changed the concentration field type from DBFFieldType.Double to DBFFieldType.Numeric and that did the trick. I think that what .NET considers to be a double is not the same a double field in a DBF table. I'm not sure.

    I don't mean to complain, but you might want to consider adding a constructor for DBFFieldInfo that includes the field length.

    Thanks for your help.

    Bruce Jacobs
Reply
  • I don't think you're right about the Visual Basic arrays. That's actually how they're defined. They have zero based indices, but you indicate the maximum index value when you create the array.

    I took your tip and added assignments for the FieldLength property. I couldn't find that DBFFieldType had a MaxTextFieldLength property, but I arbitrarily assigned it the length 12 and everything's good now.

    I also changed the concentration field type from DBFFieldType.Double to DBFFieldType.Numeric and that did the trick. I think that what .NET considers to be a double is not the same a double field in a DBF table. I'm not sure.

    I don't mean to complain, but you might want to consider adding a constructor for DBFFieldInfo that includes the field length.

    Thanks for your help.

    Bruce Jacobs
Children
No Data