Пример #1
0
    def stringToEN(cls, arg):
        if not isinstance(arg, str):
            raise OSGridError('Grid reference must be a string')

        log.debug('Parsing {}', arg)
        gridref = arg.strip().upper()

        log.debug('gridref is {}', gridref)
        match = re.match('^(\d+),\s*(\d+)$', gridref)
        if match:
            log.debug('Matched pair of numbers')
            return [int(x) for x in match.groups()]

        match = re.match('^([A-Z]{2})\s*([0-9]+)(\s*)([0-9]+)$', gridref)
        if not match:
            log.error("Couldn't match expected format")
            raise OSGridError('Invalid grid reference')

        g = match.groups()
        alpha = g[0]
        l1 = ord(alpha[0]) - ord('A')
        l2 = ord(alpha[1]) - ord('A')

        if l1 > 7: l1 -= 1
        if l2 > 7: l2 -= 1

        e100km = ((l1 - 2) % 5) * 5 + (l2 % 5)
        n100km = 19 - 5 * (l1 // 5) - l2 // 5
        log.debug("e100k = {}, n100k = {}", e100km, n100km)
        if e100km < 0 or e100km > 6 or n100km < 0 or n100km > 12:
            log.error("e100k = {}, n100k = {} - OOR", e100km, n100km)
            raise OSGridError('Invalid grid reference')

        if len(g[2]) == 0:
            s = g[1] + g[3]
            c = len(s) // 2
            en = [s[:c], s[c:]]
        else:
            en = [g[1], g[3]]

        if len(en[0]) != len(en[1]):
            log.error('e=*{}* n=*{}* - unequal lengths', *en)
            raise OSGridError('Invalid grid reference')

        en = [int((x + '00000')[:5]) for x in en]
        log.debug('EN is {}', en)
        factor = pow(10, 5)
        return [en[0] + e100km * factor, en[1] + n100km * factor]
Пример #2
0
    def coordinatesToString(cls, coords):
        try:
            E = int(coords.E)
            N = int(coords.N)
            e100k = E // 100000
            n100k = N // 100000

            if e100k < 0 or e100k > 6 or n100k < 0 or n100k > 12:
                log.error("e100k = {}, n100k = {} - OOR", e100k, n100k)
                raise OSGridError('Position out of range')

            nf = 19 - n100k
            ef = 10 + e100k

            l1 = nf - (nf % 5) + (ef // 5)
            l2 = (5 * nf) % 25 + (ef % 5)
            l = [l1, l2]
            log.debug("l = {}", l)
            rect = ''.join([GridReference.alphabet[int(x)] for x in l])
            log.debug("l = {}, rect = {}", l, rect)

            e = E % 100000
            n = N % 100000
            log.debug('e = {}, n = {}', e, n)

            return ' '.join([rect, str(e).rjust(5, '0'), str(n).rjust(5, '0')])
        except:
            traceback.print_exc()
            log.debug('{}', traceback.format_exc())
            return ''
Пример #3
0
 def outerProduct(cls, left, right=None, n=3):
     r = right or left
     if len(left) != n or len(r) != n:
         raise OSGridError(
             'Outer product requires two vectors of length {}'.format(n))
     rows = [r * rv for rv in left]
     return Matrix(rows, n)
Пример #4
0
 def axis(cls, axis):
     try:
         axis = axis.upper()
         pos = ['X', 'Y', 'Z'].index(axis)
         args = [0, 0, 0]
         args[pos] = 1
         return Vector3(args)
     except ValueError:
         raise OSGridError('Axis must be X, Y or Z')
Пример #5
0
    def __matmul__(self, other):
        if self.nColumns != other.nRows:
            raise OSGridError(
                'Product requires elements with compatible sizes')

        col = other.columns
        if len(col) == 1:
            c = col[0]
            return Vector([row | c for row in self.rows])
        else:
            return Matrix([[row | c for c in col] for row in self.rows])
Пример #6
0
    def __init__(self, arg):
        if isinstance(arg, Matrix):
            self.rows = [row[:] for row in arg.rows]
        else:
            try:
                check = all([allNumbers(row) for row in arg])
                if not check: raise Exception()
                self.rows = [row[:] for row in arg]
            except:
                raise OSGridError('Constructor requires Matrix or [[numeric]]')

        self.nRows = len(self.rows)
        if self.nRows == 0:
            self.nColumns = 0
        else:
            self.nColumns = len(self.rows[0])
            for row in self.rows:
                if len(row) != self.nColumns:
                    raise OSGridError(
                        "All rows in array must have same length")
Пример #7
0
    def __init__(self, arg):
        if isinstance(arg, Vector):
            self.array = arg.array[:]
        else:
            try:
                if not allNumbers(arg): raise Exception()
                self.array = arg[:]
            except:
                raise OSGridError(
                    'Constructor requires either Vector or [numeric]')

        self.nRows = len(self.array)
        self.nColumns = 1
Пример #8
0
 def __init__(self, arg, tag='WGS84'):
     try:
         self.tag = tag
         self.datum = Datum.get(tag)
         if isinstance(arg, Cartesian):
             self.latitude, self.longitude = arg.toLatLong(
                 self.datum.ellipsoid)
         elif isinstance(arg, str):
             match1 = re.match(
                 r'^\s*([+-]?(?:\d*\.)?\d+)([NnSs])\s*,\s*([+-]?(?:\d*\.)?\d+)([EeWw])\s*$',
                 arg)
             match2 = re.match(
                 r'^\s*([+-]?(?:\d*\.)?\d+)\s*,\s*([+-]?(?:\d*\.)?\d+)\s*$',
                 arg)
             if match1:
                 lat, ns, long, ew = match1.groups()
                 lat = float(lat)
                 long = float(long)
                 if ns.upper() == 'S': lat = -lat
                 if ew.upper() == 'W': long = -long
                 self.latitude, self.longitude = lat, long
             elif match2:
                 self.latitude, self.longitude = [
                     float(x) for x in match2.groups()
                 ]
             else:
                 raise OSGridError('Cannot parse argument {}'.format(arg))
         elif isinstance(arg, list) and areNumbers(arg):
             self.latitude, self.longitude = *arg
         else:
             raise Exception()
     except OSGridError as e:
         raise e
     except:
         raise OSGridError(
             'Arguments to LatLong constructor must be Cartesian or lat,long'
         )
Пример #9
0
    def __init__(self, *args, tag='WGS84'):

        if len(args) == 0:
            raise OSGridError(
                'Initialisation of LatLong requires at least one argument')
        self.tag = tag
        self.datum = Data[tag]
        arg = args[0]
        if isinstance(arg, Cartesian):
            self.latitude, self.longitude = arg.LatLong(self.datum.ellipsoid)
        elif isinstance(arg, str):
            match1 = re.match(
                r'^\s*([+-]?(?:\d*\.)?\d+)([NnSs])\s*,\s*([+-]?(?:\d*\.)?\d+)([EeWw])\s*$',
                arg)
            match2 = re.match(
                r'^\s*([+-]?(?:\d*\.)?\d+)\s*,\s*([+-]?(?:\d*\.)?\d+)\s*$',
                arg)
            if match1:
                lat, ns, long, ew = match1.groups()
                lat = float(lat)
                long = float(long)
                if ns.upper() == 'S': lat = -lat
                if ew.upper() == 'W': long = -long
                self.latitude, self.longitude = lat, long
            elif match2:
                self.latitude, self.longitude = [
                    float(x) for x in match2.groups()
                ]
            else:
                raise OSGridError('Cannot parse argument {}'.format(arg))
        elif len(args) >= 2 and areNumbers(args[:2]):
            self.latitude, self.longitude = args
        else:
            OSGridError(
                'Arguments to LatLong constructor must be Cartesian or lat,long'
            )
Пример #10
0
def singleAxis(axis, angle):
    try:
        axis = axis.upper()
        pos = ['X', 'Y', 'Z'].index(axis)
        i1 = (pos + 1) % 3
        i2 = (pos + 2) % 3
        sgn = 2 * (pos % 2) - 1
        c = cos(angle)
        s = sin(angle) * sgn
        rows = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
        rows[i1][i1] = c
        rows[i1][i2] = s
        rows[i2][i2] = c
        rows[i2][i1] = -s
        return Matrix(rows)
    except ValueError:
        raise OSGridError('Axis must be X, Y or Z')
Пример #11
0
 def __init__(self,arg):
     if isinstance(arg,LatitudeLongitude):
         if arg.tag!='OSGB36' : 
             log.debug("Transforming {} to OSGB36",arg)
             arg=arg.transform('OSGB36')
             log.debug("Transformed value is {}",arg)
         phi=radians(arg.latitude)
         l  =radians(arg.longitude)
     
         log.debug("phi = {}, l = {}",phi,l)
         v=OSDefaultGrid(phi,l)
         parsed = v.latLongToGrid()
     elif isinstance(arg,list) and areNumbers(arg):
         parsed=arg[:2]
     elif isinstance(arg,str):
         parsed=GridReference.stringToEN(arg)
     else:
         raise OSGridError('Arguments to OSGridRef constructor must be string, LatLong or E,N') 
     
     log.debug('out is {}',parsed)
     self.E, self.N = [floor(x) for x in parsed] # [round(x,0) for x in parsed]
     log.debug("E = {}, N = {}",self.E,self.N)
Пример #12
0
 def __add__(self, other):
     if self.size != other.size:
         raise OSGridError('Sum requires elements of same size')
     rows = [x + y for (x, y) in zip(self.rows, other.rows)]
     return Matrix(rows)
Пример #13
0
 def __setitem__(self, key, value):
     if key < 0 or key >= len(self):
         raise OSGridError("Index out of range for vector")
     self.array[key] = value
Пример #14
0
 def __getitem__(self, key):
     if key < 0 or key >= len(self):
         raise OSGridError("Index out of range for vector")
     return self.array[key]
Пример #15
0
    def __init__(self, *args):
        if len(args) == 0:
            raise OSGridError(
                'Initialisation of OSGRidReference requires at least one argument'
            )
        arg = args[0]

        if isinstance(arg, str):
            log.debug('Parsing {}', arg)
            gridref = arg.strip().upper()

            log.debug('gridref is {}', gridref)
            match = re.match('^(\d+),\s*(\d+)$', gridref)
            if match:
                log.debug('Matched pair of numbers')
                return [int(x) for x in match.groups()]

            match = re.match('^([A-Z]{2})\s*([0-9]+)(\s*)([0-9]+)$', gridref)
            if not match:
                log.error("Couldn't match expected format")
                raise OSGridError('Invalid grid reference')

            g = match.groups()
            alpha = g[0]
            l1 = ord(alpha[0]) - ord('A')
            l2 = ord(alpha[1]) - ord('A')

            if l1 > 7: l1 -= 1
            if l2 > 7: l2 -= 1

            e100km = ((l1 - 2) % 5) * 5 + (l2 % 5)
            n100km = 19 - 5 * (l1 // 5) - l2 // 5
            log.debug("e100k = {}, n100k = {}", e100km, n100km)
            if e100km < 0 or e100km > 6 or n100km < 0 or n100km > 12:
                log.error("e100k = {}, n100k = {} - OOR", e100km, n100km)
                raise OSGridError('Invalid grid reference')

            if len(g[2]) == 0:
                s = g[1] + g[3]
                c = len(s) // 2
                en = [s[:c], s[c:]]
            else:
                en = [g[1], g[3]]

            if len(en[0]) != len(en[1]):
                log.error('e=*{}* n=*{}* - unequal lengths', *en)
                raise OSGridError('Invalid grid reference')

            en = [int((x + '00000')[:5]) for x in en]
            log.debug('EN is {}', en)
            factor = pow(10, 5)
            parsed = [en[0] + e100km * factor, en[1] + n100km * factor]

        elif isinstance(arg, LatLong):
            if arg.tag != 'OSGB36':
                log.debug("Transforming {} to OSGB36", arg)
                arg = arg.transform('OSGB36')
                log.debug("Transformed value is {}", arg)
            phi = radians(arg.latitude)
            l = radians(arg.longitude)

            log.debug("phi = {}, l = {}", phi, l)
            v = OSDefaultGrid(phi, l)
            parsed = v.latLongToGrid()

        elif len(args) >= 2 and areNumbers(args[:2]):
            parsed = args[:2]
        else:
            raise OSGridError(
                'Arguments to OSGridRef constructor must be string or LatLong or E,N'
            )

        log.debug('out is {}', parsed)
        self.E, self.N = [floor(x)
                          for x in parsed]  # [round(x,0) for x in parsed]
        log.debug("E = {}, N = {}", self.E, self.N)