/usr/lib/python3/dist-packages/postgresql/types/geometry.py is in python3-postgresql 1.1.0-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | import math
from operator import itemgetter
get0 = itemgetter(0)
get1 = itemgetter(1)
# Geometric types
class Point(tuple):
"""
A point; a pair of floating point numbers.
"""
__slots__ = ()
x = property(fget = lambda s: s[0])
y = property(fget = lambda s: s[1])
def __new__(subtype, pair):
return tuple.__new__(subtype, (float(pair[0]), float(pair[1])))
def __repr__(self):
return '%s.%s(%s)' %(
type(self).__module__,
type(self).__name__,
tuple.__repr__(self),
)
def __str__(self):
return tuple.__repr__(self)
def __add__(self, ob):
wx, wy = ob
return type(self)((self[0] + wx, self[1] + wy))
def __sub__(self, ob):
wx, wy = ob
return type(self)((self[0] - wx, self[1] - wy))
def __mul__(self, ob):
wx, wy = ob
rx = (self[0] * wx) - (self[1] * wy)
ry = (self[0] * wy) + (self[1] * wx)
return type(self)((rx, ry))
def __div__(self, ob):
sx, sy = self
wx, wy = ob
div = (wx * wx) + (wy * wy)
rx = ((sx * wx) + (sy * wy)) / div
ry = ((wx * sy) + (wy * sx)) / div
return type(self)((rx, ry))
def distance(self, ob, sqrt = math.sqrt):
wx, wy = ob
dx = self[0] - float(wx)
dy = self[1] - float(wy)
return sqrt(dx**2 + dy**2)
class Lseg(tuple):
__slots__ = ()
one = property(fget = lambda s: s[0])
two = property(fget = lambda s: s[1])
length = property(fget = lambda s: s[0].distance(s[1]))
vertical = property(fget = lambda s: s[0][0] == s[1][0])
horizontal = property(fget = lambda s: s[0][1] == s[1][1])
slope = property(
fget = lambda s: (s[1][1] - s[0][1]) / (s[1][0] - s[0][0])
)
center = property(
fget = lambda s: Point((
(s[0][0] + s[1][0]) / 2.0,
(s[0][1] + s[1][1]) / 2.0,
))
)
def __new__(subtype, pair):
p1, p2 = pair
return tuple.__new__(subtype, (Point(p1), Point(p2)))
def __repr__(self):
# Avoid the point representation
return '%s.%s(%s, %s)' %(
type(self).__module__,
type(self).__name__,
tuple.__repr__(self[0]),
tuple.__repr__(self[1]),
)
def __str__(self):
return '[(%s,%s),(%s,%s)]' %(
self[0][0],
self[0][1],
self[1][0],
self[1][1],
)
def parallel(self, ob):
return self.slope == type(self)(ob).slope
def intersect(self, ob):
raise NotImplementedError
def perpendicular(self, ob):
return (self.slope / type(self)(ob).slope) == -1.0
class Box(tuple):
"""
A pair of points. One specifying the top-right point of the box; the other
specifying the bottom-left. `high` being top-right; `low` being bottom-left.
http://www.postgresql.org/docs/current/static/datatype-geometric.html
>>> Box(( (0,0), (-2, -2) ))
postgresql.types.geometry.Box(((0.0, 0.0), (-2.0, -2.0)))
It will also relocate values to enforce the high-low expectation:
>>> t.box(((-4,0),(-2,-3)))
postgresql.types.geometry.Box(((-2.0, 0.0), (-4.0, -3.0)))
::
(-2, 0) `high`
|
|
(-4,-3) -------+-x
`low` y
This happens because ``-4`` is less than ``-2``; therefore the ``-4``
belongs on the low point. This is consistent with what PostgreSQL does
with its ``box`` type.
"""
__slots__ = ()
high = property(fget = get0, doc = "high point of the box")
low = property(fget = get1, doc = "low point of the box")
center = property(
fget = lambda s: Point((
(s[0][0] + s[1][0]) / 2.0,
(s[0][1] + s[1][1]) / 2.0
)),
doc = "center of the box as a point"
)
def __new__(subtype, hl):
if isinstance(hl, Box):
return hl
one, two = hl
if one[0] > two[0]:
hx = one[0]
lx = two[0]
else:
hx = two[0]
lx = one[0]
if one[1] > two[1]:
hy = one[1]
ly = two[1]
else:
hy = two[1]
ly = one[1]
return tuple.__new__(subtype, (Point((hx, hy)), Point((lx, ly))))
def __repr__(self):
return '%s.%s((%s, %s))' %(
type(self).__module__,
type(self).__name__,
tuple.__repr__(self[0]),
tuple.__repr__(self[1]),
)
def __str__(self):
return '%s,%s' %(self[0], self[1])
class Circle(tuple):
"""
type for PostgreSQL circles
"""
__slots__ = ()
center = property(fget = get0, doc = "center of the circle (point)")
radius = property(fget = get1, doc = "radius of the circle (radius >= 0)")
def __new__(subtype, pair):
center, radius = pair
if radius < 0:
raise ValueError("radius is subzero")
return tuple.__new__(subtype, (Point(center), float(radius)))
def __repr__(self):
return '%s.%s((%s, %s))' %(
type(self).__module__,
type(self).__name__,
tuple.__repr__(self[0]),
repr(self[1])
)
def __str__(self):
return '<%s,%s>' %(self[0], self[1])
|