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
Example #2
0
    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
Example #3
0
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
    }
Example #4
0
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
Example #7
0
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}