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]
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 ''
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)
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')
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])
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")
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
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' )
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' )
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')
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)
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)
def __setitem__(self, key, value): if key < 0 or key >= len(self): raise OSGridError("Index out of range for vector") self.array[key] = value
def __getitem__(self, key): if key < 0 or key >= len(self): raise OSGridError("Index out of range for vector") return self.array[key]
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)