def matchingSens(osmLine): index = 0 # Looping over the stations because sometimes some of them # are not the same depending of the direction while index+2 < len(osmLine["sensA"])-1: firstStationName = ots.stationName(osmLine["sensA"][index+0]) secondStationName = ots.stationName(osmLine["sensA"][index+1]) if secondStationName == firstStationName: secondStationName = ots.stationName(osmLine["sensA"][index+2]) lineId = mbt.idForLine(osmLine["name"]) #ordered Stations list from mobitrans lineStations = mbt.stationsForLine(lineId, 1) stationList = [x["name"] for x in lineStations] result1 = difflib.get_close_matches(firstStationName, stationList) result2 = difflib.get_close_matches(secondStationName, stationList) #second chance, looking for substrings: if not result1: result1 = [s for s in stationList if s in firstStationName] if not result2: result2 = [s for s in stationList if s in secondStationName] # third change, doing the same but with no accent nor diacritics if not result1: asciiName = ''.join(c for c in unicodedata.normalize('NFD', firstStationName) if unicodedata.category(c) != 'Mn') result1 = [s for s in stationList if s in asciiName] if not result2: asciiName = ''.join(c for c in unicodedata.normalize('NFD', secondStationName) if unicodedata.category(c) != 'Mn') result2 = [s for s in stationList if s in asciiName] if result1 and result2: break else: index += 1 if not result1 or not result2: #print(firstStationName, secondStationName, stationList) print("\n*No match found while calculating directions for line", osmLine["name"], firstStationName, secondStationName, "") print(stationList) return index1 = stationList.index(result1[0]) index2 = stationList.index(result2[0]) if index1 < index2: sens = 1 else: sens = 2 return sens
def fetchStations(self): # Overpass doesn't provide a ordered detailled list, so it uses the base OSM API. url = "http://api.openstreetmap.org/api/0.6/relation/" + str(self.id) #f = urlopen(url) #s = f.read() s = localPageCache.getPage(url) soup = BeautifulSoup(s) orderedStations = soup.findAll(member_role_stop) for aStation in orderedStations: # Only storing the OSM node ID of the station self.__stations.append(int(aStation["ref"])) if not ots.hasStation(int(aStation["ref"])): print("Error : ", int(aStation["ref"]), "not present")
def dispatchDirections(self, index): # Using the first direction for the base of the comparison. baseStations = self.directions[0].stations() # First direction is sensA by default if index < len(baseStations): aId = baseStations[index] else: print(" ", len(baseStations), self.name) quit() # Related stations are all the stations at location (== same name) relatedStations = ots.relatedStations(aId) # Search for a station present in every direction for aDirection in self.directions[ 1:]: # Since index 0 is the base for this, skipping it every time. if ots.isSoloStation(aId): if aId not in aDirection.stations(): return else: if not set.intersection(set(aDirection.stations()), set(relatedStations)): return False # Skipping the station if its present multiple times on a track (ex: dead-end loop in middle of the line) if ots.hasDuplicateName(baseStations, index): return False # Skipping when previous and next station == previous station (occurs in dead-end loop like above) if index - 1 >= 0 and index + 1 < len( self.directions[0].stations()): # bounds checking if ots.stationName(baseStations[index - 1]) == ots.stationName( baseStations[index + 1]): return False # At this point we have to station we need # now comparing the next or the previous station nextStationId = baseStations[index + 1] if (index > 0): previousStationId = baseStations[index - 1] # Lists for where the station will be added sensA = [self.directions[0] ] # Already adding stations of the first direction sensB = list() self.terminusA.append(self.directions[0][-1]) # Actually dispatching the directions for aDirection in self.directions[1:]: # skipping index 0 # Index of the sharedStation for this direction # The intersection should return only one item. # If not there is a problem in selecting the station if ots.isSoloStation(aId): sharedStation = [aId] else: sharedStation = set.intersection(set(aDirection.stations()), set(relatedStations)) if len(sharedStation) == 1: # Index of the station for this direction stationIndex = aDirection.stations().index(sharedStation.pop()) # The next Station is the same than for the 1st sub-direction if stationIndex < len( aDirection.stations()) - 1 and ots.isSameStation( nextStationId, aDirection[stationIndex + 1]): sensA.append(aDirection) self.terminusA.append(aDirection[-1]) # The previous Station is the same than for the 1st sub-direction elif index > 0 and ots.isSameStation( previousStationId, aDirection[stationIndex - 1]): sensA.append(aDirection) self.terminusA.append(aDirection[-1]) # Every other case : It's the opposite direction of 1st sub-direction else: self.terminusB.append(aDirection[-1]) sensB.append(aDirection) else: print("ERROR IN SHARED STATION") mergedDirectionA = list(itertools.chain.from_iterable(sensA)) mergedDirectionB = list(itertools.chain.from_iterable(sensB)) # Removing partial terminus, only keeping branch terminus & trunk terminus for aTerminus in self.terminusA: # sensA is a list of osmDirection objet, can't iterate directly therefore using itertools if mergedDirectionA.count(aTerminus) > 1: if (aTerminus == 1804374990): print("coucou", mergedDirectionA.count(aTerminus)) self.terminusA.remove(aTerminus) mergedDirectionA.remove(aTerminus) for aTerminus in self.terminusB: # sensB is a list of osmDirection objet, can't iterate directly therefore using itertools if mergedDirectionB.count(aTerminus) > 1: self.terminusB.remove(aTerminus) mergedDirectionB.remove(aTerminus) # Making a bigList of the stations for each direction. Always with unique values and ordered # Ordered is important for the first direction as it will be use to compare with Mobitrans self.stationsSensA[:] = unique(itertools.chain.from_iterable(sensA)) self.stationsSensB[:] = unique(itertools.chain.from_iterable(sensB)) return True
def associateOppositeStations(linesDict): resultList = list() for aLine in linesDict: if "MbtId" not in aLine: continue aLineDict = dict() lineName = aLine["name"] lineId = aLine["MbtId"] if "OsmId" in aLine: aLineDict["osmId"] = aLine["OsmId"] aLineDict["mbtId"] = lineId aLineDict["name"] = lineName aLineDict["sens1"] = list() aLineDict["sens2"] = list() if not "sens1" in aLine: print(aLine) for osmStationId in aLine["sens1"]: aDict = dict() aDict["name"] = ots.stationName(osmStationId) aDict["osmId"] = osmStationId aDict["mbtId"] = mbt.stationIdForLine(aDict["name"], lineId, 1) aDict["terminus"] = osmStationId in aLine["terminus1"] # If there is no mobitrans id for this station on the line with sens1, not adding it # /!\ Data should probably be changed on OSM to match with the one from Mobitrans if aDict["mbtId"] is None: continue aLineDict["sens1"].append(aDict) for osmStationId in aLine["sens2"]: aDict = dict() aDict["name"] = ots.stationName(osmStationId) aDict["osmId"] = osmStationId aDict["mbtId"] = mbt.stationIdForLine(aDict["name"], lineId, 2) aDict["terminus"] = osmStationId in aLine["terminus2"] # If there is no mobitrans id for this station on the line with sens2, not adding it # /!\ Data should probably be changed on OSM to match with the one from Mobitrans if aDict["mbtId"] is None: continue aLineDict["sens2"].append(aDict) resultList.append(aLineDict) if verbose: (termWidth, height) = console.getTerminalSize() pprint.pprint(resultList, width=termWidth) # jsonData = json.dumps(resultList, indent=2, sort_keys=True) exportToXml(resultList) return resultList
def dispatchDirections(self, index): # Using the first direction for the base of the comparison. baseStations = self.directions[0].stations() # First direction is sensA by default if index < len(baseStations): aId = baseStations[index] else: print (" ", len(baseStations), self.name) quit() # Related stations are all the stations at location (== same name) relatedStations = ots.relatedStations(aId) # Search for a station present in every direction for aDirection in self.directions[1:]: # Since index 0 is the base for this, skipping it every time. if ots.isSoloStation(aId): if aId not in aDirection.stations(): return else: if not set.intersection(set(aDirection.stations()),set(relatedStations)): return False # Skipping the station if its present multiple times on a track (ex: dead-end loop in middle of the line) if ots.hasDuplicateName(baseStations, index): return False # Skipping when previous and next station == previous station (occurs in dead-end loop like above) if index-1 >= 0 and index+1 < len(self.directions[0].stations()): # bounds checking if ots.stationName(baseStations[index-1]) == ots.stationName(baseStations[index+1]): return False # At this point we have to station we need # now comparing the next or the previous station nextStationId = baseStations[index+1] if(index > 0): previousStationId = baseStations[index-1] # Lists for where the station will be added sensA = [self.directions[0]] # Already adding stations of the first direction sensB = list() self.terminusA.append(self.directions[0][-1]) # Actually dispatching the directions for aDirection in self.directions[1:]: # skipping index 0 # Index of the sharedStation for this direction # The intersection should return only one item. # If not there is a problem in selecting the station if ots.isSoloStation(aId): sharedStation = [aId] else: sharedStation = set.intersection(set(aDirection.stations()), set(relatedStations)) if len(sharedStation) == 1: # Index of the station for this direction stationIndex = aDirection.stations().index(sharedStation.pop()) # The next Station is the same than for the 1st sub-direction if stationIndex < len(aDirection.stations())-1 and ots.isSameStation(nextStationId, aDirection[stationIndex+1]): sensA.append(aDirection) self.terminusA.append(aDirection[-1]) # The previous Station is the same than for the 1st sub-direction elif index > 0 and ots.isSameStation(previousStationId, aDirection[stationIndex-1]): sensA.append(aDirection) self.terminusA.append(aDirection[-1]) # Every other case : It's the opposite direction of 1st sub-direction else: self.terminusB.append(aDirection[-1]) sensB.append(aDirection) else: print("ERROR IN SHARED STATION") mergedDirectionA = list(itertools.chain.from_iterable(sensA)) mergedDirectionB = list(itertools.chain.from_iterable(sensB)) # Removing partial terminus, only keeping branch terminus & trunk terminus for aTerminus in self.terminusA: # sensA is a list of osmDirection objet, can't iterate directly therefore using itertools if mergedDirectionA.count(aTerminus) > 1: if(aTerminus == 1804374990): print("coucou", mergedDirectionA.count(aTerminus)) self.terminusA.remove(aTerminus) mergedDirectionA.remove(aTerminus) for aTerminus in self.terminusB: # sensB is a list of osmDirection objet, can't iterate directly therefore using itertools if mergedDirectionB.count(aTerminus) > 1: self.terminusB.remove(aTerminus) mergedDirectionB.remove(aTerminus) # Making a bigList of the stations for each direction. Always with unique values and ordered # Ordered is important for the first direction as it will be use to compare with Mobitrans self.stationsSensA[:] = unique(itertools.chain.from_iterable(sensA)) self.stationsSensB[:] = unique(itertools.chain.from_iterable(sensB)) return True