changeset 0:f026f0b3afe2

Added mq repo
author Nicolas Évrard <nicoe@b2ck.com>
date Mon, 19 Dec 2011 18:47:07 +0100
parents
children c44983f8a17d
files .hgignore add_wkt modular_dbapi series unittests
diffstat 5 files changed, 429 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Mon Dec 19 18:47:07 2011 +0100
@@ -0,0 +1,5 @@
+^\.hg
+^\.mq
+syntax: glob
+status
+guards
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/add_wkt	Mon Dec 19 18:47:07 2011 +0100
@@ -0,0 +1,194 @@
+# HG changeset patch
+# Parent b1151b47015bffd74825706e78459f2931a72c5c
+diff -r b1151b47015b -r de7ce982acf4 src/ppygis.py
+--- a/src/ppygis.py	Mon Dec 19 18:27:40 2011 +0100
++++ b/src/ppygis.py	Mon Dec 19 18:30:04 2011 +0100
+@@ -159,6 +159,8 @@
+ 
+ class Geometry(object):
+ 
++    _type = 'Geometry'
++
+     @property
+     def has_z(self):
+         return False
+@@ -168,6 +170,18 @@
+         return False
+ 
+     @property
++    def wkt(self):
++        wkt = self._type + ' '
++        if self.has_z:
++            wkt += 'z'
++        if self.has_m:
++            wkt += 'm'
++        if self.has_z or self.has_m:
++            wkt += ' '
++        wkt += self.untagged_wkt
++        return wkt.upper()
++
++    @property
+     def has_srid(self):
+         return self.srid is not None
+ 
+@@ -201,6 +215,8 @@
+ 
+ class Point(Geometry):
+ 
++    _type = 'Point'
++
+     def __init__(self, x, y, z=None, m=None, srid=None):
+         self.x = x
+         self.y = y
+@@ -214,7 +230,20 @@
+ 
+     @property
+     def has_m(self):
+-        return hasattr(self, 'm')
++        return self.m is not None
++
++    @property
++    def untagged_wkt(self):
++        return '(' + self.coordinates + ')'
++
++    @property
++    def coordinates(self):
++        uwkt = '%s %s' % (self.x, self.y)
++        if self.has_z:
++            uwkt += ' %s' % self.z
++        if self.has_m:
++            uwkt += ' %s' % self.m
++        return uwkt
+ 
+     @classmethod
+     def _read_ewkb_body(cls, reader, srid=None):
+@@ -253,6 +282,8 @@
+ 
+ class LineString(Geometry):
+ 
++    _type = 'LineString'
++
+     def __init__(self, points, srid=None):
+         self.points = list(points)
+         if srid:
+@@ -266,6 +297,10 @@
+     def has_m(self):
+         return self.points[0].has_m
+ 
++    @property
++    def untagged_wkt(self):
++        return '(' + ', '.join(p.coordinates for p in self.points) + ')'
++
+     @classmethod
+     def _read_ewkb_body(cls, reader, srid=None):
+         return cls([Point._read_ewkb_body(reader) for index in
+@@ -286,6 +321,8 @@
+ 
+ class Polygon(Geometry):
+ 
++    _type = 'Polygon'
++
+     def __init__(self, rings, srid=None):
+         self.rings = list(rings)
+         self.srid = srid
+@@ -298,6 +335,10 @@
+     def has_m(self):
+         return self.rings[0].has_m
+ 
++    @property
++    def untagged_wkt(self):
++        return '(' + ', '.join(r.untagged_wkt for r in self.rings) + ')'
++
+     @classmethod
+     def _read_ewkb_body(cls, reader, srid=None):
+         return cls([LineString._read_ewkb_body(reader) for index in
+@@ -318,6 +359,8 @@
+ 
+ class GeometryCollection(Geometry):
+ 
++    _type = 'GeometryCollection'
++
+     def __init__(self, geometries, srid=None):
+         self.geometries = list(geometries)
+         self.srid = srid
+@@ -347,6 +390,8 @@
+ 
+ class MultiPoint(GeometryCollection):
+ 
++    _type = 'MultiPoint'
++
+     def __init__(self, points, srid=None):
+         self.points = list(points)
+         self.srid = srid
+@@ -359,6 +404,10 @@
+     def has_m(self):
+         return self.points[0].has_m
+ 
++    @property
++    def untagged_wkt(self):
++        return '(' + ', '.join(p.untagged_wkt for p in self.points) + ')'
++
+     @classmethod
+     def _read_ewkb_body(cls, reader, srid=None):
+         points = []
+@@ -384,6 +433,8 @@
+ 
+ class MultiLineString(GeometryCollection):
+ 
++    _type = 'MultiLineString'
++
+     def __init__(self, lines, srid=None):
+         self.lines = list(lines)
+         self.srid = srid
+@@ -421,6 +472,8 @@
+ 
+ class MultiPolygon(GeometryCollection):
+ 
++    _type = 'MultiPolygon'
++
+     def __init__(self, polygons, srid=None):
+         self.polygons = list(polygons)
+         self.srid = srid
+diff -r b1151b47015b -r de7ce982acf4 src/tests/test_ppygis.py
+--- a/src/tests/test_ppygis.py	Mon Dec 19 18:27:40 2011 +0100
++++ b/src/tests/test_ppygis.py	Mon Dec 19 18:30:04 2011 +0100
+@@ -2,7 +2,38 @@
+ import binascii
+ 
+ import ppygis
+-from ppygis import Point
++from ppygis import Point, LineString, Polygon, MultiPoint
++
++
++class TestWKT(unittest.TestCase):
++
++    def test_point(self):
++        point = Point(30, 10)
++        self.assertEqual(point.wkt, 'POINT (30 10)')
++
++    def test_linestring(self):
++        line = LineString([Point(30, 10), Point(10, 30), Point(40, 40)])
++        self.assertEqual(line.wkt, 'LINESTRING (30 10, 10 30, 40 40)')
++
++    def test_polygon(self):
++        polygon = Polygon([
++                LineString([Point(30, 10), Point(10, 20), Point(20, 40),
++                        Point(40, 40), Point(30, 10)])])
++        self.assertEqual(polygon.wkt, 'POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))')
++
++        polygon = Polygon([
++                LineString([Point(35, 10), Point(10, 20), Point(15, 40),
++                        Point(45, 45), Point(35, 10)]),
++                LineString([Point(20, 30), Point(35, 35), Point(30, 20),
++                        Point(20, 30)]),
++                ])
++        self.assertEqual(polygon.wkt,
++            'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10), (20 30, 35 35, 30 20, 20 30))')
++
++    def test_multipoint(self):
++        multipoint = MultiPoint([Point(10, 40), Point(40, 30), Point(20, 20),
++                Point(30, 10)])
++        self.assertEqual(multipoint.wkt, 'MULTIPOINT ((10 40), (40 30), (20 20), (30 10))')
+ 
+ 
+ class TestSQLite(unittest.TestCase):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modular_dbapi	Mon Dec 19 18:47:07 2011 +0100
@@ -0,0 +1,187 @@
+# HG changeset patch
+# Parent a29eb0d4a386cdaf343bf93f1f84da22688f750a
+diff -r a29eb0d4a386 -r e6b97c5cb8d7 src/ppygis.py
+--- a/src/ppygis.py	Sun Dec 04 15:32:39 2011 +0100
++++ b/src/ppygis.py	Mon Dec 19 18:25:47 2011 +0100
+@@ -32,8 +32,6 @@
+ import cStringIO
+ import struct
+ 
+-import psycopg2.extensions
+-
+ 
+ class _EWKBReader(object):
+ 
+@@ -123,6 +121,42 @@
+         self.stream.write(struct.pack('<d', value))
+ 
+ 
++class _SQLiteBlobReader(object):
++
++    def __init__(self, stream):
++        if isinstance(stream, (str, buffer)):
++            stream = cStringIO.StringIO(stream)
++        self.stream = stream
++
++    def read_geometry(self):
++        self.stream.read(1)
++        byte_order = self.stream.read(1)
++        if byte_order == '\x00':
++            self.endianness = '>'
++        elif byte_order == '\x01':
++            self.endianness = '<'
++        else:
++            raise ValueError('Incorrect endianness value')
++        srid = self.read_int()
++        self.stream.read(32)
++        assert self.stream.read(1) == '\x7C'
++        geom_type = self.read_int()
++
++        if geom_type == 1:
++            geom = Point._read_sqlite_body(self, srid)
++        else:
++            raise ValueError('Unsupported geometry type')
++
++        assert self.stream.read(1) == '\xFE'
++        return geom
++
++    def read_int(self):
++        return struct.unpack(self.endianness + 'I', self.stream.read(4))[0]
++
++    def read_double(self):
++        return struct.unpack(self.endianness + 'd', self.stream.read(8))[0]
++
++
+ class Geometry(object):
+ 
+     @property
+@@ -135,7 +169,7 @@
+ 
+     @property
+     def has_srid(self):
+-        return hasattr(self, 'srid')
++        return self.srid is not None
+ 
+     @staticmethod
+     def read_ewkb(value, cursor=None):
+@@ -146,9 +180,9 @@
+     def _read_ewkb(reader):
+         return _EWKBReader(reader.stream).read_geometry()
+ 
+-    def __conform__(self, protocol):
+-        if protocol is psycopg2.extensions.ISQLQuote:
+-            return self
++    @staticmethod
++    def read_sqlite_blob(value, cursor=None):
++        return _SQLiteBlobReader(value).read_geometry() if value else None
+ 
+     def write_ewkb(self):
+         writer = _EWKBWriter(self)
+@@ -165,26 +199,18 @@
+         return ', SRID: {0}'.format(self.srid) if self.has_srid else ''
+ 
+ 
+-GEOMETRY = psycopg2.extensions.new_type((218754, ), "GEOMETRY",
+-        Geometry.read_ewkb)
+-psycopg2.extensions.register_type(GEOMETRY)
+-
+-
+ class Point(Geometry):
+ 
+     def __init__(self, x, y, z=None, m=None, srid=None):
+         self.x = x
+         self.y = y
+-        if z != None:
+-            self.z = z
+-        if m != None:
+-            self.m = m
+-        if srid != None:
+-            self.srid = srid
++        self.z = z
++        self.m = m
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+-        return hasattr(self, 'z')
++        return self.z is not None
+ 
+     @property
+     def has_m(self):
+@@ -207,6 +233,10 @@
+         if hasattr(self, 'm'):
+             writer.write_double(self.m)
+ 
++    @classmethod
++    def _read_sqlite_body(cls, reader, srid=None):
++        return cls(reader.read_double(), reader.read_double(), srid=srid)
++
+     def __str__(self):
+         return 'Point(X: {0}, Y: {1}'.format(self.x, self.y) + \
+                 (', Z: {0}'.format(self.z) if self.has_z else '') + \
+@@ -251,8 +281,7 @@
+ 
+     def __init__(self, rings, srid=None):
+         self.rings = list(rings)
+-        if srid:
+-            self.srid = srid
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+@@ -284,8 +313,7 @@
+ 
+     def __init__(self, geometries, srid=None):
+         self.geometries = list(geometries)
+-        if srid:
+-            self.srid = srid
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+@@ -314,8 +342,7 @@
+ 
+     def __init__(self, points, srid=None):
+         self.points = list(points)
+-        if srid:
+-            self.srid = srid
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+@@ -352,8 +379,7 @@
+ 
+     def __init__(self, lines, srid=None):
+         self.lines = list(lines)
+-        if srid:
+-            self.srid = srid
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+@@ -390,8 +416,7 @@
+ 
+     def __init__(self, polygons, srid=None):
+         self.polygons = list(polygons)
+-        if srid:
+-            self.srid = srid
++        self.srid = srid
+ 
+     @property
+     def has_z(self):
+@@ -422,3 +447,15 @@
+     def __str__(self):
+         return 'MultiPolygon(' + ', '.join([str(polygon) for polygon in
+                 self.polygons]) + self._str_srid() + ')'
++
++def register_psycopg():
++    from psycopg2.extensions import (new_type, register_type, register_adapter,
++        AsIs)
++
++    GEOMETRY = new_type((436421,), "POINT", Geometry.read_ewkb)
++    register_type(GEOMETRY)
++    register_adapter(Point, lambda o: AsIs("'%s'" % o.write_ewkb()))
++
++def register_spatialite():
++    from pyspatialite.dbapi2 import register_converter
++    register_converter('POINT', Point.read_sqlite_blob)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/series	Mon Dec 19 18:47:07 2011 +0100
@@ -0,0 +1,3 @@
+modular_dbapi
+unittests
+add_wkt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/unittests	Mon Dec 19 18:47:07 2011 +0100
@@ -0,0 +1,40 @@
+# HG changeset patch
+# Parent e6b97c5cb8d7f295a3b0b4ea76de1a48a54ae1b4
+diff -r e6b97c5cb8d7 -r b1151b47015b src/ppygis.py
+--- a/src/ppygis.py	Mon Dec 19 18:25:47 2011 +0100
++++ b/src/ppygis.py	Mon Dec 19 18:27:40 2011 +0100
+@@ -237,6 +237,13 @@
+     def _read_sqlite_body(cls, reader, srid=None):
+         return cls(reader.read_double(), reader.read_double(), srid=srid)
+ 
++    def __eq__(self, other):
++        return (self.srid == other.srid
++            and self.x == other.x
++            and self.y == other.y
++            and self.z == other.z
++            and self.m == other.m)
++
+     def __str__(self):
+         return 'Point(X: {0}, Y: {1}'.format(self.x, self.y) + \
+                 (', Z: {0}'.format(self.z) if self.has_z else '') + \
+diff -r e6b97c5cb8d7 -r b1151b47015b src/tests/test_ppygis.py
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/src/tests/test_ppygis.py	Mon Dec 19 18:27:40 2011 +0100
+@@ -0,0 +1,17 @@
++import unittest
++import binascii
++
++import ppygis
++from ppygis import Point
++
++
++class TestSQLite(unittest.TestCase):
++
++    def test_read(self):
++        point_binary = binascii.a2b_hex("0001e610000000000000000024400000000000002440000000000000244000000000000024407c0100000000000000000024400000000000002440fe")
++        point = ppygis._SQLiteBlobReader(point_binary)
++        self.assertEqual(Point(10, 10, srid=4326), point.read_geometry())
++
++
++if __name__ == '__main__':
++    unittest.main()