コード例 #1
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_infotext(self, filename, sprache):
		"""Lesen der Datei INFOTEXT
			INFOTEXT aus INFO+ ist sprachabhängig in dem Format INFOTEXT_XX
		"""
		if sprache.strip():	# wird keine Sprache übergeben, dann bleibt der Dateiname unverändert
			filename = filename + '_' + sprache
		else:
			sprache = '--'
		logger.info('lesen und verarbeiten der Datei '+filename)

		infotext_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			infotext_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										+line[:7]+';'
										+sprache.lower()+';'
										+line[8:].replace(';','\;')
										+'\n')
		
		infotext_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_INFOTEXT_TAB (fk_eckdatenid,infotextno,languagecode,infotext) FROM STDIN USING DELIMITERS ';' NULL AS ''", infotext_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		infotext_strIO.close()
コード例 #2
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_bahnhof(self, filename):
		"""Lesen der Datei BAHNHOF"""
		logger.info('lesen und verarbeiten der Datei BAHNHOF')
		bahnhof_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			stopname = ''
			stopnamelong = ''
			stopnameshort = ''
			stopnamealias = ''
			# Die Analyse betrachtet noch keine Sprachangaben
			for tmpName in re.split(">", line[12:62].strip()):
				pos = tmpName.find("<");
				typeinfo = tmpName[pos:]
				name = tmpName[:pos].replace("$", "")
				for c in typeinfo[1:]:
					if c == "1": stopname = name[:30]
					if c == "2": stopnamelong = name[:50]
					if c == "3": stopnameshort = name
					if c == "4": stopnamealias = name

			bahnhof_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:7].strip()+';'
										 +line[8:11].strip()+';'
										 +stopname+';'
										 +stopnamelong+';'
										 +stopnameshort+';'
										 +stopnamealias
										+'\n')
		bahnhof_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_BAHNHOF_TAB (fk_eckdatenid,stopno,transportUnion,stopname,stopnamelong,stopnameshort,stopnamealias) FROM STDIN USING DELIMITERS ';' NULL AS ''", bahnhof_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		bahnhof_strIO.close()
コード例 #3
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_bitfeld(self, filename):
		"""Lesen der Datei BITFELD"""
		logger.info('lesen und verarbeiten der Datei BITFELD')
		bitfeld_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n','')
			bitfield = str(Bits(hex=line[7:]).bin)[2:-2]
			daycnt = (self.__eckdaten_validTo - self.__eckdaten_validFrom).days
			# Aufbauen des Datums-Array auf Grund der gesetzen Bits
			validDays = []
			i = 0
			while i <= daycnt:
				if bitfield[i] == "1":
					validDays.append(str(self.__eckdaten_validFrom + timedelta(days=i)))
				i += 1

			if len(validDays) == 0:
				validDaysString = "{}"
			else:
				validDaysString = "{'" + "','".join(map(str,validDays)) + "'}"

			bitfeld_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										+line[:6]+';'
										+line[7:]+';'
										+bitfield+';'
										+validDaysString
										+'\n')
		bitfeld_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_BITFELD_TAB (fk_eckdatenid,bitfieldno,bitfield,bitfieldextend,bitfieldarray) FROM STDIN USING DELIMITERS ';' NULL AS ''",bitfeld_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		bitfeld_strIO.close()
コード例 #4
0
def generate_timetable_from_hrdf(eckdatenId, generateFrom, generateTo, dbname, host):
	"""Generiert einen Tagesfahrplan aus den HRDF-Daten für die
	Betriebstage im angegebenen Zeitbereich

	eckdatenId -- ID aus der Tabelle HRDF_ECKDATEN_TAB
	generateFrom -- Beginn des Zeitbereichs, für den der Tagesfahrlan generiert wird (String-Format '%d.%m.%Y')
	generateTo -- Ende des Zeitbereichs, für den der Tagesfahrplan generiert wird (String-Format '%d.%m.%Y')
	dbname -- Datenbankname
	host -- Host auf dem die Datenbank läuft
	"""
	hrdf_db = HrdfDB(dbname, host, "hrdf", "bmHRDF")
	if hrdf_db.connect():
	
		# Initialisierung des HRDF-TTGenerators
		ttGenerator = HrdfTTG(hrdf_db)
		dtGenerateFrom = datetime.strptime(generateFrom, '%d.%m.%Y').date()
		dtGenerateTo = datetime.strptime(generateTo, '%d.%m.%Y').date()
		logger.info("Generierung des Tagesfahrplan für den Zeitraum von {:%d.%m.%Y} bis {:%d.%m.%Y}:".format(dtGenerateFrom, dtGenerateTo))
		if ( ttGenerator.setup(eckdatenId, dtGenerateFrom, dtGenerateTo) ):
			iErrorCnt = ttGenerator.generateTT()
			if ( iErrorCnt == 0):
				logger.info("Der Tagesfahrplan für den Zeitraum von {:%d.%m.%Y} bis {:%d.%m.%Y} wurde erfolgreich generiert".format(dtGenerateFrom, dtGenerateTo))
			else:
				logger.warning("Der Tagesfahrplan für den Zeitraum von {:%d.%m.%Y} bis {:%d.%m.%Y} konnte nicht vollständig generiert werden. {} fehlerhafte Fahrten".format(dtGenerateFrom, dtGenerateTo, iErrorCnt))
		else:
			logger.error("Der Tagesfahrplan-Generator konnte nicht initialisiert werden")
			
	else:
		logger.error("Es konnte keine Verbindung zur Datenbank aufgebaut werden")
コード例 #5
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_zugart(self, filename):
		"""Lesen der Datei ZUGART"""
		logger.info('lesen und verarbeiten der Datei ZUGART')
		zugart_strIO = StringIO()
		zugartcategory_strIO = StringIO()
		zugartclass_strIO = StringIO()
		zugartoption_strIO = StringIO()

		languagecode = "--"
		bTextblock = False
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			# Eine Zeile mit dem Inhalt "<text>" gibt an, dass nun nur noch die Textangaben in verschiedenen Sprachen folgen
			if not bTextblock:
				# solange das nicht der Fall ist, sollen die Daten als Zugarten weiter eingearbeitet werden
				if line != '<text>':
					# Der string setzt sich aus folgenden Elementen zusammen: code,produktklasse,tarifgruppe,ausgabesteuerung,gattungsbezeichnung,zuschlag,flag,gattungsbildernamen,kategorienummer
					zugart_strIO.write(self.__fkdict['fk_eckdatenid']+';'
											+line[:3].strip()+';'
											+line[4:6].strip()+';'
											+line[7:8]+';'
											+line[9:10]+';'
											+line[11:19].strip()+';'
											+line[20:21].strip()+';'
											+line[22:23]+';'
											+line[24:28].strip()+';'
											+line[30:33]+
											'\n')
				# sobald die Textangaben beginnen, werden die Daten sprachspezifisch in das jeweilige dictionary geschrieben
				else:
					bTextblock = True
			elif line[0] == '<':
				languagecode = line[1:3].lower()
			elif line[:8] == 'category':
				zugartcategory_strIO.write(self.__fkdict['fk_eckdatenid']+';'+line[8:11]+';'+languagecode+';'+line[12:]+'\n')
			elif line[:6] == 'option':
				zugartoption_strIO.write(self.__fkdict['fk_eckdatenid']+';'+line[6:8]+';'+languagecode+';'+line[9:]+'\n')
			elif line[:5] == 'class':
				zugartclass_strIO.write(self.__fkdict['fk_eckdatenid']+';'+line[5:7]+';'+languagecode+';'+line[8:]+'\n')

		zugart_strIO.seek(0)
		zugartcategory_strIO.seek(0)
		zugartclass_strIO.seek(0)
		zugartoption_strIO.seek(0)

		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_ZUGART_TAB (fk_eckdatenid,categorycode,classno,tariffgroup,outputcontrol,categorydesc,extracharge,flags,categoryimage,categoryno) FROM STDIN USING DELIMITERS ';' NULL AS ''", zugart_strIO)
		cur.copy_expert("COPY HRDF_ZUGARTKategorie_TAB (fk_eckdatenid,categoryno,languagecode,categorytext) FROM STDIN USING DELIMITERS ';' NULL AS ''",zugartcategory_strIO)
		cur.copy_expert("COPY HRDF_ZUGARTKlasse_TAB (fk_eckdatenid,classno,languagecode,classtext) FROM STDIN USING DELIMITERS ';' NULL AS ''",zugartclass_strIO)
		cur.copy_expert("COPY HRDF_ZUGARTOption_TAB (fk_eckdatenid,optionno,languagecode,optiontext) FROM STDIN USING DELIMITERS ';' NULL AS ''",zugartoption_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		zugart_strIO.close()
		zugartcategory_strIO.close()
		zugartclass_strIO.close()
		zugartoption_strIO.close()
コード例 #6
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def determine_linesperstop(self):
		"""Ermitteln und Schreiben der Linien, die in der aktuellen Fahrplanperiode an einem Halt vorkommen"""
		logger.info('ermitteln der Linien pro Halt')
		sql_stopsLookup = "INSERT INTO HRDF.HRDF_LINESPERSTOP_TAB (fk_eckdatenid, stopno, operationalno, lineno, categorycode) "\
					"(SELECT DISTINCT fahrt.fk_eckdatenid, flw.stopno, fahrt.operationalno, line.lineno, cat.categorycode "\
					"FROM hrdf.hrdf_fplanfahrtlaufweg_tab flw "\
					"LEFT OUTER JOIN hrdf.hrdf_fplanfahrt_tab fahrt on flw.fk_fplanfahrtid = fahrt.id and flw.fk_eckdatenid = fahrt.fk_eckdatenid "\
					"LEFT OUTER JOIN hrdf.hrdf_fplanfahrtl_tab line on line.fk_fplanfahrtid = fahrt.id and line.fk_eckdatenid = fahrt.fk_eckdatenid "\
					"LEFT OUTER JOIN hrdf.hrdf_fplanfahrtg_tab cat on cat.fk_fplanfahrtid = fahrt.id and cat.fk_eckdatenid = fahrt.fk_eckdatenid "\
					"WHERE fahrt.fk_eckdatenid = %s)"

		curLookup = self.__hrdfdb.connection.cursor()
		curLookup.execute(sql_stopsLookup, (self.__fkdict['fk_eckdatenid'],))
		self.__hrdfdb.connection.commit()
		curLookup.close()
コード例 #7
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_richtung(self, filename):
		"""Lesen der Datei RICHTUNG"""
		logger.info('lesen und verarbeiten der Datei RICHTUNG')
		richtung_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			richtung_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:7].strip()+';'
										 +line[8:59].strip()
										+'\n')
		richtung_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_RICHTUNG_TAB (fk_eckdatenid,directioncode, directiontext) FROM STDIN USING DELIMITERS ';' NULL AS ''", richtung_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		richtung_strIO.close()
コード例 #8
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_bfprios(self, filename):
		"""Lesen der Datei BFPRIOS"""
		logger.info('lesen und verarbeiten der Datei BFPRIOS')
		bfprios_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			bfprios_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:7]+';'
										 +line[8:10]
										+'\n')
		bfprios_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_BFPRIOS_TAB (fk_eckdatenid,stopno,transferprio) FROM STDIN USING DELIMITERS ';' NULL AS ''", bfprios_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		bfprios_strIO.close()
コード例 #9
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_attribut(self, filename, sprache):
		"""Lesen der Datei ATTRIBUT
			ATTRIBUT aus INFO+ ist sprachabhängig in dem Format ATTRIBUT_XX
		"""
		if sprache.strip():	# wird keine Sprache übergeben, dann bleibt der Dateiname unverändert
			filename = filename + '_' + sprache
		else:
			sprache = '--'
		logger.info('lesen und verarbeiten der Datei '+filename)

		# Erster Durchlauf um die Ausgabeattributcodes für Teil- und Vollstrecke zu ermitteln
		targetcodes = {}
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			if line[:1] == '#':
				targetcodes[line[2:4].strip()] = [line[5:7].strip(), line[8:10].strip()]

		attribute_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			if line[:1] != '#':
				attrcode = line[:2].strip()
				if attrcode in targetcodes:
					attrcode_section = targetcodes[attrcode][0]
					attrcode_complete = targetcodes[attrcode][1]
				else:
					attrcode_section = ""
					attrcode_complete = ""

				attribute_strIO.write(self.__fkdict['fk_eckdatenid']+';'
											+attrcode+';'
											+sprache.lower()+';'
											+line[3:4]+';'
											+line[5:8]+';'
											+line[9:11]+';'
											+line[12:-1].replace(';','\;')+';'
											+attrcode_section+';'
											+attrcode_complete
											+'\n')
		
		attribute_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_ATTRIBUT_TAB (fk_eckdatenid,attributecode,languagecode,stopcontext,outputprio,outputpriosort,attributetext,outputforsection,outputforcomplete) FROM STDIN USING DELIMITERS ';' NULL AS ''", attribute_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		attribute_strIO.close()
コード例 #10
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def readfiles(self):
		"""Liest die gewünschten HRDF-Dateien und schreibt sie in die Datenbank"""

		for filename in self.__hrdffiles:
			if filename == "ECKDATEN":
				self.read_eckdaten(filename)
			elif filename == "BITFELD":
				self.read_bitfeld(filename)
			elif filename == "RICHTUNG":
				self.read_richtung(filename)
			elif filename == "ZUGART":
				self.read_zugart(filename)
			elif filename == "ATTRIBUT":
				self.read_attribut(filename, "DE")
				self.read_attribut(filename, "EN")
				self.read_attribut(filename, "FR")
				self.read_attribut(filename, "IT")
			elif filename == "INFOTEXT":
				self.read_infotext(filename, "DE")
				self.read_infotext(filename, "EN")
				self.read_infotext(filename, "FR")
				self.read_infotext(filename, "IT")
			elif filename == "FPLAN":
				self.read_fplan(filename)
			elif filename == "BAHNHOF":
				self.read_bahnhof(filename)
			elif filename == "GLEIS":
				self.read_gleis(filename)
			elif filename == "DURCHBI":
				self.read_durchbi(filename)
			elif filename == "BFKOORD_GEO":
				self.read_bfkoordgeo(filename)
			elif filename == "UMSTEIGB":
				self.read_umsteigb(filename)
			elif filename == "BFPRIOS":
				self.read_bfprios(filename)
			elif filename == "METABHF":
				self.read_metabhf(filename)
			else:
				logger.error("Das Lesen der Datei ["+filename+"] wird nicht unterstützt")

		# Aufbereitung und Verdichtung der importierten Daten
		self.determine_linesperstop()
		self.determine_tripcount()				
				
		logger.info("Der HRDF-Import <{}> wurde eingearbeitet".format(self.__hrdfzip.filename))
コード例 #11
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_bfkoordgeo(self, filename):
		"""Lesen der Datei BFKOORD_GEO"""
		logger.info('lesen und verarbeiten der Datei BFKOORD_GEO')
		bfkoordgeo_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			bfkoordgeo_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:7]+';'
										 +line[8:18]+';'
										 +line[19:29]+';'
										 +line[30:36]
										+'\n')
		bfkoordgeo_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_BFKOORD_TAB (fk_eckdatenid,stopno,longitude_geo,latitude_geo,altitude_geo) FROM STDIN USING DELIMITERS ';' NULL AS ''", bfkoordgeo_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		bfkoordgeo_strIO.close()
コード例 #12
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_eckdaten(self, filename):
		"""Lesen der Datei ECKDATEN"""
		logger.info('lesen und verarbeiten der Datei ECKDATEN')
		lines = self.__hrdfzip.read(filename).decode(self.__charset).split('\r\n')[:-1]
 		# spezifisch für SBB-Version sind die Trenner in der Bezeichnung, die hier in separate Felder geschrieben werden
		bezeichnung,exportdatum,hrdfversion,lieferant = lines[2].split('$')
		cur = self.__hrdfdb.connection.cursor()
		sql_string = "INSERT INTO HRDF_ECKDATEN_TAB (importFileName, importDateTime, validFrom, validTo, descriptionhrdf, description, creationdatetime, hrdfversion, exportsystem) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s) RETURNING id;" 
		importFileName = os.path.basename(self.__hrdfzip.filename)
		importDateTime = str(datetime.now())
		validFrom = str(datetime.strptime(lines[0], '%d.%m.%Y').date())
		validTo = str(datetime.strptime(lines[1], '%d.%m.%Y').date())
		exportdatum = str(datetime.strptime(exportdatum, '%d.%m.%Y %H:%M:%S'))
		cur.execute(sql_string, (importFileName, importDateTime, validFrom, validTo, lines[2], bezeichnung, exportdatum, hrdfversion, lieferant))
		self.__fkdict["fk_eckdatenid"] = str(cur.fetchone()[0])
		self.__hrdfdb.connection.commit()
		self.__eckdaten_validFrom = datetime.strptime(lines[0], '%d.%m.%Y').date()
		self.__eckdaten_validTo = datetime.strptime(lines[1], '%d.%m.%Y').date()
		cur.close()
コード例 #13
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def determine_tripcount(self):
		"""Ermitteln und Schreiben der Anzahl Fahrten (Linien/Kategorie) pro Verwaltungsnummer - Taktdefinitionen mit eingeschlossen"""
		logger.info('ermitteln der Anzahl Fahrten (Linien/Kategorie) pro Verwaltung')

		sql_tripsLookup = "INSERT INTO HRDF.HRDF_TripCount_Operator_TAB (fk_eckdatenid, operationalno, lineno, categorycode, tripcount) "\
					"(SELECT fahrt.fk_eckdatenid, fahrt.operationalno, line.lineno, cat.categorycode, sum(coalesce(array_length(bit.bitfieldarray, 1), eckdaten.maxdays)*coalesce(cyclecount+1,1)) "\
					"   FROM hrdf.hrdf_fplanfahrt_tab fahrt "\
					"        inner join (SELECT id, validto + 1 - validfrom as maxdays FROM hrdf.hrdf_eckdaten_tab) eckdaten on fahrt.fk_eckdatenid = eckdaten.id "\
					"        LEFT OUTER JOIN hrdf.hrdf_fplanfahrtve_tab ve on fahrt.fk_eckdatenid = ve.fk_eckdatenid and fahrt.id = ve.fk_fplanfahrtid "\
					"        LEFT OUTER JOIN hrdf.hrdf_bitfeld_tab bit on ve.bitfieldno = bit.bitfieldno and ve.fk_eckdatenid = bit.fk_eckdatenid "\
					"        LEFT OUTER JOIN hrdf.hrdf_fplanfahrtl_tab line on line.fk_fplanfahrtid = fahrt.id and line.fk_eckdatenid = fahrt.fk_eckdatenid "\
					"        LEFT OUTER JOIN hrdf.hrdf_fplanfahrtg_tab cat on cat.fk_fplanfahrtid = fahrt.id and cat.fk_eckdatenid = fahrt.fk_eckdatenid "\
					"  WHERE fahrt.fk_eckdatenid = %s "\
					"  GROUP BY fahrt.fk_eckdatenid, fahrt.operationalno, line.lineno, cat.categorycode)"

		curLookup = self.__hrdfdb.connection.cursor()
		curLookup.execute(sql_tripsLookup, (self.__fkdict['fk_eckdatenid'],))
		self.__hrdfdb.connection.commit()
		curLookup.close()
コード例 #14
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_gleis(self, filename):
		"""Lesen der Datei GLEIS"""
		logger.info('lesen und verarbeiten der Datei GLEIS')
		gleis_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			gleis_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:7].strip()+';'
										 +line[8:13].strip()+';'
										 +line[14:20].strip()+';'
										 +line[21:29].strip()+';'
										 +line[30:34].strip()+';'
										 +line[35:41].strip()
										+'\n')
		gleis_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_GLEIS_TAB (fk_eckdatenid,stopno,tripno,operationalno,stoppointtext,stoppointtime,bitfieldno) FROM STDIN USING DELIMITERS ';' NULL AS ''", gleis_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		gleis_strIO.close()
コード例 #15
0
ファイル: hrdfTTG.py プロジェクト: BERNMOBIL/hrdfreader
    def deleteDailyTimetable(self, eckdatenid, generationDay):
        """
		Die Funktion löscht den gewünschten Tagesfahrplan eines Fahrplanimports
		Nach dem Löschen des Tagesfahrplan wird der entsprechende Eintrag in der Eckdaten-Tabelle
		angepasst
		"""
        # Löschen des Tagesfahrplans
        curDeleteDay = self.__hrdfdb.connection.cursor()
        sql_delDay = "DELETE FROM HRDF_DailyTimeTable_TAB WHERE fk_eckdatenid = %s AND operatingday = %s"
        curDeleteDay.execute(sql_delDay, (eckdatenid, str(generationDay)))
        deletedRows = curDeleteDay.rowcount
        logger.info(
            "{:%d.%m.%Y} => {} bestehende Einträge wurden geloescht".format(
                generationDay, deletedRows))
        curDeleteDay.close()

        # Anpassen des Eintrags in der Eckdaten-Tabelle
        curUpdTTGenerated = self.__hrdfdb.connection.cursor()
        sql_updTTGenerated = "UPDATE HRDF.HRDF_Eckdaten_TAB SET ttgenerated = array_remove(ttgenerated, %s) WHERE id = %s"
        curUpdTTGenerated.execute(sql_updTTGenerated,
                                  (str(generationDay), eckdatenid))
        curUpdTTGenerated.close()
        self.__hrdfdb.connection.commit()
コード例 #16
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_durchbi(self, filename):
		"""Lesen der Datei DURCHBI"""
		logger.info('lesen und verarbeiten der Datei DURCHBI')
		durchbi_strIO = StringIO()
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			durchbi_strIO.write(self.__fkdict['fk_eckdatenid']+';'
										 +line[:5]+';'
										 +line[6:12].strip()+';'
										 +line[13:20]+';'
										 +line[21:26]+';'
										 +line[27:33].strip()+';'
										 +line[34:40]+';'
										 +line[41:48]+';'
										 +line[49:51].strip()+';'
										 +line[53:].strip()
										+'\n')
		durchbi_strIO.seek(0)
		cur = self.__hrdfdb.connection.cursor()
		cur.copy_expert("COPY HRDF_DURCHBI_TAB (fk_eckdatenid,tripno1,operationalno1,laststopno1,tripno2,operationalno2,bitfieldno,firststopno2,attribute,comment) FROM STDIN USING DELIMITERS ';' NULL AS ''", durchbi_strIO)
		self.__hrdfdb.connection.commit()
		cur.close()
		durchbi_strIO.close()
コード例 #17
0
ファイル: hrdfTTGCache.py プロジェクト: BERNMOBIL/hrdfreader
    def createCacheData(self, eckdatenid, generateFrom, generateTo):
        """ Die Funktion erstellt die Daten des Fahrplan-Cache """

        # Lookup der Verkehrstagesdefinitionen
        # für jeden erforderlichen Tag werden die Verkehrstagesdefinitionen geladen
        logger.info("Lookup der Verkehrstagesdefinitionen aufbauen")
        self.__bitfieldnumbersOfDay.clear()
        dayCnt = (generateTo - generateFrom).days
        i = 0
        while (i <= dayCnt):
            # Laden der Verkehrstagesdefinitionen für den Generierungstag als set() für schnellen Zugriff/Abfrage auf Existenz
            generationDay = generateFrom + timedelta(days=i)
            sql_selBitfieldNos = "SELECT bitfieldno FROM HRDF_Bitfeld_TAB where bitfieldarray @> ARRAY[%s::date] AND fk_eckdatenid = %s"
            curBits = self.__hrdfdb.connection.cursor()
            curBits.execute(sql_selBitfieldNos,
                            (str(generationDay), eckdatenid))
            bitfieldNos = curBits.fetchall()
            bitfieldnumbers = set()
            for bitfield in bitfieldNos:
                bitfieldnumbers.add(bitfield[0])
            curBits.close()
            self.__bitfieldnumbersOfDay[generationDay] = bitfieldnumbers
            # Tageszähler hochzählen und nächsten gewünschten Tag generieren
            i += 1

        # Lookup für Zugarten der Fahrplanfahrten
        logger.info("Lookup für Zugarten aufbauen")
        self.__fahrtZugartLookup.clear()
        sql_zugartLookup = "SELECT a.fk_fplanfahrtid, a.categorycode, fromstop, tostop, deptimefrom, arrtimeto, b.classno, b.categoryno"\
               "  FROM HRDF_FPlanFahrtG_TAB a, "\
               "       HRDF_ZUGART_TAB b "\
               " WHERE a.fk_eckdatenid = %s "\
               "   and a.fk_eckdatenid = b.fk_eckdatenid "\
               "   and a.categorycode = b.categorycode "\
               " ORDER BY a.fk_fplanfahrtid, a.id"

        curFahrtZugart = self.__hrdfdb.connection.cursor()
        curFahrtZugart.execute(sql_zugartLookup, (eckdatenid, ))
        fahrtZugarten = curFahrtZugart.fetchall()
        curFahrtZugart.close()
        for fahrtZugart in fahrtZugarten:
            fahrtId = fahrtZugart[0]
            if (fahrtId in self.__fahrtZugartLookup):
                self.__fahrtZugartLookup[fahrtId].append(fahrtZugart)
            else:
                zugartList = list()
                zugartList.append(fahrtZugart)
                self.__fahrtZugartLookup[fahrtId] = zugartList
        fahrtZugarten.clear()

        # Lookup für Bahnhofsnamen, Übergangszeiten (mit Standardzeit aus erster Zeile stopno 9999999) und GEO-Koordinaten
        logger.info("Lookup für Bahnhofsinformation aufbauen")
        sql_bahnhofLookup = "SELECT a.stopno, a.stopname, a.stopnamelong, a.stopnameshort, a.stopnamealias,"\
                "       coalesce(c.transfertime1,b.transfertime1) as transfertime1, coalesce(c.transfertime2,b.transfertime2) as transfertime2,"\
                "       d.transferprio,"\
                "       e.longitude_geo, e.latitude_geo, e.altitude_geo"\
                "  FROM HRDF_bahnhof_TAB a"\
             "       INNER JOIN (SELECT transfertime1, transfertime2, fk_eckdatenid FROM HRDF_umsteigb_TAB WHERE stopno = 9999999) b ON b.fk_eckdatenid = a.fk_eckdatenid"\
                "       LEFT OUTER JOIN HRDF_umsteigb_TAB c ON c.stopno = a.stopno AND c.fk_eckdatenid = a.fk_eckdatenid"\
                "       LEFT OUTER JOIN HRDF_bfprios_TAB d ON d.stopno = a.stopno AND d.fk_eckdatenid = a.fk_eckdatenid"\
                "       LEFT OUTER JOIN HRDF_bfkoord_TAB e ON e.stopno = a.stopno AND e.fk_eckdatenid = a.fk_eckdatenid"\
                " WHERE a.fk_eckdatenid = %s"
        curBahnhof = self.__hrdfdb.connection.cursor()
        curBahnhof.execute(sql_bahnhofLookup, (eckdatenid, ))
        bahnhoefe = curBahnhof.fetchall()
        curBahnhof.close()
        for bahnhof in bahnhoefe:
            self.__bahnhofLookup[bahnhof[0]] = bahnhof
        bahnhoefe.clear()

        # Lookup für Haltepositionstexte aufbauen (a.id zu beginn ist schneller als es wegzulassen oder am Ende zu stellen)
        # key => <FahrtId>-<StopNo>[-<StopPointTime>]
        logger.info("Lookup für Haltepositionstexte aufbauen")
        sql_selGleisData = "SELECT distinct a.id, a.id::varchar||'-'||stopno::varchar||coalesce('-'||stoppointtime::varchar,'') as key, stoppointtext, bitfieldno "\
               "  FROM HRDF_FPlanFahrt_TAB a, HRDF_GLEIS_TAB b "\
               " WHERE a.fk_eckdatenid = %s "\
               "   AND a.fk_eckdatenid = b.fk_eckdatenid "\
               "   AND b.tripno = a.tripno "\
               "   AND b.operationalno = a.operationalno "
        curGleis = self.__hrdfdb.connection.cursor()
        curGleis.execute(sql_selGleisData, (eckdatenid, ))
        allGleise = curGleis.fetchall()
        curGleis.close()
        for gleis in allGleise:
            if (gleis[3] is None or gleis[3] == 0):
                self.__gleisLookup[gleis[1]] = gleis[2]
            else:
                # Gleisangabe ist nur für einen bestimmten Tag => gehört dieser zur Generierungszeitspanne?
                # Wenn ja dann baue eine Gleis-Tages-LookupTabelle auf
                i = 0
                while (i <= dayCnt):
                    generationDay = generateFrom + timedelta(days=i)
                    if (generationDay in self.__bitfieldnumbersOfDay):
                        if (gleis[3]
                                in self.__bitfieldnumbersOfDay[generationDay]):
                            if (generationDay in self.__gleisLookupDay):
                                self.__gleisLookupDay[generationDay][
                                    gleis[1]] = gleis[2]
                            else:
                                gleisLookup = dict()
                                gleisLookup[gleis[1]] = gleis[2]
                                self.__gleisLookupDay[
                                    generationDay] = gleisLookup
                    # Tageszähler hochzählen und nächsten gewünschten Tag generieren
                    i += 1
        allGleise.clear()

        # Lookup für allTripStops erstellen. allTripStops einer Fahrt enthält den kompletten Laufweg der Fahrt.
        logger.info("Lookup für Laufwege der Fahrten aufbauen")
        sql_selStops = "SELECT stopno, stopname, sequenceno, arrtime, deptime, tripno, operationalno, ontripsign, "\
              "       fk_fplanfahrtid||'-'||stopno as gleislookup, "\
              "	   fk_fplanfahrtid||'-'||stopno||'-'||arrtime as gleislookupArr, "\
              "       fk_fplanfahrtid||'-'||stopno||'-'||deptime as gleislookupDep, "\
              "       fk_fplanfahrtid "\
                       "  FROM HRDF_FPlanFahrtLaufweg_TAB WHERE fk_eckdatenid = %s ORDER BY fk_fplanfahrtid, sequenceno"
        curStop = self.__hrdfdb.connection.cursor()
        curStop.execute(sql_selStops, (eckdatenid, ))
        allTripStops = curStop.fetchall()
        curStop.close()
        for tripStop in allTripStops:
            if (tripStop[11] in self.__allTripStopsLookup):
                self.__allTripStopsLookup[tripStop[11]].append(tripStop)
            else:
                tripStopList = list()
                tripStopList.append(tripStop)
                self.__allTripStopsLookup[tripStop[11]] = tripStopList
        allTripStops.clear()

        # Lookup für allVEs erstellen. allVEs einer Fahrt enthält alle Verkehrstagesdefinitionen einer Fahrt
        logger.info("Lookup für Verkehrstagesinformation der Fahrten aufbauen")
        sql_selVEData = "SELECT bitfieldno, fromstop, tostop, deptimefrom, arrtimeto, fk_fplanfahrtid FROM HRDF_FPlanFahrtVE_TAB WHERE fk_eckdatenid = %s ORDER BY fk_fplanfahrtid, id"
        curVE = self.__hrdfdb.connection.cursor()
        curVE.execute(sql_selVEData, (eckdatenid, ))
        allVEs = curVE.fetchall()
        curVE.close()
        for fahrtVE in allVEs:
            if (fahrtVE[5] in self.__allVEsLookup):
                self.__allVEsLookup[fahrtVE[5]].append(fahrtVE)
            else:
                VEList = list()
                VEList.append(fahrtVE)
                self.__allVEsLookup[fahrtVE[5]] = VEList
        allVEs.clear()

        # Lookup für Linieninformationen der Fahrten
        logger.info("Lookup für Linieninformationen der Fahrten aufbauen")
        sql_selLData = "SELECT lineno, fromstop, tostop, deptimefrom, arrtimeto, fk_fplanfahrtid FROM HRDF_FPlanFahrtL_TAB WHERE fk_eckdatenid = %s ORDER BY fk_fplanfahrtid, id"
        curL = self.__hrdfdb.connection.cursor()
        curL.execute(sql_selLData, (eckdatenid, ))
        allLs = curL.fetchall()
        curL.close()
        for fahrtL in allLs:
            if (fahrtL[5] in self.__fahrtLinienLookup):
                self.__fahrtLinienLookup[fahrtL[5]].append(fahrtL)
            else:
                LList = list()
                LList.append(fahrtL)
                self.__fahrtLinienLookup[fahrtL[5]] = LList
        allLs.clear()

        # Lookup für Richtungstexte der Fahrten
        logger.info("Lookup für Richtungstexte der Fahrten aufbauen")
        sql_selRData = "SELECT a.directionshort, fromstop, tostop, deptimefrom, arrtimeto, b.directiontext, fk_fplanfahrtid "\
              "  FROM HRDF_FPlanFahrtR_TAB a, "\
              "       HRDF_Richtung_TAB b "\
              " WHERE a.fk_eckdatenid = %s "\
              "   AND a.fk_eckdatenid = b.fk_eckdatenid "\
              "   AND b.directioncode = a.directioncode "\
              " ORDER BY a.fk_fplanfahrtid, a.id"
        curR = self.__hrdfdb.connection.cursor()
        curR.execute(sql_selRData, (eckdatenid, ))
        allRs = curR.fetchall()
        curR.close()
        for fahrtR in allRs:
            if (fahrtR[6] in self.__fahrtRichtungLookup):
                self.__fahrtRichtungLookup[fahrtR[6]].append(fahrtR)
            else:
                RList = list()
                RList.append(fahrtR)
                self.__fahrtRichtungLookup[fahrtR[6]] = RList
        allRs.clear()

        # Lookup der Attribute einer Fahrt
        logger.info("Lookup für Attribute der Fahrten aufbauen")
        sql_selAData = "SELECT a.attributecode as attributecodeArray, fromstop, tostop, deptimefrom, arrtimeto, bitfieldno, "\
            "       b.attributetext as text_de, "\
            "       c.attributetext as text_fr, "\
            "       d.attributetext as text_en, "\
            "       e.attributetext as text_it, "\
            "       b.stopcontext as stopcontext, "\
            "       b.outputforsection as outputforsection, "\
            "       b.outputforcomplete as outputforcomplete, "\
            "       a.fk_fplanfahrtid "\
            "  FROM HRDF_FPlanFahrtA_TAB a "\
            "       LEFT OUTER JOIN HRDF_Attribut_TAB b ON b.attributecode = a.attributecode and a.fk_eckdatenid = b.fk_eckdatenid and b.languagecode = 'de' "\
            "       LEFT OUTER JOIN HRDF_Attribut_TAB c ON c.attributecode = a.attributecode and a.fk_eckdatenid = c.fk_eckdatenid and c.languagecode = 'fr' "\
            "	    LEFT OUTER JOIN HRDF_Attribut_TAB d ON d.attributecode = a.attributecode and a.fk_eckdatenid = d.fk_eckdatenid and d.languagecode = 'en' "\
            "	    LEFT OUTER JOIN HRDF_Attribut_TAB e ON e.attributecode = a.attributecode and a.fk_eckdatenid = e.fk_eckdatenid and e.languagecode = 'it' "\
            "  WHERE a.fk_eckdatenid = %s "
        curA = self.__hrdfdb.connection.cursor()
        curA.execute(sql_selAData, (eckdatenid, ))
        allAs = curA.fetchall()
        curA.close()
        for fahrtA in allAs:
            if (fahrtA[13] in self.__fahrtAttributLookup):
                self.__fahrtAttributLookup[fahrtA[13]].append(fahrtA)
            else:
                AList = list()
                AList.append(fahrtA)
                self.__fahrtAttributLookup[fahrtA[13]] = AList
        allAs.clear()

        # Lookup für die Infotext einer Fahrt
        logger.info("Lookup für Infotexte der Fahrten aufbauen")
        sql_selIData = "SELECT a.infotextcode, fromstop, tostop, deptimefrom, arrtimeto, bitfieldno, "\
            "       b.infotext as text_de, "\
            "       c.infotext as text_fr, "\
            "       d.infotext as text_en, "\
            "       e.infotext as text_it, "\
            "       a.fk_fplanfahrtid "\
            "  FROM HRDF_FPlanFahrtI_TAB a "\
            "       LEFT OUTER JOIN HRDF_Infotext_TAB b ON b.infotextno = a.infotextno and a.fk_eckdatenid = b.fk_eckdatenid and b.languagecode = 'de' "\
            "   	LEFT OUTER JOIN HRDF_Infotext_TAB c ON c.infotextno = a.infotextno and a.fk_eckdatenid = c.fk_eckdatenid and c.languagecode = 'fr' "\
            "	   LEFT OUTER JOIN HRDF_Infotext_TAB d ON d.infotextno = a.infotextno and a.fk_eckdatenid = d.fk_eckdatenid and d.languagecode = 'en' "\
            "	   LEFT OUTER JOIN HRDF_Infotext_TAB e ON e.infotextno = a.infotextno and a.fk_eckdatenid = e.fk_eckdatenid and e.languagecode = 'it' "\
            "  WHERE a.fk_eckdatenid = %s "
        curI = self.__hrdfdb.connection.cursor()
        curI.execute(sql_selIData, (eckdatenid, ))
        allIs = curI.fetchall()
        curI.close()
        for fahrtI in allIs:
            if (fahrtI[10] in self.__fahrtInfoLookup):
                self.__fahrtInfoLookup[fahrtI[10]].append(fahrtI)
            else:
                IList = list()
                IList.append(fahrtI)
                self.__fahrtInfoLookup[fahrtI[10]] = IList
        allIs.clear()

        # Lookup für die DurchbindungsInformation zu einer Fahrt
        logger.info("Lookup für Durchbindungsinformation der Fahrten aufbauen")
        sql_selDurchBiData = "SELECT b.laststopno1, b.bitfieldno, b.tripno2, b.operationalno2, coalesce(b.firststopno2, b.laststopno1), b.comment, a.id "\
            "  FROM HRDF_FPlanFahrt_TAB a, "\
            "       HRDF_DURCHBI_TAB b "\
            " WHERE b.tripno1 = a.tripno "\
            "   AND b.operationalno1 = a.operationalno "\
            "   AND b.fk_eckdatenid = a.fk_eckdatenid "\
            "   AND a.fk_eckdatenid = %s "
        curDurchBi = self.__hrdfdb.connection.cursor()
        curDurchBi.execute(sql_selDurchBiData, (eckdatenid, ))
        allDurchBi = curDurchBi.fetchall()
        curDurchBi.close()
        for fahrtDuBI in allDurchBi:
            if (fahrtDuBI[6] in self.__fahrtDurchbindungLookup):
                self.__fahrtDurchbindungLookup[fahrtDuBI[6]].append(fahrtDuBI)
            else:
                DuBiList = list()
                DuBiList.append(fahrtDuBI)
                self.__fahrtDurchbindungLookup[fahrtDuBI[6]] = DuBiList
        allDurchBi.clear()
コード例 #18
0
ファイル: hrdfTTG.py プロジェクト: BERNMOBIL/hrdfreader
    def generateTT(self):
        """ Die Funktion generiert den gewünschten Tagesfahrplan bzgl. der Daten, die über setup() bestimmt wurden"""
        iErrorCnt = 0
        logger.info("Anzahl der Worker: {}".format(self.__numberOfWorker))
        logger.info("Arbeitspaketgröße: {}".format(self.__chunkSize))

        # Aufbau/Erzeugen des TTG-Cache mit den Lookup-Tabellen
        self.__TTGCache.createCacheData(self.__eckdatenid, self.__generateFrom,
                                        self.__generateTo)

        sql_selDayTrips = "SELECT b.id, b.tripno, b.operationalno, b.tripversion, array_agg(a.bitfieldno) as bitfieldnos, b.cyclecount, b.cycletimemin "\
              "FROM HRDF_FPlanFahrtVE_TAB a, "\
              "     HRDF_FPLanFahrt_TAB b "\
              "WHERE (a.bitfieldno in (SELECT bitfieldno FROM HRDF_Bitfeld_TAB where bitfieldarray @> ARRAY[%s::date] AND fk_eckdatenid = %s) "\
              "       OR a.bitfieldno is NULL OR a.bitfieldno = 0) "\
              "  and a.fk_fplanfahrtid = b.id "\
              "  and b.fk_eckdatenid = a.fk_eckdatenid "\
              "  and a.fk_eckdatenid = %s "\
              "GROUP BY b.id, b.tripno, b.operationalno, b.tripversion"

        # Worker anlegen und starten
        workerPool = []
        for x in range(self.__numberOfWorker):
            worker = HrdfTTGWorker(self.__hrdfdb, x, "worker-" + str(x),
                                   self.__workQueue, self.__commQueue,
                                   self.__responseQueue, self.__TTGCache)
            workerPool.append(worker)

        dayCnt = (self.__generateTo - self.__generateFrom).days
        i = 0
        while (i <= dayCnt):
            generationDay = self.__generateFrom + timedelta(days=i)

            # Löschen bestehender Tagesfahrten => Sicherstellen, dass bestehende Daten gelöscht werden bevor neue generiert werden
            logger.info(
                "{:%d.%m.%Y} => Löschen des bestehenden Tagesfahrplan".format(
                    generationDay))
            self.deleteDailyTimetable(self.__eckdatenid, generationDay)

            logger.info(
                "{:%d.%m.%Y} => Start der Generierung".format(generationDay))
            # mit einer Schleife über den selDayTrip-Cursor, der in self.__chunkSize - Blöcken abgearbeitet wird
            curDayTrip = self.__hrdfdb.connection.cursor("cursor_selDayTrip")
            curDayTrip.execute(
                sql_selDayTrips,
                (str(generationDay), self.__eckdatenid, self.__eckdatenid))
            currentRowCnt = 0
            paketCnt = 0
            while True:
                trips = curDayTrip.fetchmany(self.__chunkSize)
                if not trips: break
                paketCnt += 1
                # Schiebe die zu generierenden Trips in die Workqueue, damit sie dort von den Workern abgeholt werden können
                dataItem = dict(eckdatenid=self.__eckdatenid,
                                day=generationDay,
                                trips=trips)
                self.__workQueue.put(dataItem.copy())
                currentRowCnt += len(trips)

            # Aufbau einer tagesbezogenen Response-Datenstruktur zur Verarbeitung der Ergebnisse der Worker
            logger.info(
                "{:%d.%m.%Y} => {} Fahrten wurden in {} Arbeitspakete aufgeteilt"
                .format(generationDay, currentRowCnt, paketCnt))
            self.__responseData[generationDay] = dict(paketCnt=paketCnt,
                                                      receivedPakets=0)

            curDayTrip.close()

            # Nachdem der erste Tag aufgeteilt ist, können die Worker gestartet werden
            if (i == 0):
                for worker in workerPool:
                    worker.start()

            # Tageszähler hochzählen und nächsten gewünschten Tag generieren
            i += 1

        # Auf Responsedaten warten und dann verarbeiten
        moreResponseData = True
        while moreResponseData:
            responseData = self.__responseQueue.get()
            #self.__responseData[responseData["day"]]["dataItems"].add(responseData["data"])
            self.__responseData[responseData["day"]]["receivedPakets"] += 1
            logger.info(
                "{:%d.%m.%Y} => Tagesfahrplanpaket {} wird gesichert".format(
                    responseData["day"], self.__responseData[
                        responseData["day"]]["receivedPakets"]))
            _start_new_thread(self.saveNewDailyTimetable, (
                self.__eckdatenid,
                responseData["day"],
                responseData["data"],
                self.__responseData[responseData["day"]]["paketCnt"],
                self.__responseData[responseData["day"]]["receivedPakets"],
            ))

            # Prüfen ob alle Pakete aller Tage gespeichert wurden
            allComplete = True
            for day, resData in self.__responseData.items():
                if (resData["paketCnt"] > resData["receivedPakets"]):
                    allComplete = False
                    break

            if (allComplete): moreResponseData = False

        # Mindestens ein DB-Thread sollte gestartet worden sein
        while not self.__DBThreadStarted:
            time.sleep(5)
        # Alle DB-Threads müssen sich beendet haben
        while self.__numOfCurrentDBThreads > 0:
            time.sleep(5)

        # Warten bis alle dataItem abgearbeitet sind
        self.__workQueue.join()
        # Kontrolliertes schließen der Threads
        self.__commQueue.put(True)

        # Warten auf Beenden der Worker
        for worker in workerPool:
            worker.join()

        return iErrorCnt
コード例 #19
0
ファイル: hrdfTTG.py プロジェクト: BERNMOBIL/hrdfreader
    def saveNewDailyTimetable(self, eckdatenid, generationDay, ttChunk,
                              paketCnt, receivedPackets):
        """
		Die Funktion speichert den übergebenen TimeTable-Chunk in der Datenbank.
		Um konsistent zu bleiben wird der bestehende Tagesfahrplan zuerst gelöscht
		Die Funktion wird als Thread aufgerufen

		eckdatenid - id der Fahrplandaten
		generationDay - Generierungsdatum
		ttChunk - Chunk (csv-Sting) eines Tagesfahrplans
		paketCnt - Anzahl der Pakete für diesen Tag
		"""
        self.__lock.acquire()
        self.__numOfCurrentDBThreads += 1
        self.__DBThreadStarted = True
        self.__lock.release()

        # Lokale DB-Verbindung erstellen
        hrdfDBSingle = HrdfDB(self.__hrdfdb.dbname, self.__hrdfdb.host,
                              self.__hrdfdb.user, self.__hrdfdb.password)

        if (hrdfDBSingle.connect()):

            # Das Löschen des Tagesfahrplans erfolgt kontrolliert vor dem Starten der Threads, die den neuen Fahrplan sichern

            # Speichern des Chunks in der Datenbank
            curSaveTrip = hrdfDBSingle.connection.cursor()
            strCopy = "COPY HRDF_DailyTimeTable_TAB (fk_eckdatenid,tripident,tripno,operationalno,tripversion,"\
               "operatingday,stopsequenceno,stopident,stopname,stoppointident,stoppointname,arrstoppointtext,depstoppointtext,arrdatetime,depdatetime,noentry,noexit,"\
               "categorycode,classno,categoryno,lineno,directionshort,directiontext,"\
               "attributecode,attributetext_de,attributetext_fr,attributetext_en,attributetext_it,"\
               "infotextcode,infotext_de,infotext_fr,infotext_en,infotext_it,"\
               "longitude_geo,latitude_geo,altitude_geo,transfertime1,transfertime2,transferprio,tripno_continued,operationalno_continued,stopno_continued)"\
               " FROM STDIN USING DELIMITERS ';' NULL AS ''"

            #logger.info("Sichern Chunk {} von {} für Tag {:%d.%m.%Y}".format(receivedPackets, paketCnt, generationDay))
            dailytimetable_strIO = StringIO()
            dailytimetable_strIO.write(ttChunk)
            dailytimetable_strIO.seek(0)
            curSaveTrip.copy_expert(strCopy, dailytimetable_strIO)
            dailytimetable_strIO.close()
            curSaveTrip.close()
            hrdfDBSingle.connection.commit()

            # Beim letzten Paket
            if (receivedPackets == paketCnt):
                logger.info(
                    "{:%d.%m.%Y} => Neuer Tagesfahrplan wurde komplett gesichert"
                    .format(generationDay))
                # Aktualisieren der Eckdatentabelle mit dem neuen Tag
                curUpdTTGenerated = hrdfDBSingle.connection.cursor()
                sql_updTTGenerated = "UPDATE HRDF.HRDF_Eckdaten_TAB SET ttgenerated = array_append(ttgenerated, %s) WHERE id = %s"
                curUpdTTGenerated.execute(sql_updTTGenerated,
                                          (str(generationDay), eckdatenid))
                curUpdTTGenerated.close()
                hrdfDBSingle.connection.commit()

        else:
            logger.error(
                "{:%d.%m.%Y} => DB-Thread konnte keine Verbindung zur Datenbank aufbauen"
                .format(generationDay))

        # DB-Thread-Zähler wieder zurücksetzen
        self.__lock.acquire()
        self.__numOfCurrentDBThreads -= 1
        self.__lock.release()
コード例 #20
0
ファイル: hrdfTTGWorker.py プロジェクト: BERNMOBIL/hrdfreader
    def processTrips(self, eckdatenid, generationDay, trips):
        """ Die Funktion generiert den Tagesfahrplan für die übergebenen Trips am gewünschten Tag"""
        if (len(trips) > 1):
            #logger.error("{}: bearbeitet {} Fahrten".format(self.__name, len(trips)))
            tripStops = dict()
            dailytimetable_strIO = StringIO()
            numberOfGeneratedTrips = 0
            iErrorCnt = 0
            for trip in trips:
                tripStops.clear()
                origtripident = "{}-{}-{}".format(trip[1], trip[2], trip[3])

                try:
                    self.generateTrip(trip, tripStops, generationDay)
                    # Ein Trip kann Taktdefinitionen enthalten, dann muss diese Fahrt mit ihren Stops x mal mit versetzten Zeiten eingetragen werden
                    # Um die Einträge eindeutig der gleichen Fahrt zuordnen zu können wird bei Taktdefinitionen der TripIdentifier erweitert
                    cycletimemin = 0
                    cyclecount = 0
                    cycledefs = False
                    if (trip[5] is not None):
                        cycledefs = True
                        cyclecount = trip[5]
                        cycletimemin = trip[6]

                    i = 0
                    while i <= cyclecount:
                        additionalCycletimeMin = cycletimemin * i
                        # Erweiterung des TripIdentifiers um eine 4-stellige Zahl mit führenden Nullen
                        # 1440 Minuten = 24 Std bei minütlicher Taktung
                        if (cycledefs == True):
                            tripident = "{}-{:04d}".format(origtripident, i)
                        else:
                            tripident = origtripident

                        # Schreibe Fahrtinformation in Tabellenformat
                        for tripStop in tripStops.values():
                            arrival = tripStop["stop"][3]
                            departure = tripStop["stop"][4]
                            noentry = False
                            noexit = False

                            arrdatetime = ""
                            if (arrival is not None):
                                if (arrival < 0): noexit = True
                                arrival = abs(arrival)
                                arrMins = (int(arrival / 100) * 60) + (
                                    arrival % 100) + additionalCycletimeMin
                                arrdatetime = str(
                                    datetime.combine(generationDay, time(0, 0))
                                    + timedelta(minutes=arrMins))

                            depdatetime = ""
                            if (departure is not None):
                                if (departure < 0): noenty = True
                                departure = abs(departure)
                                depMins = (int(departure / 100) * 60) + (
                                    departure % 100) + additionalCycletimeMin
                                depdatetime = str(
                                    datetime.combine(generationDay, time(0, 0))
                                    + timedelta(minutes=depMins))

                            # Attribute
                            strAttributecode = ""
                            strAttributetextDE = ""
                            strAttributetextFR = ""
                            strAttributetextEN = ""
                            strAttributetextIT = ""
                            if (len(tripStop["attributecode"]) > 0):
                                strAttributecode = "{'" + "','".join(
                                    map(str, tripStop["attributecode"])) + "'}"
                            if (len(tripStop["attributetext_de"]) > 0):
                                strAttributetextDE = "{'" + "','".join(
                                    map(str,
                                        tripStop["attributetext_de"])) + "'}"
                            if (len(tripStop["attributetext_fr"]) > 0):
                                strAttributetextFR = "{'" + "','".join(
                                    map(str,
                                        tripStop["attributetext_fr"])) + "'}"
                            if (len(tripStop["attributetext_en"]) > 0):
                                strAttributetextEN = "{'" + "','".join(
                                    map(str,
                                        tripStop["attributetext_en"])) + "'}"
                            if (len(tripStop["attributetext_it"]) > 0):
                                strAttributetextIT = "{'" + "','".join(
                                    map(str,
                                        tripStop["attributetext_it"])) + "'}"

                            # Infotexte
                            strInfotextcode = ""
                            strInfotextDE = ""
                            strInfotextFR = ""
                            strInfotextEN = ""
                            strInfotextIT = ""
                            if (len(tripStop["infotextcode"]) > 0):
                                strInfotextcode = '{"' + '","'.join(
                                    map(self.infohelp,
                                        tripStop["infotextcode"])) + '"}'
                            if (len(tripStop["infotext_de"]) > 0):
                                strInfotextDE = '{"' + '","'.join(
                                    map(self.infohelp,
                                        tripStop["infotext_de"])) + '"}'
                            if (len(tripStop["infotext_fr"]) > 0):
                                strInfotextFR = '{"' + '","'.join(
                                    map(self.infohelp,
                                        tripStop["infotext_fr"])) + '"}'
                            if (len(tripStop["infotext_en"]) > 0):
                                strInfotextEN = '{"' + '","'.join(
                                    map(self.infohelp,
                                        tripStop["infotext_en"])) + '"}'
                            if (len(tripStop["infotext_it"]) > 0):
                                strInfotextIT = '{"' + '","'.join(
                                    map(self.infohelp,
                                        tripStop["infotext_it"])) + '"}'

                            # Angaben zur Haltestelle
                            strLongitudeGeo = ""
                            strLatitudeGeo = ""
                            strAltitudeGeo = ""
                            strTransferTime1 = ""
                            strTransferTime2 = ""
                            strTransferPrio = ""
                            strTripNoContinued = ""
                            strOperationalNoContinued = ""
                            strStopNoContinued = ""
                            if (tripStop["longitude_geo"] is not None):
                                strLongitudeGeo = str(
                                    tripStop["longitude_geo"])
                            if (tripStop["latitude_geo"] is not None):
                                strLatitudeGeo = str(tripStop["latitude_geo"])
                            if (tripStop["altitude_geo"] is not None):
                                strAltitudeGeo = str(tripStop["altitude_geo"])
                            if (tripStop["transfertime1"] is not None):
                                strTransferTime1 = str(
                                    tripStop["transfertime1"])
                            if (tripStop["transfertime2"] is not None):
                                strTransferTime2 = str(
                                    tripStop["transfertime2"])
                            if (tripStop["transferprio"] is not None):
                                strTransferPrio = str(tripStop["transferprio"])
                            if (tripStop["tripno_continued"] is not None):
                                strTripNoContinued = str(
                                    tripStop["tripno_continued"])
                            if (tripStop["operationalno_continued"]
                                    is not None):
                                strOperationalNoContinued = str(
                                    tripStop["operationalno_continued"])
                            if (tripStop["stopno_continued"] is not None):
                                strStopNoContinued = str(
                                    tripStop["stopno_continued"])

                            # Schreiben des Datensatzes
                            dailytimetable_strIO.write(eckdatenid)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(tripident)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(trip[1]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(trip[2])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(trip[3]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(generationDay))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(
                                tripStop["stop"][2]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(
                                tripStop["stop"][0]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(tripStop["stop"][1])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(
                                tripStop["stop"][0]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(tripStop["stop"][1])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                tripStop["arrstoppointtext"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                tripStop["depstoppointtext"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(arrdatetime)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(depdatetime)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(noentry))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(noexit))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                tripStop["categorycode"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(str(
                                tripStop["classno"]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                str(tripStop["categoryno"]))
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(tripStop["lineno"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                tripStop["directionshort"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                tripStop["directiontext"])
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAttributecode)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAttributetextDE)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAttributetextFR)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAttributetextEN)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAttributetextIT)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strInfotextcode)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strInfotextDE)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strInfotextFR)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strInfotextEN)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strInfotextIT)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strLongitudeGeo)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strLatitudeGeo)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strAltitudeGeo)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strTransferTime1)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strTransferTime2)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strTransferPrio)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strTripNoContinued)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(
                                strOperationalNoContinued)
                            dailytimetable_strIO.write(';')
                            dailytimetable_strIO.write(strStopNoContinued)
                            dailytimetable_strIO.write('\n')
                            numberOfGeneratedTrips += 1
                        i += 1

                except Exception as err:
                    iErrorCnt += 1
                    logger.error(
                        "Die Fahrt {} konnte nicht generiert werden. Error:\n{}"
                        .format(tripident, err))

            # Alle Fahrten des Sets im IO abgelegt => Zurückgabe an den Main-Thread
            logger.info(
                "\t{}: {:%d.%m.%Y} => {} Tagesfahrplaneinträge erstellt ...".
                format(self.__name, generationDay, numberOfGeneratedTrips))
            # Ergebnis liefern
            dailytimetable_strIO.seek(0)
            self.__responseQueue.put(
                dict(day=generationDay, data=dailytimetable_strIO.getvalue()))
            dailytimetable_strIO.close()
            tripStops.clear()
コード例 #21
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_fplan(self, filename):
		"""Lesen der Datei FPLAN"""
		logger.info('lesen und verarbeiten der Datei FPLAN')
		curIns = self.__hrdfdb.connection.cursor()

		bDataLinesRead = False
		iSequenceCnt = 0
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n','')

			if line[:1] == '*':
				if bDataLinesRead:
					# Datenzeilen wurden gelesen, wir sind jetzt wieder beim nächsten Zug und schreiben den Vorgänger erstmal in die DB
					self.save_currentFplanFahrt()
					bDataLinesRead = False
					iSequenceCnt = 0

				# Attribut-Zeilen (!! längste Attribut-Kennung zuerst abfragen, dann weiter absteigend !!)
				if line[:5] == "*A VE":
					if self.__AVE_type == "*Z" or self.__AVE_type == "*T":
						self.__fplanFahrtAVE_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													  +self.__fkdict["fk_fplanfahrtid"]+';'
													  +line[6:13].strip()+';'
													  +line[14:21].strip()+';'
													  +line[22:28].strip()+';'
													  +line[29:35].strip()+';'
													  +line[36:42].strip()+
													  '\n')
					else:
						logger.warning("*A VE-Zeile gehört zu nicht unterstützter "+self.__AVE_type+"-Zeile und wird nicht verarbeitet")
						
				elif line[:4] == "*KWZ":
					self.__AVE_type = line[:4]
					logger.warning("Zeile "+line[:4]+" wird derzeit nicht unterstützt")

				elif line[:3] == "*KW" or line[:3] == "*TT":
					self.__AVE_type = line[:3]
					logger.warning("Zeile "+line[:3]+" wird derzeit nicht unterstützt")

				elif line[:3] == "*SH":
					self.__fplanFahrtSH_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[4:11].strip()+';'
													+line[12:18].strip()+';'
													+line[19:25].strip()+
													'\n')

				elif line[:3] == "*GR":
					self.__fplanFahrtGR_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[4:11].strip()+';'
													+line[12:19].strip()+';'
													+line[20:27].strip()+';'
													+line[28:34].strip()+';'
													+line[35:41].strip()+
													'\n')


				elif line[:2] == "*B" or line[:2] == "*E":
					logger.warning("Zeile "+line[:2]+" wird derzeit nicht unterstützt")

				elif line[:2] == "*Z":
					self.__AVE_type = line[:2]
					sql_string = "INSERT INTO HRDF_FPLANFahrt_TAB (fk_eckdatenid,triptype,tripno,operationalno,tripversion,cyclecount,cycletimemin) VALUES (%s,%s,%s,%s,%s,%s,%s) RETURNING id;"
					cyclecount = line[22:25].strip()
					cycletimemin = line[26:29].strip()
					if not cyclecount:
						cyclecount = None
					if not cycletimemin:
						cycletimemin = None
					curIns.execute(sql_string, (self.__fkdict['fk_eckdatenid'], line[1:2], line[3:8], line[9:15], line[18:21], cyclecount, cycletimemin))
					self.__fkdict["fk_fplanfahrtid"] = str(curIns.fetchone()[0])

				elif line[:2] == "*T":
					self.__AVE_type = line[:2]
					sql_string = "INSERT INTO HRDF_FPLANFahrt_TAB (fk_eckdatenid,triptype,tripno,operationalno,triptimemin,cycletimesec) VALUES (%s,%s,%s,%s,%s,%s,%s) RETURNING id;"
					triptimemin = line[16:20].strip()
					cycletimesec = line[21:25].strip()
					if not triptimemin:
						triptimemin = None
					if not cycletimesec:
						cycletimesec = None
					curIns.execute(sql_string, (self.__fkdict['fk_eckdatenid'], line[1:2], line[3:8], line[9:15], triptimemin, cycletimesec))
					self.__fkdict["fk_fplanfahrtid"] = str(curIns.fetchone()[0])

				elif line[:2] == "*C":
					checkinTime = '';
					checkoutTime = '';
					if line[:3] == "*CI":
						checkinTime = line[4:8].strip();
					if line[:3] == "*CO":
						checkoutTime = line[4:8].strip();
					self.__fplanFahrtC_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+checkinTime+';'
													+checkoutTime+';'
													+line[9:16].strip()+';'
													+line[17:24].strip()+';'
													+line[25:31].strip()+';'
													+line[32:38].strip()+
													'\n')

				elif line[:2] == "*G":
					self.__fplanFahrtG_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[3:6].strip()+';'
													+line[7:14].strip()+';'
													+line[15:22].strip()+';'
													+line[23:29].strip()+';'
													+line[30:36].strip()+
													'\n')
				elif line[:2] == "*A":
					self.__fplanFahrtA_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[3:5].strip()+';'
													+line[6:13].strip()+';'
													+line[14:21].strip()+';'
													+line[22:28].strip()+';'
													+line[29:35].strip()+';'
													+line[36:42].strip()+
													'\n')

				elif line[:2] == "*R":
					self.__fplanFahrtR_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[3:4].strip()+';'
													+line[5:12].strip()+';'
													+line[13:20].strip()+';'
													+line[21:28].strip()+';'
													+line[29:35].strip()+';'
													+line[36:42].strip()+
													'\n')
				elif line[:2] == "*I":
					self.__fplanFahrtI_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[3:5].strip()+';'
													+line[29:36].strip()+';'
													+line[6:13].strip()+';'
													+line[14:21].strip()+';'
													+line[22:28].strip()+';'
													+line[37:43].strip()+';'
													+line[44:50].strip()+
													'\n')

				elif line[:2] == "*L":
					self.__fplanFahrtL_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
													+self.__fkdict["fk_fplanfahrtid"]+';'
													+line[3:11].strip()+';'
													+line[12:19].strip()+';'
													+line[20:27].strip()+';'
													+line[28:34].strip()+';'
													+line[35:41].strip()+
													'\n')

			else:
				# Laufwegszeilen
				bDataLinesRead = True
				if (line[:1] == "+"):
					logger.warning("Laufwegsdaten mit Regionen werden nicht unterstützt")
				else:
					self.__fplanFahrtLauf_strIO.write(self.__fkdict["fk_eckdatenid"]+';'
														+self.__fkdict["fk_fplanfahrtid"]+';'
														+line[:7].strip()+';'
														+line[8:29].strip()+';'
														+str(iSequenceCnt)+';'
														+line[29:35].strip()+';'
														+line[36:42].strip()+';'
														+line[43:48].strip()+';'
														+line[49:55].strip()+';'
														+line[56:57].strip()+
														'\n')
					iSequenceCnt += 1


		# Nach dem Durchlauf der Schleife muss der letzte Zug noch gespeichert werden
		if bDataLinesRead:
			self.save_currentFplanFahrt()
			bDataLinesRead = False
			iSequenceCnt = 0

		curIns.close()
コード例 #22
0
ファイル: hrdfreader.py プロジェクト: BERNMOBIL/hrdfreader
	def read_metabhf(self, filename):
		"""Lesen der Datei METABHF"""
		logger.info('lesen und verarbeiten der Datei METABHF')
		metabhfUB_strIO = StringIO()
		metabhfHG_strIO = StringIO()

		previousUB = False
		strStopNoFrom = None;
		strStopNoTo = None;
		strTransferTimeMin = None;
		strTransferTimeSec = None;
		strAttributeCodes = "";
		attributeCodeList = list();
		stopMemberList = list();
		for line in fileinput.input(filename, openhook=self.__hrdfzip.open):
			line = line.decode(self.__charset).replace('\r\n', '')
			
			if line[:1] == '*':
				# Attributszeile der Übergangsbeziehung				
				if line[1:2] == 'A':
					# Uns interessieren momentan nur die A-Zeilen (Attributecode)
					attributeCodeList.append(line[3:5].strip())

			elif line[7:8] == ':':
				# Haltestellengruppen-Zeile
				# Ist noch eine offene Übergangsbeziehung vorhanden? Die muss noch gespeichert werden
				if (previousUB):
					if (len(attributeCodeList) > 0): strAttributeCodes = "{'" + "','".join(map(str,attributeCodeList)) + "'}"
					metabhfUB_strIO.write(self.__fkdict['fk_eckdatenid']+';'
												 +strStopNoFrom+';'
												 +strStopNoTo+';'
												 +strTransferTimeMin+';'
												 +strTransferTimeSec+';'
												 +strAttributeCodes
												+'\n')
					# Zurücksetzen der Attributcodes-Liste
					attributeCodeList.clear();
					strAttributeCodes = "";
					previousUB = False;

				# Behandlung der Haltestellengruppen-Zeile
				# Erster Stop beginnt bei Zeichen 10, danach beliebig viele Stops in der Länge von 7 Zeichen
				stopMemberList.clear()
				strStopMember = ""
				nextMemberStart = 10
				while (nextMemberStart < len(line)):
					stopMemberList.append(line[nextMemberStart:nextMemberStart+7])
					nextMemberStart = nextMemberStart+9
				if (len(stopMemberList) > 0): strStopMember = "{" + ",".join(map(str,stopMemberList)) + "}"
				metabhfHG_strIO.write(self.__fkdict['fk_eckdatenid']+';'
								+line[10:17]+';'
								+strStopMember
							+'\n')

			else:
				# 1. Zeile einer Übergangsbeziehung
				if (previousUB):
					# Sichern der Übergangsbeziehung
					if (len(attributeCodeList) > 0): strAttributeCodes = "{'" + "','".join(map(str,attributeCodeList)) + "'}"
					metabhfUB_strIO.write(self.__fkdict['fk_eckdatenid']+';'
												 +strStopNoFrom+';'
												 +strStopNoTo+';'
												 +strTransferTimeMin+';'
												 +strTransferTimeSec+';'
												 +strAttributeCodes
												+'\n')

				# Zurücksetzen der Attributcodes-Liste
				attributeCodeList.clear();
				strAttributeCodes = "";
				strStopNoFrom = line[:7]
				strStopNoTo = line[8:15]
				strTransferTimeMin = line[16:19]
				strTransferTimeSec = line[20:22]
				previousUB = True

		metabhfUB_strIO.seek(0)
		curUB = self.__hrdfdb.connection.cursor()
		curUB.copy_expert("COPY HRDF_METABHF_TAB (fk_eckdatenid,stopnofrom,stopnoto,transfertimemin,transfertimesec,attributecode) FROM STDIN USING DELIMITERS ';' NULL AS ''", metabhfUB_strIO)
		self.__hrdfdb.connection.commit()
		curUB.close()
		metabhfUB_strIO.close()

		metabhfHG_strIO.seek(0)
		curHG = self.__hrdfdb.connection.cursor()
		curHG.copy_expert("COPY HRDF_METABHFGRUPPE_TAB (fk_eckdatenid,stopgroupno,stopmember) FROM STDIN USING DELIMITERS ';' NULL AS ''", metabhfHG_strIO)
		self.__hrdfdb.connection.commit()
		curHG.close()
		metabhfHG_strIO.close()