Ticket #1704 (closed defect: fixed)

Opened 5 years ago

Last modified 4 years ago

ogr2ogr kml export of polygons can have incorrect vertex winding order

Reported by: mashbridge Owned by: mloskot
Priority: high Milestone: 1.5.0
Component: OGR_SF Version: 1.4.2
Severity: normal Keywords: kml
Cc: condit@…, Didge, warmerdam

Description

Exporting to KML via ogr2ogr, particularly where the source data is an ESRI Shapefile, often results in an incorrect polygon winding order.

3D implementations of KML use the vertex winding order of a polygon to calculate lighting. The "front" of a face is defined as a face with an anti-clockwise winding order (positive surface normal). I have attached two images showing the effect of correct and incorrect winding orders.

Attachments

bad_winding_order.jpg Download (98.8 KB) - added by mashbridge 5 years ago.
screenshot of exported poly with incorrect (clockwise) winding order
good_winding_order.jpg Download (102.1 KB) - added by mashbridge 5 years ago.
screenshot of polygon with corrected (anti-clockwise) winding order
reversewindingorder.patch Download (3.3 KB) - added by mashbridge 5 years ago.
patch for top of trunk
test-before.kml Download (0.5 KB) - added by mloskot 4 years ago.
Clockwise order of KML polygon coords generated with ogr2ogr before applying the patch
test-after.kml Download (0.5 KB) - added by mloskot 4 years ago.
Correct KML polygon with anti-clockwise coords generated with patched OGR

Change History

Changed 5 years ago by mashbridge

screenshot of exported poly with incorrect (clockwise) winding order

Changed 5 years ago by mashbridge

screenshot of polygon with corrected (anti-clockwise) winding order

Changed 5 years ago by mashbridge

patch for top of trunk

Changed 5 years ago by mashbridge

I created a patch for the current TOT. I regret to say that this evening's experimentation is the totality of my familiarity with the GDAL codebase. Apologies for the inevitable naivety of my fix.

Briefly, I:

- added a generic reverseWindingOrder() method to the OGRLinearRing class in ogr/ogr_geometry.h - which is implemented in ogr/ogrlinearring.cpp as an efficient array swap - and called in ogr/ogrsf_frmts/kml/ogr2kmlgeometry.cpp if the winding order is determined to be clockwise

No doubt there are many issues of which I'm unaware, but I hope this helps a little.

Changed 5 years ago by warmerdam

  • cc Didge, warmerdam added
  • keywords kml added
  • owner changed from warmerdam to mloskot

Jens / Matuesz,

Could you jointly review this patch for appropriateness?

Changed 5 years ago by mloskot

  • priority changed from normal to high
  • status changed from new to assigned

Changed 5 years ago by mloskot

I'm pasting e-mail from Jens:

Jens Oberender wrote:
> The patch looks fine, clear and efficient.
> I haven't testet it with data,
> but tried the algorithm with pen and paper.
> 
> Ciao,
> 	Jens

Jens, thanks for the review. I will test it.

Changed 4 years ago by mloskot

Clockwise order of KML polygon coords generated with ogr2ogr before applying the patch

Changed 4 years ago by mloskot

Correct KML polygon with anti-clockwise coords generated with patched OGR

Changed 4 years ago by mloskot

  • status changed from assigned to closed
  • resolution set to fixed

I've also tested the patch. It works correct, so it's been applied (r1185).

I'm closing this Ticket.

Changed 4 years ago by mashbridge

Cool. Thanks guys.

Changed 4 years ago by mloskot

One note of clarification. The fix was applied to the trunk as r11885, but not r1185.

Changed 4 years ago by mloskot

The fix has been ported to branches/1.4 (r12517)

Changed 4 years ago by mloskot

  • status changed from closed to reopened
  • resolution fixed deleted

This patch has broken the C++ ABI so it should be removed from 1.4.x line. More details here: [ http://lists.osgeo.org/pipermail/gdal-dev/2007-November/014975.html GDAL/OGR 1.4.3 ABI incompatability with 1.4.2}

Changed 4 years ago by mloskot

  • status changed from reopened to closed
  • resolution set to fixed
  • milestone changed from 1.4.3 to 1.5.0

The patch has been removed from branches/1.4 (r12921). It's still available in trunk and targets 1.5.0.

Note: See TracTickets for help on using tickets.