NetTopologySuite / NetTopologySuite.IO.ShapeFile

The ShapeFile IO module for NTS.
33 stars 25 forks source link

DbaseFileWriter DBF write Geometry issue with the Geometry type "Polygon" and "Multipolygon" #86

Closed SonaliDogra closed 1 month ago

SonaliDogra commented 1 year ago

Trying to export "Polygon" and "MultiPolygon" Geometry points using shapeFileDataWriter.Write(), Getting the following error "Expected geometry that implements 'MultiLineString' or 'LineString', but was 'Polygon' (Parameter 'geometry')". Any suggestions for a workaround or possible solution?

DGuidi commented 1 year ago

please add some details about the code you wrote and the data you use

SonaliDogra commented 1 year ago
        foreach (DataRow row in dt.Rows)
        {
            var geomStr = row[wktColumn].ToString();
            if (string.IsNullOrEmpty(geomStr))
                continue;
            Geometry geometry = null;
            try
            {
                var geom = reader.Read<Geometry>(geomStr);
                geometry = spatialReturnType == SpatialReturnType.WorkProgramPointCloud
                    ? geom.ToPointCloud()
                    : geom;

                var coordinates = new Coordinate[geometry.Coordinates.Length];
            }
            catch (Exception e)
            {
                _logger.LogError("Shapefile read geometry error", e);
            }

            if (geometry == null)
                continue;

            var attributesTable = new AttributesTable();
            foreach (DataColumn column in dt.Columns)
            {
                if (column.ColumnName == wktColumn ||
                    string.IsNullOrEmpty(column.ColumnName)
                )
                    continue;
                var value = row[column] == DBNull.Value ? null : row[column];

                attributesTable.Add(mappings[column.ColumnName], value);
                if (!first)
                    continue;

                if (column.DataType == typeof(int))
                    mockAttributesTable.Add(mappings[column.ColumnName], 99);
                else if (column.DataType == typeof(decimal) || column.DataType == typeof(float) ||
                         column.DataType == typeof(double))
                    mockAttributesTable.Add(mappings[column.ColumnName], 99.99);
                else if (column.DataType == typeof(DateTime))
                    mockAttributesTable.Add(mappings[column.ColumnName], DateTime.Now);
                else if (column.DataType == typeof(bool))
                    mockAttributesTable.Add(mappings[column.ColumnName], true);
                else
                    mockAttributesTable.Add(mappings[column.ColumnName], "test");
            }
            first = false;
            features.Add(new Feature(geometry, attributesTable));
        }

        var outDbaseHeader = ShapefileDataWriter.GetHeader(new Feature(null, mockAttributesTable), features.Count);
        if (spatialReturnType == SpatialReturnType.WorkProgramPointCloud)
        {
            ShapefileWriter.WriteFeatures($"{varTempPath}.shp", features, outDbaseHeader.Fields,
                ShapeGeometryType.MultiPoint);
        }
        else
        {
            var outGeomFactory = new GeometryFactory();
            var writer = new ShapefileDataWriter(varTempPath, outGeomFactory) {Header = outDbaseHeader};
            writer.Write(features);
        }

Above is the piece of code that is giving error at the last line

writer.Write(features);

image image

DataSet:- ShapeFilePolygonExport.xlsx

FObermaier commented 1 year ago

I assume that the first item in your collection of features has a (Multi)LineString geometry and thus specifies that the Shapefile can contain only lineal geometries.

DGuidi commented 1 year ago

the excel states cleary that you have LineString and Polygon geometries in your data, you can write in a shapefile only LineString OR Polygon geometries, not both at the same time. As far as I remember, the shapefile is created using the "kind" of the first geometry in the set, and the error is thrown if a "non conformant" geometry is then processed

KubaSzostak commented 1 month ago

According to the ESRI Shapefile specification

Currently, shapefiles are restricted to contain the same type of shape

This means that mixing LineString and Polygon geometries is not possible.