django/contrib/gis/geos/tests/pymutable_geometries.py
author Justin Bronn <jbronn@geodjango.org>
Sat Jan 31 15:18:50 2009 -0600 (3 years ago)
branchtrunk
changeset 138 466bece04a15
child 354 3fcbf6e3e599
permissions -rw-r--r--
Merged in patch from Aryeh Leib Taurog for #9877, adapting as necessary.
jbronn@138
     1
from django.contrib.gis.geos import *
jbronn@138
     2
from random import random
jbronn@138
     3
jbronn@138
     4
SEQ_LENGTH = 10
jbronn@138
     5
SEQ_RANGE = (-1 * SEQ_LENGTH, SEQ_LENGTH)
jbronn@138
     6
SEQ_BOUNDS = (-1 * SEQ_LENGTH, -1, 0, SEQ_LENGTH - 1)
jbronn@138
     7
SEQ_OUT_OF_BOUNDS = (-1 * SEQ_LENGTH -1 , SEQ_LENGTH)
jbronn@138
     8
jbronn@138
     9
def seqrange(): return xrange(*SEQ_RANGE)
jbronn@138
    10
jbronn@138
    11
def random_coord(dim    = 2,           # coordinate dimensions
jbronn@138
    12
                 rng    = (-50,50),    # coordinate range
jbronn@138
    13
                 num_type     = float,
jbronn@138
    14
                 round_coords = True):
jbronn@138
    15
jbronn@138
    16
    if round_coords:
jbronn@138
    17
        num = lambda: num_type(round(random() * (rng[1]-rng[0]) + rng[0]))
jbronn@138
    18
    else:
jbronn@138
    19
        num = lambda: num_type(random() * (rng[1]-rng[0]) + rng[0])
jbronn@138
    20
    
jbronn@138
    21
    return tuple( num() for axis in xrange(dim) )
jbronn@138
    22
jbronn@138
    23
def random_list(length = SEQ_LENGTH, ring = False, **kwargs):
jbronn@138
    24
    result  = [ random_coord(**kwargs) for index in xrange(length) ]
jbronn@138
    25
    if ring:
jbronn@138
    26
        result[-1] = result[0]
jbronn@138
    27
jbronn@138
    28
    return result
jbronn@138
    29
jbronn@138
    30
random_list.single = random_coord
jbronn@138
    31
jbronn@138
    32
def random_coll(count = SEQ_LENGTH, **kwargs):
jbronn@138
    33
    return [ tuple(random_list(**kwargs)) for i in xrange(count) ]
jbronn@138
    34
jbronn@138
    35
random_coll.single = random_list
jbronn@138
    36
jbronn@138
    37
class PyMutTestGeom:
jbronn@138
    38
    "The Test Geometry class container."
jbronn@138
    39
    def __init__(self, geom_type, coords_fcn=random_list, subtype=tuple, **kwargs):
jbronn@138
    40
        self.geom_type  = geom_type
jbronn@138
    41
        self.subtype    = subtype
jbronn@138
    42
        self.coords_fcn = coords_fcn
jbronn@138
    43
        self.fcn_args   = kwargs
jbronn@138
    44
        self.coords = self.coords_fcn(**kwargs)
jbronn@138
    45
        self.geom   = self.make_geom()
jbronn@138
    46
jbronn@138
    47
    def newitem(self, **kwargs):
jbronn@138
    48
        a = self.coords_fcn.single(**kwargs)
jbronn@138
    49
        return self.subtype(a), tuple(a)
jbronn@138
    50
jbronn@138
    51
    @property
jbronn@138
    52
    def tuple_coords(self):
jbronn@138
    53
        return tuple(self.coords)
jbronn@138
    54
jbronn@138
    55
    def make_geom(self):
jbronn@138
    56
        return self.geom_type(map(self.subtype,self.coords))
jbronn@138
    57
jbronn@138
    58
jbronn@138
    59
def slice_geometries(ring=True): 
jbronn@138
    60
    testgeoms = [
jbronn@138
    61
        PyMutTestGeom(LineString),
jbronn@138
    62
        PyMutTestGeom(MultiPoint, subtype=Point),
jbronn@138
    63
        PyMutTestGeom(MultiLineString, coords_fcn=random_coll, subtype=LineString),
jbronn@138
    64
        ]
jbronn@138
    65
    if ring:
jbronn@138
    66
        testgeoms.append(PyMutTestGeom(LinearRing, ring=True))
jbronn@138
    67
jbronn@138
    68
    return testgeoms
jbronn@138
    69
jbronn@138
    70
def getslice_functions(): 
jbronn@138
    71
    def gs_01(x): x[0:4],   
jbronn@138
    72
    def gs_02(x): x[5:-1],  
jbronn@138
    73
    def gs_03(x): x[6:2:-1],
jbronn@138
    74
    def gs_04(x): x[:],     
jbronn@138
    75
    def gs_05(x): x[:3],    
jbronn@138
    76
    def gs_06(x): x[::2],   
jbronn@138
    77
    def gs_07(x): x[::-4],  
jbronn@138
    78
    def gs_08(x): x[7:7],   
jbronn@138
    79
    def gs_09(x): x[20:],   
jbronn@138
    80
jbronn@138
    81
    # don't really care about ringy-ness here
jbronn@138
    82
    return mark_ring(vars(), 'gs_')
jbronn@138
    83
jbronn@138
    84
def delslice_functions():
jbronn@138
    85
    def ds_01(x): del x[0:4]   
jbronn@138
    86
    def ds_02(x): del x[5:-1]  
jbronn@138
    87
    def ds_03(x): del x[6:2:-1]
jbronn@138
    88
    def ds_04(x): del x[:]     # should this be allowed?
jbronn@138
    89
    def ds_05(x): del x[:3]    
jbronn@138
    90
    def ds_06(x): del x[1:9:2]   
jbronn@138
    91
    def ds_07(x): del x[::-4]  
jbronn@138
    92
    def ds_08(x): del x[7:7]   
jbronn@138
    93
    def ds_09(x): del x[-7:-2]
jbronn@138
    94
jbronn@138
    95
    return mark_ring(vars(), 'ds_')
jbronn@138
    96
jbronn@138
    97
def setslice_extended_functions(g):
jbronn@138
    98
    a = g.coords_fcn(3, rng=(100,150))
jbronn@138
    99
    def maptype(x,a):
jbronn@138
   100
        if isinstance(x, list): return a
jbronn@138
   101
        else: return map(g.subtype, a)
jbronn@138
   102
jbronn@138
   103
    def sse_00(x): x[:3:1]      = maptype(x, a)
jbronn@138
   104
    def sse_01(x): x[0:3:1]     = maptype(x, a)
jbronn@138
   105
    def sse_02(x): x[2:5:1]     = maptype(x, a)
jbronn@138
   106
    def sse_03(x): x[-3::1]     = maptype(x, a)
jbronn@138
   107
    def sse_04(x): x[-4:-1:1]   = maptype(x, a)
jbronn@138
   108
    def sse_05(x): x[8:5:-1]    = maptype(x, a)
jbronn@138
   109
    def sse_06(x): x[-6:-9:-1]  = maptype(x, a)
jbronn@138
   110
    def sse_07(x): x[:8:3]      = maptype(x, a)
jbronn@138
   111
    def sse_08(x): x[1::3]      = maptype(x, a)
jbronn@138
   112
    def sse_09(x): x[-2::-3]    = maptype(x, a)
jbronn@138
   113
    def sse_10(x): x[7:1:-2]    = maptype(x, a)
jbronn@138
   114
    def sse_11(x): x[2:8:2]     = maptype(x, a)
jbronn@138
   115
jbronn@138
   116
    return mark_ring(vars(), 'sse_')
jbronn@138
   117
jbronn@138
   118
def setslice_simple_functions(g):
jbronn@138
   119
    a = g.coords_fcn(3, rng=(100,150))
jbronn@138
   120
    def maptype(x,a):
jbronn@138
   121
        if isinstance(x, list): return a
jbronn@138
   122
        else: return map(g.subtype, a)
jbronn@138
   123
jbronn@138
   124
    def ss_00(x): x[:0]  = maptype(x, a)
jbronn@138
   125
    def ss_01(x): x[:1]  = maptype(x, a)
jbronn@138
   126
    def ss_02(x): x[:2]  = maptype(x, a)
jbronn@138
   127
    def ss_03(x): x[:3]  = maptype(x, a)
jbronn@138
   128
    def ss_04(x): x[-4:] = maptype(x, a)
jbronn@138
   129
    def ss_05(x): x[-3:] = maptype(x, a)
jbronn@138
   130
    def ss_06(x): x[-2:] = maptype(x, a)
jbronn@138
   131
    def ss_07(x): x[-1:] = maptype(x, a)
jbronn@138
   132
    def ss_08(x): x[5:]  = maptype(x, a)
jbronn@138
   133
    def ss_09(x): x[:]   = maptype(x, a)
jbronn@138
   134
    def ss_10(x): x[4:4] = maptype(x, a)
jbronn@138
   135
    def ss_11(x): x[4:5] = maptype(x, a)
jbronn@138
   136
    def ss_12(x): x[4:7] = maptype(x, a)
jbronn@138
   137
    def ss_13(x): x[4:8] = maptype(x, a)
jbronn@138
   138
    def ss_14(x): x[10:] = maptype(x, a)
jbronn@138
   139
    def ss_15(x): x[20:30]  = maptype(x, a)
jbronn@138
   140
    def ss_16(x): x[-13:-8] = maptype(x, a)
jbronn@138
   141
    def ss_17(x): x[-13:-9] = maptype(x, a)
jbronn@138
   142
    def ss_18(x): x[-13:-10] = maptype(x, a)
jbronn@138
   143
    def ss_19(x): x[-13:-11] = maptype(x, a)
jbronn@138
   144
jbronn@138
   145
    return mark_ring(vars(), 'ss_')
jbronn@138
   146
jbronn@138
   147
def test_geos_functions():
jbronn@138
   148
jbronn@138
   149
    return (
jbronn@138
   150
        lambda x: x.num_coords,
jbronn@138
   151
        lambda x: x.empty,
jbronn@138
   152
        lambda x: x.valid,
jbronn@138
   153
        lambda x: x.simple,
jbronn@138
   154
        lambda x: x.ring,
jbronn@138
   155
        lambda x: x.boundary,
jbronn@138
   156
        lambda x: x.convex_hull,
jbronn@138
   157
        lambda x: x.extend,
jbronn@138
   158
        lambda x: x.area,
jbronn@138
   159
        lambda x: x.length,
jbronn@138
   160
            )
jbronn@138
   161
jbronn@138
   162
def mark_ring(locals, name_pat, length=SEQ_LENGTH):
jbronn@138
   163
    '''
jbronn@138
   164
    Accepts an array of functions which perform slice modifications
jbronn@138
   165
    and labels each function as to whether or not it preserves ring-ness
jbronn@138
   166
    '''
jbronn@138
   167
    func_array = [ val for name, val in locals.items()
jbronn@138
   168
                    if hasattr(val, '__call__')
jbronn@138
   169
                    and name.startswith(name_pat) ]
jbronn@138
   170
jbronn@138
   171
    for i in xrange(len(func_array)):
jbronn@138
   172
        a = range(length)
jbronn@138
   173
        a[-1] = a[0]
jbronn@138
   174
        func_array[i](a)
jbronn@138
   175
        ring = len(a) == 0 or (len(a) > 3 and a[-1] == a[0])
jbronn@138
   176
        func_array[i].ring = ring
jbronn@138
   177
jbronn@138
   178
    return func_array
jbronn@138
   179
jbronn@138
   180
def getcoords(o):
jbronn@138
   181
    if hasattr(o, 'coords'):
jbronn@138
   182
        return o.coords
jbronn@138
   183
    else:
jbronn@138
   184
        return o