<s> """<STR_LIT>""" <EOL> import sys <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> range = xrange <EOL> from ctypes import c_double , c_void_p , cast , POINTER <EOL> from ctypes import ArgumentError <EOL> import weakref <EOL> from shapely . algorithms . cga import signed_area <EOL> from shapely . coords import required <EOL> from shapely . geos import lgeos <EOL> from shapely . geometry . base import BaseGeometry , geos_geom_from_py <EOL> from shapely . geometry . linestring import LineString , LineStringAdapter <EOL> from shapely . geometry . proxy import PolygonProxy <EOL> __all__ = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> class LinearRing ( LineString ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , coordinates = None ) : <EOL> """<STR_LIT>""" <EOL> BaseGeometry . __init__ ( self ) <EOL> if coordinates is not None : <EOL> self . _set_coords ( coordinates ) <EOL> @ property <EOL> def __geo_interface__ ( self ) : <EOL> return { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : tuple ( self . coords ) <EOL> } <EOL> _get_coords = BaseGeometry . _get_coords <EOL> def _set_coords ( self , coordinates ) : <EOL> self . empty ( ) <EOL> self . _geom , self . _ndim = geos_linearring_from_py ( coordinates ) <EOL> coords = property ( _get_coords , _set_coords ) <EOL> @ property <EOL> def is_ccw ( self ) : <EOL> """<STR_LIT>""" <EOL> return bool ( self . impl [ '<STR_LIT>' ] ( self ) ) <EOL> @ property <EOL> def is_simple ( self ) : <EOL> """<STR_LIT>""" <EOL> return LineString ( self ) . is_simple <EOL> class LinearRingAdapter ( LineStringAdapter ) : <EOL> __p__ = None <EOL> def __init__ ( self , context ) : <EOL> self . context = context <EOL> self . factory = geos_linearring_from_py <EOL> @ property <EOL> def __geo_interface__ ( self ) : <EOL> return { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : tuple ( self . coords ) <EOL> } <EOL> coords = property ( BaseGeometry . _get_coords ) <EOL> def asLinearRing ( context ) : <EOL> """<STR_LIT>""" <EOL> return LinearRingAdapter ( context ) <EOL> class InteriorRingSequence ( object ) : <EOL> _factory = None <EOL> _geom = None <EOL> __p__ = None <EOL> _ndim = None <EOL> _index = <NUM_LIT:0> <EOL> _length = <NUM_LIT:0> <EOL> __rings__ = None <EOL> _gtag = None <EOL> def __init__ ( self , parent ) : <EOL> self . __p__ = parent <EOL> self . _geom = parent . _geom <EOL> self . _ndim = parent . _ndim <EOL> def __iter__ ( self ) : <EOL> self . _index = <NUM_LIT:0> <EOL> self . _length = self . __len__ ( ) <EOL> return self <EOL> def __next__ ( self ) : <EOL> if self . _index < self . _length : <EOL> ring = self . _get_ring ( self . _index ) <EOL> self . _index += <NUM_LIT:1> <EOL> return ring <EOL> else : <EOL> raise StopIteration <EOL> if sys . version_info [ <NUM_LIT:0> ] < <NUM_LIT:3> : <EOL> next = __next__ <EOL> def __len__ ( self ) : <EOL> return lgeos . GEOSGetNumInteriorRings ( self . _geom ) <EOL> def __getitem__ ( self , key ) : <EOL> m = self . __len__ ( ) <EOL> if isinstance ( key , int ) : <EOL> if key + m < <NUM_LIT:0> or key >= m : <EOL> raise IndexError ( "<STR_LIT>" ) <EOL> if key < <NUM_LIT:0> : <EOL> i = m + key <EOL> else : <EOL> i = key <EOL> return self . _get_ring ( i ) <EOL> elif isinstance ( key , slice ) : <EOL> res = [ ] <EOL> start , stop , stride = key . indices ( m ) <EOL> for i in range ( start , stop , stride ) : <EOL> res . append ( self . _get_ring ( i ) ) <EOL> return res <EOL> else : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> @ property <EOL> def _longest ( self ) : <EOL> max = <NUM_LIT:0> <EOL> for g in iter ( self ) : <EOL> l = len ( g . coords ) <EOL> if l > max : <EOL> max = l <EOL> def gtag ( self ) : <EOL> return hash ( repr ( self . __p__ ) ) <EOL> def _get_ring ( self , i ) : <EOL> gtag = self . gtag ( ) <EOL> if gtag != self . _gtag : <EOL> self . __rings__ = { } <EOL> if i not in self . __rings__ : <EOL> g = lgeos . GEOSGetInteriorRingN ( self . _geom , i ) <EOL> ring = LinearRing ( ) <EOL> ring . _geom = g <EOL> ring . __p__ = self <EOL> ring . _other_owned = True <EOL> ring . _ndim = self . _ndim <EOL> self . __rings__ [ i ] = weakref . ref ( ring ) <EOL> return self . __rings__ [ i ] ( ) <EOL> class Polygon ( BaseGeometry ) : <EOL> """<STR_LIT>""" <EOL> _exterior = None <EOL> _interiors = [ ] <EOL> _ndim = <NUM_LIT:2> <EOL> def __init__ ( self , shell = None , holes = None ) : <EOL> """<STR_LIT>""" <EOL> BaseGeometry . __init__ ( self ) <EOL> if shell is not None : <EOL> self . _geom , self . _ndim = geos_polygon_from_py ( shell , holes ) <EOL> @ property <EOL> def exterior ( self ) : <EOL> if self . is_empty : <EOL> return None <EOL> elif self . _exterior is None or self . _exterior ( ) is None : <EOL> g = lgeos . GEOSGetExteriorRing ( self . _geom ) <EOL> ring = LinearRing ( ) <EOL> ring . _geom = g <EOL> ring . __p__ = self <EOL> ring . _other_owned = True <EOL> ring . _ndim = self . _ndim <EOL> self . _exterior = weakref . ref ( ring ) <EOL> return self . _exterior ( ) <EOL> @ property <EOL> def interiors ( self ) : <EOL> if self . is_empty : <EOL> return [ ] <EOL> return InteriorRingSequence ( self ) <EOL> def __eq__ ( self , other ) : <EOL> if not isinstance ( other , Polygon ) : <EOL> return False <EOL> check_empty = ( self . is_empty , other . is_empty ) <EOL> if all ( check_empty ) : <EOL> return True <EOL> elif any ( check_empty ) : <EOL> return False <EOL> my_coords = [ <EOL> tuple ( self . exterior . coords ) , <EOL> [ tuple ( interior . coords ) for interior in self . interiors ] <EOL> ] <EOL> other_coords = [ <EOL> tuple ( other . exterior . coords ) , <EOL> [ tuple ( interior . coords ) for interior in other . interiors ] <EOL> ] <EOL> return my_coords == other_coords <EOL> def __ne__ ( self , other ) : <EOL> return not self . __eq__ ( other ) <EOL> __hash__ = None <EOL> @ property <EOL> def ctypes ( self ) : <EOL> if not self . _ctypes_data : <EOL> self . _ctypes_data = self . exterior . ctypes <EOL> return self . _ctypes_data <EOL> @ property <EOL> def __array_interface__ ( self ) : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" ) <EOL> def _get_coords ( self ) : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" ) <EOL> def _set_coords ( self , ob ) : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" ) <EOL> @ property <EOL> def coords ( self ) : <EOL> raise NotImplementedError ( <EOL> "<STR_LIT>" ) <EOL> @ property <EOL> def __geo_interface__ ( self ) : <EOL> coords = [ tuple ( self . exterior . coords ) ] <EOL> for hole in self . interiors : <EOL> coords . append ( tuple ( hole . coords ) ) <EOL> return { <EOL> '<STR_LIT:type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : tuple ( coords ) <EOL> } <EOL> def svg ( self , scale_factor = <NUM_LIT:1.> , fill_color = None ) : <EOL> """<STR_LIT>""" <EOL> if self . is_empty : <EOL> return '<STR_LIT>' <EOL> if fill_color is None : <EOL> fill_color = "<STR_LIT>" if self . is_valid else "<STR_LIT>" <EOL> exterior_coords = [ <EOL> [ "<STR_LIT>" . format ( * c ) for c in self . exterior . coords ] ] <EOL> interior_coords = [ <EOL> [ "<STR_LIT>" . format ( * c ) for c in interior . coords ] <EOL> for interior in self . interiors ] <EOL> path = "<STR_LIT:U+0020>" . join ( [ <EOL> "<STR_LIT>" . format ( coords [ <NUM_LIT:0> ] , "<STR_LIT>" . join ( coords [ <NUM_LIT:1> : ] ) ) <EOL> for coords in exterior_coords + interior_coords ] ) <EOL> return ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> ) . format ( <NUM_LIT> * scale_factor , path , fill_color ) <EOL> class PolygonAdapter ( PolygonProxy , Polygon ) : <EOL> def __init__ ( self , shell , holes = None ) : <EOL> self . shell = shell <EOL> self . holes = holes <EOL> self . context = ( shell , holes ) <EOL> self . factory = geos_polygon_from_py <EOL> @ property <EOL> def _ndim ( self ) : <EOL> try : <EOL> array = self . shell . __array_interface__ <EOL> n = array [ '<STR_LIT>' ] [ <NUM_LIT:1> ] <EOL> assert n == <NUM_LIT:2> or n == <NUM_LIT:3> <EOL> return n <EOL> except AttributeError : <EOL> return len ( self . shell [ <NUM_LIT:0> ] ) <EOL> def asPolygon ( shell , holes = None ) : <EOL> """<STR_LIT>""" <EOL> return PolygonAdapter ( shell , holes ) <EOL> def orient ( polygon , sign = <NUM_LIT:1.0> ) : <EOL> s = float ( sign ) <EOL> rings = [ ] <EOL> ring = polygon . exterior <EOL> if signed_area ( ring ) / s >= <NUM_LIT:0.0> : <EOL> rings . append ( ring ) <EOL> else : <EOL> rings . append ( list ( ring . coords ) [ : : - <NUM_LIT:1> ] ) <EOL> for ring in polygon . interiors : <EOL> if signed_area ( ring ) / s <= <NUM_LIT:0.0> : <EOL> rings . append ( ring ) <EOL> else : <EOL> rings . append ( list ( ring . coords ) [ : : - <NUM_LIT:1> ] ) <EOL> return Polygon ( rings [ <NUM_LIT:0> ] , rings [ <NUM_LIT:1> : ] ) <EOL> def geos_linearring_from_py ( ob , update_geom = None , update_ndim = <NUM_LIT:0> ) : <EOL> if isinstance ( ob , LineString ) : <EOL> if type ( ob ) == LinearRing : <EOL> return geos_geom_from_py ( ob ) <EOL> else : <EOL> if ob . is_closed and len ( ob . coords ) >= <NUM_LIT:4> : <EOL> return geos_geom_from_py ( ob , lgeos . GEOSGeom_createLinearRing ) <EOL> ob = required ( ob ) <EOL> try : <EOL> array = ob . __array_interface__ <EOL> assert len ( array [ '<STR_LIT>' ] ) == <NUM_LIT:2> <EOL> m = array [ '<STR_LIT>' ] [ <NUM_LIT:0> ] <EOL> n = array [ '<STR_LIT>' ] [ <NUM_LIT:1> ] <EOL> if m < <NUM_LIT:3> : <EOL> raise ValueError ( <EOL> "<STR_LIT>" ) <EOL> assert n == <NUM_LIT:2> or n == <NUM_LIT:3> <EOL> if isinstance ( array [ '<STR_LIT:data>' ] , tuple ) : <EOL> cp = cast ( array [ '<STR_LIT:data>' ] [ <NUM_LIT:0> ] , POINTER ( c_double ) ) <EOL> else : <EOL> cp = array [ '<STR_LIT:data>' ] <EOL> if cp [ <NUM_LIT:0> ] != cp [ m * n - n ] or cp [ <NUM_LIT:1> ] != cp [ m * n - n + <NUM_LIT:1> ] : <EOL> M = m + <NUM_LIT:1> <EOL> else : <EOL> M = m <EOL> if update_geom is not None : <EOL> cs = lgeos . GEOSGeom_getCoordSeq ( update_geom ) <EOL> if n != update_ndim : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % update_ndim ) <EOL> else : <EOL> cs = lgeos . GEOSCoordSeq_create ( M , n ) <EOL> for i in range ( m ) : <EOL> lgeos . GEOSCoordSeq_setX ( cs , i , cp [ n * i ] ) <EOL> lgeos . GEOSCoordSeq_setY ( cs , i , cp [ n * i + <NUM_LIT:1> ] ) <EOL> if n == <NUM_LIT:3> : <EOL> lgeos . GEOSCoordSeq_setZ ( cs , i , cp [ n * i + <NUM_LIT:2> ] ) <EOL> if M > m : <EOL> lgeos . GEOSCoordSeq_setX ( cs , M - <NUM_LIT:1> , cp [ <NUM_LIT:0> ] ) <EOL> lgeos . GEOSCoordSeq_setY ( cs , M - <NUM_LIT:1> , cp [ <NUM_LIT:1> ] ) <EOL> if n == <NUM_LIT:3> : <EOL> lgeos . GEOSCoordSeq_setZ ( cs , M - <NUM_LIT:1> , cp [ <NUM_LIT:2> ] ) <EOL> except AttributeError : <EOL> try : <EOL> m = len ( ob ) <EOL> except TypeError : <EOL> ob = list ( ob ) <EOL> m = len ( ob ) <EOL> n = len ( ob [ <NUM_LIT:0> ] ) <EOL> if m < <NUM_LIT:3> : <EOL> raise ValueError ( <EOL> "<STR_LIT>" ) <EOL> assert ( n == <NUM_LIT:2> or n == <NUM_LIT:3> ) <EOL> if m == <NUM_LIT:3> or ob [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] != ob [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] or ob [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] != ob [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] : <EOL> M = m + <NUM_LIT:1> <EOL> else : <EOL> M = m <EOL> if update_geom is not None : <EOL> cs = lgeos . GEOSGeom_getCoordSeq ( update_geom ) <EOL> if n != update_ndim : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % update_ndim ) <EOL> else : <EOL> cs = lgeos . GEOSCoordSeq_create ( M , n ) <EOL> for i in range ( m ) : <EOL> coords = ob [ i ] <EOL> lgeos . GEOSCoordSeq_setX ( cs , i , coords [ <NUM_LIT:0> ] ) <EOL> lgeos . GEOSCoordSeq_setY ( cs , i , coords [ <NUM_LIT:1> ] ) <EOL> if n == <NUM_LIT:3> : <EOL> try : <EOL> lgeos . GEOSCoordSeq_setZ ( cs , i , coords [ <NUM_LIT:2> ] ) <EOL> except IndexError : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if M > m : <EOL> coords = ob [ <NUM_LIT:0> ] <EOL> lgeos . GEOSCoordSeq_setX ( cs , M - <NUM_LIT:1> , coords [ <NUM_LIT:0> ] ) <EOL> lgeos . GEOSCoordSeq_setY ( cs , M - <NUM_LIT:1> , coords [ <NUM_LIT:1> ] ) <EOL> if n == <NUM_LIT:3> : <EOL> lgeos . GEOSCoordSeq_setZ ( cs , M - <NUM_LIT:1> , coords [ <NUM_LIT:2> ] ) <EOL> if update_geom is not None : <EOL> return None <EOL> else : <EOL> return lgeos . GEOSGeom_createLinearRing ( cs ) , n <EOL> def update_linearring_from_py ( geom , ob ) : <EOL> geos_linearring_from_py ( ob , geom . _geom , geom . _ndim ) <EOL> def geos_polygon_from_py ( shell , holes = None ) : <EOL> if isinstance ( shell , Polygon ) : <EOL> return geos_geom_from_py ( shell ) <EOL> if shell is not None : <EOL> geos_shell , ndim = geos_linearring_from_py ( shell ) <EOL> if holes is not None and len ( holes ) > <NUM_LIT:0> : <EOL> ob = holes <EOL> L = len ( ob ) <EOL> exemplar = ob [ <NUM_LIT:0> ] <EOL> try : <EOL> N = len ( exemplar [ <NUM_LIT:0> ] ) <EOL> except TypeError : <EOL> N = exemplar . _ndim <EOL> if not L >= <NUM_LIT:1> : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> if not N in ( <NUM_LIT:2> , <NUM_LIT:3> ) : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> geos_holes = ( c_void_p * L ) ( ) <EOL> for l in range ( L ) : <EOL> geom , ndim = geos_linearring_from_py ( ob [ l ] ) <EOL> geos_holes [ l ] = cast ( geom , c_void_p ) <EOL> else : <EOL> geos_holes = POINTER ( c_void_p ) ( ) <EOL> L = <NUM_LIT:0> <EOL> return ( <EOL> lgeos . GEOSGeom_createPolygon ( <EOL> c_void_p ( geos_shell ) , <EOL> geos_holes , <EOL> L <EOL> ) , <EOL> ndim <EOL> ) <EOL> def _test ( ) : <EOL> import doctest <EOL> doctest . testmod ( ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> _test ( ) </s>
