OSGeo / gdal

GDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.
https://gdal.org
Other
4.8k stars 2.52k forks source link

ogr2ogr: DXF -> GeoJSON generate invalid Polygon #9240

Closed Rodrigodd closed 7 months ago

Rodrigodd commented 7 months ago

Expected behavior and actual behavior.

Hatch entities of a DXF file may generate a GeoJSON Polygon with multiple non-overlapping rings, which is invalid according to the last point of section 3.16 of RFC 7946:

  • For Polygons with more than one of these rings, the first MUST be the exterior ring, and any others MUST be interior rings. The exterior ring bounds the surface, and the interior rings (if present) bound holes within the surface.

This was causing bugs when visualizing the GeoJSON in geojson.io:

image

the JSON down below, but scaled down: test.json

Steps to reproduce the problem.

Running the following command:

ogr2ogr.exe -f GeoJSON .\test.json .\test.dxf

With the following DXF file:

test.zip

Generate the following output:

{
  "type": "FeatureCollection",
  "name": "entities",
  "features": [
    {
      "type": "Feature",
      "properties": { "Layer": "0", "SubClasses": "AcDbEntity:AcDbHatch", "Linetype": "ByLayer", "EntityHandle": "4D", "Text": "SOLID" },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [ [ 100, 100, 0 ], [ 120, 100, 0 ], [ 120, 80, 0 ], [ 100, 80, 0 ], [ 100, 100, 0 ] ],
          [ [ 120, 80, 0 ], [ 140, 80, 0 ], [ 140, 60, 0 ], [ 120, 60, 0 ], [ 120, 80, 0 ] ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "Layer": "0",
        "SubClasses": "AcDbEntity:AcDbPolyline",
        "Linetype": "ByLayer",
        "EntityHandle": "4E"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [ [ 100, 100 ], [ 120, 100 ], [ 120, 80 ], [ 100, 80 ], [ 100, 100 ] ]
      }
    },
    {
      "type": "Feature",
      "properties": { "Layer": "0", "SubClasses": "AcDbEntity:AcDbPolyline", "Linetype": "ByLayer", "EntityHandle": "4F" },
      "geometry": {
        "type": "LineString",
        "coordinates": [ [ 120, 80 ], [ 140, 80 ], [ 140, 60 ], [ 120, 60 ], [ 120, 80 ] ]
      }
    }
  ]
}

Operating system

Windows 11, x64

GDAL version and provenance

GDAL 3.8.3, released 2024/01/04 from https://www.osgeo.org/projects/osgeo4w/.

jratike80 commented 7 months ago

ogrinfo test.dxf -al finds this geometry

POLYGON Z ((100 100 0,120 100 0,120 80 0,100 80 0,100 100 0),(120 80 0,140 80 0,140 60 0,120 60 0,120 80 0))

It is invalid (hole lies outside shell) but it seems to be invalid already in the DXF file. Do you have any reference software that reads it right?

Ogr2ogr has an option -makevalid, documented here https://gdal.org/programs/ogr2ogr.html#cmdoption-ogr2ogr-makevalid. It could fix the data for me.

ogr2ogr -f GeoJSON -makevalid output.json test.dxf

Rodrigodd commented 7 months ago

Can confirm that -makevalid does work (I tried it once before, but I didn't notice it converted it to a MultiPolygon).

I created the test file in LibreCAD. I drew the two rects, selected Tools->Hatch, selected both of them, pressed Enter, and filled them with a solid color. But I was seeing this behavior in another file, but I don't know how it was generated.

I tried rendering with LibreCAD and ezdxf, and both rendered it correctly.

I took a quick look at the DXF file, and it appears that only LWPOLYLINEs are being defined. I also looked at the DXF spec, on page 90, Boundary Path Data, and they don't define polygons there, but I didn't read further.

~Are you sure that the DXF needs to uphold the same invariants as the GeoJSON file?~

I tried opening it in AutoDesk DWG TrueView, and it in fact rendered it incorrectly:

image

The online Autodesk Viewer rendered the same way.

Feel free to close this issue if this is really the DXF file fault. The -makevalid may be enough.

jratike80 commented 7 months ago

CAD and GIS have a slightly different view to the same world. Maybe you could ask from the LibreCAD and exdxf developers about the validity of such hatch. If it is valid DXF then GDAL might process the polygons automatically. But because the Autocad products do not render them right I think they should be avoided in any case.

BTW converting the output.json into DXF with GDAL seems to explode the multipolygon into two polygons.

rouault commented 7 months ago

CC @atlight I believe we can close this as "not a GDAL bug"

atlight commented 7 months ago

Since a workaround is available I don't think we need to take any action here. DXF allows all kinds of invalid geometries and sometimes you need to just make them valid.