def convert_token(tag, value): ''' Given a LandXML tag and it's value, return it as the data type specified in KeyMaps ''' if not tag or not value: return None _typ = None for _k, _v in KeyMaps.XML_TYPES.items(): if tag in _v: _typ = _k break if not _typ or _typ == 'string': return value if _typ == 'int': return Utils.to_int(value) if _typ == 'float': return Utils.to_float(value) if _typ == 'vector': coords = Utils.to_float(value.split(' ')) if coords: return App.Vector(coords) return None
def _parse_data(self, align_name, tags, attrib): ''' Build a dictionary keyed to the internal attribute names from the XML ''' result = {} #test to ensure all required tags are in the imrpoted XML data missing_tags = set(tags[0]).difference(set(list(attrib.keys()))) #report error and skip the alignment if required tags are missing if missing_tags: self.errors.append( 'The required XML tags were not found in alignment %s:\n%s' % (align_name, missing_tags)) return None #merge the required / optional tag dictionaries and iterate the items for _tag in tags[0] + tags[1]: attr_val = LandXml.convert_token(_tag, attrib.get(_tag)) if attr_val is None: if _tag in tags[0]: self.errors.append( 'Missing or invalid %s attribute in alignment %s' % (_tag, align_name)) #test for angles and convert to radians elif _tag in maps.XML_TAGS['angle']: attr_val = Utils.to_float(attrib.get(_tag)) if attr_val: attr_val = math.radians(attr_val) #test for lengths to convert to mm elif _tag in maps.XML_TAGS['length']: attr_val = Utils.to_float(attrib.get(_tag)) if attr_val: attr_val = attr_val * Units.scale_factor() #convert rotation from string to number elif _tag == 'rot': attr_val = 0.0 if attrib.get(_tag) == 'cw': attr_val = 1.0 elif attrib.get(_tag) == 'ccw': attr_val = -1.0 if not attr_val: attr_val = LandXml.get_tag_default(_tag) result[maps.XML_MAP[_tag]] = attr_val return result
def get_bearings(arc, mat, delta, rot): ''' Calculate the bearings from the matrix and delta value ''' bearing_in = arc.get('BearingIn') bearing_out = arc.get('BearingOut') bearings = [] for _i in range(0, 6): bearings.append(_GEO.FUNC[6][_i](mat.A[6][_i], delta, rot)) _b = [_v % C.TWO_PI for _v in bearings[0:6] if Utils.to_float(_v)] if _b: #check to ensure all tangent start bearing values are identical if not Support.within_tolerance(_b): return None #default to calculated if different from supplied bearing if not Support.within_tolerance(_b[0], bearing_in): bearing_in = _b[0] if not bearing_in: return None _b_out = bearing_in + (delta * rot) if not Support.within_tolerance(_b_out, bearing_out): bearing_out = _b_out _row = mat.A[6] _rad = [_row[0], _row[1]] _tan = [bearing_in, bearing_out] _int = [_row[4], _row[5]] if not Utils.to_float(_rad[0]): _rad[0] = bearing_in - rot * (C.HALF_PI) if not Utils.to_float(_rad[1]): _rad[1] = _rad[0] + rot * delta if not Utils.to_float(_int[0]): _int[0] = _rad[0] + rot * (delta / 2.0) if not Utils.to_float(_int[1]): _int[1] = _rad[0] + rot * ((math.pi + delta) / 2.0) mat_bearings = {'Radius': _rad, 'Tangent': _tan, 'Internal': _int} return { 'BearingIn': bearing_in, 'BearingOut': bearing_out, 'Bearings': mat_bearings }
def vector_from_angle(angle): ''' Returns a vector form a given angle in radians ''' _angle = Utils.to_float(angle) if not _angle: return None return App.Vector(math.sin(_angle), math.cos(_angle), 0.0)
def build_vector(coords): ''' Returns an App.Vector of the passed coordinates, ensuring they are float-compatible ''' if not coords: return None float_coords = Utils.to_float(coords) if not all(float_coords): return None return App.Vector(float_coords)
def assign_station_data(self): ''' Assign the station and intersection equation data ''' obj = self.Object _eqs = self.geometry['station'] _meta = self.geometry['meta'] _eqn_list = [] _start_sta = Utils.to_float(_meta.get('StartStation')) if _start_sta: _eqn_list.append(App.Vector(0.0, _start_sta, 0.0)) else: self.errors.append('Unable to convert starting station %s' % _meta.get('StartStation')) for _eqn in _eqs: eq_vec = None #default to increasing station if unspecified if not _eqn['Direction']: _eqn['Direction'] = 1.0 try: eq_vec = App.Vector(float(_eqn['Back']), float(_eqn['Ahead']), float(_eqn['Direction'])) except: self.errors.append('Unable to convert station equation (%s)' % (_eqn)) continue _eqn_list.append(eq_vec) obj.Station_Equations = _eqn_list
def get_delta(arc, mat): ''' Get the delta value from the matrix, if possible, Default to the user-provided parameter if no calculated or values within tolerance ''' #get the delta from the arc data as a default delta = arc.get('Delta') if not delta: if arc.get('BearingIn') and arc.get('BearingOut'): delta = abs(arc['BearingOut'] - arc['BearingIn']) #find the first occurence of the delta value for _i in range(1, 6): for _j in range(0, _i): if Utils.to_float(mat.A[_i][_j]): delta = mat.A[_i][_j] break if not delta: return None return {'Delta': delta}