How to use _findAll method in pyatom

Best Python code snippet using pyatom_python

vissim_v5.py

Source:vissim_v5.py Github

copy

Full Screen

1#!/usr/bin/env python2""" VISSIM Tools v2.0 """3from re import findall as _findall, match as _match, search as _search4from re import split as _split5from math import sqrt as _sqrt6from copy import copy as _copy789def _median(lst):10 """ Stock median function from: http://stackoverflow.11 com/questions/24101524/finding-median-of-list-in-python12 """13 lst = sorted(lst)14 if len(lst) < 1:15 return None16 if len(lst) % 2 == 1:17 return lst[((len(lst) + 1) / 2) - 1]18 else:19 return float(sum(lst[(len(lst) / 2) - 1:(len(lst) / 2) + 1])) / 2.0202122def _flatten(coll):23 """ Flatten list and convert elements to int24 """25 if isinstance(coll, list):26 return [int(a) for i in coll for a in _flatten(i)]27 else:28 return [coll]293031def _importSection(obj, filename):32 """ Imports section's syntax into dictionary.33 """34 name = obj.name35 try:36 with open(filename, 'r') as data:37 section = None38 for row in data:39 found = _findall(r'(?<=\- )(.*?)(?=\: -)', row)40 if row in ['\n', '\r\n']:41 continue42 elif found:43 section = found[0]44 elif section == name and row[0] != '-':45 obj._readSection(row)46 else:47 continue48 except IOError:49 print ('cannot open', filename)505152def _updateFile(orgFile, newFile, name, printData):53 """ Update a section of a VISSIM .INP file.54 Inputs: filename, object type(Inputs, Routing Decision, etc.) and list55 of strings with VISSIM syntax.56 Outputs: new file57 """58 search = '-- ' + name + ': --'59 f = open(orgFile, 'r')60 lines = f.readlines()61 f.close()62 f = open(newFile, 'w')63 startDelete = False64 print ('Writing %s to %s ...' % (name, newFile))65 for line in lines:66 if startDelete is True and line[:3] == '-- ':67 startDelete = False68 f.write('\n\n\n')69 if line[:len(search)] == search:70 startDelete = True71 for newLine in printData:72 f.write(str(newLine) + '\n')73 if startDelete is False:74 f.write(line)75 f.close()767778def _exportSection(obj, filename):79 """ Prepare for export all dictionaries within a given object8081 Input: Dict object82 Output: List of all items for a given class in VISSIM syntax83 """84 first_line = '-- ' + obj.name + ': --\n'85 second_line = '-' * (len(first_line) - 1) + '\n'86 print_data = [first_line + second_line]87 print ('Reading %s ...' % obj.name)88 for value in obj.data.values():89 print_data += obj._output(value)90 print ('Updating %s ...' % obj.name)91 _updateFile(obj.filename, filename, obj.name, print_data)929394def _checkKeyData(obj, key, label):95 """ Checks whether key and label exist96 """97 if key is not None:98 if key not in obj.data:99 raise KeyError('%s not a valid key for object %s' %100 (key, obj.name))101 if label not in obj.types:102 raise KeyError('%s not a valid label for object %s' %103 (label, obj.name))104 return True105106107def _getData(obj, key, label):108 """ Returns requested value from vissim object109 """110 _checkKeyData(obj, key, label)111 if key is None:112 new = obj.data[label]113 else:114 new = obj.data[key][label]115 return _copy(new)116117118def _setData(obj, key, label, value):119 """ Sets given value in vissim object120 """121 _checkKeyData(obj, key, label)122 if not isinstance(value, obj.types[label]):123 value = obj.types[label](value)124 if key is None:125 obj.data[label] = value126 else:127 obj.data[key][label] = value128129130def _updateData(obj, key, label, value, pos=None, newKey=None):131 """ Updates vissim object132 Input: object, key, label and value133 Output: adds value to object.134 """135 _checkKeyData(obj, key, label)136 if key is None:137 if (isinstance(obj.data[label], list) is True) and (pos is None):138 obj.data[label].append(value)139 obj.data[label] = list(_flatten(obj.data[label]))140 elif isinstance(obj.data[label], list) and pos:141 obj.data[label].insert(pos, value)142 obj.data[label] = list(_flatten(obj.data[label]))143 else:144 if isinstance(obj.data[key][label], dict):145 obj.data[key][label][newKey] = value146 if (isinstance(obj.data[key][label], list) is True) and (pos is None):147 obj.data[label].append(value)148 obj.data[label] = list(_flatten(obj.data[label]))149 elif isinstance(obj.data[key][label], list) and pos:150 obj.data[label].insert(pos, value)151 obj.data[label] = list(_flatten(obj.data[label]))152153154def _convertType(iterable, newType):155 """ Converts element type within iterable.156 """157 iterType = type(iterable)158 return iterType([newType(i) for i in iterable])159160161class Inputs:162 """ Handles Inputs section of .INP file.163 """164 def __init__(self, filename):165 self.filename = filename166 self.name = 'Inputs'167 self.data = {}168 self.currData = None169 self.types = {'composition': int, 'exact': bool, 'from': float,170 'input': int, 'label': tuple, 'link': int, 'name': str,171 'q': float, 'until': float}172 _importSection(self, filename)173174 def get(self, inputNum, label, string=True):175 """ Get value from Input.176 Input: Input number, Value label177 Output: Value178 """179 if string:180 return str(_getData(self, inputNum, label))181 else:182 return _getData(self, inputNum, label)183184 def set(self, inputNum, label, value):185 """ Set value from Input.186 Input: Input number, Value label, value187 Output: Change is made in place188 """189 _setData(self, inputNum, label, value)190191 def getInputNumByLink(self, linkNum):192 """ Get value from Input by link number193 Input: Link number194 Output: List of input numbers195 """196 result = [k for k, v in self.data.items() if v['link'] == linkNum]197 if len(result) == 0:198 raise KeyError('%s not in data' % (linkNum))199 else:200 return result201202 def create(self, linkNum, demand, comp, **kwargs):203 """ Create new Input204 Input: link number, demand, vehicle composition205 Output: Creates Input object206 """207 if self.data.keys():208 num = max(self.data.keys()) + 1209 else:210 num = 1211 inputNum = kwargs.get('input', num)212 self.data[inputNum] = {}213 self.set(inputNum, 'input', inputNum)214 self.set(inputNum, 'q', demand)215 self.set(inputNum, 'link', linkNum)216 self.set(inputNum, 'composition', comp)217 # Default values218 self.set(inputNum, 'name', kwargs.get('name', '""'))219 self.set(inputNum, 'label', kwargs.get('label', ('0.00', '0.00')))220 self.set(inputNum, 'from', kwargs.get('from', '0.0'))221 self.set(inputNum, 'until', kwargs.get('until', '3600.0'))222 self.set(inputNum, 'exact', kwargs.get('exact', False))223224 def _readSection(self, line):225 """ Process the Input section of the INP file.226 """227 if _match('^INPUT\s+\d+', line):228 inputNum = self.types['input'](_findall('INPUT\s+(\d+)', line)[0])229 self.currData = {'input': inputNum}230 elif _match('^\s+NAME', line):231 self.currData['name'] = _findall('NAME\s+(".+"|"")', line)[0]232 self.currData['label'] = _findall('LABEL\s+(-?\d+.\d+)\s(-?\d+.\d+)', line)[0]233 elif _match('^\s+LINK', line):234 self.currData['link'] = _findall('LINK\s+(\d+)', line)[0]235 if _search('EXACT', line):236 self.currData['exact'] = True237 self.currData['q'] = _findall('Q EXACT (.+) COMPOSITION',238 line)[0]239 else:240 self.currData['exact'] = False241 self.currData['q'] = _findall('Q (.+) COMPOSITION', line)[0]242 self.currData['composition'] = _findall('COMPOSITION (\d)',243 line)[0]244 elif _match('^\s+TIME', line):245 self.currData['from'] = _findall('FROM (\d+.\d+)', line)[0]246 self.currData['until'] = _findall('UNTIL (\d+.\d+)', line)[0]247 # Last line, create Input object248 self.create(self.currData['link'], self.currData['q'],249 self.currData['composition'], **self.currData)250 else:251 print ('Non-Input data provided: %s' % line)252253 def _output(self, inputs):254 """ Outputs Inputs syntax to VISSIM.255256 Input: A single Inputs dictionary257 Output: Inputs back into VISSIM syntax258 """259 vissimOut = []260 inputNum = inputs['input']261262 def _out(label, s=True):263 return self.get(inputNum, label, string=s)264 vissimOut.append('INPUT ' + _out('input').rjust(6))265 vissimOut.append('NAME '.rjust(10) + _out('name') + ' LABEL ' +266 _out('label', s=False)[0] + ' ' +267 _out('label', s=False)[1])268 if _out('exact', s=False) is True:269 vissimOut.append('LINK '.rjust(10) + _out('link') + ' Q EXACT ' +270 _out('q') + ' COMPOSITION ' +271 _out('composition'))272 else:273 vissimOut.append('LINK '.rjust(10) + _out('link') + ' Q ' +274 _out('q') + ' COMPOSITION ' + _out('composition'))275 vissimOut.append('TIME FROM '.rjust(15) + _out('from') + ' UNTIL ' +276 _out('until'))277 return vissimOut278279 def export(self, filename):280 """ Prepare for export all inputs in a given inputs object281282 Input: Inputs object283 Output: List of all inputs in VISSIM syntax284 """285 _exportSection(self, filename)286287288class Links:289 """ Handles Links section of .INP file.290 """291 def __init__(self, filename):292 self.filename = filename293 self.name = 'Links'294 self.data = {}295 self.over = None296 self.currData = None297 self.closed = None298 self.types = {'link': int, 'name': str, 'label': tuple,299 'behaviortype': int, 'displaytype': int, 'length': float,300 'lanes': int, 'lane_width': list, 'gradient': float,301 'cost': float, 'surcharges': list,302 'segment_length': float, 'evaluation': bool,303 'from': list, 'over': list, 'to': list, 'closed': dict}304 _importSection(self, filename)305306 def get(self, linkNum, label, string=True):307 """ Get value from Link.308 Input: Link number, Value label309 Output: Value310 """311 if string:312 return str(_getData(self, linkNum, label))313 else:314 return _getData(self, linkNum, label)315316 def set(self, linkNum, label, value):317 """ Set value from Link.318 Input: Link number, Value label, value319 Output: Change is made in place320 """321 _setData(self, linkNum, label, value)322323 def create(self, coordFrom, coordTo, **kwargs):324 if self.data.keys():325 num = max(self.data.keys()) + 1326 else:327 num = 1328 linkNum = kwargs.get('link', num)329 self.data[linkNum] = {}330 self.set(linkNum, 'link', linkNum)331 self.set(linkNum, 'from', coordFrom)332 self.set(linkNum, 'to', coordTo)333 # Default values334 self.set(linkNum, 'name', kwargs.get('name', '""'))335 self.set(linkNum, 'behaviortype', kwargs.get('behaviortype', 1))336 self.set(linkNum, 'cost', kwargs.get('cost', 0.00000))337 self.set(linkNum, 'displaytype', kwargs.get('displaytype', 1))338 self.set(linkNum, 'gradient', kwargs.get('gradient', 0.00000))339 self.set(linkNum, 'label', kwargs.get('label', ('0.00', '0.00')))340 self.set(linkNum, 'lane_width', kwargs.get('lane_width', [3.66]))341 self.set(linkNum, 'lanes', kwargs.get('lanes', 1))342 self.set(linkNum, 'segment_length', kwargs.get('segment_length',343 10.000))344 self.set(linkNum, 'surcharges', kwargs.get('surcharges',345 [0.00000, 0.00000]))346 self.set(linkNum, 'evaluation', kwargs.get('evaluation', False))347 self.set(linkNum, 'over', kwargs.get('over', []))348 self.set(linkNum, 'length', kwargs.get('length', 0))349 if self.get(linkNum, 'over') and self.get(linkNum, 'length') == 0:350 x1, y1 = self.get(linkNum, 'from')351 z1 = 0352 length = 0353 for coord in self.get(linkNum, 'over'):354 x2, y2, z2 = _convertType(coord, float)355 dx, dy, dz = x2 - x1, y2 - y1, z2 - z1356 length += _sqrt(dx**2 + dy**2 + dz**2)357 x1, y1, z1 = x2, y2, z2358 self.set(linkNum, 'length', round(length, 3))359 elif self.get(linkNum, 'length') == 0:360 length = round(_sqrt((self.get(linkNum, 'to')[0] -361 self.get(linkNum, 'from')[0])**2 +362 (self.get(linkNum, 'to'[1] - self.get(linkNum,363 'from')[1])**2), 3))364 self.set(linkNum, 'length', length)365366 def _readSection(self, line):367 if _match('^LINK', line):368 linkNum = (self.types['link'](_findall('LINK\s+(\d+)', line)[0]))369 self.currData = {'link': linkNum}370 self.currData['name'] = _findall('NAME\s+(".+"|"")', line)[0]371 self.currData['label'] = (_findall(372 'LABEL\s+(-?\d+.\d+)\s(-?\d+.\d+)',373 line)[0])374 elif _match('^\s+BEHAVIORTYPE', line):375 self.currData['behaviortype'] = _findall('BEHAVIORTYPE\s+(\d+)',376 line)[0]377 self.currData['displaytype'] = _findall('DISPLAYTYPE\s+(\d+)',378 line)[0]379 elif _match('^\s+LENGTH', line):380 self.currData['length'] = _findall('LENGTH\s+(\d+.\d+)', line)[0]381 self.currData['lanes'] = _findall('LANES\s+(\d)', line)[0]382 width = _findall('LANE_WIDTH\s+(.+)\s+GRADIENT', line)[0]383 self.currData['lane_width'] = _split('\s+', width)384 self.currData['gradient'] = _findall('GRADIENT\s+(-?\d+.\d+)',385 line)[0]386 self.currData['cost'] = _findall('COST\s+(\d+.\d+)', line)[0]387 self.currData['surcharges'] = _findall('SURCHARGE\s+(\d+.\d+)',388 line)389 self.currData['segment_length'] = (_findall(390 'SEGMENT LENGTH\s+(\d+.\d+)',391 line)[0])392 if _search('EVALUATION', line):393 self.currData['evaluation'] = True394 else:395 self.currData['evaluation'] = False396 elif _match('^\s+FROM', line):397 self.currData['from'] = _findall('(-?\d+.\d+)', line)398 elif _match('^\s+OVER', line):399 if 'over' not in self.currData:400 self.currData['over'] = []401 self.currData['over'] += _findall('OVER (-?\d+.\d+) (-?\d+.\d+) (-?\d+.\d+)', line)402 elif _match('^\s+TO', line):403 self.currData['to'] = _findall('(-?\d+.\d+)', line)404 self.create(self.currData['from'], self.currData['to'], **self.currData)405 elif _match('^\s+CLOSED', line):406 self.currData['closed'] = {}407 elif 'closed' in self.currData and _match('^LANE', line):408 lane = _findall('^LANE\s+(\d+)', line)409 veh_classes = _findall('VEHICLE_CLASSES (.+)', line)410 self.currData['closed'][lane] = _split('\s', veh_classes)411 self.set(self.currData['link'], 'closed', self.currData['closed'])412 else:413 print ('Non-link data provided: %s' % line)414415 def _output(self, links):416 """ Outputs Links syntax to VISSIM.417418 Input: A single links dictionary419 Output: Route decisions back into VISSIM syntax420 """421 vissimOut = []422 linkNum = links['link']423424 def _out(label, s=True):425 a = self.get(linkNum, label, string=s)426 return str(a)427428 vissimOut.append('LINK ' + _out('link').rjust(6) + ' NAME ' +429 _out('name') + ' LABEL ' +430 _out('label', s=False)[0] + ' ' +431 _out('label', s=False)[1])432 vissimOut.append('BEHAVIORTYPE '.rjust(15) + _out('behaviortype').433 rjust(5) + ' DISPLAYTYPE' + _out('displaytype').434 rjust(5))435 laneWidth = ''436 if len(_out('lane_width', s=False)) > 1:437 for width in _out('lane_width', s=False):438 laneWidth += width.rjust(5)439 else:440 laneWidth = _out('lane_width', s=False)[0].rjust(5)441 evaluation = 'EVALUATION' if _out('evaluation', s=False) else ''442 vissimOut.append('LENGTH '.rjust(9) + _out('length').rjust(8) +443 ' LANES ' + _out('lanes').rjust(2) +444 ' LANE_WIDTH ' + laneWidth + ' GRADIENT ' +445 _out('gradient').ljust(10) + ' COST ' +446 _out('cost').ljust(7) + ' SURCHARGE ' +447 _out('surcharges', s=False)[0] + ' SURCHARGE ' +448 _out('surcharges', s=False)[1] + ' SEGMENT LENGTH ' +449 _out('segment_length').rjust(8) +450 evaluation)451 vissimOut.append('FROM '.rjust(7) + _out('from', s=False)[0] + ' ' +452 _out('from', s=False)[1])453454 print (vissimOut)455 print(_out('from', s=False))456 print (_out('over', s=False))457 print(_out('to', s=False))458459 if _out('over', s=False):460 overStr = ''461462 for no, i in enumerate(_out('over', s=False)):463 print (str(no) + ": " + str(i))464 # overStr += ' OVER ' + i[0] + ' ' + i[1] + ' ' + i[2]465 if no == 30:466 raise ("Stop here!")467 vissimOut.append(overStr)468 vissimOut.append('TO '.rjust(5) + _out('to', s=False)[0].rjust(10) +469 ' ' + _out('to', s=False)[1])470 return vissimOut471472 def export(self, filename):473 """ Prepare for export all links in a given links object474475 Input: Links object476 Output: List of all links in VISSIM syntax477 """478 _exportSection(self, filename)479480481class Connector:482 """ Handles Connector section of .INP file.483 """484 def __init__(self, filename):485 self.filename = filename486 self.name = 'Connectors'487 self.data = {}488 self.currData = None489 self.curr_lane = None490 self.types = {'connector': int, 'name': str, 'label': tuple,491 'from': int, 'from_lanes': list, 'from_at': float,492 'over': list, 'to': int, 'to_lanes': list,493 'to_at': float, 'behavior_type': int,494 'display_type': int, 'dx_emerg_stop': float,495 'dx_lane_change': float, 'gradient': float,496 'cost': float, 'surcharges': list,497 'segment_length': float, 'animation': bool,498 'nolanechange': dict}499 _importSection(self, filename)500 self.links = Links(self.filename)501502 def get(self, connNum, label, string=True):503 """ Get value from Connector.504 Input: Connector number, Value label505 Output: Value506 """507 if string:508 return str(_getData(self, connNum, label))509 else:510 return _getData(self, connNum, label)511512 def set(self, connNum, label, value):513 """ Set value from Connector.514 Input: Connector number, Value label, value515 Output: Change is made in place516 """517 _setData(self.data, connNum, label, value)518519 def create(self, fromLink, toLink, **kwargs):520 if self.data.keys():521 num = max(self.data.keys()) + 1522 else:523 num = 1524 connNum = kwargs.get('connector', num)525 self.data[connNum] = {}526 connector = self.data[connNum]527 self.set(connNum, 'connector', connNum)528 self.set(connNum, 'from', fromLink)529 self.set(connNum, 'to', toLink)530 # Default values531 self.set(connNum, 'label', kwargs.get('label', ('0.00', '0.00')))532 self.set(connNum, 'from_lanes', kwargs.get('from_lanes', 1))533 self.set(connNum, 'from_at', kwargs.get('from_at',534 self.links.get(fromLink, 'length')))535 # Calculate default spline points between from link and to link:536 over1 = self.links.get(fromLink, 'to').append('0.000')537 over4 = self.links.get(toLink, 'from').append('0.000')538 if over4[0] == over1[0] and over4[1] == over1[1]:539 over1[1] = over1[1] + 0.001540 over2 = [over4[0] + 0.001, over4[1], over4[2]]541 over3 = [_median([over2[0], over4[0]]), _median([over2[1],542 over4[1]]), _median([over2[2], over4[2]])]543 else:544 over2 = [_median([over4[0], over1[0]]), _median([over4[1],545 over1[1]]), _median([over4[2], over1[2]])]546 over3 = [_median([over2[0], over4[0]]), _median([over2[1],547 over4[1]]), _median([over2[2], over4[2]])]548 self.set(connNum, 'over', kwargs.get('over',549 [over1, over2, over3, over4]))550 self.set(connNum, 'name', kwargs.get('name', '""'))551 self.set(connNum, 'to_lanes', kwargs.get('to_lanes', ['1']))552 self.set(connNum, 'to_at', kwargs.get('to_at', '0.000'))553 self.set(connNum, 'behaviortype', kwargs.get('behaviortype', 1))554 self.set(connNum, 'displaytype', kwargs.get('displaytype', 1))555 self.set(connNum, 'dx_emerg_stop', kwargs.get('dx_emerg_stop', 4.999))556 self.set(connNum, 'dx_lane_change', kwargs.get('dx_lane_change',557 200.010))558 self.set(connNum, 'gradient', kwargs.get('gradient', 0.00000))559 self.set(connNum, 'cost', kwargs.get('cost', 0.00000))560 self.set(connNum, 'surcharges', kwargs.get('surcharges',561 ['0.00000', '0.00000']))562 self.set(connNum, 'segment_length', kwargs.get('segment_length',563 10.000))564 self.set(connNum, 'animation', kwargs.get('animation', True))565 self.set(connNum, 'nolanechange', kwargs.get('nolanechange', None))566567 def _readSection(self, line):568 if _match('^CONNECTOR', line):569 # Connector number is dictionary key570 conn = _findall('^CONNECTOR\s+(\d+)', line)[0]571 self.data[conn] = {}572 self.currData = self.data[conn]573 self.currData['connector'] = conn574 self.currData['name'] = _findall('NAME\s+(".+"|"")', line)[0]575 self.currData['label'] = _findall('LABEL\s+(-?\d+.\d+)\s(-?\d+.\d+)', line)[0]576 elif _match('^\s+FROM', line):577 self.currData['from'] = _findall('LINK\s+(\d+)', line)[0]578 lanes = _findall('LANES\s(.+)\sAT', line)[0]579 self.currData['from_lanes'] = _split('\s+', lanes)580 self.currData['from_at'] = _findall('AT\s+(\d+.\d+)', line)[0]581 elif _match('^\s+OVER', line):582 if 'over' not in self.currData:583 self.currData['over'] = []584 self.currData['over'] += _findall('OVER (-?\d+.\d+) (-?\d+.\d+) (-?\d+.\d+)', line)585 elif _match('^\s+TO', line):586 self.currData['to'] = _findall('LINK\s+(\d+)', line)[0]587 lanes = _findall('LANES\s(.+)\sAT', line)[0]588 self.currData['to_lanes'] = _split('\s+', lanes)589 self.currData['to_at'] = _findall('AT\s+(\d+.\d+)', line)[0]590 self.currData['behaviortype'] = _findall('BEHAVIORTYPE\s+(\d+)',591 line)[0]592 self.currData['displaytype'] = _findall('DISPLAYTYPE\s+(\d+)',593 line)[0]594 elif _match('^\s+DX_EMERG_STOP', line):595 self.currData['dx_emerg_stop'] = _findall('DX_EMERG_STOP\s+(\d+.\d+)', line)[0]596 self.currData['dx_lane_change'] = _findall('DX_LANE_CHANGE\s+(\d+.\d+)', line)[0]597 elif _match('^\s+GRADIENT', line):598 self.currData['gradient'] = _findall('GRADIENT\s+(-?\d+.\d+)',599 line)[0]600 self.currData['cost'] = _findall('COST\s+(\d+.\d+)', line)[0]601 self.currData['surcharges'] = _findall('SURCHARGE\s+(\d+.\d+)',602 line)603 elif _match('^\s+SEGMENT', line):604 self.currData['segment_length'] = _findall('LENGTH\s+(\d+.\d+)',605 line)[0]606 if _search('NONE ANIMATION', line):607 self.currData['animation'] = False608 else:609 self.currData['animation'] = True610 elif _search('NOLANECHANGE', line):611 self.currData['nolanechange'] = {}612 lanes = _findall('LANE\s+(\d+) (\w+) (\w+)', line)613 for lane, o, d in lanes:614 self.currData['nolanechange'][lane] = {'from': o, 'to': d}615 else:616 print ('Non-connector data provided: %s' % line)617618 def _output(self, connector):619 """ Outputs connector syntax to VISSIM.620621 Input: A single connector dictionary622 Output: connector back into VISSIM syntax623 """624 vissimOut = []625 connNum = connector['connector']626627 def _out(label, s=True):628 return self.get(connNum, label, string=s)629 vissimOut.append('CONNECTOR ' + _out('connector') +630 ' NAME ' + _out('name') + ' LABEL ' +631 _out('label')[0] + ' ' + _out('label')[1])632 fromLanesStr = ''633 for i in _out('from_lanes', s=False):634 fromLanesStr += i + ' '635 vissimOut.append('FROM LINK '.rjust(12) + _out('from') +636 ' LANES ' + fromLanesStr + 'AT ' + _out('from_at'))637 overStr = ''638 for i in _out('over', s=False):639 overStr += ' OVER ' + i[0] + ' ' + i[1] + ' ' + i[2]640 vissimOut.append(overStr)641 toLanesStr = ''642 for i in _out('to_lanes'):643 toLanesStr += i + ' '644 vissimOut.append('TO LINK '.rjust(10) + _out('to') +645 ' LANES '.rjust(7) + toLanesStr + 'AT ' +646 _out('to_at').ljust(6) + ' BEHAVIORTYPE ' +647 _out('behaviortype') + ' DISPLAYTYPE ' +648 _out('displaytype') + ' ALL')649 vissimOut.append('DX_EMERG_STOP '.rjust(16) + _out('dx_emerg_stop') +650 ' DX_LANE_CHANGE ' + _out('dx_lane_change'))651 vissimOut.append('GRADIENT '.rjust(11) + _out('gradient') +652 ' COST ' + _out('cost') + ' SURCHARGE ' +653 _out('surcharges')[0] + ' SURCHARGE ' +654 _out('surcharges')[1])655 if connector['animation'] is False:656 vissimOut.append('SEGMENT LENGTH '.rjust(17) +657 _out('segment_length') + ' NONE ANIMATION')658 else:659 vissimOut.append('SEGMENT LENGTH '.rjust(17) +660 _out('segment_length') + ' ANIMATION')661 return vissimOut662663 def export(self, filename):664 """ Prepare for export all connector lots in a given connector object665666 Input: connector object667 Output: List of all connector lots in VISSIM syntax668 """669 _exportSection(self, filename)670671672class Parking:673 """ Handles Parking section of .INP file.674 """675 def __init__(self, filename):676 self.filename = filename677 self.name = 'Parking Lots'678 self.data = {}679 self.currData = None680 _importSection(self, filename)681682 def create(self, linksobj, link, length, at, lane, **kwargs):683 parking_num = int(kwargs.get('num', max(self.data.keys())+1))684 self.data[parking_num] = {}685 parking = self.data[parking_num]686 parking['parking'] = parking_num687 parking['lane'] = lane688 parking['at'] = at689 parking['position_link'] = link690 parking['length'] = length691 # Default values692 parking['name'] = kwargs.get('name', '""')693 parking['label'] = kwargs.get('label', ['0.000', '0.000'])694 parking['spaces_length'] = kwargs.get('spaces_length', '6.000')695 parking['zones'] = kwargs.get('zones', '""')696 parking['fraction'] = kwargs.get('fraction', '1.000')697 parking['capacity'] = kwargs.get('capacity', '100')698 parking['occupancy'] = kwargs.get('occupancy', '0')699 parking['desired_speed'] = kwargs.get('desired_speed', '999')700 parking['open_hours'] = kwargs.get('open_hours', ('0', '99999'))701 parking['max_time'] = kwargs.get('max_time', '99999')702 parking['flat_fee'] = kwargs.get('flat_fee', '0.0')703 parking['fee_per_hour'] = kwargs.get('fee_per_hour', '0.0')704 parking['attraction'] = kwargs.get('attraction', '0.0 0.0')705 parking['composition'] = kwargs.get('composition', '1')706707 def _readSection(self, line):708 if _match('^\s+PARKING_LOT', line):709 # Parking lot number is dictionary key710 parking = _findall('PARKING_LOT\s+(\d+)')[0]711 self.data[parking] = {}712 self.currData = self.data[parking]713 self.currData['parking'] = parking714 self.currData['name'] = _findall('NAME\s+(".+"|"")', line)[0]715 self.currData['label'] = _findall('LABEL\s+(-?\d+.\d+)\s(-?\d+.\d+)', line)[0]716 elif _match('^\s+PARKING_SPACES', line):717 self.currData['spaces_length'] = _findall('LENGTH\s+(\d+.\d+)', line)[0]718 elif _match('^\s+ZONES', line):719 self.currData['zones'] = _findall('ZONES\s+(\d+)', line)[0]720 self.currData['fraction'] = _findall('FRACTION\s+(\d+.\d+), line')[0]721 elif _match('^\s+POSITION', line):722 self.currData['position_link'] = _findall('POSITION LINK\s+(\d+)', line)[0]723 self.currData['at'] = _findall('AT\s+(\d+.\d+)', line)[0]724 if _match('POSITION LINK \d+ LANE \d+', line):725 self.currData['lane'] = _findall('LANE (\d+)', line)[0]726 elif _match('^\s+LENGTH', line):727 self.currData['length'] = _findall('LENGTH\s+(\d+.\d+)', line)[0]728 elif _match('^\s+CAPACITY', line):729 self.currData['capacity'] = _findall('CAPACITY\s+(\d+)', line)[0]730 elif _match('^\s+OCCUPANCY', line):731 self.currData['occupancy'] = _findall('OCCUPANCY\s+(\d+)', line)[0]732 elif _match('^\s+DEFAULT', line):733 self.currData['desired_speed'] = _findall('DESIRED_SPEED\s+(\d+)', line)[0]734 elif _match('^\s+OPEN_HOURS', line):735 self.currData['open_hours'] = _findall('FROM\s+(\d+)\s+UNTIL\s+(\d+)', line)736 elif _match('^\s+MAX_TIME', line):737 self.currData['max_time'] = _findall('MAX_TIME\s+(\d+)', line)[0]738 elif _match('^\s+FLAT_FEE', line):739 self.currData['flat_fee'] = _findall('FLAT_FEE\s+(\d+.\d+)', line)[0]740 elif _match('^\s+FEE_PER_HOUR', line):741 self.currData['fee_per_hour'] = _findall('FEE_PER_HOUR\s+(\d+.\d+)', line)[0]742 elif _match('^\s+ATTRACTION', line):743 if 'spaces_length' in self.currData:744 self.currData['attraction'] = _findall('ATTRACTION\s+(\d+.\d+)\s(\d+.\d+)', line)745 else:746 self.currData['attraction'] = _findall('ATTRACTION\s+(\d+.\d+)', line)747 elif _match('^\s+COMPOSITION', line):748 self.currData['composition'] = _findall('COMPOSITION\s+(\d+)', line)[0]749 else:750 print ('Non-parking data provided: %s' % line)751752 def _output(self, parking):753 """ Outputs Parking syntax to VISSIM.754755 Input: A single parking dictionary756 Output: Parking back into VISSIM syntax757 """758 vissimOut = []759 vissimOut.append('PARKING_LOT ' + str(parking['parking']) + ' NAME ' +760 parking['name'] + ' LABEL ' + parking['label'][0] +761 ' ' + parking['label'][1])762 if 'spaces_length' in parking:763 vissimOut.append('PARKING_SPACES LENGTH '.rjust(24) + parking764 ['spaces_length'])765 vissimOut.append('ZONES '.rjust(8) + parking['zones'].rjust(6) +766 ' FRACTION ' + parking['fraction'].rjust(7))767 if 'lane' in parking:768 vissimOut.append('POSITION LINK '.rjust(16) + str(parking[769 'position_link']) + ' LANE ' + str(parking770 ['lane']) + ' AT ' + str(parking['at']))771 else:772 vissimOut.append('POSITION LINK '.rjust(16) + str(parking773 ['position_link']) + ' AT ' + str(parking['at']))774 vissimOut.append('LENGTH '.rjust(9) + str(parking['length']).rjust(9))775 vissimOut.append('CAPACITY '.rjust(13) + parking['capacity'])776 vissimOut.append('OCCUPANCY '.rjust(12) + parking['occupancy'])777 vissimOut.append('DEFAULT DESIRED_SPEED '.rjust(24) + parking778 ['desired_speed'])779 vissimOut.append('OPEN_HOURS FROM '.rjust(19) + parking['open_hours']780 [0].ljust(2) + ' UNTIL ' + parking['open_hours'][1])781 vissimOut.append('MAX_TIME '.rjust(11) + parking['max_time'])782 vissimOut.append('FLAT_FEE '.rjust(11) + parking['flat_fee'])783 vissimOut.append('FEE_PER_HOUR '.rjust(15) + parking['fee_per_hour'])784 if len(parking['attraction']) > 1:785 vissimOut.append('ATTRACTION '.rjust(13) +786 parking['attraction'][0] + ' ' +787 parking['attraction'][1])788 else:789 vissimOut.append('ATTRACTION '.rjust(13) +790 parking['attraction'][0])791 if 'composition' in parking:792 vissimOut.append('COMPOSITION '.rjust(14) + parking793 ['composition'])794 return vissimOut795796 def __export(self, filename):797 """ Prepare for export all parking lots in a given parking object798799 Input: Parking object800 Output: List of all parking lots in VISSIM syntax801 """802 _exportSection(self, filename)803804805class Transit:806 """ Handles Transit section of .INP file.807 """808 def __init__(self, filename):809 self.filename = filename810 self.name = 'Public Transport'811 self.data = {}812 self.currData = None813 _importSection(self, filename)814815 def create(self, link, dest_link, at, desired_speed, vehicle_type,816 **kwargs):817 transit_num = kwargs.get('num', max(self.data.keys() or [0]) + 1)818 self.data[transit_num] = {}819 transit = self.data[transit_num]820 transit['line'] = str(transit_num)821 transit['link'] = str(link)822 transit['at'] = str(at)823 transit['destination_link'] = str(dest_link)824 transit['desired_speed'] = str(desired_speed)825 transit['vehicle_type'] = str(vehicle_type)826 # Default values827 transit['anm'] = kwargs.get('anm', '""')828 transit['name'] = kwargs.get('name', '""')829 transit['route'] = kwargs.get('route', '0')830 transit['priority'] = kwargs.get('priority', '0')831 transit['length'] = kwargs.get('length', '0')832 transit['mdn'] = kwargs.get('mdn', '0')833 transit['pt'] = kwargs.get('pt', False)834 transit['color'] = kwargs.get('color', 'CYAN')835 transit['time_offset'] = kwargs.get('time_offset', '0.0')836 transit['start_times'] = kwargs.get('start_times', [])837838 def _readSection(self, line):839 """ Process the Transit Decision section of the INP file840 """841 if line[0] == "LINE":842 # Dictionary key is the line number843 self.data[line[1]] = {}844 self.currData = self.data[line[1]]845 self.currData['line'] = line[1]846 self.currData['name'] = line[3]847 self.currData['route'] = line[7]848 self.currData['priority'] = line[9]849 self.currData['length'] = line[11]850 self.currData['mdn'] = line[13]851 if len(line) == 14:852 self.currData['pt'] = True853 elif line[0] == "ANM_ID":854 self.currData['link'] = line[4]855 self.currData['desired_speed'] = line[6]856 self.currData['vehicle_type'] = line[8]857 elif line[0] == "COLOR":858 self.currData['color'] = line[1]859 self.currData['time_offset'] = line[3]860 elif line[0] == "DESTINATION":861 self.currData['destination_link'] = line[2]862 self.currData['at'] = line[4]863 elif line[0] == "START_TIMES":864 self.currData['start_times'] = []865 num = (len(line)-1)/5866 for i in range(num):867 self.currData['start_times'].append([line[1+(5*i)], line868 [3+(5*i)], line[5+(5*i)]])869 elif line[1] == "COURSE":870 num = (len(line)/5)871 for i in range(num):872 self.currData['start_times'].append([line[(5*i)], line873 [2+(5*i)], line[4+(5*i)]])874 else:875 print ('Non-transit data provided: %s' % line)876877 def _output(self, transit):878 """ Outputs transit Decision syntax to VISSIM.879880 Input: A single transit decision dictionary881 Output: transit decisions back into VISSIM syntax882 """883 vissimOut = []884 pt = ''885 if transit['pt'] == True:886 pt = ' PT_TELE'887 vissimOut.append(str('LINE ' + transit['line'].rjust(4) + ' NAME ' +888 transit['name'] + ' LINE ' + transit['line'].889 rjust(3) + ' ROUTE ' + transit['route'].rjust(3)890 + ' PRIORITY ' + transit['priority'] +891 ' LENGTH ' + transit['length'] + ' MDN ' +892 transit['mdn']) + pt + '\n')893 vissimOut.append(str('ANM_ID '.rjust(12) + transit['anm'] +894 ' SOURCE LINK ' + transit['link'] +895 ' DESIRED_SPEED ' + transit['desired_speed'] +896 ' VEHICLE_TYPE ' + transit['vehicle_type']))897 vissimOut.append(str('COLOR '.rjust(24) + transit['color'] +898 ' TIME_OFFSET ' + transit['time_offset'].899 rjust(6)))900 vissimOut.append(str('DESTINATION LINK '.rjust(32) + transit901 ['destination_link'] + ' AT ' + transit['at'].902 rjust(8)))903 time_str = 'START_TIMES '.rjust(24)904 count = 1905 for i in transit['start_times']:906 time_str += str(i[0] + ' COURSE ' + i[1] + ' OCCUPANCY ' + i[2] +907 ' ')908 if count % 5 == 0:909 time_str += '\n'910 count += 1911 if len(transit['start_times']) > 0:912 vissimOut.append(time_str)913 return vissimOut914915 def export(self, filename):916 """ Prepare for export all transit routes in a given transit object917918 Input: transit object919 Output: List of all transit lots in VISSIM syntax920 """921 _exportSection(self, filename)922923924class Routing:925 """ Handles Routing Decision section of .INP file.926 """927 def __init__(self, filename):928 self.filename = filename929 self.name = 'Routing Decisions'930 self.data = {}931 self.currData = None932 self.destinationLink = None933 self.atLink = None934 self.currRouteNum = None935 self.currRoute = None936 self.over = None937 self.types = {'name': str, 'route': dict, 'number': int,938 'label': tuple, 'link': int, 'at': float, 'time': list,939 'vehicle_classes': int, 'PT': int, 'alternatives': bool}940 _importSection(self, filename)941942 class Route:943 """ Individual routes within a given Route Decisions944 """945 def __init__(self, routeNum, destinationLink, atLink, fraction):946 self.name = 'Route'947 self.number = routeNum948 self.types = {'at': float, 'fraction': list, 'link': int,949 'number': int, 'over': list}950 self.data = {'number': self.types['number'](routeNum),951 'link': self.types['link'](destinationLink),952 'at': self.types['at'](atLink),953 'fraction': self.types['fraction'](fraction)}954955 def get(self, label, string=True):956 """ Get value from Route.957 Input: Route number, Value label958 Output: Value959 """960 if string:961 return str(_getData(self, None, label))962 else:963 return _getData(self, None, label)964965 def set(self, label, value):966 """ Set value from Route.967 Input: Route number, Value label, value968 Output: Change is made in place969 """970 _setData(self, None, label, value)971972 def update(self, label, value, pos=None):973 """ Update list with new value.974 Input: label and value975 Output: Value is appended to data976 """977 _updateData(self, None, label, value, pos=pos)978979 def output(self):980 """ Outputs Route syntax to VISSIM.981 """982 vissimOut = []983 routeNum = self.data['number']984985 def _out(label, s=True):986 return self.get(label, string=s)987 vissimOut.append('ROUTE '.rjust(11) + _out('number').rjust(6) +988 ' DESTINATION LINK' + _out('link').rjust(6) +989 ' AT' + _out('at').rjust(9))990 fractionStr = ''991 for j in _out('fraction', s=False):992 fractionStr += 'FRACTION '.rjust(16) + j993 vissimOut.append(fractionStr)994 # Sometimes the route ends on the same link it began:995 if not _out('over', s=False):996 return vissimOut997 else:998 for count, j in enumerate(_out('over', s=False)):999 if count == 0:1000 overStr = 'OVER '.rjust(12)1001 overStr += str(j)1002 elif count == len(_out('over', s=False)) - 1:1003 overStr += str(j).rjust(6)1004 vissimOut.append(overStr)1005 break1006 elif (count + 1 % 10) == 0:1007 overStr += str(j).rjust(6)1008 vissimOut.append(overStr)1009 overStr = ' ' * 111010 else:1011 overStr += str(j).rjust(6)1012 if len(_out('over', s=False)) == 1:1013 vissimOut.append(overStr)1014 return vissimOut10151016 def getRoute(self, decnum, routenum=None):1017 """ Get route objects from a given routing decision number.1018 Input: Routing decision number, route number (optional)1019 Output: If route number is given, return the route object,1020 otherwise return all route objects for the given decision.1021 """1022 if isinstance(routenum, str) is False:1023 routenum = str(routenum)1024 if isinstance(decnum, str) is False:1025 decnum = str(decnum)1026 if routenum is None:1027 _getData(self.data, decnum, 'route').keys()1028 elif decnum not in self.data:1029 raise KeyError('%s not in data' % (decnum))1030 elif routenum not in self.data[decnum]:1031 raise KeyError('%s not in routing decision' % (routenum))1032 else:1033 return self.data[decnum]['route'][routenum]10341035 def get(self, decNum, label, string=True):1036 """ Get value from Routing data.1037 Input: Routing decision number, Value label1038 Output: Value1039 """1040 if string:1041 return str(_getData(self, decNum, label))1042 else:1043 return _getData(self, decNum, label)10441045 def set(self, decNum, label, value):1046 """ Set value from Routing data.1047 Input: Routing decision number, Value label, value1048 Output: Change is made in place1049 """1050 _setData(self, decNum, label, value)10511052 def update(self, decNum, label, key, value):1053 """ Update dict with new key and value.1054 Input: Routing decision number, key, value1055 Output: Change is made in place1056 """1057 _updateData(self, decNum, label, value, newKey=key)10581059 def create(self, startLink, startAt, vehClass, **kwargs):1060 if self.data.keys():1061 num = max(self.data.keys()) + 11062 else:1063 num = 11064 decNum = kwargs.get('number', num)1065 self.data[decNum] = {}1066 self.set(decNum, 'number', decNum)1067 self.set(decNum, 'link', startLink)1068 self.set(decNum, 'at', startAt)1069 self.set(decNum, 'vehicle_classes', vehClass)1070 # Default values1071 self.set(decNum, 'name', kwargs.get('name', '""'))1072 self.set(decNum, 'label', kwargs.get('label', ('0.00', '0.00')))1073 self.set(decNum, 'time', kwargs.get('time', [0.0000, 99999.0000]))1074 self.set(decNum, 'route', kwargs.get('route', {}))1075 self.set(decNum, 'alternatives', kwargs.get('alternatives', False))10761077 def _readSection(self, line):1078 """ Process the Route Decision section of the INP file1079 """1080 if _match('^ROUTING_DECISION', line):1081 # Reset from previous routes1082 self.currRoute = None1083 decNum = (self.types['number'](_findall(1084 'ROUTING_DECISION\s+(\d+)', line)[0]))1085 # Routing decision number is dict key1086 self.currData = {'number': decNum, 'route': {}}1087 self.currData['name'] = _findall('NAME\s+(".+"|"")', line)[0]1088 self.currData['label'] = _findall('LABEL\s+(-?\d+.\d+)\s(-?\d+.\d+)', line)[0]1089 elif _match('^\s+LINK', line):1090 self.currData['link'] = _findall('LINK\s+(\d+)', line)[0]1091 self.currData['at'] = _findall('AT\s+(\d+.\d+)', line)[0]1092 elif _match('^\s+TIME', line):1093 self.currData['time'] = _findall('FROM\s+(\d+.\d+)\s+UNTIL\s+(\d+.\d+)', line)1094 elif _match('^\s+FROM', line):1095 self.currData['time'].append(_findall('FROM\s+(\d+.\d+)\s+UNTIL\s+(\d+.\d+)', line))1096 elif _match('^\s+VEHICLE_CLASSES', line):1097 self.currData['vehicle_classes'] = _findall('VEHICLE_CLASSES\s+(\d+)', line)[0]1098 self.create(self.currData['link'], self.currData['at'], self.currData['vehicle_classes'], **self.currData)1099 elif _match('^\s+PT', line):1100 self.currData['PT'] = _findall('PT\s+(\d+)', line)[0]1101 self.set(self.currData['number'], 'PT', self.currData['PT'])1102 elif _match('^\s+ALTERNATIVES', line):1103 self.set(self.currData['number'], 'alternatives', True)1104 elif _match('^\s+ROUTE', line):1105 self.over = False1106 # Reset the variables from previous route1107 self.currRouteNum = int(_findall('ROUTE\s+(\d+)', line)[0])1108 self.destinationLink = _findall('LINK\s+(\d+)', line)[0]1109 self.atLink = _findall('AT\s+(\d+.\d+)', line)[0]1110 elif _match('^\s+FRACTION', line):1111 currFraction = _findall('FRACTION\s+(\d+.\d+)', line)1112 self.currRoute = self.Route(self.currRouteNum,1113 self.destinationLink, self.atLink,1114 currFraction)1115 self.update(self.currData['number'], 'route', self.currRouteNum,1116 self.currRoute)1117 elif _match('^\s+OVER', line):1118 self.over = True1119 self.currRoute.set('over', _findall('(\d+)',1120 line))1121 elif self.over is True:1122 self.currRoute.update('over', _findall('(\d+)', line))1123 else:1124 print ('Non-routing data provided: %s' % line)11251126 def _output(self, routing):1127 """ Outputs Route Decision syntax to VISSIM.1128 """1129 decNum = routing['number']1130 vissimOut = []11311132 def _out(label, s=True):1133 return self.get(decNum, label, string=s)1134 vissimOut.append(str('ROUTING_DECISION ' + _out('number').ljust(4) +1135 ' NAME ' + _out('name') + ' LABEL ' +1136 _out('label', s=False)[0] + ' ' +1137 _out('label', s=False)[1]))1138 vissimOut.append(str('LINK '.rjust(10) + _out('link') + 'AT '.rjust1139 (5) + _out('at')))1140 timeStr = 'TIME'.rjust(9)1141 for i in _out('time', s=False):1142 timeStr += str(' FROM ' + str(i[0]) + ' UNTIL ' + str(i[1]))1143 vissimOut.append(timeStr)1144 if _out('vehicle_classes'):1145 vissimOut.append('VEHICLE_CLASSES '.rjust(21) +1146 _out('vehicle_classes'))1147 elif _out('PT'):1148 vissimOut.append('PT '.rjust(21) + _out('PT'))1149 for route in self.get(decNum, 'route', string=False).values():1150 vissimOut += route.output()1151 return vissimOut11521153 def export(self, filename):1154 """ Prepare for export all routes in a given route object11551156 Input: Route object1157 Output: List of all routes in VISSIM syntax1158 """1159 _exportSection(self, filename)116011611162class Node:1163 """ Handles Node section of .INP file.1164 """1165 def __init__(self, filename):1166 self.filename = filename1167 self.name = 'Nodes'1168 self.data = {}1169 self.curr_node_num = None1170 self.curr_node = None1171 self.node = None1172 _importSection(self, filename)11731174 def _readSection(self, line):1175 if line[0] == 'NODE':1176 self.curr_node_num = int(line[1])1177 self.data[self.curr_node_num] = {}1178 self.curr_node = self.data[self.curr_node_num]1179 self.curr_node['node'] = self.curr_node1180 self.curr_node['name'] = line[3]1181 self.curr_node['label'] = [line[5], line[6]]1182 elif line[0] == 'EVALUATION':1183 self.curr_node['evaluation'] = line[1]1184 elif line[0] == 'NETWORK_AREA':1185 self.curr_node['network_area'] = line[1]1186 self.curr_node['over'] = []1187 overs = int(line[1])1188 for num in range(overs):1189 self.curr_node['over'].append((line[(num*2)+2],1190 line[(num*2)+3]))1191 else:1192 print ('Non-node data provided: %s' % line)11931194 def _output(self, node):1195 """ Outputs node syntax to VISSIM.11961197 Input: A single node dictionary1198 Output: node back into VISSIM syntax1199 """1200 vissimOut = []1201 vissimOut.append('NODE ' + str(node['node']) + ' NAME ' + node['name']1202 + ' LABEL ' + node['label'][0] + ' ' + node['label']1203 [1])1204 vissimOut.append('EVALUATION '.rjust(13) + node['evaluation'])1205 over_str = ''1206 over_count = 01207 if 'over' in node:1208 for i in node['over']:1209 over_str += ' ' + str(i[0]) + ' ' + str(i[1])1210 over_count += 11211 vissimOut.append('NETWORK_AREA '.rjust(15) + str(over_count) +1212 over_str)1213 elif 'links' in node:1214 for i in node['links']:1215 over_str += '\nLINK '.rjust(10) + str(i).rjust(10)1216 vissimOut.append('NETWORK_AREA'.rjust(16) + over_str)1217 return vissimOut12181219 def export(self, filename):1220 """ Prepare for export all node lots in a given node object12211222 Input: node object1223 Output: List of all node lots in VISSIM syntax1224 """1225 _exportSection(self, filename)12261227 def createArea(self, area, **kwargs):1228 if 'num' in kwargs:1229 node_num = int(kwargs['num'])1230 elif len(self.data.keys()) == 0:1231 node_num = 11232 else:1233 node_num = max(self.data.keys())+11234 self.data[node_num] = {}1235 node = self.data[node_num]1236 node['node'] = node_num1237 node['over'] = area1238 node['network_area'] = len(area)1239 # Default values1240 node['name'] = '""'1241 node['label'] = ['0.00', '0.00']1242 node['evaluation'] = 'NO'1243 # User defined changes to the default values1244 for name, value in kwargs.items():1245 node[name] = value12461247 def createLink(self, link, **kwargs):1248 if 'num' in kwargs:1249 node_num = int(kwargs['num'])1250 elif len(self.data.keys()) == 0:1251 node_num = 11252 else:1253 node_num = max(self.data.keys())+11254 self.data[node_num] = {}1255 node = self.data[node_num]1256 node['node'] = node_num1257 node['links'] = link1258 # Default values1259 node['name'] = '""'1260 node['label'] = ['0.00', '0.00']1261 node['evaluation'] = 'NO'1262 # User defined changes to the default values1263 for name, value in kwargs.items(): ...

Full Screen

Full Screen

wml.py

Source:wml.py Github

copy

Full Screen

1from owslib.etree import etree2from owslib.util import nspath, testXMLValue, openURL3from owslib.util import xml_to_dict as _xml_to_dict4from datetime import datetime5from dateutil import parser6namespaces = {7 'wml1.1':'{http://www.cuahsi.org/waterML/1.1/}',8 'wml1.0':'{http://www.cuahsi.org/waterML/1.0/}',9 'xsi':'{http://www.w3.org/2001/XMLSchema-instance',10 'xsd':'{http://www.w3.org/2001/XMLSchema'11}12def ns(namespace):13 return namespaces.get(namespace)14class XMLParser(object):15 """16 Convienence class; provides some useful shortcut methods to make retrieving xml elements from etree17 a little easier.18 """19 def __init__(self,xml_root,namespace):20 try:21 self._root = etree.parse(xml_root)22 except:23 self._root = xml_root24 if not namespace in namespaces:25 raise ValueError('Unsupported namespace passed in to parser!')26 self._ns = namespace27 def _find(self,tofind):28 try:29 return self._root.find(namespaces.get(self._ns) + tofind)30 except:31 return None32 def _findall(self,tofind):33 try:34 return self._root.findall(namespaces.get(self._ns) + tofind)35 except:36 return None37class SitesResponse(XMLParser):38 """39 Parses the response from a 'GetSites' request40 Parameters41 ===========42 :xmlio - A file-like object that holds the xml response from the request.43 Return 44 =======45 An object constructed from a dictionary parse of the response. The object has get access and can iterate46 over the sites returned.47 """48 def __init__(self,xml,version='wml1.1'):49 super(SitesResponse,self).__init__(xml,version)50 self.parse_sites_response()51 def __iter__(self):52 for s in self.sites:53 yield s54 def __getitem__(self,key):55 if isinstance(key,int) and key < len(self.sites):56 return self.sites[key]57 if isinstance(key,str):58 site = [site for site in self.sites for code in site.site_info.site_codes if code == key]59 if len(site) > 0:60 return site[0]61 raise KeyError('Unknown key ' + str(key))62 def parse_sites_response(self,xml=None):63 """64 """65 if xml is not None:66 try:67 self._root = etree.parse(xml)68 except:69 self._root = xml70 # try:71 self.query_info = QueryInfo(self._find('queryInfo'), self._ns)72 self.sites = [Site(site, self._ns) for site in self._findall('site')]73 # except:74 # raise ValueError('Cannot parse sitesResponse element correctly')75 """Accesability properties/methods"""76 @property77 def site_codes(self):78 return [site.site_info.site_codes for site in self.sites]79 @property80 def site_names(self):81 return [site.site_info.site_name for site in self.sites]82class QueryInfo(XMLParser):83 """84 """85 def __init__(self,xml_root,version='wml1.1'):86 super(QueryInfo, self).__init__(xml_root,version)87 self.parse_query_info()88 def parse_query_info(self, xml=None):89 if xml is not None:90 try:91 self._root = etree.parse(xml)92 except:93 self._root = xml94 # try:95 # create queryinfo object from dict96 xml_dict = _xml_to_dict(self._root)97 self.creation_time = parser.parse(xml_dict.get('creation_time')) if xml_dict.get('creation_time') is not None else None98 self.notes = [testXMLValue(note) for note in self._findall('note')]99 self.criteria = Criteria(self._find('criteria'), self._ns)100 # except:101 # raise ValueError('Unable to parse queryInfo element correctly')102class Criteria(XMLParser):103 """104 """105 def __init__(self,xml_root,version='wml1.1'):106 super(Criteria, self).__init__(xml_root,version)107 self.parse_criteria()108 def parse_criteria(self, xml=None):109 if xml is not None:110 try:111 self._root = etree.parse(xml)112 except:113 self._root = xml114 # try:115 xml_dict = _xml_to_dict(self._root,depth=4)116 self.method_called = self._root.attrib.get('MethodCalled')117 self.location_param = xml_dict.get('location_param')118 self.variable_param = xml_dict.get('variable_param')119 try:120 self.begin_date_time = parser.parse(xml_dict['begin_date_time'])121 except:122 self.begin_date_time = None123 try:124 self.end_date_time = parser.parse(xml_dict['end_date_time'])125 except:126 self.end_date_time = None127 self.parameters = [(param.attrib.get('name'),param.attrib.get('value')) for param in self._findall('parameter')]128 # except:129 # raise ValueError('Unable to parse xml for criteria element')130class Site(XMLParser):131 def __init__(self, xml, version='wml1.1'):132 super(Site,self).__init__(xml,version)133 self.parse_site()134 def __iter__(self):135 for c in self.series_catalogs:136 yield c137 def __getitem__(self,key):138 if isinstance(key,int) and key < len(self.series_catalogs):139 return self.series_catalogs[key]140 if isinstance(key,str):141 var = [series.variable for catalog in self.series_catalogs for series in catalog if series.code == key]142 if len(var) > 0:143 return var[0]144 raise KeyError('Unknown key ' + str(key))145 """Accessor propeties/methods"""146 @property147 def name(self):148 return self.site_info.site_name149 @property150 def codes(self):151 return self.site_info.site_codes152 @property153 def variable_names(self):154 return list(set([series.variable.variable_name for catalog in self.series_catalogs for series in catalog]))155 @property156 def variable_codes(self):157 return list(set([series.variable.variable_code for catalog in self.series_catalogs for series in catalog]))158 @property159 def geo_coords(self):160 return self.site_info.location.geo_coords161 @property162 def latitudes(self):163 return [g[1] for g in self.site_info.location.geo_coords]164 @property165 def longitudes(self):166 return [g[0] for g in self.site_info.location.geo_coords]167 def parse_site(self,xml=None):168 if xml is not None:169 try:170 self._root = etree.parse(xml)171 except:172 self._root = xml173 # try:174 self.site_info = SiteInfo(self._find('siteInfo'), self._ns)175 self.series_catalogs = [SeriesCatalog(elm, self._ns) for elm in self._findall('seriesCatalog')]176 # self.extension = Extension(self._find('extension'), self._ns)177 # except:178 # raise ValueError('Unable to parse site element correctly')179class SiteInfo(XMLParser):180 def __init__(self,xml,version='wml1.1'):181 super(SiteInfo,self).__init__(xml,version)182 self.parse_siteinfo()183 def parse_siteinfo(self,xml=None):184 if xml is not None:185 try:186 self._root = etree.parse(xml)187 except:188 self._root = xml189 # try:190 xml_dict = _xml_to_dict(self._root)191 self.site_name = xml_dict.get('site_name')192 self.site_codes = [testXMLValue(code) for code in self._findall('siteCode')]193 self.elevation = xml_dict.get('elevation_m')194 self.vertical_datum = xml_dict.get('vertical_datum')195 self.site_types = [testXMLValue(typ) for typ in self._findall('siteType')]196 self.site_properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('siteProperty')])197 self.altname = xml_dict.get('altname')198 self.notes = [testXMLValue(note) for note in self._findall('note')]199 # sub-objects200 tzi = self._find('timeZoneInfo')201 if tzi is not None:202 self.time_zone_info = TimeZoneInfo(tzi, self._ns)203 self.location = Location(self._find('geoLocation'), self._ns)204 # except:205 # raise ValueError('Unable to parse siteInfo element')206class Location(XMLParser):207 def __init__(self,xml,version='wml1.1'):208 super(Location,self).__init__(xml,version)209 self.parse_location()210 def parse_location(self,xml=None):211 if xml is not None:212 try:213 self._root = etree.parse(xml)214 except:215 self._root = xml216 # try:217 xml_dict = _xml_to_dict(self._root)218 geogs = self._findall('geogLocation')219 self.geo_coords = list()220 self.srs = list()221 for g in geogs:222 self.geo_coords.append((testXMLValue(g.find(ns(self._ns) + 'longitude')),testXMLValue(g.find(ns(self._ns) + 'latitude'))))223 self.srs.append(g.attrib.get('srs'))224 locsite = self._findall('localSiteXY')225 self.local_sites = list()226 self.notes = list()227 self.projections = list()228 for ls in locsite:229 z = testXMLValue(ls.find(ns(self._ns) + 'Z'))230 if z is not None:231 self.local_sites.append((testXMLValue(ls.find(ns(self._ns) + 'X')),testXMLValue(ls.find(ns(self._ns) + 'Y')),z))232 else:233 self.local_sites.append((testXMLValue(ls.find(ns(self._ns) + 'X')),testXMLValue(ls.find(ns(self._ns) + 'Y')),'0'))234 self.notes.append([testXMLValue(note) for note in ls.findall(ns(self._ns) + 'note')])235 self.projections.append(ls.attrib.get('projectionInformation'))236 # except:237 # raise ValueError('Unable to parse geoLocation element')238class TimeZoneInfo(XMLParser):239 def __init__(self,xml,version='wml1.1'):240 super(TimeZoneInfo,self).__init__(xml,version)241 self.parse_timezoneinfo()242 def parse_timezoneinfo(self,xml=None):243 if xml is not None:244 try:245 self._root = etree.parse(xml)246 except:247 self._root = xml248 # try:249 xml_dict = _xml_to_dict(self._root)250 default = self._find('defaultTimeZone')251 if default is not None:252 self.zone_offset = default.attrib.get('zoneOffset')253 self.zone_abbreviation = default.attrib.get('zoneAbbreviation')254 daylight = self._find('daylightSavingsTimeZone')255 if daylight is not None:256 self.daylight_zone_offset = daylight.attrib.get('zoneOffset')257 self.daylight_zone_abbreviation = daylight.attrib.get('zoneAbbreviation')258 # except:259 # raise ValueError('Unable to properly parset the timeZoneInfo element')260 261class SeriesCatalog(XMLParser):262 def __init__(self,xml,version='wml1.1'):263 super(SeriesCatalog,self).__init__(xml,version)264 self.parse_seriescatalog()265 def __iter__(self):266 for s in self.series:267 yield s268 def __getitem__(self,key):269 if isinstance(key,int) and key < len(self.series):270 return self.series[key]271 if isinstance(key,str):272 srs = [series for series in self.series if series.code == key]273 if len(srs) > 0:274 return srs[0]275 raise KeyError('Unknown key ' + str(key))276 def parse_seriescatalog(self,xml=None):277 if xml is not None:278 try:279 self._root = etree.parse(xml)280 except:281 self._root = xml282 # try:283 self.series = [Series(elm,self._ns) for elm in self._findall('series')]284 # except:285 # raise ValueError('Unable to properly parse the seriesCatalog element')286class Series(XMLParser):287 def __init__(self,xml,version='wml1.1'):288 super(Series,self).__init__(xml,version)289 self.parse_series()290 """Accessor proeprties/methods"""291 @property292 def name(self):293 return self.variable.variable_name294 @property295 def code(self):296 return self.variable.variable_code297 def parse_series(self,xml=None):298 if xml is not None:299 try:300 self._root = etree.parse(xml)301 except:302 self._root = xml303 # try:304 xml_dict = _xml_to_dict(self._root,depth=3)305 self.value_count = xml_dict.get('value_count')306 self.value_type = xml_dict.get('value_type')307 self.general_category = xml_dict.get('general_category')308 self.sample_medium = xml_dict.get('sample_medium')309 self.data_type = xml_dict.get('data_type')310 # date-time311 self.begin_date_time = parser.parse(xml_dict.get('begin_date_time'))312 self.begin_date_time_utc = parser.parse(xml_dict.get('begin_date_time_utc')) if xml_dict.get('begin_date_time_utc') is not None else None313 self.end_date_time = parser.parse(xml_dict.get('end_date_time'))314 self.end_date_time_utc = parser.parse(xml_dict.get('end_date_time_utc')) if xml_dict.get('end_date_time_utc') is not None else None315 # method info316 self.method_description = xml_dict.get('method_description')317 self.method_code = xml_dict.get('method_code')318 self.method_link = xml_dict.get('method_link')319 method = self._find('method')320 if method is not None:321 self.method_id = method.attrib.get('methodID')322 else:323 self.method_id = None324 # source info325 self.organization = xml_dict.get('organization')326 self.source_description = xml_dict.get('source_description')327 self.citation = xml_dict.get('citation')328 source = self._find('source')329 if source is not None:330 self.source_id = source.attrib.get('sourceID')331 else:332 self.source_id = None333 # quality control info334 self.quality_control_level_code = xml_dict.get('quality_control_level_code')335 self.definition = xml_dict.get('definition')336 qa = self._find('qualityControlLevel')337 if qa is not None:338 self.quality_control_level_id = qa.attrib.get('qualityControlLevelID')339 else:340 self.quality_control_level_id = None341 # properties342 self.properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('seriesProperty')])343 # sub-objects344 self.variable = Variable(self._find('variable'),self._ns)345 # except:346 # raise ValueError('Unable to correctly parse Series element')347class Variable(XMLParser):348 def __init__(self,xml,version='wml1.1'):349 super(Variable,self).__init__(xml,version)350 self.parse_variable()351 def parse_variable(self,xml=None):352 if xml is not None:353 try:354 self._root = etree.parse(xml)355 except:356 self._root = xml357 # try:358 xml_dict = _xml_to_dict(self._root)359 self.value_type = xml_dict.get('value_type')360 self.data_type = xml_dict.get('data_type')361 self.general_category = xml_dict.get('general_category')362 self.sample_medium = xml_dict.get('sample_medium')363 self.no_data_value = xml_dict.get('no_data_value')364 self.variable_name = xml_dict.get('variable_name')365 self.variable_code = xml_dict.get('variable_code')366 self.variable_description = xml_dict.get('variable_description')367 self.speciation = xml_dict.get('speciation')368 # notes and properties369 notes = [(note.attrib.get('title'),testXMLValue(note)) for note in self._findall('note')]370 none_notes = [note[1] for note in notes if note[0] is None]371 self.notes = dict([note for note in notes if note[0] is not None])372 if len(none_notes) > 0:373 self.notes['none'] = none_notes374 self.properties = dict([(prop.attrib.get('name'),testXMLValue(prop)) for prop in self._findall('variableProperty')])375 # related376 related = self._find('related')377 if related is not None:378 self.parent_codes = [dict([('network',code.attrib.get('network')),('vocabulary',code.attrib.get('vocabulary')),('default',code.attrib.get('default'))])379 for code in related.findall(ns(self._ns) + 'parentCode')]380 self.related_codes = [dict([('network',d.get('network')),('vocabulary',d.get('vocabulary')),('default',d.get('default'))])381 for code in related.findall(ns(self._ns) + 'relatedCode')]382 else:383 self.parent_codes = None384 self.related_codes = None385 # sub-objects386 if self._ns == 'wml1.0':387 unit = self._find('units')388 self.unit = Unit1_0(unit, self._ns) if unit is not None else None389 timesupport = self._find('timeSupport')390 self.time_support = TimeScale(timesupport, self._ns) if timesupport is not None else None391 else:392 unit = self._find('unit')393 self.unit = Unit(unit, self._ns) if unit is not None else None394 timescale = self._find('timeScale')395 self.time_scale = TimeScale(timescale, self._ns) if timescale is not None else None396 categories = self._find('categories')397 if categories is not None:398 self.categories = [Category(cat,self._ns) for cat in categories.findall(ns(self._ns) + 'category')]399 else:400 self.categories = None401 # except:402 # raise ValueError('Unable to correctly parse variable element')403class TimeScale(XMLParser):404 def __init__(self,xml,version='wml1.1'):405 super(TimeScale,self).__init__(xml,version)406 self.parse_timescale()407 def parse_timescale(self):408 try:409 xml_dict = _xml_to_dict(self._root)410 self.time_spacing = xml_dict.get('time_spacing')411 self.time_support = xml_dict.get('time_support')412 self.time_interval = xml_dict.get('time_interval')413 unit = self._find('unit')414 self.unit = Unit(unit, self._ns) if unit is not None else None415 except:416 raise417class Unit(XMLParser):418 def __init__(self,xml,version='wml1.1'):419 super(Unit,self).__init__(xml,version)420 self.parse_unit()421 def parse_unit(self):422 try:423 xml_dict = _xml_to_dict(self._root)424 self.name = xml_dict.get('unit_name')425 self.unit_type = xml_dict.get('unit_type')426 self.description = xml_dict.get('unit_description')427 self.abbreviation = xml_dict.get('unit_abbreviation')428 self.code = xml_dict.get('unit_code')429 self.id = self._root.attrib.get('UnitID')430 except:431 raise432class Unit1_0(XMLParser):433 def __init__(self,xml,version='wml1.0'):434 super(Unit1_0,self).__init__(xml,version)435 self.parse_unit()436 def parse_unit(self):437 try:438 self.name = testXMLValue(self._root)439 self.code = self._root.attrib.get('unitsCode')440 self.abbreviation = self._root.attrib.get('unitsAbbreviation')441 self.type = self._root.attrib.get('unitsType')442 self.id = self._root.attrib.get('unitID')443 except:444 raise445class Category(XMLParser):446 def __init__(self,xml,version='wml1.1'):447 super(Category,self).__init__(xml,version)448 self.parse_category()449 def parse_category(self):450 try:451 xml_dict = _xml_to_dict(self._root)452 self.data_value = xml_dict.get('data_value')453 self.description = xml_dict.get('description')454 self.id = self._root.attrib.get('categoryID')455 except:456 raise457class TimeSeriesResponse(XMLParser):458 """459 Parses the response from a 'GetValues' request460 Parameters461 ===========462 :xmlio - A file-like object that holds the xml response from the request.463 Return 464 =======465 An object constructed from a dictionary parse of the response. The object has get access and can466 also iterate over each timeSeries element returned.467 """468 def __init__(self,xml,version='wml1.1'):469 super(TimeSeriesResponse,self).__init__(xml,version)470 self.parse_timeseriesresponse()471 """Accessor properties/methods"""472 @property473 def series_names(self):474 return [series.name for series in self.time_series]475 @property476 def variable_names(self):477 return list(set([series.variable.variable_name for series in self.time_series]))478 @property479 def variable_codes(self):480 return list(set([s.variable.variable_code for s in self.time_series]))481 def get_series_by_variable(self,var_name=None,var_code=None):482 if var_code is not None:483 return [s for s in self.time_series if s.variable.variable_code == var_code]484 elif var_name is not None:485 return [series for series in self.time_series if series.variable.variable_name == var_name]486 return None487 def parse_timeseriesresponse(self):488 try:489 qi = self._find('queryInfo')490 self.query_info = QueryInfo(qi,self._ns)491 self.time_series = [TimeSeries(series,self._ns) for series in self._findall('timeSeries')]492 except:493 raise494class TimeSeries(XMLParser):495 def __init__(self,xml,version='wml1.1'):496 super(TimeSeries,self).__init__(xml,version)497 self.parse_timeseries()498 def parse_timeseries(self):499 try:500 self.variable = Variable(self._find('variable'), self._ns)501 self.values = [Values(val,self._ns) for val in self._findall('values')]502 self.source_info = SiteInfo(self._find('sourceInfo'), self._ns)503 self.name = self._root.attrib.get('name')504 except:505 raise506class Values(XMLParser):507 def __init__(self,xml,version='wml1.1'):508 super(Values,self).__init__(xml,version)509 self.parse_values()510 def __iter__(self):511 for v in self.values:512 yield v513 """Accessor properties/methods"""514 def get_date_values(self,method_id=None,source_id=None,sample_id=None,quality_level=None,utc=False):515 varl = [v for v in self.values]516 if method_id is not None:517 varl = [v for v in varl if v.method_id == method_id]518 if source_id is not None:519 varl = [v for v in varl if v.source_id == source_id]520 if sample_id is not None:521 varl = [v for v in varl if v.sample_id == sample_id]522 if quality_level is not None:523 varl = [v for v in varl if v.quality_control_level == quality_level]524 if not utc:525 return [(v.date_time,v.value) for v in varl]526 else:527 return [(v.date_time_utc,v.value) for v in varl]528 def parse_values(self):529 xml_dict = _xml_to_dict(self._root)530 # method info531 self.methods = [Method(method,self._ns) for method in self._findall('method')]532 # source info533 self.sources = [Source(source,self._ns) for source in self._findall('source')]534 # quality control info535 self.qualit_control_levels = [QualityControlLevel(qal, self._ns) for qal in self._findall('qualityControlLevel')]536 # offset info537 self.offsets = [Offset(os,self._ns) for os in self._findall('offset')]538 # sample info539 self.samples = [Sample(sample,self._ns) for sample in self._findall('sample')]540 # censor codes541 self.censor_codes = [CensorCode(code, self._ns) for code in self._findall('censorCode')]542 # unit543 if self._ns == 'wml1.0':544 self.unit_abbreviation = self._root.attrib.get('unitsAbbreviation')545 self.unit_code = self._root.attrib.get('unitsCode')546 self.count = self._root.attrib.get('count')547 else:548 unit = self._find('unit')549 self.unit = Unit(unit, self._ns) if unit is not None else None550 # values551 self.values = [Value(val, self._ns) for val in self._findall('value')]552class Value(XMLParser):553 def __init__(self,xml,version='wml1.1'):554 super(Value,self).__init__(xml,version)555 self.parse_value()556 def parse_value(self):557 try:558 self.value = testXMLValue(self._root)559 d = self._root.attrib560 self.qualifiers = d.get('qualifiers')561 self.censor_code = d.get('censorCode')562 self.date_time = parser.parse(d.get('dateTime')) if d.get('dateTime') is not None else None563 self.time_offset = d.get('timeOffset')564 self.date_time_utc = parser.parse(d.get('dateTimeUTC')) if d.get('dateTimeUTC') is not None else None565 self.method_id = d.get('methodID')566 self.source_id = d.get('sourceID')567 self.accuracy_std_dev = d.get('accuracyStdDev')568 self.sample_id = d.get('sampleID')569 self.method_code = d.get('methodCode')570 self.source_code = d.get('sourceCode')571 self.lab_sample_code = d.get('lab_sample_code')572 self.offset_value = d.get('offsetValue')573 self.offset_type_id = d.get('offsetTypeID')574 self.offset_type_code = d.get('offsetTypeCode')575 self.coded_vocabulary = d.get('codedVocabulary')576 self.coded_vocabulary_term = d.get('codedVocabularyTerm')577 self.quality_control_level = d.get('qualityControlLevel')578 self.metadata_time = d.get('metadataTime')579 self.oid = d.get('oid')580 except:581 raise582class Sample(XMLParser):583 def __init__(self,xml,version='wml1.1'):584 super(Sample,self).__init__(xml,version)585 self.parse_sample()586 def parse_sample(self):587 try:588 xml_dict = _xml_to_dict(self._root)589 self.code = xml_dict.get('lab_sample_code')590 self.type = xml_dict.get('sample_type')591 lm = self._find('labMethod')592 self.method = LabMethod(lm, self._ns) if lm is not None else None593 except:594 raise595class LabMethod(XMLParser):596 def __init__(self,xml,version='wml1.1'):597 super(LabMethod,self).__init__(xml,version)598 self.parse_labmethod()599 def parse_labmethod(self):600 try:601 xml_dict = _xml_to_dict(self._root)602 self.code = xml_dict.get('lab_code')603 self.name = xml_dict.get('lab_name')604 self.organization = xml_dict.get('lab_organization')605 self.method_name = xml_dict.get('lab_method_name')606 self.method_description = xml_dict.get('lab_method_description')607 self.method_link = xml_dict.get('lab_method_link')608 # sub-objects609 source = self._find('labSourceDetails')610 self.source_details = Source(source,self._ns) if source is not None else None611 except:612 raise613class Source(XMLParser):614 def __init__(self,xml,version='wml1.1'):615 super(Source,self).__init__(xml,version)616 self.parse_source()617 def __str__(self):618 return str(self.__dict__)619 def get_contact(self,name):620 ci = [ci for ci in self.contact_info if ci.name == name]621 if len(ci) < 0:622 return ci[0]623 return None624 def parse_source(self):625 try:626 xml_dict = _xml_to_dict(self._root)627 self.code = xml_dict.get('source_code')628 self.organization = xml_dict.get('organization')629 self.description = xml_dict.get('source_description')630 self.links = [testXMLValue(link) for link in self._findall('sourceLink')]631 self.citation = xml_dict.get('citation')632 # metadata633 self.topic_category = xml_dict.get('topic_category')634 self.title = xml_dict.get('title')635 self.abstract = xml_dict.get('abstract')636 self.profile_version = xml_dict.get('profile_version')637 self.metadata_link = xml_dict.get('metadata_link')638 # contact info639 self.contact_info = [ContactInformation(ci,self._ns) for ci in self._findall('contactInformation')]640 except:641 raise642class ContactInformation(XMLParser):643 def __init__(self,xml,version='wml1.1'):644 super(ContactInformation,self).__init__(xml,version)645 self.parse_contactinformation()646 def parse_contactinformation(self):647 try:648 xml_dict = _xml_to_dict(self._root)649 self.name = xml_dict.get('contact_name')650 self.type = xml_dict.get('type_of_contact')651 self.email = [testXMLValue(email) for email in self._findall('email')]652 self.phone = [testXMLValue(phone) for phone in self._findall('phone')]653 self.address = [testXMLValue(address) for address in self._findall('address')]654 except:655 raise656class Offset(XMLParser):657 def __init__(self,xml,version='wml1.1'):658 super(Offset,self).__init__(xml,version)659 self.parse_offset()660 def parse_offset(self):661 try:662 xml_dict = _xml_to_dict(self._root)663 self.type_code = xml_dict.get('offset_type_code')664 self.value = xml_dict.get('offset_value')665 self.description = xml_dict.get('offset_description')666 self.is_vertical = xml_dict.get('offset_is_vertical')667 self.azimuth_degrees = xml_dict.get('offset_azimuth_degrees')668 unit = self._root.find('unit')669 if self._ns == 'wml1.0':670 self.unit = Unit1_0(unit, self._ns) if unit is not None else None671 else:672 self.unit = Unit(unit,self._ns) if unit is not None else None673 except:674 raise675class Method(XMLParser):676 def __init__(self,xml,version='wml1.1'):677 super(Method,self).__init__(xml,version)678 self.parse_method()679 def parse_method(self):680 try:681 xml_dict = _xml_to_dict(self._root)682 self.code = xml_dict.get('method_code')683 self.description = xml_dict.get('method_description')684 self.link = xml_dict.get('method_link')685 self.id = self._root.attrib.get('methodID')686 except:687 raise688class QualityControlLevel(XMLParser):689 def __init__(self,xml,version='wml1.1'):690 super(QualityControlLevel,self).__init__(xml,version)691 self.parse_qcl()692 def parse_qcl(self):693 try:694 xml_dict = _xml_to_dict(self._root)695 self.code = xml_dict.get('quality_control_level_code')696 self.definition = xml_dict.get('definition')697 self.explanation = xml_dict.get('explanation')698 self.id = self._root.attrib.get('qualityControlLevelID')699 except:700 raise701class CensorCode(XMLParser):702 def __init__(self,xml,version='wml1.1'):703 super(CensorCode,self).__init__(xml,version)704 self.parse_censorcode()705 def parse_censorcode(self):706 try:707 xml_dict = _xml_to_dict(self._root)708 self.code = xml_dict.get('censor_code')709 self.description = xml_dict.get('censor_code_description')710 self.id = self._root.attrib.get('censorCodeID')711 except:712 raise713class VariablesResponse(XMLParser):714 """715 Parses the response from a 'GetVariableInfo' request716 Parameters717 ===========718 :xmlio - A file-like object that holds the xml response from the request.719 Return720 =======721 An object constructed from a dictionary parse of the response. The object has get access to its variables and722 can also be used as an iterator.723 """724 def __init__(self,xml,version='wml1.1'):725 super(VariablesResponse,self).__init__(xml,version)726 self.parse_variablesresponse()727 def __iter__(self):728 for v in self.variables:729 yield v730 def __getitem__(self,key):731 if isinstance(key,int) and key < len(self.variables):732 return self.variables[key]733 if isinstance(key,str):734 v = [var for var in self.variables if var.variable_code == key]735 if len(v) > 0:736 return v[0]737 v = [var for var in self.variables if var.variable_name == key]738 if len(v) > 0:739 return v[0]740 raise KeyError('Unknown key ' + str(key))741 """Accessor properties/methods"""742 @property743 def variable_names(self):744 return list(set([var.variable_name for var in self.variables]))745 @property746 def variable_codes(self):747 return [var.variable_code for var in self.variables]748 def parse_variablesresponse(self):749 try:750 qi = self._find('queryInfo')751 self.query_info = QueryInfo(qi, self._ns) if qi is not None else None752 varis = self._find('variables')753 self.variables = [Variable(var,self._ns) for var in varis.findall(ns(self._ns) + 'variable')]754 except:...

Full Screen

Full Screen

setup.py

Source:setup.py Github

copy

Full Screen

1#!/usr/bin/env python2# This file is part of ranger, the console file manager.3# License: GNU GPL version 3, see the file "AUTHORS" for details.4import distutils.core5import os.path6import ranger7def _findall(directory):8 return [os.path.join(directory, f) for f in os.listdir(directory) \9 if os.path.isfile(os.path.join(directory, f))]10if __name__ == '__main__':11 distutils.core.setup(12 name='ranger',13 description='Vim-like file manager',14 long_description=ranger.__doc__,15 version=ranger.__version__,16 author=ranger.__author__,17 author_email=ranger.__email__,18 license=ranger.__license__,19 url='http://ranger.nongnu.org',20 scripts=['scripts/ranger', 'scripts/rifle'],21 data_files=[22 ('share/applications',23 ['doc/ranger.desktop']),24 ('share/man/man1',25 ['doc/ranger.1',26 'doc/rifle.1']),27 ('share/doc/ranger',28 ['README.md',29 'CHANGELOG.md',30 'HACKING.md',31 'doc/colorschemes.txt']),32 ('share/doc/ranger/config/colorschemes',33 _findall('doc/config/colorschemes')),34 ('share/doc/ranger/config', _findall('doc/config')),35 ('share/doc/ranger/tools', _findall('doc/tools')),36 ('share/doc/ranger/examples', _findall('examples')),37 ],38 package_data={'ranger': ['data/*', 'config/rc.conf',39 'config/rifle.conf']},40 packages=('ranger',41 'ranger.api',42 'ranger.colorschemes',43 'ranger.container',44 'ranger.core',45 'ranger.config',46 'ranger.ext',47 'ranger.gui',48 'ranger.gui.widgets',...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run pyatom automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful