oracle requires that polygon rings are in proper orientation this affects spatial operations and an invalid orientation may cause failures correct orientations are outer ring counter clockwise inner rings clockwise fix single polygon orientation as described in init if clone poly poly clone if not poly exteriorring iscounterclockwise poly exteriorring listreversedpoly exteriorring for i in range1 lenpoly if polyi iscounterclockwise polyi listreversedpolyi return poly classmethod def fixgeometrycollectioncls coll coll coll clone for i geom in enumeratecoll if isinstancegeom polygon colli cls fixpolygongeom clonefalse return coll oracle requires that polygon rings are in proper orientation this affects spatial operations and an invalid orientation may cause failures correct orientations are outer ring counter clockwise inner ring s clockwise fix single polygon orientation as described in __init__ fix polygon orientations in geometry collections as described in __init__
from django.contrib.gis.db.backends.base.adapter import WKTAdapter
from django.contrib.gis.geos import GeometryCollection, Polygon
from django.db.backends.oracle.oracledb_any import oracledb


class OracleSpatialAdapter(WKTAdapter):
    input_size = oracledb.CLOB

    def __init__(self, geom):
        
        if isinstance(geom, Polygon):
            if self._polygon_must_be_fixed(geom):
                geom = self._fix_polygon(geom)
        elif isinstance(geom, GeometryCollection):
            if any(
                isinstance(g, Polygon) and self._polygon_must_be_fixed(g) for g in geom
            ):
                geom = self._fix_geometry_collection(geom)

        self.wkt = geom.wkt
        self.srid = geom.srid

    @staticmethod
    def _polygon_must_be_fixed(poly):
        return not poly.empty and (
            not poly.exterior_ring.is_counterclockwise
            or any(x.is_counterclockwise for x in poly)
        )

    @classmethod
    def _fix_polygon(cls, poly, clone=True):
        
        if clone:
            poly = poly.clone()

        if not poly.exterior_ring.is_counterclockwise:
            poly.exterior_ring = list(reversed(poly.exterior_ring))

        for i in range(1, len(poly)):
            if poly[i].is_counterclockwise:
                poly[i] = list(reversed(poly[i]))

        return poly

    @classmethod
    def _fix_geometry_collection(cls, coll):
        
        coll = coll.clone()
        for i, geom in enumerate(coll):
            if isinstance(geom, Polygon):
                coll[i] = cls._fix_polygon(geom, clone=False)
        return coll