|
@@ -259,34 +259,84 @@ class Geo(object):
|
|
gtype = None
|
|
gtype = None
|
|
|
|
|
|
def __init__(self, v_id=0, c_mapinfo=None, c_points=None, c_cats=None,
|
|
def __init__(self, v_id=0, c_mapinfo=None, c_points=None, c_cats=None,
|
|
- table=None, writeable=False, is2D=True):
|
|
|
|
|
|
+ table=None, writeable=False, is2D=True, free_points=False,
|
|
|
|
+ free_cats=False):
|
|
|
|
+ """Constructor of a geometry object
|
|
|
|
+
|
|
|
|
+ :param v_id: The vector feature id
|
|
|
|
+ :param c_mapinfo: A pointer to the vector mapinfo structure
|
|
|
|
+ :param c_points: A pointer to a libvect.line_pnts structure, this
|
|
|
|
+ is optional, if not set an internal structure will
|
|
|
|
+ be allocated and free'd at object destruction
|
|
|
|
+ :param c_cats: A pointer to a libvect.line_cats structure, this
|
|
|
|
+ is optional, if not set an internal structure will
|
|
|
|
+ be allocated and free'd at object destruction
|
|
|
|
+ :param table: The attribute table to select attributes for
|
|
|
|
+ this feature
|
|
|
|
+ :param writeable: Not sure what this is for?
|
|
|
|
+ :param is2D: If True this feature has two dimensions, False if
|
|
|
|
+ this feature has three dimensions
|
|
|
|
+ :param free_points: Set this True if the provided c_points structure
|
|
|
|
+ should be free'd at object destruction, be aware
|
|
|
|
+ that no other object should free them, otherwise
|
|
|
|
+ you can expect a double free corruption segfault
|
|
|
|
+ :param free_cats: Set this True if the provided c_cats structure
|
|
|
|
+ should be free'd at object destruction, be aware
|
|
|
|
+ that no other object should free them, otherwise
|
|
|
|
+ you can expect a double free corruption segfault
|
|
|
|
+
|
|
|
|
+ """
|
|
self.id = v_id # vector id
|
|
self.id = v_id # vector id
|
|
self.c_mapinfo = c_mapinfo
|
|
self.c_mapinfo = c_mapinfo
|
|
self.is2D = (is2D if is2D is not None else
|
|
self.is2D = (is2D if is2D is not None else
|
|
bool(libvect.Vect_is_3d(self.c_mapinfo) != 1))
|
|
bool(libvect.Vect_is_3d(self.c_mapinfo) != 1))
|
|
|
|
|
|
|
|
+ # Set True if cats and points are allocated by this object
|
|
|
|
+ # to free the cats and points structures on destruction
|
|
|
|
+ self._free_points = False
|
|
|
|
+ self._free_cats = False
|
|
|
|
+
|
|
read = False
|
|
read = False
|
|
# set c_points
|
|
# set c_points
|
|
if c_points is None:
|
|
if c_points is None:
|
|
self.c_points = ctypes.pointer(libvect.line_pnts())
|
|
self.c_points = ctypes.pointer(libvect.line_pnts())
|
|
|
|
+ self._free_points = True
|
|
read = True
|
|
read = True
|
|
else:
|
|
else:
|
|
self.c_points = c_points
|
|
self.c_points = c_points
|
|
|
|
+ self._free_points = free_points
|
|
|
|
|
|
# set c_cats
|
|
# set c_cats
|
|
if c_cats is None:
|
|
if c_cats is None:
|
|
self.c_cats = ctypes.pointer(libvect.line_cats())
|
|
self.c_cats = ctypes.pointer(libvect.line_cats())
|
|
|
|
+ self._free_cats = free_cats
|
|
read = True
|
|
read = True
|
|
else:
|
|
else:
|
|
self.c_cats = c_cats
|
|
self.c_cats = c_cats
|
|
|
|
+ self._free_cats = True
|
|
|
|
|
|
if self.id and self.c_mapinfo is not None and read:
|
|
if self.id and self.c_mapinfo is not None and read:
|
|
self.read()
|
|
self.read()
|
|
|
|
|
|
# set the attributes as last thing to do
|
|
# set the attributes as last thing to do
|
|
- self.attrs = None
|
|
|
|
|
|
+ self.attrs = None
|
|
if table is not None and self.cat is not None:
|
|
if table is not None and self.cat is not None:
|
|
self.attrs = Attrs(self.cat, table, writeable)
|
|
self.attrs = Attrs(self.cat, table, writeable)
|
|
|
|
+
|
|
|
|
+ def __del__(self):
|
|
|
|
+ """Take care of the allocated line_pnts and line_cats allocation
|
|
|
|
+ """
|
|
|
|
+ if self._free_points == True and self.c_points:
|
|
|
|
+ if self.c_points.contents.alloc_points > 0:
|
|
|
|
+ #print("G_free(points) [%i]"%(self.c_points.contents.alloc_points))
|
|
|
|
+ libgis.G_free(self.c_points.contents.x)
|
|
|
|
+ libgis.G_free(self.c_points.contents.y)
|
|
|
|
+ if self.c_points.contents.z:
|
|
|
|
+ libgis.G_free(self.c_points.contents.z)
|
|
|
|
+ if self._free_cats == True and self.c_cats:
|
|
|
|
+ if self.c_cats.contents.alloc_cats > 0:
|
|
|
|
+ #print("G_free(cats) [%i]"%(self.c_cats.contents.alloc_cats))
|
|
|
|
+ libgis.G_free(self.c_cats.contents.cat)
|
|
|
|
|
|
@property
|
|
@property
|
|
def cat(self):
|
|
def cat(self):
|
|
@@ -314,11 +364,6 @@ class Geo(object):
|
|
>>> pnt = Point(10, 100)
|
|
>>> pnt = Point(10, 100)
|
|
>>> pnt.to_wkt()
|
|
>>> pnt.to_wkt()
|
|
'POINT (10.0000000000000000 100.0000000000000000)'
|
|
'POINT (10.0000000000000000 100.0000000000000000)'
|
|
-
|
|
|
|
- .. warning::
|
|
|
|
-
|
|
|
|
- Only ``POINT`` (2/3D) are supported, ``POINTM`` and ``POINT`` with:
|
|
|
|
- ``XYZM`` are not supported yet.
|
|
|
|
"""
|
|
"""
|
|
return libvect.Vect_line_to_wkt(self.c_points, self.gtype, not self.is2D)
|
|
return libvect.Vect_line_to_wkt(self.c_points, self.gtype, not self.is2D)
|
|
|
|
|
|
@@ -330,12 +375,6 @@ class Geo(object):
|
|
>>> wkb = pnt.to_wkb()
|
|
>>> wkb = pnt.to_wkb()
|
|
>>> len(wkb)
|
|
>>> len(wkb)
|
|
21
|
|
21
|
|
-
|
|
|
|
-
|
|
|
|
- .. warning::
|
|
|
|
-
|
|
|
|
- Only ``POINT`` (2/3D) are supported, ``POINTM`` and ``POINT`` with:
|
|
|
|
- ``XYZM`` are not supported yet.
|
|
|
|
"""
|
|
"""
|
|
size = ctypes.c_size_t()
|
|
size = ctypes.c_size_t()
|
|
barray = libvect.Vect_line_to_wkb(self.c_points, self.gtype,
|
|
barray = libvect.Vect_line_to_wkb(self.c_points, self.gtype,
|
|
@@ -366,6 +405,19 @@ class Point(Geo):
|
|
>>> print(pnt)
|
|
>>> print(pnt)
|
|
POINT Z (0.0000000000000000 0.0000000000000000 0.0000000000000000)
|
|
POINT Z (0.0000000000000000 0.0000000000000000 0.0000000000000000)
|
|
|
|
|
|
|
|
+
|
|
|
|
+ >>> c_points = ctypes.pointer(libvect.line_pnts())
|
|
|
|
+ >>> c_cats = ctypes.pointer(libvect.line_cats())
|
|
|
|
+ >>> p = Point(c_points = c_points, c_cats=c_cats)
|
|
|
|
+ >>> del p
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ >>> c_points = ctypes.pointer(libvect.line_pnts())
|
|
|
|
+ >>> c_cats = ctypes.pointer(libvect.line_cats())
|
|
|
|
+ >>> p = Point(c_points=c_points, c_cats=c_cats, free_points=True,
|
|
|
|
+ ... free_cats=True)
|
|
|
|
+ >>> del p
|
|
|
|
+
|
|
..
|
|
..
|
|
"""
|
|
"""
|
|
# geometry type
|
|
# geometry type
|
|
@@ -1742,13 +1794,24 @@ def c_read_next_line(c_mapinfo, c_points, c_cats):
|
|
def read_next_line(c_mapinfo, table=None, writeable=False,
|
|
def read_next_line(c_mapinfo, table=None, writeable=False,
|
|
c_points=None, c_cats=None, is2D=True):
|
|
c_points=None, c_cats=None, is2D=True):
|
|
"""Return the next geometry feature of a vector map."""
|
|
"""Return the next geometry feature of a vector map."""
|
|
|
|
+
|
|
|
|
+ # Take care of good memory management
|
|
|
|
+ free_points = False
|
|
|
|
+ if c_points == None:
|
|
|
|
+ free_points = True
|
|
|
|
+
|
|
|
|
+ free_cats = False
|
|
|
|
+ if c_cats == None:
|
|
|
|
+ free_cats = True
|
|
|
|
+
|
|
c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts())
|
|
c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts())
|
|
c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats())
|
|
c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats())
|
|
ftype, v_id, c_points, c_cats = c_read_next_line(c_mapinfo, c_points,
|
|
ftype, v_id, c_points, c_cats = c_read_next_line(c_mapinfo, c_points,
|
|
c_cats)
|
|
c_cats)
|
|
return GV_TYPE[ftype]['obj'](v_id=v_id, c_mapinfo=c_mapinfo,
|
|
return GV_TYPE[ftype]['obj'](v_id=v_id, c_mapinfo=c_mapinfo,
|
|
c_points=c_points, c_cats=c_cats,
|
|
c_points=c_points, c_cats=c_cats,
|
|
- table=table, writeable=writeable, is2D=is2D)
|
|
|
|
|
|
+ table=table, writeable=writeable, is2D=is2D,
|
|
|
|
+ free_points=free_points, free_cats=free_cats)
|
|
|
|
|
|
|
|
|
|
def c_read_line(feature_id, c_mapinfo, c_points, c_cats):
|
|
def c_read_line(feature_id, c_mapinfo, c_points, c_cats):
|
|
@@ -1768,6 +1831,15 @@ def read_line(feature_id, c_mapinfo, table=None, writeable=False,
|
|
c_points=None, c_cats=None, is2D=True):
|
|
c_points=None, c_cats=None, is2D=True):
|
|
"""Return a geometry object given the feature id and the c_mapinfo.
|
|
"""Return a geometry object given the feature id and the c_mapinfo.
|
|
"""
|
|
"""
|
|
|
|
+ # Take care of good memory management
|
|
|
|
+ free_points = False
|
|
|
|
+ if c_points == None:
|
|
|
|
+ free_points = True
|
|
|
|
+
|
|
|
|
+ free_cats = False
|
|
|
|
+ if c_cats == None:
|
|
|
|
+ free_cats = True
|
|
|
|
+
|
|
c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts())
|
|
c_points = c_points if c_points else ctypes.pointer(libvect.line_pnts())
|
|
c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats())
|
|
c_cats = c_cats if c_cats else ctypes.pointer(libvect.line_cats())
|
|
feature_id, ftype, c_points, c_cats = c_read_line(feature_id, c_mapinfo,
|
|
feature_id, ftype, c_points, c_cats = c_read_line(feature_id, c_mapinfo,
|
|
@@ -1775,8 +1847,9 @@ def read_line(feature_id, c_mapinfo, table=None, writeable=False,
|
|
if GV_TYPE[ftype]['obj'] is not None:
|
|
if GV_TYPE[ftype]['obj'] is not None:
|
|
return GV_TYPE[ftype]['obj'](v_id=feature_id, c_mapinfo=c_mapinfo,
|
|
return GV_TYPE[ftype]['obj'](v_id=feature_id, c_mapinfo=c_mapinfo,
|
|
c_points=c_points, c_cats=c_cats,
|
|
c_points=c_points, c_cats=c_cats,
|
|
- table=table, writeable=writeable, is2D=is2D)
|
|
|
|
-
|
|
|
|
|
|
+ table=table, writeable=writeable, is2D=is2D,
|
|
|
|
+ free_points=free_points,
|
|
|
|
+ free_cats=free_cats)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if __name__ == "__main__":
|
|
import doctest
|
|
import doctest
|