structure saas with tools
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
import unittest
|
||||
from math import pi
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from shapely import affinity
|
||||
from shapely.geometry import Point
|
||||
from shapely.wkt import loads as load_wkt
|
||||
|
||||
|
||||
class AffineTestCase(unittest.TestCase):
|
||||
def test_affine_params(self):
|
||||
g = load_wkt("LINESTRING(2.4 4.1, 2.4 3, 3 3)")
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
affinity.affine_transform(g, None)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
affinity.affine_transform(g, [1, 2, 3, 4, 5, 6, 7, 8, 9])
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
affinity.affine_transform(None, [1, 2, 3, 4, 5, 6])
|
||||
|
||||
def test_affine_geom_types(self):
|
||||
# identity matrices, which should result with no transformation
|
||||
matrix2d = (1, 0, 0, 1, 0, 0)
|
||||
matrix3d = (1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
|
||||
# empty in, empty out
|
||||
empty2d = load_wkt("MULTIPOLYGON EMPTY")
|
||||
assert affinity.affine_transform(empty2d, matrix2d).is_empty
|
||||
|
||||
def test_geom(g2, g3=None):
|
||||
assert not g2.has_z
|
||||
a2 = affinity.affine_transform(g2, matrix2d)
|
||||
assert not a2.has_z
|
||||
assert g2.equals(a2)
|
||||
if g3 is not None:
|
||||
assert g3.has_z
|
||||
a3 = affinity.affine_transform(g3, matrix3d)
|
||||
assert a3.has_z
|
||||
assert g3.equals(a3)
|
||||
|
||||
pt2d = load_wkt("POINT(12.3 45.6)")
|
||||
pt3d = load_wkt("POINT(12.3 45.6 7.89)")
|
||||
test_geom(pt2d, pt3d)
|
||||
ls2d = load_wkt("LINESTRING(0.9 3.4, 0.7 2, 2.5 2.7)")
|
||||
ls3d = load_wkt("LINESTRING(0.9 3.4 3.3, 0.7 2 2.3, 2.5 2.7 5.5)")
|
||||
test_geom(ls2d, ls3d)
|
||||
lr2d = load_wkt("LINEARRING(0.9 3.4, 0.7 2, 2.5 2.7, 0.9 3.4)")
|
||||
lr3d = load_wkt("LINEARRING(0.9 3.4 3.3, 0.7 2 2.3, 2.5 2.7 5.5, 0.9 3.4 3.3)")
|
||||
test_geom(lr2d, lr3d)
|
||||
test_geom(
|
||||
load_wkt(
|
||||
"POLYGON((0.9 2.3, 0.5 1.1, 2.4 0.8, 0.9 2.3), "
|
||||
"(1.1 1.7, 0.9 1.3, 1.4 1.2, 1.1 1.7), "
|
||||
"(1.6 1.3, 1.7 1, 1.9 1.1, 1.6 1.3))"
|
||||
)
|
||||
)
|
||||
test_geom(
|
||||
load_wkt("MULTIPOINT ((-300 300), (700 300), (-800 -1100), (200 -300))")
|
||||
)
|
||||
test_geom(
|
||||
load_wkt(
|
||||
"MULTILINESTRING((0 0, -0.7 -0.7, 0.6 -1), (-0.5 0.5, 0.7 0.6, 0 -0.6))"
|
||||
)
|
||||
)
|
||||
test_geom(
|
||||
load_wkt(
|
||||
"MULTIPOLYGON(((900 4300, -1100 -400, 900 -800, 900 4300)), "
|
||||
"((1200 4300, 2300 4400, 1900 1000, 1200 4300)))"
|
||||
)
|
||||
)
|
||||
test_geom(
|
||||
load_wkt(
|
||||
"GEOMETRYCOLLECTION(POINT(20 70),"
|
||||
" POLYGON((60 70, 13 35, 60 -30, 60 70)),"
|
||||
" LINESTRING(60 70, 50 100, 80 100))"
|
||||
)
|
||||
)
|
||||
|
||||
def test_affine_2d(self):
|
||||
g = load_wkt("LINESTRING(2.4 4.1, 2.4 3, 3 3)")
|
||||
# custom scale and translate
|
||||
expected2d = load_wkt("LINESTRING(-0.2 14.35, -0.2 11.6, 1 11.6)")
|
||||
matrix2d = (2, 0, 0, 2.5, -5, 4.1)
|
||||
a2 = affinity.affine_transform(g, matrix2d)
|
||||
assert a2.equals_exact(expected2d, 1e-6)
|
||||
assert not a2.has_z
|
||||
# Make sure a 3D matrix does not make a 3D shape from a 2D input
|
||||
matrix3d = (2, 0, 0, 0, 2.5, 0, 0, 0, 10, -5, 4.1, 100)
|
||||
a3 = affinity.affine_transform(g, matrix3d)
|
||||
assert a3.equals_exact(expected2d, 1e-6)
|
||||
assert not a3.has_z
|
||||
|
||||
def test_affine_3d(self):
|
||||
g2 = load_wkt("LINESTRING(2.4 4.1, 2.4 3, 3 3)")
|
||||
g3 = load_wkt("LINESTRING(2.4 4.1 100.2, 2.4 3 132.8, 3 3 128.6)")
|
||||
# custom scale and translate
|
||||
matrix2d = (2, 0, 0, 2.5, -5, 4.1)
|
||||
matrix3d = (2, 0, 0, 0, 2.5, 0, 0, 0, 0.3048, -5, 4.1, 100)
|
||||
# Combinations of 2D and 3D geometries and matrices
|
||||
a22 = affinity.affine_transform(g2, matrix2d)
|
||||
a23 = affinity.affine_transform(g2, matrix3d)
|
||||
a32 = affinity.affine_transform(g3, matrix2d)
|
||||
a33 = affinity.affine_transform(g3, matrix3d)
|
||||
# Check dimensions
|
||||
assert not a22.has_z
|
||||
assert not a23.has_z
|
||||
assert a32.has_z
|
||||
assert a33.has_z
|
||||
|
||||
# 2D equality checks
|
||||
expected2d = load_wkt("LINESTRING(-0.2 14.35, -0.2 11.6, 1 11.6)")
|
||||
expected3d = load_wkt(
|
||||
"LINESTRING(-0.2 14.35 130.54096, -0.2 11.6 140.47744, 1 11.6 139.19728)"
|
||||
)
|
||||
expected32 = load_wkt(
|
||||
"LINESTRING(-0.2 14.35 100.2, -0.2 11.6 132.8, 1 11.6 128.6)"
|
||||
)
|
||||
assert a22.equals_exact(expected2d, 1e-6)
|
||||
assert a23.equals_exact(expected2d, 1e-6)
|
||||
# Do explicit 3D check of coordinate values
|
||||
for a, e in zip(a32.coords, expected32.coords):
|
||||
for ap, ep in zip(a, e):
|
||||
self.assertAlmostEqual(ap, ep)
|
||||
for a, e in zip(a33.coords, expected3d.coords):
|
||||
for ap, ep in zip(a, e):
|
||||
self.assertAlmostEqual(ap, ep)
|
||||
|
||||
|
||||
class TransformOpsTestCase(unittest.TestCase):
|
||||
def test_rotate(self):
|
||||
ls = load_wkt("LINESTRING(240 400, 240 300, 300 300)")
|
||||
# counter-clockwise degrees
|
||||
rls = affinity.rotate(ls, 90)
|
||||
els = load_wkt("LINESTRING(220 320, 320 320, 320 380)")
|
||||
assert rls.equals(els)
|
||||
# retest with named parameters for the same result
|
||||
rls = affinity.rotate(geom=ls, angle=90, origin="center")
|
||||
assert rls.equals(els)
|
||||
# clockwise radians
|
||||
rls = affinity.rotate(ls, -pi / 2, use_radians=True)
|
||||
els = load_wkt("LINESTRING(320 380, 220 380, 220 320)")
|
||||
assert rls.equals(els)
|
||||
## other `origin` parameters
|
||||
# around the centroid
|
||||
rls = affinity.rotate(ls, 90, origin="centroid")
|
||||
els = load_wkt("LINESTRING(182.5 320, 282.5 320, 282.5 380)")
|
||||
assert rls.equals(els)
|
||||
# around the second coordinate tuple
|
||||
rls = affinity.rotate(ls, 90, origin=ls.coords[1])
|
||||
els = load_wkt("LINESTRING(140 300, 240 300, 240 360)")
|
||||
assert rls.equals(els)
|
||||
# around the absolute Point of origin
|
||||
rls = affinity.rotate(ls, 90, origin=Point(0, 0))
|
||||
els = load_wkt("LINESTRING(-400 240, -300 240, -300 300)")
|
||||
assert rls.equals(els)
|
||||
|
||||
def test_rotate_empty(self):
|
||||
rls = affinity.rotate(load_wkt("LINESTRING EMPTY"), 90)
|
||||
els = load_wkt("LINESTRING EMPTY")
|
||||
assert rls.equals(els)
|
||||
|
||||
def test_rotate_angle_array(self):
|
||||
ls = load_wkt("LINESTRING(240 400, 240 300, 300 300)")
|
||||
els = load_wkt("LINESTRING(220 320, 320 320, 320 380)")
|
||||
# check with degrees
|
||||
theta = np.array(90.0)
|
||||
rls = affinity.rotate(ls, theta)
|
||||
assert theta.item() == 90.0
|
||||
assert rls.equals(els)
|
||||
# check with radians
|
||||
theta = np.array(pi / 2)
|
||||
rls = affinity.rotate(ls, theta, use_radians=True)
|
||||
assert theta.item() == pi / 2
|
||||
assert rls.equals(els)
|
||||
|
||||
def test_scale(self):
|
||||
ls = load_wkt("LINESTRING(240 400 10, 240 300 30, 300 300 20)")
|
||||
# test defaults of 1.0
|
||||
sls = affinity.scale(ls)
|
||||
assert sls.equals(ls)
|
||||
# different scaling in different dimensions
|
||||
sls = affinity.scale(ls, 2, 3, 0.5)
|
||||
els = load_wkt("LINESTRING(210 500 5, 210 200 15, 330 200 10)")
|
||||
assert sls.equals(els)
|
||||
# Do explicit 3D check of coordinate values
|
||||
for a, b in zip(sls.coords, els.coords):
|
||||
for ap, bp in zip(a, b):
|
||||
self.assertEqual(ap, bp)
|
||||
# retest with named parameters for the same result
|
||||
sls = affinity.scale(geom=ls, xfact=2, yfact=3, zfact=0.5, origin="center")
|
||||
assert sls.equals(els)
|
||||
## other `origin` parameters
|
||||
# around the centroid
|
||||
sls = affinity.scale(ls, 2, 3, 0.5, origin="centroid")
|
||||
els = load_wkt("LINESTRING(228.75 537.5, 228.75 237.5, 348.75 237.5)")
|
||||
assert sls.equals(els)
|
||||
# around the second coordinate tuple
|
||||
sls = affinity.scale(ls, 2, 3, 0.5, origin=ls.coords[1])
|
||||
els = load_wkt("LINESTRING(240 600, 240 300, 360 300)")
|
||||
assert sls.equals(els)
|
||||
# around some other 3D Point of origin
|
||||
sls = affinity.scale(ls, 2, 3, 0.5, origin=Point(100, 200, 1000))
|
||||
els = load_wkt("LINESTRING(380 800 505, 380 500 515, 500 500 510)")
|
||||
assert sls.equals(els)
|
||||
# Do explicit 3D check of coordinate values
|
||||
for a, b in zip(sls.coords, els.coords):
|
||||
for ap, bp in zip(a, b):
|
||||
assert ap == bp
|
||||
|
||||
def test_scale_empty(self):
|
||||
sls = affinity.scale(load_wkt("LINESTRING EMPTY"))
|
||||
els = load_wkt("LINESTRING EMPTY")
|
||||
assert sls.equals(els)
|
||||
|
||||
def test_skew(self):
|
||||
ls = load_wkt("LINESTRING(240 400 10, 240 300 30, 300 300 20)")
|
||||
# test default shear angles of 0.0
|
||||
sls = affinity.skew(ls)
|
||||
assert sls.equals(ls)
|
||||
# different shearing in x- and y-directions
|
||||
sls = affinity.skew(ls, 15, -30)
|
||||
els = load_wkt(
|
||||
"LINESTRING (253.39745962155615 417.3205080756888, "
|
||||
"226.60254037844385 317.3205080756888, "
|
||||
"286.60254037844385 282.67949192431126)"
|
||||
)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
# retest with radians for the same result
|
||||
sls = affinity.skew(ls, pi / 12, -pi / 6, use_radians=True)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
# retest with named parameters for the same result
|
||||
sls = affinity.skew(geom=ls, xs=15, ys=-30, origin="center", use_radians=False)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
## other `origin` parameters
|
||||
# around the centroid
|
||||
sls = affinity.skew(ls, 15, -30, origin="centroid")
|
||||
els = load_wkt(
|
||||
"LINESTRING(258.42150697963973 406.49519052838332, "
|
||||
"231.6265877365273980 306.4951905283833185, "
|
||||
"291.6265877365274264 271.8541743770057337)"
|
||||
)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
# around the second coordinate tuple
|
||||
sls = affinity.skew(ls, 15, -30, origin=ls.coords[1])
|
||||
els = load_wkt(
|
||||
"LINESTRING(266.7949192431123038 400, 240 300, 300 265.3589838486224153)"
|
||||
)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
# around the absolute Point of origin
|
||||
sls = affinity.skew(ls, 15, -30, origin=Point(0, 0))
|
||||
els = load_wkt(
|
||||
"LINESTRING(347.179676972449101 261.435935394489832, "
|
||||
"320.3847577293367976 161.4359353944898317, "
|
||||
"380.3847577293367976 126.7949192431122754)"
|
||||
)
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
|
||||
def test_skew_empty(self):
|
||||
sls = affinity.skew(load_wkt("LINESTRING EMPTY"))
|
||||
els = load_wkt("LINESTRING EMPTY")
|
||||
assert sls.equals(els)
|
||||
|
||||
def test_skew_xs_ys_array(self):
|
||||
ls = load_wkt("LINESTRING(240 400 10, 240 300 30, 300 300 20)")
|
||||
els = load_wkt(
|
||||
"LINESTRING (253.39745962155615 417.3205080756888, "
|
||||
"226.60254037844385 317.3205080756888, "
|
||||
"286.60254037844385 282.67949192431126)"
|
||||
)
|
||||
# check with degrees
|
||||
xs_ys = np.array([15.0, -30.0])
|
||||
sls = affinity.skew(ls, xs_ys[0, ...], xs_ys[1, ...])
|
||||
assert xs_ys[0] == 15.0
|
||||
assert xs_ys[1] == -30.0
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
# check with radians
|
||||
xs_ys = np.array([pi / 12, -pi / 6])
|
||||
sls = affinity.skew(ls, xs_ys[0, ...], xs_ys[1, ...], use_radians=True)
|
||||
assert xs_ys[0] == pi / 12
|
||||
assert xs_ys[1] == -pi / 6
|
||||
assert sls.equals_exact(els, 1e-6)
|
||||
|
||||
def test_translate(self):
|
||||
ls = load_wkt("LINESTRING(240 400 10, 240 300 30, 300 300 20)")
|
||||
# test default offset of 0.0
|
||||
tls = affinity.translate(ls)
|
||||
assert tls.equals(ls)
|
||||
# test all offsets
|
||||
tls = affinity.translate(ls, 100, 400, -10)
|
||||
els = load_wkt("LINESTRING(340 800 0, 340 700 20, 400 700 10)")
|
||||
assert tls.equals(els)
|
||||
# Do explicit 3D check of coordinate values
|
||||
for a, b in zip(tls.coords, els.coords):
|
||||
for ap, bp in zip(a, b):
|
||||
assert ap == bp
|
||||
# retest with named parameters for the same result
|
||||
tls = affinity.translate(geom=ls, xoff=100, yoff=400, zoff=-10)
|
||||
assert tls.equals(els)
|
||||
|
||||
def test_translate_empty(self):
|
||||
tls = affinity.translate(load_wkt("LINESTRING EMPTY"))
|
||||
els = load_wkt("LINESTRING EMPTY")
|
||||
self.assertTrue(tls.equals(els))
|
||||
assert tls.equals(els)
|
||||
Reference in New Issue
Block a user