[Wsplgen-commits] r37 - trunk/src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Mar 14 00:53:03 CET 2006


Author: mrchip
Date: 2006-03-14 00:53:00 +0100 (Tue, 14 Mar 2006)
New Revision: 37

Removed:
   trunk/src/wsplgen.h
Modified:
   trunk/src/Makefile
   trunk/src/file.cpp
   trunk/src/file.h
   trunk/src/parameter.cpp
   trunk/src/shape.cpp
   trunk/src/shape.h
   trunk/src/test_file.cpp
   trunk/src/test_profil.cpp
   trunk/src/test_tools.cpp
   trunk/src/test_tri.cpp
   trunk/src/test_xy.cpp
   trunk/src/tools.cpp
   trunk/src/tools.h
   trunk/src/tri.cpp
   trunk/src/tri.h
   trunk/src/wsplgen.cpp
   trunk/src/xy.cpp
   trunk/src/xy.h
Log:
Dies ist die erst lauff?\195?\164hige Version von WSPLGEN. Das Programm enth?\195?\164lt noch nicht alle Features und wurde erst sehr rudiment?\195?\164r auf Fehler untersucht.
Die Unit-Tests funktionieren im Moment kaum noch, da sich eine Menge an den Klassen ge?\195?\164ndert hat.

Modified: trunk/src/Makefile
===================================================================
--- trunk/src/Makefile	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/Makefile	2006-03-13 23:53:00 UTC (rev 37)
@@ -12,7 +12,7 @@
 
 PROJECT=wsplgen.exe
 TEST=test.exe
-OBJFILES=profil.o tools.o xy.o tri.o parameter.o file.o shape.o
+OBJFILES=tools.o xy.o tri.o parameter.o file.o shape.o
 TESTOBJFILES= test_profil.o test_tools.o test_xy.o test_tri.o test_file.o
 
 all: ../bin/test.exe ../bin/wsplgen.exe

Modified: trunk/src/file.cpp
===================================================================
--- trunk/src/file.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/file.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -33,7 +33,6 @@
 		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", FileName.c_str());
 	}
 
-
 	char line[1000];
 
 	while (fgets (line, sizeof (line)-1, fh))
@@ -52,57 +51,59 @@
 }
 
 //---------------------------------------------------------------------
-bool LoadProfile(std::string FileName, TProfilList* ProfilList)
+unsigned int LoadDGM(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
 {
-	return (true);
-}
+	write_fortschritt("->DGM laden\n");
 
-//---------------------------------------------------------------------
-bool LoadWsp(std::string FileName, TProfilList* ProfilList)
-{
-	return (true);
-}
+	NodeList->Clear();
+	ElementList->Clear();
 
-//---------------------------------------------------------------------
-bool	LoadDGM(std::string FileName, TNodeList *NodeList, TElementList *ElementList)
-{
 	std::string Ext = GetFileExt(FileName);
 
+
+	int AnzScheiben = 1;
+
 	if (ToUpperCase(Ext) == ".ADF")
 	{
-		if (false == LoadDGMTIN(FileName, NodeList, ElementList))	return (false);
+		AnzScheiben = LoadDGMTIN(FileName, NodeList, ElementList, XyList, MaxNodesPerSlice, Debug);
 	}
+	else if (ToUpperCase(Ext) == ".2DM")
+	{
+		AnzScheiben = LoadDGM2DM(FileName, NodeList, ElementList, XyList, MaxNodesPerSlice, Debug);
+	}
 	else if (ToUpperCase(Ext) == ".XYZ")
 	{
-		if (false == LoadDGMXYZ(FileName, NodeList))	return (false);
-
-		if (false == Triangulate (NodeList, ElementList))	return (false);
-
+		AnzScheiben = LoadDGMXYZ(FileName, NodeList, XyList, MaxNodesPerSlice, Debug);
+		CheckForDuplicates(NodeList, Debug);
 	}
 	else if (ToUpperCase(Ext) == ".GRD")
 	{
-		if (false == LoadDGMGRD(FileName, NodeList))	return (false);
-
-		if (false == Triangulate (NodeList, ElementList))	return (false);
+		AnzScheiben = LoadDGMGRD(FileName, NodeList, XyList, MaxNodesPerSlice, Debug);
+		CheckForDuplicates(NodeList, Debug);
 	}
 	else if (ToUpperCase(Ext) == ".SHP")
 	{
-		if (false == LoadDGMSHP(FileName, NodeList))	return (false);
-
-		if (false == Triangulate (NodeList, ElementList))	return (false);
+		AnzScheiben = LoadDGMSHP(FileName, NodeList, XyList, MaxNodesPerSlice, Debug);
+		CheckForDuplicates(NodeList, Debug);
 	}
+	else
+	{
+		write_error(1222, "Ungültige Dateinamenserweiterung '%s' beim Dateinamen '%s' für den Parameter -DGM", ToUpperCase(Ext).c_str(), FileName.c_str());
+	}
 
-	return (true);
+	write_fortschritt("DGM geladen<-\n");
+
+	return (AnzScheiben);
 }
 
 //---------------------------------------------------------------------------
-bool LoadDGMTIN(std::string FileName, TNodeList *NodeList, TElementList *ElementList)
+unsigned int LoadDGMTIN(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
 {
+	write_fortschritt("->DGM TIN laden\n");
+
 	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
 	if (ElementList == 0)	dump_error(__FILE__, __LINE__, "Die Elementliste ist nicht definiert\n");
 
-	write_fortschritt("->DGM TIN laden\n");
-
 	std::string XyFileName = GetFilePath(FileName) + "tnxy.adf";
 	std::string ZFileName = GetFilePath(FileName) + "tnz.adf";
 	std::string OdFileName = GetFilePath(FileName) + "tnod.adf";
@@ -111,6 +112,8 @@
 	FILE *fhz = 0;
 	FILE *fhod = 0;
 
+	unsigned int AnzNodes = 0;
+
 	try
 	{
 		fhxy = fopen(XyFileName.c_str(), "rb");
@@ -132,10 +135,10 @@
 
 		write_fortschritt("Knoten werden geladen\n");
 
-		int AnzNodes = 0;
 		while (1 == fread(&X, sizeof(X), 1, fhxy) && fread(&Y, sizeof(Y), 1, fhxy) && 1 == fread(&Z, sizeof(Z), 1, fhz))
 		{
-			if (AnzNodes % 10000 == 0)	write_fortschritt("%d Knoten geladen\n", AnzNodes);
+			if (Debug && AnzNodes % 10000 == 0)	write_fortschritt("%d Knoten geladen\n", AnzNodes);
+			else if (AnzNodes % 100000 == 0)			write_fortschritt("%d Knoten geladen\n", AnzNodes);
 
 			Swap8Bytes((byte *)&X);
 			Swap8Bytes((byte *)&Y);
@@ -143,11 +146,20 @@
 
 			if (++AnzNodes > 4)
 			{
-				X = (long)(X * 100) / 100.0;
-				Y = (long)(Y * 100) / 100.0;
-				Z = (long)(Z * 100) / 100.0;
-				TNode *Node = new TNode(AnzNodes, X, Y, Z);
-				NodeList->push_back(Node);
+				X = (long)(X * 100.0 + 0.5) / 100.0;
+				Y = (long)(Y * 100.0 + 0.5) / 100.0;
+				Z = (long)(Z * 100.0 + 0.5) / 100.0;
+
+				TInsideTyp InsideTyp = INSIDE;
+				if (XyList) InsideTyp = XyList->IsInsideXYList(X, Y);
+				if (InsideTyp == INSIDE || InsideTyp == ON_LINE)
+				{
+					if (AnzNodes < MaxNodesPerSlice)
+					{
+						TNode *Node = new TNode(AnzNodes, X, Y, Z);
+						NodeList->push_back(Node);
+					}
+				}
 			}
 		}
 
@@ -173,7 +185,8 @@
 		int AnzElements = 0;
 		while (1 == fread(&Nr1, sizeof(Nr1), 1, fhod) && fread(&Nr2, sizeof(Nr2), 1, fhod) && 1 == fread(&Nr3, sizeof(Nr3), 1, fhod))
 		{
-			if (AnzElements % 10000 == 0)	write_fortschritt("%d Elemente geladen\n", AnzElements);
+			if (Debug && AnzElements % 10000 == 0)	write_fortschritt("%d Elemente geladen\n", AnzElements);
+			else if (AnzElements % 100000 == 0)		write_fortschritt("%d Elemente geladen\n", AnzElements);
 
 			Swap4Bytes((byte *)&Nr1);
 			Swap4Bytes((byte *)&Nr2);
@@ -185,11 +198,13 @@
 				TNode *Node2 = NodeList->FindByNr(Nr2);
 				TNode *Node3 = NodeList->FindByNr(Nr3);
 
-				TElement *Element = new TElement(Node1, Node2, Node3);
-				ElementList->push_back(Element);
-
+				if (Node1 && Node2 && Node3)
+				{
+					TElement *Element = new TElement(Node1, Node2, Node3);
+					ElementList->push_back(Element);
+				}
+				AnzElements++;
 			}
-			AnzElements++;
 		}
 
 		fclose(fhod);
@@ -207,16 +222,17 @@
 
 	write_fortschritt("DGM TIN laden beendet<-\n");
 
-	return (true);
+	if (AnzNodes <= MaxNodesPerSlice)	return (1);
+	else								return ((AnzNodes - 1) / MaxNodesPerSlice + 1);
 }
 
 //---------------------------------------------------------------------------
-bool LoadDGMXYZ(std::string FileName, TNodeList *NodeList)
+unsigned int LoadDGMXYZ(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
 {
+	write_fortschritt("->DGM XYZ laden\n");
+
 	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
 
-	write_fortschritt("->DGM XYZ laden\n");
-
 	FILE *fh = fopen(FileName.c_str(), "r");
 	if (fh == 0)
 	{
@@ -231,16 +247,17 @@
 	}
 	line[sizeof(line)-1] = '\0';
 
-	int AnzZeilen = 1;
-	int AnzKnoten = 0;
+	unsigned int AnzZeilen = 1;
+	unsigned int AnzKnoten = 0;
 	while (0 != fgets (line, sizeof(line)-1, fh))
 	{
 		AnzZeilen ++;
 
-		if (AnzZeilen % 10000 == 0)	write_fortschritt("%d Zeilen gelesen\n", AnzZeilen);
+		if (Debug && AnzZeilen % 10000 == 0)	write_fortschritt("%d Zeilen gelesen\n", AnzZeilen);
+		else if (AnzZeilen % 100000 == 0)	write_fortschritt("%d Zeilen gelesen\n", AnzZeilen);
 
-		double Rechts=0.0;
-		double Hoch=0.0;
+		double X=0.0;
+		double Y=0.0;
 		double Z=0.0;
 
 		bool Leer = true;
@@ -252,37 +269,59 @@
 
 		if (Leer)	continue;
 
-		if (3 != sscanf (line, "%lf%lf%lf", &Rechts, &Hoch, &Z))
+		if (3 != sscanf (line, "%lf%lf%lf", &X, &Y, &Z))
 		{
 			write_error(2297, "Konnte keine 3 Werte in der Datei '%s' in der Zeile %d lesen", FileName.c_str(), AnzZeilen);
 		}
 
-		Rechts = (long)(Rechts * 100) / 100.0;
-		Hoch = (long)(Hoch * 100) / 100.0;
+		X = (long)(X * 100) / 100.0;
+		Y = (long)(Y * 100) / 100.0;
 		Z = (long)(Z * 100) / 100.0;
-		TNode *Node = new TNode(++AnzKnoten, Rechts, Hoch, Z);
 
-		NodeList->push_back(Node);
+		TInsideTyp InsideTyp = INSIDE;
+		if (XyList) InsideTyp = XyList->IsInsideXYList(X, Y);
+		if (InsideTyp == INSIDE || InsideTyp == ON_LINE)
+		{
+			AnzKnoten++;
+
+			if (AnzKnoten < MaxNodesPerSlice)
+			{
+				TNode *Node = new TNode(AnzKnoten, X, Y, Z);
+				NodeList->push_back(Node);
+			}
+		}
 	}
 
 	fclose(fh);
 
 	write_fortschritt("DGM XYZ laden beendet<-\n");
 
-	return (true);
+	if (AnzKnoten <= MaxNodesPerSlice)	return (1);
+	else								return ((AnzKnoten - 1) / MaxNodesPerSlice + 1);
 }
 
 //---------------------------------------------------------------------------
-bool LoadDGMGRD(std::string FileName, TNodeList *NodeList)
+unsigned int LoadDGMGRD(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
 {
-	return (true);
+	write_fortschritt("->DGM GRD laden\n");
+
+	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
+
+	unsigned int AnzKnoten = 0;
+
+	write_fortschritt("DGM GRD laden beendet<-\n");
+
+	if (AnzKnoten <= MaxNodesPerSlice)	return (1);
+	else								return ((AnzKnoten - 1) / MaxNodesPerSlice + 1);
 }
 
 //---------------------------------------------------------------------------
-bool LoadDGMSHP(std::string FileName, TNodeList *NodeList)
+unsigned int LoadDGMSHP(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
 {
 	write_fortschritt("->DGM SHP laden\n");
 
+	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
+
 	std::string SHPFileName = ExchangeFileExt(FileName, ".SHP");
 	SHPHandle hSHP = SHPOpen(SHPFileName.c_str(), "rb");
 
@@ -291,10 +330,10 @@
 		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen", SHPFileName.c_str());
 	}
 
-	int 	RecordCount = 0;
-	int 	ShapeType = 0;
-	double	Mins[4];
-	double	Maxs[4];
+	int 		RecordCount = 0;
+	TShpType 	ShapeType = SHPT_NULL;
+	double		Mins[4];
+	double		Maxs[4];
 
 	SHPGetInfo(hSHP, &RecordCount, &ShapeType, Mins, Maxs);
 
@@ -302,13 +341,14 @@
 	{
 		SHPClose(hSHP);
 
-		write_error(2201, "Es sind keine Objekte in der Shapedatei '%s'", SHPFileName.c_str());
+		write_error(2204, "Es sind keine Objekte in der Shapedatei '%s'", SHPFileName.c_str());
 	}
 
-	int AnzKnoten = 0;
+	unsigned int AnzKnoten = 0;
 	for (int i = 0; i<RecordCount; i++)
 	{
-		if (i % 10000 == 0)	write_fortschritt("%d Objekte geladen\n", i);
+		if (Debug && i % 10000 == 0)	write_fortschritt("%d Objekte geladen %d Knoten geladen\n", i, NodeList->size());
+		else if (i % 100000 == 0)		write_fortschritt("%d Objekte geladen %d Knoten geladen\n", i, NodeList->size());
 
 		SHPObject *psCShape = SHPReadObject(hSHP, i);
 
@@ -328,23 +368,608 @@
 			X = (long)(X * 100) / 100.0;
 			Y = (long)(Y * 100) / 100.0;
 			Z = (long)(Z * 100) / 100.0;
-			TNode* Node = new TNode(++AnzKnoten, X, Y, Z);
-			NodeList->push_back(Node);
+
+			TInsideTyp InsideTyp = INSIDE;
+			if (XyList) InsideTyp = XyList->IsInsideXYList(X, Y);
+			if (InsideTyp == INSIDE || InsideTyp == ON_LINE)
+			{
+				AnzKnoten++;
+
+				if (AnzKnoten < MaxNodesPerSlice)
+				{
+					TNode* Node = new TNode(AnzKnoten, X, Y, Z);
+					NodeList->push_back(Node);
+				}
+			}
 		}
+		SHPDestroyObject(psCShape);
 	}
 
 	SHPClose(hSHP);
 
+	write_fortschritt("%d Objekte geladen %d Knoten geladen %d Knoten insgesamt\n", RecordCount, NodeList->size(), AnzKnoten);
+
 	write_fortschritt("DGM SHP laden beendet<-\n");
 
+	if (AnzKnoten <= MaxNodesPerSlice)	return (1);
+	else								return ((AnzKnoten - 1) / MaxNodesPerSlice + 1);
+}
+
+//---------------------------------------------------------------------------
+unsigned int LoadDGM2DM(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug)
+{
+	write_fortschritt("->DGM 2DM laden\n");
+
+	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
+
+	FILE *fh = fopen(FileName.c_str(), "r");
+	if (fh == 0)
+	{
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen", FileName.c_str());
+	}
+
+	char line[1000];
+
+	if (0 == fgets (line, sizeof(line)-1, fh))
+	{
+		write_error(2298, "Konnte die Kopfzeile in der Datei '%s' nicht lesen", FileName.c_str());
+	}
+	line[sizeof(line)-1] = '\0';
+
+	if (strncmp(line, "MESH2D", 6) != 0)
+	{
+		write_error(2298, "Die Kopfzeile in der Datei '%s' war nicht korrekt", FileName.c_str());
+	}
+
+	unsigned int AnzKnoten = 0;
+	unsigned int AnzElemente = 0;
+	unsigned int AnzZeilen = 1;
+
+	while (NULL != fgets (line, sizeof (line)-1, fh))
+	{
+		AnzZeilen++;
+
+		if (Debug && AnzZeilen % 10000 == 0)	write_fortschritt("%d Zeilen gelesen %d Knoten geladen %d Elemente gezählt\n", AnzZeilen, NodeList->size(), AnzElemente);
+		else if (AnzZeilen % 100000 == 0)		write_fortschritt("%d Zeilen gelesen %d Knoten geladen %d Elemente gezählt\n", AnzZeilen, NodeList->size(), AnzElemente);
+
+		if (strncmp (line, "E4Q", 3) == 0 || strncmp (line, "E3T", 3) == 0)
+		{
+			AnzElemente++;
+		}
+		else if (strncmp (line, "ND", 2) == 0)
+		{
+			int     Nr;
+			double  X;
+			double  Y;
+			double  Z;
+
+			if (4 != sscanf(line, "ND%d%lf%lf%lf\n", &Nr, &X, &Y, &Z))
+			{
+				write_error(2297, "Konnte keine 3 Werte in der Datei '%s' in der Zeile %d lesen", FileName.c_str(), AnzZeilen);
+			}
+
+			X = (long)(X * 100) / 100.0;
+			Y = (long)(Y * 100) / 100.0;
+			Z = (long)(Z * 100) / 100.0;
+
+			TInsideTyp InsideTyp = INSIDE;
+			if (XyList) InsideTyp = XyList->IsInsideXYList(X, Y);
+			if (InsideTyp == INSIDE || InsideTyp == ON_LINE)
+			{
+				AnzKnoten++;
+
+				if (AnzKnoten < MaxNodesPerSlice)
+				{
+					TNode *Node = new TNode(Nr, X, Y, Z);
+					NodeList->push_back(Node);
+				}
+			}
+		}
+	}
+
+	NodeList->SortByNr();
+
+	if (AnzElemente > 0)
+	{
+		fseek(fh, 0L, SEEK_SET);
+
+		int AnzZeilen = 0;
+
+		while (ElementList->size() < AnzElemente && NULL != fgets (line, sizeof (line)-1, fh))
+		{
+			AnzZeilen++;
+
+			if (Debug && AnzZeilen % 10000 == 0)	write_fortschritt("%d Zeilen gelesen %d Knoten geladen %d Elemente geladen\n", AnzZeilen, NodeList->size(), ElementList->size());
+			else if (AnzZeilen % 100000 == 0)		write_fortschritt("%d Zeilen gelesen %d Knoten geladen %d Elemente geladen\n", AnzZeilen, NodeList->size(), ElementList->size());
+
+			int Nr;
+			int Node1Nr;
+			int Node2Nr;
+			int Node3Nr;
+			int Node4Nr;
+			int Prop;
+
+			if (strncmp(line, "E3T", 3) == 0)
+			{
+				if (5 != sscanf(line, "E3T%d%d%d%d%d\n", &Nr, &Node1Nr, &Node2Nr, &Node3Nr, &Prop))
+				{
+					write_error(2297, "Konnte keine 5 Werte in der Datei '%s' in der Zeile %d lesen", FileName.c_str(), AnzZeilen);
+				}
+
+				TNode *Node1 = NodeList->FindByNr(Node1Nr);
+				TNode *Node2 = NodeList->FindByNr(Node2Nr);
+				TNode *Node3 = NodeList->FindByNr(Node3Nr);
+
+				if (Node1 && Node2 && Node3)
+				{
+					TElement *Element = new TElement(Node1, Node2, Node3);
+					ElementList->push_back(Element);
+				}
+				continue;
+			}
+
+			if (strncmp(line, "E4Q", 3) == 0)
+			{
+				if (6 != sscanf(line, "E4Q%d%d%d%d%d%d\n", &Nr, &Node1Nr, &Node2Nr, &Node3Nr, &Node4Nr, &Prop))
+				{
+					write_error(2297, "Konnte keine 6 Werte in der Datei '%s' in der Zeile %d lesen", FileName.c_str(), AnzZeilen);
+				}
+
+				TNode *Node1 = NodeList->FindByNr(Node1Nr);
+				TNode *Node2 = NodeList->FindByNr(Node2Nr);
+				TNode *Node3 = NodeList->FindByNr(Node3Nr);
+				TNode *Node4 = NodeList->FindByNr(Node4Nr);
+
+				if (Node1 && Node2 && Node3 && Node4)
+				{
+					TElement *Element = new TElement(Node1, Node2, Node3, Node4);
+					ElementList->push_back(Element);
+				}
+				continue;
+			}
+		}
+	}
+
+	fclose(fh);
+
+	write_fortschritt("%d Elemente, %d Knoten geladen, %d Knoten insgesamt\n", ElementList->size(), NodeList->size(), AnzKnoten);
+
+	write_fortschritt("DGM 2DM laden beendet<-\n");
+
+	if (AnzKnoten <= MaxNodesPerSlice)	return (1);
+	else								return ((AnzKnoten - 1) / MaxNodesPerSlice + 1);
+}
+
+//---------------------------------------------------------------------
+bool LoadProfile(std::string FileName, TProfilList* ProfilList)
+{
+	write_fortschritt("->Profilspuren werden geladen\n");
+
+	if (ProfilList == 0)
+	{
+		dump_error(__FILE__, __LINE__, "ProfilListe ist undefiniert\n");
+	}
+
+	std::string SHPFileName = ExchangeFileExt(FileName, ".SHP");
+	SHPHandle hSHP = SHPOpen(SHPFileName.c_str(), "rb");
+
+	if (hSHP == NULL)
+	{
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", SHPFileName.c_str());
+	}
+
+	std::string DBFFileName = ExchangeFileExt(FileName, ".DBF");
+	DBFHandle hDBF = DBFOpen(DBFFileName.c_str(), "rb");
+	if (hDBF == NULL)
+	{
+		SHPClose(hSHP);
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", DBFFileName.c_str());
+		return (false);
+	}
+
+	int 		SHPRecordCount = 0;
+	TShpType	ShapeType = SHPT_NULL;
+	double		Mins[4];
+	double		Maxs[4];
+
+	SHPGetInfo(hSHP, &SHPRecordCount, &ShapeType, Mins, Maxs);
+
+	if (SHPRecordCount == 0)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2204, "Es sind keine Objekte in der Shape-Datei '%s'\n", SHPFileName.c_str());
+	}
+
+	if (ShapeType != SHPT_ARC && ShapeType != SHPT_ARCZ && ShapeType != SHPT_ARCM)
+	{
+		write_error(2213, "Der Typ ('%s') der Shape-Datei '%s' ist nicht ARC, ARCZ oder ARCM.\nNur die genannten Typen sind für Profilspuren zulässig.\n", ShapeTypeName(ShapeType), SHPFileName.c_str());
+	}
+
+
+
+	int DBFRecordCount = DBFGetRecordCount(hDBF);
+
+	if (DBFRecordCount == 0)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2204, "Es sind keine Objekte in der DBF-Datei '%s'\n", DBFFileName.c_str());
+	}
+
+	if (DBFRecordCount != SHPRecordCount)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2205, "Shape-Datei '%s' und DBF-Datei '%s' enthalten verschieden viele Objekte\n", SHPFileName.c_str(), DBFFileName.c_str());
+	}
+
+	int RecordCount = SHPRecordCount;
+
+	int FieldCount = DBFGetFieldCount(hDBF);
+
+	if (FieldCount == 0)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2206, "In der DBD-Datei %s' sind keine Attribute definiert\nEs müssen aber mindestens die Attibute GEW und STATION definiert sein.\n", DBFFileName.c_str());
+	}
+
+	int GewFieldIndex = DBFGetFieldIndex(hDBF, "GEW");
+
+	if (GewFieldIndex == -1)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2207, "In der DBD-Datei %s' ist das Attribut GEW nicht definiert\nEs muss aber vorhanden sein.\n", DBFFileName.c_str());
+	}
+
+	int StationFieldIndex = DBFGetFieldIndex(hDBF, "STATION");
+
+	if (StationFieldIndex == -1)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2208, "In der DBD-Datei '%s' ist das Attribut STATION nicht definiert\nEs muss aber vorhanden sein.\n", DBFFileName.c_str());
+	}
+
+	int Width = 0;
+	int Decimals = 0;
+	if (DBFGetFieldInfo(hDBF, GewFieldIndex, NULL, &Width, &Decimals) != FTString)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2209, "In der DBD-Datei '%s' ist der Attribut-Typ des Attributes 'GEW' nicht Text.\n", DBFFileName.c_str());
+	}
+
+	if (DBFGetFieldInfo(hDBF, StationFieldIndex, NULL, &Width, &Decimals) != FTDouble)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2210, "In der DBD-Datei '%s' ist der Attribut-Typ des Attributes 'STATION' nicht Fliesskommazahl.\n", DBFFileName.c_str());
+	}
+
+	for (int i = 0; i<RecordCount; i++)
+	{
+		if (ProfilList->size() > 0 && ProfilList->size() % 10 == 0)	write_fortschritt("%d Profilspuren geladen\n", ProfilList->size());
+
+		std::string Gewaesser = DBFReadStringAttribute(hDBF, i, GewFieldIndex);
+		double S = DBFReadDoubleAttribute(hDBF, i, StationFieldIndex);
+
+		int Station = (int)(S * 10000.0 + 0.5);
+		if (S < 0)	Station = (int)(S * 10000.0 - 0.5);
+
+		if (ProfilList->Find(Gewaesser, Station))
+		{
+			write_warning(2111, "In der DBD-Datei '%s' kommt das Profil ('%s',%.4f) mehrfach vor.\nEs wird nur die erste Definition berücksichtigt.\n", DBFFileName.c_str(), Gewaesser.c_str(), Station / 10000.0);
+			continue;
+		}
+
+		SHPObject *psCShape = SHPReadObject(hSHP, i);
+
+		int AnzVert = psCShape->nVertices;
+
+		if (AnzVert <= 0)
+		{
+			write_warning(2112, "In der DBD-Datei '%s' hat das Profil ('%s',%.4f) keine Stützstellen.\nEs wird ignoriert.", DBFFileName.c_str(), Gewaesser.c_str(), Station / 10000.0);
+			continue;
+		}
+
+		TProfil* Profil = new TProfil(Gewaesser, Station);
+
+		ProfilList->insert(Profil);
+
+		for (int j=0; j < AnzVert; j++)
+		{
+			double X = psCShape->padfX[j];
+			double Y = psCShape->padfY[j];
+
+			X = (long)(X * 100.0 + 0.5) / 100.0;
+			Y = (long)(Y * 100.0 + 0.5) / 100.0;
+			Profil->AddPoint(X, Y);
+		}
+
+		SHPDestroyObject(psCShape);
+	}
+
+	write_fortschritt("%d Profilspuren geladen\n", ProfilList->size());
+
+	DBFClose(hDBF);
+	SHPClose(hSHP);
+
+	write_fortschritt("Profilspuren laden beendet<-\n");
+
 	return (true);
 }
 
+//---------------------------------------------------------------------
+bool LoadWsp(std::string FileName, TProfilList* ProfilList)
+{
+	write_fortschritt("->Wasserstände werden geladen\n");
+
+	FILE *fh = fopen(FileName.c_str(), "r");
+	if (fh == 0)
+	{
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", FileName.c_str());
+	}
+
+	int GewCol =0;
+	int StationCol =0;
+	int WspCol =0;
+
+	int AktZeile = 0;
+
+	char line[1000];
+	while (fgets (line, sizeof (line)-1, fh))
+	{
+		if (ProfilList->size() > 0 && ProfilList->size() % 10 == 0)	write_fortschritt("%d Wasserstände geladen\n", ProfilList->size());
+
+		AktZeile++;
+
+		line[sizeof(line)-1] = '\0';
+		if (strlen(line) > 0) line[strlen(line)-1] = '\0';
+
+		for (unsigned int i=0; i<strlen(line); i++)	if (line[i] == ',')	line[i] = '.';
+
+		char* End = line + strlen(line);
+
+		std::string Gewaesser = "";
+		double		StationD = 0.0;
+		double		Wsp = 0.0;
+
+		int AktCol = 0;
+		int ColOk = 0;
+		char* Col =0;
+		char* P = line;
+		while (P < End)
+		{
+			P = SkipSpaces(P);
+
+			Col = GetCol(P);
+			AktCol++;
+
+			if (AktZeile == 1)
+			{
+				if (strncmp(Col, "GEW", 3) == 0)
+				{
+					GewCol = AktCol;
+					ColOk++;
+				}
+				if (strncmp(Col, "STATION", 7) == 0)
+				{
+					StationCol = AktCol;
+					ColOk++;
+				}
+				if (strncmp(Col, "WSP", 3) == 0)
+				{
+					WspCol = AktCol;
+					ColOk++;
+				}
+			}
+			else
+			{
+				if (AktCol == GewCol)
+				{
+					Gewaesser = Col;
+					ColOk++;
+				}
+				if (AktCol == StationCol)
+				{
+					if (1 != sscanf(Col, "%lf", &StationD))
+					{
+						write_error(2216, "Konnte keine Zahl in Spalte %d erkennen\n", AktCol);
+					}
+					ColOk++;
+				}
+				if (AktCol == WspCol)
+				{
+					if (1 != sscanf(Col, "%lf", &Wsp))
+					{
+						write_error(2216, "Konnte keine Zahl in Spalte %d erkennen\n", AktCol);
+					}
+					ColOk++;
+				}
+			}
+			if (ColOk == 3)	break;
+
+			P = P + strlen(Col) + 1;
+		}
+		if (ColOk != 3) write_error(2215, "Nicht genug Informationen in der Zeile\n");
+
+		if (AktZeile == 1) continue;
+
+		int Station = (int)(StationD * 10000.0 + 0.5);
+		if (StationD < 0)	Station = (int)(StationD * 10000.0 - 0.5);
+
+		TProfil* Profil = new TProfil(Gewaesser, Station, Wsp);
+
+		ProfilList->insert(Profil);
+	}
+	write_fortschritt("%d Wasserstände geladen\n", ProfilList->size());
+
+	fclose(fh);
+
+	write_fortschritt("Wasserstände wurden geladen<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------
+bool LoadAchse(std::string FileName, TGewaesserAchseList* GewaesserAchseList)
+{
+	write_fortschritt("->Gewässerachse wird geladen\n");
+
+	if (GewaesserAchseList == 0)
+	{
+		dump_error(__FILE__, __LINE__, "GewässerAchse ist undefiniert\n");
+	}
+
+	std::string SHPFileName = ExchangeFileExt(FileName, ".SHP");
+	SHPHandle hSHP = SHPOpen(SHPFileName.c_str(), "rb");
+
+	if (hSHP == NULL)
+	{
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", SHPFileName.c_str());
+	}
+
+	std::string DBFFileName = ExchangeFileExt(FileName, ".DBF");
+	DBFHandle hDBF = DBFOpen(DBFFileName.c_str(), "rb");
+	if (hDBF == NULL)
+	{
+		SHPClose(hSHP);
+		write_error(2201, "Konnte '%s' nicht zum Lesen öffnen\n", DBFFileName.c_str());
+		return (false);
+	}
+
+	int 		SHPRecordCount = 0;
+	TShpType	ShapeType = SHPT_NULL;
+	double		Mins[4];
+	double		Maxs[4];
+
+	SHPGetInfo(hSHP, &SHPRecordCount, &ShapeType, Mins, Maxs);
+
+	if (SHPRecordCount == 0)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2204, "Es sind keine Objekte in der Shape-Datei '%s'\n", SHPFileName.c_str());
+	}
+
+	if (ShapeType != SHPT_ARC && ShapeType != SHPT_ARCZ && ShapeType != SHPT_ARCM)
+	{
+		write_error(2217, "Der Typ ('%s') der Shape-Datei '%s' ist nicht ARC, ARCZ oder ARCM.\nNur die genannten Typen sind für die Gewässerachse zulässig.\n", ShapeTypeName(ShapeType), SHPFileName.c_str());
+	}
+
+	int DBFRecordCount = DBFGetRecordCount(hDBF);
+
+	if (DBFRecordCount == 0)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2204, "Es sind keine Objekte in der DBF-Datei '%s'\n", DBFFileName.c_str());
+	}
+
+	if (DBFRecordCount != SHPRecordCount)
+	{
+		DBFClose(hDBF);
+		SHPClose(hSHP);
+
+		write_error(2205, "Shape-Datei '%s' und DBF-Datei '%s' enthalten verschieden viele Objekte\n", SHPFileName.c_str(), DBFFileName.c_str());
+	}
+
+	int RecordCount = SHPRecordCount;
+
+	int FieldCount = DBFGetFieldCount(hDBF);
+
+	if (FieldCount == 0)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2206, "In der DBD-Datei %s' sind keine Attribute definiert\nEs müssen aber mindestens die Attibute GEW und STATION definiert sein.\n", DBFFileName.c_str());
+	}
+
+	int GewFieldIndex = DBFGetFieldIndex(hDBF, "GEW");
+
+	if (GewFieldIndex == -1)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2207, "In der DBD-Datei %s' ist das Attribut GEW nicht definiert\nEs muss aber vorhanden sein.\n", DBFFileName.c_str());
+	}
+
+	int Width = 0;
+	int Decimals = 0;
+	if (DBFGetFieldInfo(hDBF, GewFieldIndex, NULL, &Width, &Decimals) != FTString)
+	{
+		SHPClose(hSHP);
+		DBFClose(hDBF);
+
+		write_error(2209, "In der DBD-Datei '%s' ist der Attribut-Typ des Attributes 'GEW' nicht Text.\n", DBFFileName.c_str());
+	}
+
+	for (int i = 0; i<RecordCount; i++)
+	{
+		if (GewaesserAchseList->size() > 0 && GewaesserAchseList->size() % 10 == 0)	write_fortschritt("%d Gewässerachsen geladen\n", GewaesserAchseList->size());
+
+		std::string Gewaesser = DBFReadStringAttribute(hDBF, i, GewFieldIndex);
+
+		SHPObject *psCShape = SHPReadObject(hSHP, i);
+
+		int AnzVert = psCShape->nVertices;
+
+		if (AnzVert <= 0)
+		{
+			write_warning(2118, "In der DBD-Datei '%s' hat eine Gewässerachse ('%s') keine Stützstellen.\nSie wird ignoriert.", DBFFileName.c_str(), Gewaesser.c_str());
+			continue;
+		}
+
+
+		TGewaesserAchse* GewaesserAchse = new TGewaesserAchse(Gewaesser, i);
+
+		GewaesserAchseList->insert(GewaesserAchse);
+
+		for (int j=0; j < AnzVert; j++)
+		{
+			double X = psCShape->padfX[j];
+			double Y = psCShape->padfY[j];
+
+			X = (long)(X * 100.0 + 0.5) / 100.0;
+			Y = (long)(Y * 100.0 + 0.5) / 100.0;
+			GewaesserAchse->AddPoint(X, Y);
+		}
+
+		SHPDestroyObject(psCShape);
+	}
+
+	write_fortschritt("%d Gewässerachsen geladen\n", GewaesserAchseList->size());
+
+	DBFClose(hDBF);
+	SHPClose(hSHP);
+
+	write_fortschritt("Gewässerachse wurden geladen<-\n");
+
+	return (true);
+}
+
 //---------------------------------------------------------------------------
-bool SaveNet(std::string FileName, TNodeList *NodeList, TElementList *ElementList)
+bool SaveNet(std::string FileName, TNodeList *NodeList, TElementList *ElementList, bool Debug)
 {
-	write_fortschritt("->Netz speichern\n");
+	write_fortschritt("->2dM-Netz speichern\n");
 
+	if (NodeList == 0)		dump_error(__FILE__, __LINE__, "Die Knotenliste ist nicht definiert\n");
+
 	FILE *fh = fopen (FileName.c_str(), "w");
 	if (fh == NULL)
 	{
@@ -357,7 +982,8 @@
 
 	for (unsigned int i=0; i<ElementList->size(); i++)
 	{
-		if (i % 10000 == 0)	write_fortschritt("%d Elemente gespeichert\n", i);
+		if (Debug && i % 1000 == 0)	write_fortschritt("%d Elemente gespeichert\n", i);
+		else if (i % 10000 == 0)	write_fortschritt("%d Elemente gespeichert\n", i);
 
 		TElement *Element = (*ElementList)[i];
 		TNodeList *NL = Element->NodeList;
@@ -382,7 +1008,8 @@
 
 	for (unsigned int i=0; i<NodeList->size(); i++)
 	{
-		if (i % 10000 == 0)	write_fortschritt("%d Knoten gespeichert\n", i);
+		if (Debug && i % 1000 == 0)	write_fortschritt("%d Knoten gespeichert\n", i);
+		else if (i % 10000 == 0)	write_fortschritt("%d Knoten gespeichert\n", i);
 
 		TNode *Node = (*NodeList)[i];
 
@@ -441,8 +1068,667 @@
 	return (true);
 }
 
+//---------------------------------------------------------------------------
+bool SaveProfile(std::string FileName, TProfilList *ProfilList, bool Debug)
+{
+	write_fortschritt("->Profile speichern\n");
 
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
 
+	if (DBFAddField(DBFHandle, "GEW", FTString, 255, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'GEW' nicht erzeugen", FileName.c_str());
+	}
 
+	if (DBFAddField(DBFHandle, "STATION", FTDouble, 10, 4) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'STATION' nicht erzeugen", FileName.c_str());
+	}
 
+	if (DBFAddField(DBFHandle, "WSP", FTDouble, 8, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'WSP' nicht erzeugen", FileName.c_str());
+	}
 
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_ARC);
+
+
+	int AnzProfil = 0;
+	for (TProfilList::iterator i = ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		if (Debug && AnzProfil % 100 == 0)	write_fortschritt("%d Profile bearbeitet\n", AnzProfil);
+		else if (AnzProfil % 1000 == 0)		write_fortschritt("%d Profile bearbeitet\n", AnzProfil);
+
+		TProfil* Profil = *i;
+
+		std::string Gewaesser = Profil->Gewaesser;
+		double		Station = Profil->Station;
+		double		Wsp = Profil->Wsp;
+
+		double	*x = (double *)malloc(sizeof(double) * (Profil->PointList->size() + 1));
+		double 	*y = (double *)malloc(sizeof(double) * (Profil->PointList->size() + 1));
+		double 	*z = (double *)malloc(sizeof(double) * (Profil->PointList->size() + 1));
+
+		int AnzPoint = 0;
+		for (TPointList::iterator j = Profil->PointList->begin(); j != Profil->PointList->end(); j++)
+		{
+			TPoint* Point = *j;
+
+			double X = Point->X;
+			double Y = Point->Y;
+
+			x[AnzPoint] = X;
+			y[AnzPoint] = Y;
+			z[AnzPoint] = 0.0;
+
+			AnzPoint++;
+		}
+
+		TPoint* Point = *Profil->PointList->begin();
+
+		double X = Point->X;
+		double Y = Point->Y;
+
+		x[AnzPoint] = X;
+		y[AnzPoint] = Y;
+		z[AnzPoint] = 0.0;
+
+		AnzPoint++;
+
+		SHPObject *psShape = SHPCreateSimpleObject(SHPT_ARC, AnzPoint, x, y, z);
+		SHPWriteObject(SHPHandle, -1, psShape);
+		SHPDestroyObject(psShape);
+
+		DBFWriteStringAttribute(DBFHandle, AnzProfil, 0, Gewaesser.c_str());
+		DBFWriteDoubleAttribute(DBFHandle, AnzProfil, 1, Station);
+		DBFWriteDoubleAttribute(DBFHandle, AnzProfil, 2, Wsp);
+
+		free(x);
+		free(y);
+		free(z);
+
+		AnzProfil++;
+	}
+
+	DBFClose(DBFHandle);
+	SHPClose(SHPHandle);
+
+	write_fortschritt("Profile gespeichert<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+bool SavePolygon(std::string FileName, std::string Gewaesser, int Von, int Bis, TXYList *XyList)
+{
+	write_fortschritt("->Polygon wird gespeichert\n");
+
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "GEW", FTString, 255, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'GEW' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "VON", FTInteger, 10, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'VON' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "BIS", FTInteger, 10, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'BIS' nicht erzeugen", FileName.c_str());
+	}
+
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_POLYGON);
+
+
+	double	*x = (double *)malloc(sizeof(double) * (XyList->size()+1));
+	double 	*y = (double *)malloc(sizeof(double) * (XyList->size()+1));
+	double 	*z = (double *)malloc(sizeof(double) * (XyList->size()+1));
+
+	int AnzPoint = 0;
+	for (TXYList::iterator i = XyList->begin(); i != XyList->end(); i++)
+	{
+		TXY* Xy = *i;
+
+		double X = Xy->X;
+		double Y = Xy->Y;
+
+		x[AnzPoint] = X;
+		y[AnzPoint] = Y;
+		z[AnzPoint] = 0.0;
+
+		AnzPoint++;
+	}
+
+	TXYList::iterator i = XyList->begin();
+	TXY* Xy = *i;
+
+	double X = Xy->X;
+	double Y = Xy->Y;
+
+	x[AnzPoint] = X;
+	y[AnzPoint] = Y;
+	z[AnzPoint] = 0.0;
+
+	AnzPoint++;
+
+	SHPObject *psShape = SHPCreateSimpleObject(SHPT_POLYGON, AnzPoint, x, y, z);
+	SHPWriteObject(SHPHandle, -1, psShape);
+	SHPDestroyObject(psShape);
+
+	DBFWriteStringAttribute(DBFHandle, 0, 0, Gewaesser.c_str());
+	DBFWriteDoubleAttribute(DBFHandle, 0, 1, Von);
+	DBFWriteDoubleAttribute(DBFHandle, 0, 2, Bis);
+
+	free(x);
+	free(y);
+	free(z);
+
+	DBFClose(DBFHandle);
+	SHPClose(SHPHandle);
+
+	write_fortschritt("Polygon gespeichert<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+bool SavePolygone(std::string FileName, TErgebnisPolygonList *ErgebnisPolygonList, bool Debug)
+{
+	write_fortschritt("->Polygone werden gespeichert\n");
+
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "GEW", FTString, 255, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'GEW' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "VONKM", FTDouble, 12, 4) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'VON' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "BISKM", FTDouble, 12, 4) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'BIS' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "DELTA", FTDouble, 12, 4) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'BIS' nicht erzeugen", FileName.c_str());
+	}
+
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_POLYGON);
+
+	int	AnzPolygons = 0;
+	TErgebnisPolygonList::iterator i = ErgebnisPolygonList->begin();
+	while (i != ErgebnisPolygonList->end())
+	{
+		TErgebnisPolygon* ErgebnisPolygon = *i;
+
+		std::string AktGewaesser = ErgebnisPolygon->Gewaesser;
+		double AktVonKm = ErgebnisPolygon->VonKm;
+		double AktBisKm = ErgebnisPolygon->BisKm;
+		double AktDiff = ErgebnisPolygon->Diff;
+
+		size_t	Size = 0;
+
+		int		*ps = 0;
+		int		*pt = 0;
+		double	*x = 0;
+		double 	*y = 0;
+		double 	*z = 0;
+		double 	*m = 0;
+
+		int	AnzPolyParts = 0;
+		int	AnzPolyPoints = 0;
+		for (TErgebnisPolygonList::iterator j = ErgebnisPolygonList->begin(); j != ErgebnisPolygonList->end(); j++)
+		{
+			TErgebnisPolygon* EP1 = *j;
+			if (EP1->Gewaesser != AktGewaesser || EP1->Diff != AktDiff) continue; // Die Moment nicht
+
+			TXYList::iterator First = EP1->begin();
+
+			TXY *Xy = *First;
+
+			double	X = Xy->X;
+			double	Y = Xy->Y;
+
+			bool IsInnerRing = false;
+			for (TErgebnisPolygonList::iterator k = ErgebnisPolygonList->begin(); k != ErgebnisPolygonList->end(); k++)
+			{
+				TErgebnisPolygon* EP2 = *k;
+
+				if (EP2 == EP1)	continue;
+				
+				if (EP2->Gewaesser != AktGewaesser || EP2->Diff != AktDiff) continue; // Die Moment auch nicht
+
+
+				if (EP2->IsInsideXYList(X, Y))
+				{
+					IsInnerRing = true;
+					break;
+				}
+			}
+
+			AnzPolyParts++;
+
+			// Jetzt holen wird uns den Speicher dafür
+			ps = (int *)SfRealloc(ps, sizeof(int) * AnzPolyParts);
+			pt = (int *)SfRealloc(pt, sizeof(int) * AnzPolyParts);
+
+			Size = Size + sizeof(double) * EP1->size();
+
+			x = (double *)SfRealloc(x, Size);
+			y = (double *)SfRealloc(y, Size);
+			z = (double *)SfRealloc(z, Size);
+			m = (double *)SfRealloc(m, Size);
+
+			ps[AnzPolyParts-1] = AnzPolyPoints;
+
+			if (IsInnerRing)	pt[AnzPolyParts-1] = SHPP_INNERRING;
+			else				pt[AnzPolyParts-1] = SHPP_RING;
+
+			for (TErgebnisPolygon::iterator i = EP1->begin(); i != EP1->end(); i++)
+			{
+				TXY *Xy = *i;
+
+				double X = Xy->X;
+				double Y = Xy->Y;
+
+				x[AnzPolyPoints] = X;
+				y[AnzPolyPoints] = Y;
+				z[AnzPolyPoints] = 0.0;
+				m[AnzPolyPoints] = 0.0;
+
+				AnzPolyPoints++;
+			}
+		}
+
+		if (AnzPolyParts > 0 && AnzPolyPoints > 0)
+		{
+			DBFWriteStringAttribute(DBFHandle, AnzPolygons, 0, AktGewaesser.c_str());
+			DBFWriteDoubleAttribute(DBFHandle, AnzPolygons, 1, AktVonKm);
+			DBFWriteDoubleAttribute(DBFHandle, AnzPolygons, 2, AktBisKm);
+			DBFWriteDoubleAttribute(DBFHandle, AnzPolygons, 3, AktDiff);
+
+			SHPObject *psShape = SHPCreateObject(SHPT_POLYGON, -1, AnzPolyParts, ps, NULL, AnzPolyPoints, x, y, z, m);
+			SHPRewindObject(SHPHandle, psShape);
+			SHPWriteObject(SHPHandle, -1, psShape);
+			SHPDestroyObject(psShape);
+
+			AnzPolygons++;
+		}
+
+		free(ps);
+		free(pt);
+		free(x);
+		free(y);
+		free(z);
+		free(m);
+
+		TErgebnisPolygonList::iterator j = ErgebnisPolygonList->begin();
+		while (j != ErgebnisPolygonList->end())
+		{
+			TErgebnisPolygon* EP1 = *j;
+			if (EP1->Gewaesser == AktGewaesser && EP1->Diff == AktDiff)
+			{
+				delete EP1;
+				ErgebnisPolygonList->erase(j);
+				j = ErgebnisPolygonList->begin();
+				continue;
+
+			}
+			j++;
+		}
+		i = ErgebnisPolygonList->begin();
+	}
+
+	DBFClose(DBFHandle);
+	SHPClose(SHPHandle);
+
+	write_fortschritt("Polygone sind gespeichert<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+int OutElement(int AnzPolygone, TElement *Element, DBFHandle PolygonDBFHandle, SHPHandle PolygonSHPHandle)
+{
+	if (Element->Typ == TRI)
+	{
+		TNodeList *NL = Element->NodeList;
+
+		TNode *Node1 = (*NL)[0];
+		TNode *Node2 = (*NL)[1];
+		TNode *Node3 = (*NL)[2];
+
+		double Wsp = 0.0;
+		double Depth = 0.0;
+		double Topo = 0.0;
+
+		double Z1 = Node1->Z;
+		double Z2 = Node2->Z;
+		double Z3 = Node3->Z;
+
+		double W1 = Node1->Wsp;
+		double W2 = Node2->Wsp;
+		double W3 = Node3->Wsp;
+
+		if (W1 <= Z1)	W1 = 0.00;
+		if (W2 <= Z2)	W2 = 0.00;
+		if (W3 <= Z3)	W3 = 0.00;
+
+		if (W1 <= 0.0 && W2 <= 0.0 && W3 <= 0.0)    Wsp = 0.0;
+		else if (W1 <= 0.0 && W2 <= 0.0)			Wsp = W3;
+		else if (W1 <= 0.0 && W3 <= 0.0)			Wsp = W2;
+		else if (W2 <= 0.0 && W3 <= 0.0)			Wsp = W1;
+		else if (W1 <= 0.0)							Wsp = (W2 + W3) / 2.0;
+		else if (W2 <= 0.0)							Wsp = (W1 + W3) / 2.0;
+		else if (W3 <= 0.0)							Wsp = (W1 + W2) / 2.0;
+		else										Wsp = (W1 + W2 + W3) / 3.0;
+
+		double D1 = W1 - Z1;
+		double D2 = W2 - Z2;
+		double D3 = W3 - Z3;
+
+		// Nur bei gerade geknabberten Elementen wichtig
+		if (D1 <= 0.0) D1 = 0.00;
+		if (D2 <= 0.0) D2 = 0.00;
+		if (D3 <= 0.0) D3 = 0.00;
+
+		if (D1 <= 0.0 && D2 <= 0.0 && D3 <= 0.0)    Depth = 0.0;
+		else if (D1 <= 0.0 && D2 <= 0.0)			Depth = D3;
+		else if (D1 <= 0.0 && D3 <= 0.0)			Depth = D2;
+		else if (D2 <= 0.0 && D3 <= 0.0)			Depth = D1;
+		else if (D1 <= 0.0)							Depth = (D2 + D3) / 2.0;
+		else if (D2 <= 0.0)							Depth = (D1 + D3) / 2.0;
+		else if (D3 <= 0.0)							Depth = (D1 + D2) / 2.0;
+		else										Depth = (D1 + D2 + D3) / 3.0;
+
+		if (Wsp > 0.0 && Depth <= 0.0)
+		{
+			dump_error(__FILE__, __LINE__, "Wasserstand > 0 aber Wassertiefe <= 0");
+		}
+
+		if (Wsp > 0)	Topo = Wsp - Depth;
+		else			Topo = (Z1 + Z2 + Z3) / 3;
+
+		double  x[4];
+		double  y[4];
+		double  z[4];
+
+		double win = ThreeToWin (Node2->X, Node2->Y, Node1->X, Node1->Y, Node3->X, Node3->Y, 0);
+
+		if (win > 180)
+		{
+			x[0] = Node1->X;
+			x[1] = Node2->X;
+			x[2] = Node3->X;
+			x[3] = Node1->X;
+
+			y[0] = Node1->Y;
+			y[1] = Node2->Y;
+			y[2] = Node3->Y;
+			y[3] = Node1->Y;
+		}
+		else
+		{
+			x[0] = Node1->X;
+			x[1] = Node3->X;
+			x[2] = Node2->X;
+			x[3] = Node1->X;
+
+			y[0] = Node1->Y;
+			y[1] = Node3->Y;
+			y[2] = Node2->Y;
+			y[3] = Node1->Y;
+		}
+
+		z[0] = 0.0;
+		z[1] = 0.0;
+		z[2] = 0.0;
+		z[3] = 0.0;
+
+		SHPObject *psShape = SHPCreateSimpleObject(SHPT_POLYGON, 4, x, y, z);
+		SHPWriteObject(PolygonSHPHandle, -1, psShape);
+		SHPDestroyObject(psShape);
+
+		DBFWriteDoubleAttribute(PolygonDBFHandle, AnzPolygone, 0, Topo);
+		DBFWriteDoubleAttribute(PolygonDBFHandle, AnzPolygone, 1, Wsp);
+		DBFWriteDoubleAttribute(PolygonDBFHandle, AnzPolygone, 2, Depth);
+
+		AnzPolygone++;
+	}
+	else
+	{
+		TNodeList *NL = Element->NodeList;
+
+		TNode *Node1 = (*NL)[0];
+		TNode *Node2 = (*NL)[1];
+		TNode *Node3 = (*NL)[2];
+		TNode *Node4 = (*NL)[3];
+
+		TElement *TempElement = 0;
+
+		TempElement = new TElement(Node1, Node2, Node3);
+		AnzPolygone = OutElement(AnzPolygone, TempElement, PolygonDBFHandle, PolygonSHPHandle);
+		delete TempElement;
+
+		TempElement = new TElement(Node1, Node3, Node4);
+		AnzPolygone = OutElement(AnzPolygone, TempElement, PolygonDBFHandle, PolygonSHPHandle);
+		delete TempElement;
+	}
+
+	return (AnzPolygone);
+}
+
+//---------------------------------------------------------------------------
+bool SaveElements(std::string FileName, TElementList *ElementList, bool Debug)
+{
+	write_fortschritt("->Elemente speichern\n");
+
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Topo", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Topo' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Wsp", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Wsp' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Depth", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Depth' nicht erzeugen", FileName.c_str());
+	}
+
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_POLYGON);
+
+	int AnzPolygone = 0;
+	for (TElementList::iterator i=ElementList->begin(); i != ElementList->end(); i++)
+	{
+		if (Debug && AnzPolygone % 10000 == 0)	write_fortschritt("%d Polygone gespeichert\n", AnzPolygone);
+		else if (AnzPolygone % 100000 == 0)		write_fortschritt("%d Polygone gespeichert\n", AnzPolygone);
+
+		TElement *Element = *i;
+
+		AnzPolygone = OutElement(AnzPolygone, Element, DBFHandle, SHPHandle);
+	}
+	write_fortschritt("%d Polygone gespeichert\n", AnzPolygone);
+
+	SHPClose(SHPHandle);
+	DBFClose(DBFHandle);
+
+	write_fortschritt("Elemente gespeichert<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+bool SaveNodes(std::string FileName, TNodeList *NodeList, bool Debug)
+{
+	write_fortschritt("->Knoten speichern\n");
+
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Topo", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Topo' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Wsp", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Wsp' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Depth", FTDouble, 7, 2) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Depth' nicht erzeugen", FileName.c_str());
+	}
+
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_POINT);
+
+	int AnzNodes = 0;
+	for (TNodeList::iterator i=NodeList->begin(); i != NodeList->end(); i++)
+	{
+		if (Debug && AnzNodes % 10000 == 0)	write_fortschritt("%d Knoten gespeichert\n", AnzNodes);
+		else if (AnzNodes % 100000 == 0)	write_fortschritt("%d Knoten gespeichert\n", AnzNodes);
+
+		TNode *Node = *i;
+
+		double X = Node->X;
+		double Y = Node->Y;
+		double Z = 0.0;
+
+		SHPObject *psShape = SHPCreateSimpleObject(SHPT_POINT, 1, &X, &Y, &Z);
+		SHPWriteObject(SHPHandle, -1, psShape);
+		SHPDestroyObject(psShape);
+
+		DBFWriteDoubleAttribute(DBFHandle, AnzNodes, 0, Node->Z);
+		DBFWriteDoubleAttribute(DBFHandle, AnzNodes, 1, Node->Wsp);
+		DBFWriteDoubleAttribute(DBFHandle, AnzNodes, 2, Node->Wsp - Node->Z);
+
+		AnzNodes++;
+	}
+	write_fortschritt("%d Knoten gespeichert\n", AnzNodes);
+
+	SHPClose(SHPHandle);
+	DBFClose(DBFHandle);
+
+	write_fortschritt("Knoten gespeichert<-\n");
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+bool SaveEdges(std::string FileName, TEdgeList *EdgeList, bool Debug)
+{
+	write_fortschritt("->Kanten speichern\n");
+
+	DBFHandle DBFHandle = DBFCreate(FileName.c_str());
+	if(DBFHandle == NULL )
+	{
+		write_error(4201, "Kann Datei '%s' nicht zum Schreiben öffnen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Nr1", FTInteger, 10, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Nr1' nicht erzeugen", FileName.c_str());
+	}
+
+	if (DBFAddField(DBFHandle, "Nr2", FTInteger, 10, 0) == -1)
+	{
+		DBFClose(DBFHandle);
+		write_error(4204, "Kann bei Datei '%s' das Attribut 'Nr2' nicht erzeugen", FileName.c_str());
+	}
+
+	SHPHandle SHPHandle = SHPCreate(FileName.c_str(), SHPT_ARC);
+
+
+	double	x[2];
+	double 	y[2];
+	double 	z[2];
+
+	z[0] = 0.0;
+	z[1] = 0.0;
+
+	int RecordCount = 0;
+	for (TEdgeListNrSorted::iterator i = EdgeList->EdgeListNrSorted.begin(); i != EdgeList->EdgeListNrSorted.end(); i++)
+	{
+		if (Debug && RecordCount % 10000 == 0)	write_fortschritt("%d Kanten gespeichert\n", RecordCount);
+		else if (RecordCount % 100000 == 0)	write_fortschritt("%d Kanten gespeichert\n", RecordCount);
+
+		TEdge* Edge = *i;
+
+		TNode* Node1 = Edge->Node1;
+		TNode* Node2 = Edge->Node2;
+
+		int Nr1 = Node1->Nr;
+		int Nr2 = Node2->Nr;
+
+		x[0] = Node1->X;
+		y[0] = Node1->Y;
+		x[1] = Node2->X;
+		y[1] = Node2->Y;
+
+		SHPObject *psShape = SHPCreateSimpleObject(SHPT_ARC, 2, x, y, z);
+		SHPWriteObject(SHPHandle, -1, psShape);
+		SHPDestroyObject(psShape);
+
+		DBFWriteIntegerAttribute(DBFHandle, RecordCount, 0, Nr1);
+		DBFWriteIntegerAttribute(DBFHandle, RecordCount, 1, Nr2);
+
+		RecordCount++;
+	}
+
+	DBFClose(DBFHandle);
+	SHPClose(SHPHandle);
+
+	write_fortschritt("->Kanten speichern\n");
+
+	return (true);
+}
+

Modified: trunk/src/file.h
===================================================================
--- trunk/src/file.h	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/file.h	2006-03-13 23:53:00 UTC (rev 37)
@@ -18,18 +18,26 @@
 #include "xy.h"
 
 //----------------------------------------------------------------------------
-bool	LoadPar(std::string FileName, std::vector<std::string> *ParList);
+bool			LoadPar(std::string FileName, std::vector<std::string> *ParList);
 
-bool 	LoadProfile(std::string FileName, TProfilList* ProfilList);
-bool 	LoadWsp(std::string FileName, TProfilList* ProfilList);
+unsigned int	LoadDGM(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
+unsigned int	LoadDGMTIN(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
+unsigned int	LoadDGMXYZ(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
+unsigned int	LoadDGMGRD(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
+unsigned int	LoadDGMSHP(std::string FileName, TNodeList *NodeList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
+unsigned int	LoadDGM2DM(std::string FileName, TNodeList *NodeList, TElementList *ElementList, TXYList *XyList, unsigned int MaxNodesPerSlice, bool Debug);
 
-bool	LoadDGM(std::string FileName, TNodeList *NodeList, TElementList *ElementList);
-bool	LoadDGMTIN(std::string FileName, TNodeList *NodeList, TElementList *ElementList);
-bool	LoadDGMXYZ(std::string FileName, TNodeList *NodeList);
-bool	LoadDGMGRD(std::string FileName, TNodeList *NodeList);
-bool	LoadDGMSHP(std::string FileName, TNodeList *NodeList);
+bool 			LoadProfile(std::string FileName, TProfilList* ProfilList);
+bool 			LoadWsp(std::string FileName, TProfilList* ProfilList);
+bool			LoadAchse(std::string FileName, TGewaesserAchseList* GewaesserAchseList);
 
-bool 	SaveNet(std::string FileName, TNodeList *NodeList, TElementList *ElementList);
+bool 			SaveNet(std::string FileName, TNodeList *NodeList, TElementList *ElementList, bool Debug);
+bool 			SaveNodes(std::string FileName, TNodeList *NodeList, bool Debug);
+bool 			SaveElements(std::string FileName, TElementList *ElementList, bool Debug);
+bool 			SaveProfile(std::string FileName, TProfilList *ProfilList, bool Debug);
+bool 			SavePolygon(std::string FileName, std::string Gewaesser, int Von, int Bis, TXYList *XyList);
+bool 			SavePolygone(std::string FileName, TErgebnisPolygonList *ErgebnisPolygonList, bool Debug);
+bool 			SaveEdges(std::string FileName, TEdgeList *EdgeList, bool Debug);
 
 //----------------------------------------------------------------------------
 #endif

Modified: trunk/src/parameter.cpp
===================================================================
--- trunk/src/parameter.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/parameter.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -19,12 +19,12 @@
 //---------------------------------------------------------------------------
 TParameter::TParameter(int argc, char **argv)
 {
-	write_fortschritt("Die Kommandozeilen-Parameter werden ausgewertet.\n");
+	write_fortschritt("->Die Kommandozeilen-Parameter werden ausgewertet\n");
 
 	IsDebug = false;
 
 	IsSetPar = false;
-	std::string	FileNamePar = "";
+	FileNamePar = "";
 
 	IsSetDelta = false;
 	IsSetVon = false;
@@ -38,22 +38,22 @@
 	Sperre = true;
 
 	IsSetDgm = false;
-	std::string	FileNameDgm = "";
+	FileNameDgm = "";
 
 	IsSetPro = false;
-	std::string	FileNamePro = "";
+	FileNamePro = "";
 
 	IsSetWsp = false;
-	std::string	FileNameWsp = "";
+	FileNameWsp = "";
 
 	IsSetLin = false;
-	std::string	FileNameLin = "";
+	FileNameLin = "";
 
 	IsSetAchse = false;
-	std::string	FileNameAchse = "";
+	FileNameAchse = "";
 
 	IsSetAusgabe = false;
-	std::string	FileNameAusgabe = "WSPLGEN.SHP";
+	FileNameAusgabe = "WSPLGEN.SHP";
 
 	if (argc == 0 || argv == 0)
 	{
@@ -103,6 +103,9 @@
 
 			FileNamePar = Parameter.substr(5);
 
+			if (FileNamePar[0] == '"') 						FileNamePar = FileNamePar.substr(1);
+			if (FileNamePar[FileNamePar.length()-1] == '"') FileNamePar = FileNamePar.substr(0, FileNamePar.length()-1);
+
 			IsSetPar = true;
 
 			if (IsDebug) write_fortschritt("Parameterdatei: '%s'\n", FileNamePar.c_str());
@@ -237,6 +240,9 @@
 
 			FileNameDgm = Parameter.substr(5);
 
+			if (FileNameDgm[0] == '"') 						FileNameDgm = FileNameDgm.substr(1);
+			if (FileNameDgm[FileNameDgm.length()-1] == '"') FileNameDgm = FileNameDgm.substr(0, FileNameDgm.length()-1);
+
 			IsSetDgm = true;
 
 			if (IsDebug) write_fortschritt("DGM-Datei: '%s'\n", FileNameDgm.c_str());
@@ -261,6 +267,9 @@
 
 			FileNamePro = Parameter.substr(5);
 
+			if (FileNamePro[0] == '"') 						FileNamePro = FileNamePro.substr(1);
+			if (FileNamePro[FileNamePro.length()-1] == '"') FileNamePro = FileNamePro.substr(0, FileNamePro.length()-1);
+
 			IsSetPro = true;
 
 			if (IsDebug) write_fortschritt("Profillagen-Datei: '%s'\n", FileNamePro.c_str());
@@ -285,6 +294,9 @@
 
 			FileNameWsp = Parameter.substr(5);
 
+			if (FileNameWsp[0] == '"') 						FileNameWsp = FileNameWsp.substr(1);
+			if (FileNameWsp[FileNameWsp.length()-1] == '"') FileNameWsp = FileNameWsp.substr(0, FileNameWsp.length()-1);
+
 			IsSetWsp = true;
 
 			if (IsDebug) write_fortschritt("WSP-Datei: '%s'\n", FileNameWsp.c_str());
@@ -309,6 +321,9 @@
 
 			FileNameLin = Parameter.substr(5);
 
+			if (FileNameLin[0] == '"') 						FileNameLin = FileNameLin.substr(1);
+			if (FileNameLin[FileNameLin.length()-1] == '"') FileNameLin = FileNameLin.substr(0, FileNameLin.length()-1);
+
 			IsSetLin = true;
 
 			if (IsDebug) write_fortschritt("Bruch- und Sperr-Datei: '%s'\n", FileNameLin.c_str());
@@ -333,6 +348,9 @@
 
 			FileNameAchse = Parameter.substr(7);
 
+			if (FileNameAchse[0] == '"') 						FileNameAchse = FileNameAchse.substr(1);
+			if (FileNameAchse[FileNameAchse.length()-1] == '"') FileNameAchse = FileNameAchse.substr(0, FileNameAchse.length()-1);
+
 			IsSetAchse = true;
 
 			if (IsDebug) write_fortschritt("Gewässerachse: '%s'\n", FileNameAchse.c_str());
@@ -357,10 +375,13 @@
 
 			FileNameAusgabe = Parameter.substr(9);
 
-			if (IsDebug) write_fortschritt("Ausage-Datei: '%s'\n", FileNameAusgabe.c_str());
+			if (FileNameAusgabe[0] == '"') 							FileNameAusgabe = FileNameAusgabe.substr(1);
+			if (FileNameAusgabe[FileNameAusgabe.length()-1] == '"') FileNameAusgabe = FileNameAusgabe.substr(0, FileNameAusgabe.length()-1);
 
 			IsSetAusgabe = true;
 
+			if (IsDebug) write_fortschritt("Ausage-Datei: '%s'\n", FileNameAusgabe.c_str());
+
 			continue;
 		}
 	}
@@ -434,6 +455,8 @@
 	{
 		write_warning(1121, "Der Parameter -DELTA oder sein Argument <Diff> wurden nicht angegeben.\nEs wird <Diff> als (<Bis> minus <Von>) geteilt durch 10 angenommen.\n");
 	}
+
+	write_fortschritt("Die Kommandozeilen-Parameter wurden ausgewertet<-\n");
 }
 
 

Modified: trunk/src/shape.cpp
===================================================================
--- trunk/src/shape.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/shape.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -105,7 +105,7 @@
     ByteCopy( &dValue, abyHeader+68, 8 );
     if( bBigEndian ) SwapWord( 8, abyHeader+68 );
 
-    dValue = psSHP->adBoundsMax[2];
+	dValue = psSHP->adBoundsMax[2];
     ByteCopy( &dValue, abyHeader+76, 8 );
     if( bBigEndian ) SwapWord( 8, abyHeader+76 );
 
@@ -305,7 +305,7 @@
     memcpy( &dValue, pabyBuf+76, 8 );
     psSHP->adBoundsMax[2] = dValue;
     
-    if( bBigEndian ) SwapWord( 8, pabyBuf+84 );		/* m */
+	if( bBigEndian ) SwapWord( 8, pabyBuf+84 );		/* m */
     memcpy( &dValue, pabyBuf+84, 8 );
     psSHP->adBoundsMin[3] = dValue;
 
@@ -360,32 +360,30 @@
 /*	Close the .shp and .shx files.					*/
 /************************************************************************/
 
-void SHPAPI_CALL
-SHPClose(SHPHandle psSHP )
-
+void SHPAPI_CALL SHPClose(SHPHandle psSHP)
 {
 /* -------------------------------------------------------------------- */
 /*	Update the header if we have modified anything.			*/
 /* -------------------------------------------------------------------- */
     if( psSHP->bUpdated )
     {
-	SHPWriteHeader( psSHP );
+		SHPWriteHeader( psSHP );
     }
 
 /* -------------------------------------------------------------------- */
 /*      Free all resources, and close files.                            */
 /* -------------------------------------------------------------------- */
-    free( psSHP->panRecOffset );
+	free( psSHP->panRecOffset );
     free( psSHP->panRecSize );
 
     fclose( psSHP->fpSHX );
-    fclose( psSHP->fpSHP );
+	fclose( psSHP->fpSHP );
 
     if( psSHP->pabyRec != NULL )
     {
         free( psSHP->pabyRec );
     }
-    
+
     free( psSHP );
 }
 
@@ -395,25 +393,38 @@
 /*      Fetch general information about the shape file.                 */
 /************************************************************************/
 
-void SHPAPI_CALL
-SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType,
-           double * padfMinBound, double * padfMaxBound )
+void SHPAPI_CALL SHPGetInfo(SHPHandle psSHP, int * pnEntities, TShpType *pnShapeType, double * padfMinBound, double * padfMaxBound)
 
 {
     int		i;
     
-    if( pnEntities != NULL )
-        *pnEntities = psSHP->nRecords;
+	if (pnEntities != NULL) *pnEntities = psSHP->nRecords;
 
-    if( pnShapeType != NULL )
-        *pnShapeType = psSHP->nShapeType;
+	if (pnShapeType != NULL)
+	{
+		switch(psSHP->nShapeType)
+		{
+			case 0: *pnShapeType = SHPT_NULL; break;
+			case 1: *pnShapeType = SHPT_POINT; break;
+			case 3: *pnShapeType = SHPT_ARC; break;
+			case 5: *pnShapeType = SHPT_POLYGON; break;
+			case 8: *pnShapeType = SHPT_MULTIPOINT; break;
+			case 11: *pnShapeType = SHPT_POINTZ; break;
+			case 13: *pnShapeType = SHPT_ARCZ; break;
+			case 15: *pnShapeType = SHPT_POLYGONZ; break;
+			case 18: *pnShapeType = SHPT_MULTIPOINTZ; break;
+			case 21: *pnShapeType = SHPT_POINTM; break;
+			case 23: *pnShapeType = SHPT_ARCM; break;
+			case 28: *pnShapeType = SHPT_POLYGONM; break;
+			case 31: *pnShapeType = SHPT_MULTIPATCH; break;
+			default: *pnShapeType = SHPT_NULL;
+		}
+	}
 
-    for( i = 0; i < 4; i++ )
-    {
-        if( padfMinBound != NULL )
-            padfMinBound[i] = psSHP->adBoundsMin[i];
-        if( padfMaxBound != NULL )
-            padfMaxBound[i] = psSHP->adBoundsMax[i];
+	for (i = 0; i < 4; i++)
+	{
+		if( padfMinBound != NULL ) padfMinBound[i] = psSHP->adBoundsMin[i];
+		if( padfMaxBound != NULL ) padfMaxBound[i] = psSHP->adBoundsMax[i];
     }
 }
 
@@ -1425,26 +1436,17 @@
 /*                          SHPDestroyObject()                          */
 /************************************************************************/
 
-void SHPAPI_CALL
-SHPDestroyObject( SHPObject * psShape )
-
+void SHPAPI_CALL SHPDestroyObject( SHPObject * psShape )
 {
-    if( psShape == NULL )
-        return;
+	if( psShape == NULL ) return;
     
-    if( psShape->padfX != NULL )
-        free( psShape->padfX );
-    if( psShape->padfY != NULL )
-        free( psShape->padfY );
-    if( psShape->padfZ != NULL )
-        free( psShape->padfZ );
-    if( psShape->padfM != NULL )
-        free( psShape->padfM );
+	if( psShape->padfX != NULL )		free( psShape->padfX );
+	if( psShape->padfY != NULL )        free( psShape->padfY );
+	if( psShape->padfZ != NULL )        free( psShape->padfZ );
+	if( psShape->padfM != NULL )        free( psShape->padfM );
 
-    if( psShape->panPartStart != NULL )
-        free( psShape->panPartStart );
-    if( psShape->panPartType != NULL )
-        free( psShape->panPartType );
+	if( psShape->panPartStart != NULL )        free( psShape->panPartStart );
+	if( psShape->panPartType != NULL )         free( psShape->panPartType );
 
     free( psShape );
 }

Modified: trunk/src/shape.h
===================================================================
--- trunk/src/shape.h	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/shape.h	2006-03-13 23:53:00 UTC (rev 37)
@@ -1,6 +1,7 @@
 #ifndef _SHAPEFILE_H_INCLUDED
 #define _SHAPEFILE_H_INCLUDED
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
@@ -79,11 +80,11 @@
 /************************************************************************/
 typedef	struct
 {
-    FILE        *fpSHP;
-    FILE	*fpSHX;
+	FILE    *fpSHP;
+	FILE	*fpSHX;
 
-    int		nShapeType;				/* SHPT_* */
-    
+	int		nShapeType;				/* SHPT_* */
+
     int		nFileSize;				/* SHP file */
 
     int         nRecords;
@@ -173,31 +174,17 @@
 /* -------------------------------------------------------------------- */
 /*      SHP API Prototypes                                              */
 /* -------------------------------------------------------------------- */
-SHPHandle SHPAPI_CALL
-      SHPOpen( const char * pszShapeFile, const char * pszAccess );
-SHPHandle SHPAPI_CALL
-      SHPCreate( const char * pszShapeFile, int nShapeType );
-void SHPAPI_CALL
-      SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
-                  double * padfMinBound, double * padfMaxBound );
+SHPHandle SHPAPI_CALL 		SHPOpen( const char * pszShapeFile, const char * pszAccess );
+SHPHandle SHPAPI_CALL 		SHPCreate( const char * pszShapeFile, int nShapeType );
+void SHPAPI_CALL 			SHPGetInfo( SHPHandle hSHP, int * pnEntities, TShpType *pnShapeType, double * padfMinBound, double * padfMaxBound );
 
-SHPObject SHPAPI_CALL1(*)
-      SHPReadObject( SHPHandle hSHP, int iShape );
-int SHPAPI_CALL
-      SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
+SHPObject SHPAPI_CALL1(*)	SHPReadObject( SHPHandle hSHP, int iShape );
+int SHPAPI_CALL             SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
 
-void SHPAPI_CALL
-      SHPDestroyObject( SHPObject * psObject );
-void SHPAPI_CALL
-      SHPComputeExtents( SHPObject * psObject );
-SHPObject SHPAPI_CALL1(*)
-      SHPCreateObject( int nSHPType, int nShapeId,
-                       int nParts, int * panPartStart, int * panPartType,
-                       int nVertices, double * padfX, double * padfY,
-                       double * padfZ, double * padfM );
-SHPObject SHPAPI_CALL1(*)
-      SHPCreateSimpleObject( int nSHPType, int nVertices,
-                             double * padfX, double * padfY, double * padfZ );
+void SHPAPI_CALL            SHPDestroyObject( SHPObject * psObject );
+void SHPAPI_CALL            SHPComputeExtents( SHPObject * psObject );
+SHPObject SHPAPI_CALL1(*)   SHPCreateObject( int nSHPType, int nShapeId, int nParts, int * panPartStart, int * panPartType, int nVertices, double * padfX, double * padfY, double * padfZ, double * padfM );
+SHPObject SHPAPI_CALL1(*)   SHPCreateSimpleObject( int nSHPType, int nVertices, double * padfX, double * padfY, double * padfZ );
 
 int SHPAPI_CALL
       SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );

Modified: trunk/src/test_file.cpp
===================================================================
--- trunk/src/test_file.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/test_file.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,7 +10,9 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------------
 #include <stdio.h>
@@ -27,6 +29,8 @@
 #define DGMXYZFILE3		"test_daten\\dgm_ziemlich_gross.xyz"
 #define DGMXYZFILE4		"test_daten\\dgm_sehr_gross.xyz"
 #define NETFILE			"test_daten\\net.2dm"
+#define PROFILFILE		"test_daten\\profile.shp"
+#define PROFILZFILE		"test_daten\\profilez.shp"
 #else
 #define DGMTINFILE		"test_daten/dgmtin/tnxy.adf"
 #define DGMXYZFILE		"test_daten/dgm.xyz"
@@ -34,6 +38,8 @@
 #define DGMXYZFILE3		"test_daten/dgm_ziemlich_gross.xyz"
 #define DGMXYZFILE4		"test_daten/dgm_sehr_gross.xyz"
 #define NETFILE			"test_daten/net.2dm"
+#define PROFILFILE		"test_daten/profile.shp"
+#define PROFILZFILE		"test_daten/profilez.shp"
 #endif
 
 //---------------------------------------------------------------------
@@ -52,36 +58,11 @@
 	printf ("\nTest DGM-TIN laden\n");
 
 
-	TNodeList *NodeList = 0;
-	TElementList *ElementList = 0;
+	TNodeList *NodeList = new TNodeList();
+	TElementList *ElementList = new TElementList();
 
-	try
-	{
-		LoadDGM(DGMTINFILE, NodeList, ElementList);
-	}
-	catch(TFehler)
-	{
-		printf ("Fehler korrekt gefangen\n");
-	}
+	LoadDGM(DGMTINFILE, NodeList, ElementList, 0, 100000, true);
 
-	NodeList = new TNodeList();
-
-	try
-	{
- 		LoadDGM(DGMTINFILE, NodeList, ElementList);
-	}
-	catch(TFehler)
-	{
-		printf ("Fehler korrekt gefangen\n");
-	}
-
-	ElementList = new TElementList();
-
-	////////////////////////////////////////
-	////////////////////////////////////////
-
-	LoadDGM(DGMTINFILE, NodeList, ElementList);
-
 	printf("Anzahl Knoten: %d\n", NodeList->size());
 	for (unsigned int i=0; i<NodeList->size(); i++)
 	{
@@ -111,7 +92,7 @@
 	////////////////////////////////////////
 	////////////////////////////////////////
 
-	LoadDGM(DGMXYZFILE, NodeList, ElementList);
+	LoadDGM(DGMXYZFILE, NodeList, ElementList, 0, 100000, true);
 
 	printf("Anzahl Knoten: %d\n", NodeList->size());
 	for (unsigned int i=0; i<NodeList->size(); i++)
@@ -141,7 +122,7 @@
 	NodeList->Clear();
 	ElementList->Clear();
 
-	LoadDGM(DGMXYZFILE2, NodeList, ElementList);
+	LoadDGM(DGMXYZFILE2, NodeList, ElementList, 0, 100000, true);
 
 	printf("Anzahl Knoten: %d\n", NodeList->size());
 	printf("Anzahl Elemente in Elementliste: %d\n", ElementList->size());
@@ -160,10 +141,58 @@
 	////////////////////////////////////////
 	////////////////////////////////////////
 
-	SaveNet(NETFILE, NodeList, ElementList);
+	SaveNet(NETFILE, NodeList, ElementList, true);
 
 	delete ElementList;
 	delete NodeList;
 
+	////////////////////////////////////////
+	// Test von Profilspuren laden
+	////////////////////////////////////////
+
+	printf ("\nTest Profilspuren laden\n");
+
+	TProfilList *ProfilList = new TProfilList();
+
+	LoadProfile(PROFILFILE, ProfilList);
+
+	int Anz = 0;
+	for (TProfilList::iterator i = ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		TProfil *Profil = *i;
+
+		int z = 0;
+		for (TPointList::iterator i = Profil->PointList->begin(); i != Profil->PointList->end(); i++)
+		{
+			TPoint *Point = *i;
+
+			printf("Profil %d hat Station %d und Punkt %d: X %.3f Y %.3f Z %.3f\n", Anz, Profil->Station, z, Point->X, Point->Y, Point->Z);
+			z++;
+		}
+		Anz++;
+	}
+
+	ProfilList->clear();
+
+	LoadProfile(PROFILZFILE, ProfilList);
+
+	Anz = 0;
+	for (TProfilList::iterator i = ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		TProfil *Profil = *i;
+
+		int z = 0;
+		for (TPointList::iterator i = Profil->PointList->begin(); i != Profil->PointList->end(); i++)
+		{
+			TPoint *Point = *i;
+
+			printf("Profil %d hat Station %d und Punkt %d: X %.3f Y %.3f Z %.3f\n", Anz, Profil->Station, z, Point->X, Point->Y, Point->Z);
+			z++;
+		}
+		Anz++;
+	}
+
+	ProfilList->clear();
+
 	return (0);
 }

Modified: trunk/src/test_profil.cpp
===================================================================
--- trunk/src/test_profil.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/test_profil.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,6 +10,10 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
 //---------------------------------------------------------------------------
 #include <stdio.h>
 #include <stdexcept>
@@ -24,18 +28,18 @@
 
 	printf ("\nTest Punktverwaltung\n");
 
-	TProfil *Profil1 = new TProfil("Weser", 250.200);
-	TProfil *Profil2 = new TProfil("Weser", 250.700);
+	TProfil *Profil1 = new TProfil("Weser", 2502000);
+	TProfil *Profil2 = new TProfil("Weser", 2507000);
 
 	if (Profil1 == 0)	return (TestNr);
 	if (Profil2 == 0)	return (TestNr);
 
 	Profil1->AddPoint(1.0, 2.0);
-	Profil1->AddPoint(3.0, 2.0);
-	Profil1->AddPoint(6.0, 6.0);
+	Profil1->AddPoint(3.0, 2.0, 1.0);
+	Profil1->AddPoint(6.0, 6.0, 2.0);
 
 	Profil2->AddPoint(8.0,   9.0);
-	Profil2->AddPoint(10.0, 13.0);
+	Profil2->AddPoint(10.0, 13.0, 3.0);
 	Profil2->AddPoint(12.0, 19.0);
 
 	TProfil *Profil3 = new TProfil(Profil1);
@@ -43,7 +47,7 @@
 	if (Profil3 == 0)	return (TestNr);
 
 	// Sonst wird es nicht in die ProfilListe aufgenommen (doppelte Station verboten)
-	Profil3->Station = 123.4;
+	Profil3->Station = 1234000;
 
 	double X1 = 0.0;
 	double Y1 = 0.0;
@@ -66,17 +70,17 @@
 	printf("Meter 2.0 -> X = %.3f Y = %.3f\n", X3, Y3);
 	printf("Meter 4.5 -> X = %.3f Y = %.3f\n", X4, Y4);
 
-	TProfil *Profil4 = new TProfil("Weser", 105.0);
+	TProfil *Profil4 = new TProfil("Weser", 1050000);
 
 	if (Profil4 == 0)	return (TestNr);
 
 	Profil4->AddPoint(4.0, 2.0);
 	Profil4->AddPoint(5.0, 3.0);
-	Profil4->AddPoint(6.0, 4.0);
+	Profil4->AddPoint(6.0, 4.0, 5.0);
 	Profil4->AddPoint(7.0, 5.0);
 	Profil4->AddPoint(8.0, 6.0);
 
-	TProfil *Profil5 = new TProfil("Weser", 101.5);
+	TProfil *Profil5 = new TProfil("Weser", 1015000);
 
 	if (Profil5 == 0)	return (TestNr);
 
@@ -86,7 +90,7 @@
 	Profil5->AddPoint(17.0, 25.0);
 	Profil5->AddPoint(18.0, 26.0);
 
-	TProfil *Profil6 = new TProfil("Aller", 99.4);
+	TProfil *Profil6 = new TProfil("Aller", 994000);
 
 	if (Profil6 == 0)	return (TestNr);
 
@@ -111,7 +115,7 @@
 	int Anz1 = 0;
 	for (TProfilList::iterator i = ProfilList.begin(); i != ProfilList.end(); i++)
 	{
-		printf("Profil %d hat Station %f\n", Anz1, (*i)->Station);
+		printf("Profil %d hat Station %d\n", Anz1, (*i)->Station);
 		Anz1++;
 	}
 
@@ -125,17 +129,31 @@
 	{
 		TProfil *Profil = new TProfil("Weser", (i * 79) % 113);
 
-		Profil->AddPoint(i, i+0);
-		Profil->AddPoint(i, i+1);
-		Profil->AddPoint(i, i+2);
-		Profil->AddPoint(i, i+3);
-		Profil->AddPoint(i, i+4);
+		Profil->AddPoint(i, i+0, 11000);
+		Profil->AddPoint(i, i+1, 22000);
+		Profil->AddPoint(i, i+2, 33000);
+		Profil->AddPoint(i, i+3, 44000);
+		Profil->AddPoint(i, i+4, 55000);
 
 		ProfilList.insert(Profil);
 
 //		delete Profil;
 	}
 
+	TProfil *Profil10 = new TProfil("Aller", 100000);
+
+	Profil10->AddPoint(101, 101, 101);
+	Profil10->AddPoint(102, 102, 102);
+
+	ProfilList.insert(Profil10);
+
+	TProfil *Profil11 = new TProfil("Aller", 110000);
+
+	Profil11->AddPoint(111, 111, 111);
+	Profil11->AddPoint(112, 112, 112);
+
+	ProfilList.insert(Profil11);
+
 	printf("Anzahl der Profile %d\n", ProfilList.size());
 
 	int Anz3 = 0;
@@ -148,7 +166,7 @@
 		{
 			TPoint *Point = *j;
 
-			printf("Profil %d hat Station %f und Rechts: %.3f (%d) Hoch: %.3f (%d)\n", Anz3, Profil->Station, Point->X, (int)(Point->X * 79) % 113, Point->Y, (int)((Point->Y - z) * 79) % 113);
+			printf("Profil %d hat Station %d und X: %.3f (%d) Y: %.3f (%d) Z: %.3f\n", Anz3, Profil->Station, Point->X, (int)(Point->X * 79) % 113, Point->Y, (int)((Point->Y - z) * 79) % 113, Point->Z);
 			z++;
 		}
 		Anz3++;
@@ -157,7 +175,7 @@
 	TProfilList ProfilList2 = ProfilList;
 
 	ProfilList.clear();
-	
+
 	int Anz4 = 0;
 	for (TProfilList::iterator i = ProfilList2.begin(); i != ProfilList2.end(); i++)
 	{
@@ -168,26 +186,30 @@
 		{
 			TPoint *Point = *i;
 
-			printf("Profil %d hat Station %f und Rechts: %.3f (%d) Hoch: %.3f (%d)\n", Anz4, Profil->Station, Point->X, (int)(Point->X * 79) % 113, Point->Y, (int)((Point->Y - z) * 79) % 113);
+			printf("Profil %d hat Station %d und Rechts: %.3f (%d) Hoch: %.3f (%d)\n", Anz4, Profil->Station, Point->X, (int)(Point->X * 79) % 113, Point->Y, (int)((Point->Y - z) * 79) % 113);
 			z++;
 		}
 		Anz4++;
 	}
 
-	for (double Station = 0.0; Station < 114.0; Station++)
+	for (int Station = 00000; Station < 1140000; Station++)
 	{
-		TProfil* Profil = ProfilList2.FindStation(Station);
+		TProfil* Profil = ProfilList2.Find("Weser", Station);
 
-		if (0 == Profil)
-		{
-			printf("%.3f wurde nicht gefunden\n", Station);
-		}
-		else
-		{
-			printf("%.3f wurde gefunden\n", Station);
-		}
+		if (0 == Profil)	printf("'%s' %d wurde nicht gefunden\n", "Weser", Station);
+		else				printf("'%s' %d wurde gefunden\n", Profil->Gewaesser.c_str(), Profil->Station);
 	}
 
+	TProfil* SProfil11 = ProfilList2.Find("Aller", 110000);
+
+	if (0 == SProfil11)	printf("'%s' %d wurde nicht gefunden\n", SProfil11->Gewaesser.c_str(), SProfil11->Station);
+	else				printf("'%s' %d wurde gefunden\n", SProfil11->Gewaesser.c_str(), SProfil11->Station);
+
+	TProfil* SProfil12 = ProfilList2.Find("Aller", 120000);
+
+	if (0 == SProfil12)	printf("'%s' %d wurde nicht gefunden\n", "Aller", 120000);
+	else				printf("'%s' %d wurde gefunden\n", SProfil12->Gewaesser.c_str(), SProfil12->Station);
+
 	return (0);
 }
 

Modified: trunk/src/test_tools.cpp
===================================================================
--- trunk/src/test_tools.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/test_tools.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,7 +10,9 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------------
 #include <stdio.h>
@@ -410,29 +412,29 @@
 	Y = 1.0;
 
 	alpha = IsInside(XyList, X, Y);
-	if (alpha == 0)		printf ("1,1 ist nicht im Polygon.\n");
+	if (alpha == 0)			printf ("1,1 ist nicht im Polygon.\n");
 	else if (alpha == -4)	printf ("1,1 ist im Polygon (Polygon ist mit dem Uhrzeigersinn)\n");
 	else if (alpha == 4)	printf ("1,1 ist im Polygon (Polygon ist gegen den Uhrzeigersinn)\n");
 	else if (alpha == -1)	printf ("1,1 ist auf dem Rand von Polygon\n");
-	else 				dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
+	else 					dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
 
 	X = 3.0;
 	Y = 3.0;
 	alpha = IsInside(XyList, X, Y);
-	if (alpha == 0)		printf ("3,3 ist nicht im Polygon.\n");
+	if (alpha == 0)			printf ("3,3 ist nicht im Polygon.\n");
 	else if (alpha == -4)	printf ("3,3 ist im Polygon (Polygon ist mit dem Uhrzeigersinn)\n");
 	else if (alpha == 4)	printf ("3,3 ist im Polygon (Polygon ist gegen den Uhrzeigersinn)\n");
 	else if (alpha == -1)	printf ("3,3 ist auf dem Rand von Polygon\n");
-	else 				dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
+	else 					dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
 
 	X = 2.0;
 	Y = 2.0;
 	alpha = IsInside(XyList, X, Y);
-	if (alpha == 0)		printf ("2,2 ist nicht im Polygon.\n");
+	if (alpha == 0)			printf ("2,2 ist nicht im Polygon.\n");
 	else if (alpha == -4)	printf ("2,2 ist im Polygon (Polygon ist mit dem Uhrzeigersinn)\n");
 	else if (alpha == 4)	printf ("2,2 ist im Polygon (Polygon ist gegen den Uhrzeigersinn)\n");
 	else if (alpha == -1)	printf ("2,2 ist auf dem Rand von Polygon\n");
-	else 				dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
+	else 					dump_error(__FILE__, __LINE__, "Unbekannter Wert für Alpha");
 
     delete XyList;
 

Modified: trunk/src/test_tri.cpp
===================================================================
--- trunk/src/test_tri.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/test_tri.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -44,7 +44,7 @@
 
 	TElementList *EL = new TElementList();
 
-	Triangulate(NL, EL);
+	Triangulate(NL, EL, true);
 
 	printf("Anzahl Elemente in Elementliste: %d\n", EL->size());
 	for (unsigned int j=0; j<EL->size(); j++)
@@ -83,7 +83,7 @@
 
 	EL->Clear();
 
-	Triangulate(NL, EL);
+	Triangulate(NL, EL, true);
 
 	printf("Anzahl Elemente in Elementliste: %d\n", EL->size());
 	for (unsigned int j=0; j<EL->size(); j++)
@@ -100,7 +100,7 @@
 		printf("\n");
 	}
 
-   	SaveNet("test_tri.2dm", NL, EL);
+   	SaveNet("test_tri.2dm", NL, EL, true);
 
 
 	delete EL;

Modified: trunk/src/test_xy.cpp
===================================================================
--- trunk/src/test_xy.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/test_xy.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,7 +10,9 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------------
 #include <stdio.h>
@@ -55,10 +57,10 @@
 	if (P24 == 0)	return (TestNr);
 	if (P25 == 0)	return (TestNr);
 
-	// Jetzt zwei leer PolyliniePolygone generieren
+	// Jetzt zwei leere PolyliniePolygone generieren
 	TXYList *PL1 = new TXYList();
 	TXYList *PL2 = new TXYList();
-	
+
 	if (PL1 == 0)	return (TestNr);
 	if (PL2 == 0)	return (TestNr);
 
@@ -84,23 +86,54 @@
 
 	if (PL3 == 0)	return (TestNr);
 
+	printf("Anzahl Punktepaare im Polygon: %d\n", PL3->size());
+
+	for (unsigned int j=0; j<PL3->size(); j++)
+	{
+		TXY *XY = (*PL3)[j];
+
+		printf("Koordinaten von Punkt %d: %.3f,%.3f\n", j, XY->X, XY->Y);
+	}
+
+	// Jetzt zwei leere PolyliniePolygone generieren
+	TErgebnisPolygon *EP1 = new TErgebnisPolygon(0.0);
+	TErgebnisPolygon *EP2 = new TErgebnisPolygon(0.0);
+
+	if (EP1 == 0)	return (TestNr);
+	if (EP2 == 0)	return (TestNr);
+
+	// Ein paar Punkte zur ersten Polylinie zuweisen
+	EP1->push_back(P11);
+	EP1->push_back(P12);
+	EP1->push_back(P13);
+	EP1->push_back(P14);
+	EP1->push_back(P15);
+	EP1->push_back(P16);
+	EP1->push_back(P17);
+
+	// Ein paar Punkte zur zweiten Polylinie zuweisen
+	EP2->push_back(P21);
+	EP2->push_back(P22);
+	EP2->push_back(P23);
+	EP2->push_back(P24);
+	EP2->push_back(P25);
+
 	// Eine leere Liste von Polylinien generieren
-	TPolygonList *PGL1 = new TPolygonList();
-	
-	if (PGL1 == 0)	return (TestNr);
+	TErgebnisPolygonList *EPL1 = new TErgebnisPolygonList();
 
+	if (EPL1 == 0)	return (TestNr);
+
 	// Die Polylinien zuweisen
-	PGL1->push_back(PL1);
-	PGL1->push_back(PL2);
-	PGL1->push_back(PL3);
+	EPL1->push_back(EP1);
+	EPL1->push_back(EP2);
 
-	printf("\nEine PolygonListe wurde erzeugt\n\n");
+	printf("\nEine Ergebnispolygon-Liste wurde erzeugt\n\n");
 
 	// Alles ausgeben
-	printf("Anzahl Polygone in PolygonList 1: %d\n", PGL1->size());
-	for (unsigned int i=0; i<PGL1->size(); i++)
+	printf("Anzahl Polygone in PolygonList 1: %d\n", EPL1->size());
+	for (unsigned int i=0; i<EPL1->size(); i++)
 	{
-		TXYList *PL = (*PGL1)[i];
+		TXYList *PL = (*EPL1)[i];
 
 		printf("Anzahl Punktepaare in Polygon %d: %d\n", i, PL->size());
 
@@ -114,15 +147,15 @@
 
 	// Alle Polylinien verdoppeln
 	// Dabei werden alle Polylinien und Punkte in der Liste mit verdoppelt
-	TPolygonList *PGL2 = PGL1->Copy();
+	TErgebnisPolygonList *EPL2 = EPL1->Copy();
 
 	printf("\nDie PolygonListe wurde verdoppelt\n\n");
 
 	// Wieder alle ausgeben
-	printf("Anzahl Polygone in PolygonList 2: %d\n", PGL2->size());
-	for (unsigned int i=0; i<PGL2->size(); i++)
+	printf("Anzahl Polygone in PolygonList 2: %d\n", EPL2->size());
+	for (unsigned int i=0; i<EPL2->size(); i++)
 	{
-		TXYList *PL = (*PGL2)[i];
+		TXYList *PL = (*EPL2)[i];
 
 		printf("Anzahl Punktepaare in Polygon %d: %d\n", i, PL->size());
 
@@ -135,7 +168,7 @@
 	}
 
 	// Die erste Polylinie der zweiten Liste ermitteln
-	TXYList *PL = PGL2->First();
+	TErgebnisPolygon *PL = EPL2->First();
 
 	printf("\nDie erste Polylinie der 2. PolygonListe wurde ermittelt\n\n");
 
@@ -188,16 +221,16 @@
 
 
 	// Die erste Liste von Polylinien komplett löschen
-	delete PGL1;
-	PGL1 = 0;
+	delete EPL1;
+	EPL1 = 0;
 
 	printf("\nNach dem 'Löschen' von PolygonList 1\n\n");
 
 	// Wieder alle ausgeben
-	printf("Anzahl Polygone in PolygonList 2: %d\n", PGL2->size());
-	for (unsigned int i=0; i<PGL2->size(); i++)
+	printf("Anzahl Polygone in PolygonList 2: %d\n", EPL2->size());
+	for (unsigned int i=0; i<EPL2->size(); i++)
 	{
-		TXYList *PL = (*PGL2)[i];
+		TXYList *PL = (*EPL2)[i];
 
 		printf("Anzahl Punktepaare in Polygon %d: %d\n", i, PL->size());
 
@@ -211,15 +244,15 @@
 
 	// Die zweite Liste leeren, die Liste selbst bleibt bestehen
 	// Dabei werden auch alle Elemente in der Liste freigegeben (Polylinien und Punkte)
-	PGL2->Clear();
+	EPL2->Clear();
 
 	printf("\nNach dem 'Clearen' von PolygonList 2\n\n");
 
 	// Wieder alle ausgeben
-	printf("Anzahl Polygone in PolygonList 2: %d\n", PGL2->size());
-	for (unsigned int i=0; i<PGL2->size(); i++)
+	printf("Anzahl Polygone in PolygonList 2: %d\n", EPL2->size());
+	for (unsigned int i=0; i<EPL2->size(); i++)
 	{
-		TXYList *PL = (*PGL2)[i];
+		TXYList *PL = (*EPL2)[i];
 
 		printf("Anzahl Punktepaare in Polygon %d: %d\n", i, PL->size());
 
@@ -233,8 +266,8 @@
 
 	// Die zweite Liste von Polylinien komplett löschen
 	// Dabei werden auch alle Elemente in der Liste freigegeben (Polylinien und Punkte)
-	delete PGL2;
-	PGL2 = 0;
+	delete EPL2;
+	EPL2 = 0;
 
 
 	/////////////////////////////////////////////
@@ -666,7 +699,7 @@
 	double Y = 3.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);
@@ -683,7 +716,7 @@
 	Y = 6.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);
@@ -700,7 +733,7 @@
 	Y = 6.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);
@@ -716,7 +749,7 @@
 	Y = 1.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);
@@ -732,7 +765,7 @@
 	Y = 9.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);
@@ -753,7 +786,7 @@
 	Y = 3.0;
 	try
 	{
-		TInsideTyp IsInside = Element->IsInElement(X, Y);
+		TInsideTyp IsInside = Element->IsInsideElement(X, Y);
 
 		if (INSIDE == IsInside)				printf("(%.3f, %.3f) ist im Element\n", X, Y);
 		else if (ON_LINE == IsInside)		printf("(%.3f, %.3f) ist auf dem Rand des Elementes\n", X, Y);

Modified: trunk/src/tools.cpp
===================================================================
--- trunk/src/tools.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/tools.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,14 +10,14 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------------
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#include <string>
-#include <math.h>
 #include <sys/timeb.h>
 
 #include "tools.h"
@@ -210,6 +210,12 @@
 	return (Kombi);
 }
 //---------------------------------------------------------------------------
+void* SfRealloc(void *pMem, int nNewSize)
+{
+	if( pMem == NULL )  return(malloc(nNewSize));
+	else                return(realloc(pMem, nNewSize));
+}
+//---------------------------------------------------------------------------
 void    Swap2Bytes(byte *Bytes)
 {
 	byte    Temp;
@@ -305,116 +311,1390 @@
 //---------------------------------------------------------------------------
 double CrossProduct(TNode *n1, TNode *n2, TNode *n3)
 {
-	double Dx1 =  n2->X - n1->X;
-	double Dy1 =  n2->Y - n1->Y;
-	double Dx2 =  n3->X - n1->X;
-	double Dy2 =  n3->Y - n1->Y;
-
-	return (Dx1 * Dy2 - Dy1 * Dx2);
-}
+	double Dx1 =  n2->X - n1->X;
+	double Dy1 =  n2->Y - n1->Y;
+	double Dx2 =  n3->X - n1->X;
+	double Dy2 =  n3->Y - n1->Y;
 
+	return (Dx1 * Dy2 - Dy1 * Dx2);
+}
+
 //---------------------------------------------------------------------------
 bool CircumCircle(TNode *n1, TNode *n2, TNode *n3, double *cx, double *cy, double *cr)
 {
-	double cp = CrossProduct(n1, n2, n3);
-
-	if (cp != 0.0)
-	{
-		double n1Sq = n1->X * n1->X + n1->Y * n1->Y;
-		double n2Sq = n2->X * n2->X + n2->Y * n2->Y;
-		double n3Sq = n3->X * n3->X + n3->Y * n3->Y;
-		double numx = n1Sq * (n2->Y - n3->Y) + n2Sq * (n3->Y - n1->Y) + n3Sq * (n1->Y - n2->Y);
-		double x = numx / (2.0 * cp);
-		double numy = n1Sq * (n3->X - n2->X) + n2Sq * (n1->X - n3->X) + n3Sq * (n2->X - n1->X);
-		double y = numy / (2.0 * cp);
-
-		double dx = n1->X - x;
-		double dy = n1->Y - y;
-
-		*cx = x;
-		*cy = y;
-		*cr = dx * dx + dy * dy;
-
-		return(true);
-	}
-
-	// Alle drei Knoten liegen auf einer Linie
-	return(false);
-}
+	double cp = CrossProduct(n1, n2, n3);
 
-//---------------------------------------------------------------------------
-size_t CheckMemory(bool IsDebug)
-{
-	write_fortschritt("->Ermitteln der Speicherauslastung\n");
-
-	size_t MaxMemSize = 2 * 1024 * 1024 * 1024;
-
-	while (MaxMemSize > 0)
-	{
-		void* Mem = malloc(MaxMemSize);
-
-		if (Mem)
-		{
-			free(Mem);
-			write_fortschritt("%d MB stehen zur Verfügung\n", MaxMemSize / 1024 / 1024);
-			break;
-		}
-		else
-		{
-			if (IsDebug)
-			{
-				write_fortschritt("%d MB stehen NICHT zur Verfügung\n", MaxMemSize / 1024 / 1024);
-			}
-		}
-		MaxMemSize = MaxMemSize - (1024 * 1024);
-	}
-
-	write_fortschritt("Ermitteln der Speicherauslastung beendet<-\n");
-
-	return (MaxMemSize);
-}
-
-//---------------------------------------------------------------------------
-long CheckSpeed(bool IsDebug)
-{
-	write_fortschritt("->Ermitteln der Geschwindigkeit\n");
-
-	struct timeb Now;
-	ftime (&Now);
-
-	long StartMSec = Now.time * 1000 + Now.millitm;
-
-	long DiffMSec = 0L;
-
-	long Flops = 0;
-
-	double Dummy = 0.0;
-
-	do
-	{
-		if (IsDebug)
-		{
-			if (Flops % 100 == 0)	write_fortschritt("%d Flops berechnet\n", Flops);
-		}
-
-		Dummy = Flops * 123.355 / 0.023;
-
-		Flops = Flops + 3;
-
-		struct timeb Now;
-		ftime (&Now);
-
-		int NowMSec = Now.time * 1000 + Now.millitm;
-
-		DiffMSec = NowMSec - StartMSec;
-
-	} while (DiffMSec < 2000);
-
-	write_fortschritt("%.3f MFlops berechnet\n", Flops / 1000.0 / 1000.0);
-
-	if (DiffMSec > 10000) write_fortschritt("%d Dummy\n", Dummy);
-
-	write_fortschritt("Ermitteln der Speicherauslastung beendet<-\n");
-
-	return (Flops);
-}
+	if (cp != 0.0)
+	{
+		double n1Sq = n1->X * n1->X + n1->Y * n1->Y;
+		double n2Sq = n2->X * n2->X + n2->Y * n2->Y;
+		double n3Sq = n3->X * n3->X + n3->Y * n3->Y;
+		double numx = n1Sq * (n2->Y - n3->Y) + n2Sq * (n3->Y - n1->Y) + n3Sq * (n1->Y - n2->Y);
+		double x = numx / (2.0 * cp);
+		double numy = n1Sq * (n3->X - n2->X) + n2Sq * (n1->X - n3->X) + n3Sq * (n2->X - n1->X);
+		double y = numy / (2.0 * cp);
+
+		double dx = n1->X - x;
+		double dy = n1->Y - y;
+
+		*cx = x;
+		*cy = y;
+		*cr = dx * dx + dy * dy;
+
+		return(true);
+	}
+
+	// Alle drei Knoten liegen auf einer Linie
+	return(false);
+}
+
+//---------------------------------------------------------------------------
+size_t CheckMemory(bool IsDebug)
+{
+	write_fortschritt("->Ermitteln der Speicherauslastung\n");
+
+//	size_t MaxMemSize = 2UL * 1024UL * 1024UL * 1024UL;
+	size_t MaxMemSize = 200000000;
+
+	while (MaxMemSize > 0)
+	{
+		void* Mem = malloc(MaxMemSize);
+
+		if (Mem)
+		{
+			free(Mem);
+			break;
+		}
+		else
+		{
+			if (IsDebug)
+			{
+				write_fortschritt("%d MB stehen NICHT zur Verfügung\n", MaxMemSize / 1024 / 1024);
+			}
+		}
+		MaxMemSize = MaxMemSize - (10 * 1024 * 1024);
+	}
+
+	write_fortschritt("%d MB stehen zur Verfügung\n", MaxMemSize / 1024 / 1024);
+
+	write_fortschritt("Ermitteln der Speicherauslastung beendet<-\n");
+
+	return (MaxMemSize);
+}
+
+//---------------------------------------------------------------------------
+long CheckSpeed(bool IsDebug)
+{
+	write_fortschritt("->Ermitteln der Geschwindigkeit\n");
+
+	struct timeb Now;
+	ftime (&Now);
+
+	long StartMSec = Now.time * 1000 + Now.millitm;
+
+	long DiffMSec = 0L;
+
+	long Flops = 0;
+
+	double Dummy = 0.0;
+
+	do
+	{
+		if (IsDebug)
+		{
+			if (Flops % 100000 == 0)	write_fortschritt("%d Flops berechnet\n", Flops);
+		}
+
+		Dummy = Flops * 123.355 / 0.023;
+
+		Flops = Flops + 1;
+
+		struct timeb Now;
+		ftime (&Now);
+
+		int NowMSec = Now.time * 1000 + Now.millitm;
+
+		DiffMSec = NowMSec - StartMSec;
+
+	} while (DiffMSec < 2000);
+
+	write_fortschritt("%.3f MFlops berechnet\n", Flops / 1000.0 / 1000.0);
+
+	if (DiffMSec > 10000) write_fortschritt("%d Dummy\n", Dummy);
+
+	write_fortschritt("Ermitteln der Geschwindigkeit beendet<-\n");
+
+	return (Flops);
+}
+
+//---------------------------------------------------------------------------
+const char *ShapeTypeName(TShpType ShapeType)
+{
+	switch(ShapeType)
+	{
+		case SHPT_NULL:         return "NullShape";
+		case SHPT_POINT:        return "Point";
+		case SHPT_ARC:          return "Arc";
+		case SHPT_POLYGON:      return "Polygon";
+		case SHPT_MULTIPOINT:   return "MultiPoint";
+		case SHPT_POINTZ:       return "PointZ";
+		case SHPT_ARCZ:         return "ArcZ";
+		case SHPT_POLYGONZ:     return "PolygonZ";
+		case SHPT_MULTIPOINTZ:  return "MultiPointZ";
+		case SHPT_POINTM:       return "PointM";
+		case SHPT_ARCM:         return "ArcM";
+		case SHPT_POLYGONM:     return "PolygonM";
+		case SHPT_MULTIPOINTM:  return "MultiPointM";
+		case SHPT_MULTIPATCH:   return "MultiPatch";
+		default:                return "UnknownShapeType";
+	}
+}
+
+//---------------------------------------------------------------------------
+const char *ShapePartTypeName(TPartType PartType)
+{
+	switch(PartType)
+   {
+		case SHPP_TRISTRIP:     return "TriangleStrip";
+		case SHPP_TRIFAN:       return "TriangleFan";
+		case SHPP_OUTERRING:    return "OuterRing";
+		case SHPP_INNERRING:    return "InnerRing";
+		case SHPP_FIRSTRING:    return "FirstRing";
+		case SHPP_RING:         return "Ring";
+		default:                return "UnknownPartType";
+	}
+}
+
+//---------------------------------------------------------------------------
+char *SkipSpaces(char *P)
+{
+	while (*P && (*P == ' ' || *P == '\t'))	P++;
+
+	return (P);
+}
+
+//---------------------------------------------------------------------------
+char *GetCol(char *P)
+{
+	char* Start = P;
+
+	if (*P == '"')
+	{
+		while (*P && *P != '"')	P++;
+		if (*P != '"') write_error(2214, "Zeichenkette '%s' nicht korrekt geschlossen", Start);
+		*P = '\0';
+	}
+	else
+	{
+		while (*P && *P != ' ' && *P != '\t' && *P != '\n' && *P != '\r')	P++;
+		*P = '\0';
+	}
+
+	return (Start);
+}
+
+//---------------------------------------------------------------------------
+void InterpolateWsp(TProfilList *ProfilList, TProfilList *WspProfilList, bool Debug)
+{
+	write_fortschritt ("->Wasserstände werden interpoliert\n");
+
+	int Anz = 0;
+	for (TProfilList::iterator i=ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		if (Anz > 0 && Anz % 10 == 0)	write_fortschritt ("%d Profile bearbeitet\n", Anz);
+
+		TProfil *Profil = *i;
+
+		TProfil *UnderProfil = *WspProfilList->begin();
+		TProfil *OverProfil = *WspProfilList->begin();
+		for (TProfilList::iterator j=WspProfilList->begin(); j != WspProfilList->end(); j++)
+		{
+			TProfil* WspProfil = *j;
+
+			if (WspProfil->Gewaesser == Profil->Gewaesser && WspProfil->Station == Profil->Station)
+			{
+				UnderProfil = WspProfil;
+				OverProfil = WspProfil;
+				break;
+			}
+			if (WspProfil->Gewaesser == Profil->Gewaesser && WspProfil->Station <= Profil->Station)	UnderProfil = WspProfil;
+			if (WspProfil->Gewaesser == Profil->Gewaesser && WspProfil->Station >= Profil->Station)	OverProfil = WspProfil;
+		}
+		if (UnderProfil->Station == Profil->Station)
+		{
+			Profil->Wsp = UnderProfil->Wsp;
+			if (Debug) write_fortschritt("Für das Profil %.4f konnte der Wasserstand %.2f übernommen werden\n", Profil->Station / 10000.0, Profil->Wsp);
+		}
+		else if (OverProfil->Station == Profil->Station)
+		{
+			Profil->Wsp = OverProfil->Wsp;
+			if (Debug) write_fortschritt("Für das Profil %.4f konnte der Wasserstand %.2f übernommen werden ßn", Profil->Station / 10000.0, Profil->Wsp);
+		}
+		else if (UnderProfil->Station <= Profil->Station && OverProfil->Station >= Profil->Station)
+		{
+			Profil->Wsp = UnderProfil->Wsp + (OverProfil->Wsp - UnderProfil->Wsp) * (Profil->Station - UnderProfil->Station) / (OverProfil->Station - UnderProfil->Station);
+			if (Debug) write_fortschritt("Für das Profil %.4f konnte der Wasserstand %.2f interpoliert werden\n", Profil->Station / 10000.0, Profil->Wsp);
+		}
+		else
+		{
+			write_error(2203, "Für das Profil %.4f konnte kein Wasserstand interpoliert werden\n", Profil->Station / 10000.0);
+		}
+
+		Anz++;
+	}
+	write_fortschritt ("%d Profile bearbeitet\n", Anz);
+	write_fortschritt ("Wasserstände wurden interpoliert<-\n");
+}
+
+//---------------------------------------------------------------------------
+TProfilMap BuildGewaesserListen(TProfilList *ProfilList, bool Debug)
+{
+	write_fortschritt ("->Gewässerlisten werden erzeugt\n");
+
+	TProfilMap	ProfilMap;
+
+	for (TProfilList::iterator i = ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		TProfil* Profil = *i;
+
+		TProfilMap::iterator p = ProfilMap.find(Profil->Gewaesser);
+
+		if (p == ProfilMap.end())
+		{
+			TProfilList *MapProfilList = new TProfilList;
+
+			MapProfilList->insert(Profil);
+
+			ProfilMap[Profil->Gewaesser] = MapProfilList;
+		}
+		else
+		{
+			TProfilList *MapProfilList = p->second;
+
+			MapProfilList->insert(Profil);
+		}
+	}
+
+	if (Debug)
+	{
+		for (TProfilMap::iterator i = ProfilMap.begin(); i != ProfilMap.end(); i++)
+		{
+			std::string Gewaesser = i->first;
+			write_fortschritt("Gewaesser '%s'\n", Gewaesser.c_str());
+
+			TProfilList* ProfilList = i->second;
+			for (TProfilList::iterator j = ProfilList->begin(); j != ProfilList->end(); j++)
+			{
+				TProfil* Profil = *j;
+				write_fortschritt("Profil '%s' '%.4f'}\n", Profil->Gewaesser.c_str(), Profil->Station / 10000.0);
+			}
+		}
+	}
+
+	write_fortschritt ("Gewässerlisten wurden erzeugt<-\n");
+
+	return (ProfilMap);
+}
+
+//---------------------------------------------------------------------------
+void BuildPolygon(TProfilList *ProfilList, TXYList *XyList, bool Debug)
+{
+	write_fortschritt ("->Begrenzungspolygon wird erzeugt\n");
+
+	if (ProfilList->size() < 2)
+	{
+		write_error(3205, "Es gibt für das Gewaesser nur %d Querprofilspuren.\nEs werden aber mindestens 2 benötigt.\n", ProfilList->size());
+	}
+
+	XyList->Clear();
+
+	TProfilList::iterator ProfilIter = ProfilList->begin();
+	for (unsigned int i = 0; i < ProfilList->size()-1; i++)
+	{
+		TProfil* Profil = *ProfilIter;
+
+		if (i == 0)
+		{
+			for (TPointList::iterator j = Profil->PointList->begin(); j != Profil->PointList->end(); j++)
+			{
+				TPoint* Point = *j;
+				XyList->Add(Point->X, Point->Y);
+			}
+		}
+		else
+		{
+			TPoint* Point = *Profil->PointList->rbegin();
+			XyList->Add(Point->X, Point->Y);
+		}
+		ProfilIter++;
+	}
+
+	TProfilList::reverse_iterator RProfilIter = ProfilList->rbegin();
+	for (unsigned int i = ProfilList->size()-1; i > 0; i--)
+	{
+		TProfil* Profil = *RProfilIter;
+
+		if (i == ProfilList->size()-1)
+		{
+			for (TPointList::reverse_iterator j = Profil->PointList->rbegin(); j != Profil->PointList->rend(); j++)
+			{
+				TPoint* Point = *j;
+				XyList->Add(Point->X, Point->Y);
+			}
+		}
+		else
+		{
+			TPoint* Point = *Profil->PointList->begin();
+			XyList->Add(Point->X, Point->Y);
+		}
+		RProfilIter++;
+	}
+
+	if (Debug)
+	{
+		write_fortschritt("Polygon:\n");
+		for (TXYList::iterator j = XyList->begin(); j != XyList->end(); j++)
+		{
+			TXY* Xy = *j;
+			write_fortschritt("%.3f %.3f\n", Xy->X, Xy->Y);
+		}
+	}
+
+	write_fortschritt ("Begrenzungspolygon wurde erzeugt<-\n");
+}
+
+//---------------------------------------------------------------------------
+void CheckForDuplicates(TNodeList *NodeList, bool Debug)
+{
+	write_fortschritt ("->Doppelte Knoten werden gesucht\n");
+
+	write_fortschritt ("%d Knoten vorhanden\n", NodeList->size());
+
+	NodeList->SortByX();
+
+	int AnzDeleted = 0;
+	TNode* FirstNode = 0;
+	TNode* NextNode = 0;
+	for (TNodeList::iterator i = NodeList->begin(); i != NodeList->end(); i++)
+	{
+		if (FirstNode == 0)
+		{
+			FirstNode = *i;
+			continue;
+		}
+		else if (NextNode == 0)
+		{
+			NextNode = *i;
+		}
+		else
+		{
+			FirstNode = NextNode;
+			NextNode = *i;
+		}
+
+		double FX = FirstNode->X;
+		double FY = FirstNode->Y;
+
+		double NX = NextNode->X;
+		double NY = NextNode->Y;
+
+		double Dx = NX - FX;
+		double Dy = NY - FY;
+
+		if (Dx < 0.01 && Dx > -0.01 && Dy < 0.01 && Dy > -0.01)
+		{
+			if (Debug)
+			{
+				write_fortschritt("Lösche Knoten %d (%.2f, %.2f)\Er ist ident mit Knoten %d (%.2f, %.2f)\n", FirstNode->Nr, FirstNode->X, FirstNode->Y, NextNode->Nr, NextNode->X, NextNode->Y);
+			}
+			NodeList->erase(i);
+			NextNode = 0;
+			AnzDeleted++;
+		}
+	}
+
+	write_fortschritt ("%d Knoten gelöscht\n", AnzDeleted);
+
+	write_fortschritt ("%d Knoten vorhanden\n", NodeList->size());
+
+	write_fortschritt ("Doppelte Knoten wurden gesucht<-\n");
+}
+
+//---------------------------------------------------------------------------
+void BuildEdgeList(TEdgeList* EdgeList, TElementList* ElementList, bool Debug)
+{
+	write_fortschritt ("->Kanten werden erzeugt\n");
+
+	EdgeList->Clear();
+
+	TEdge* NewEdge = 0;
+	TEdge* AntiEdge = 0;
+
+	int Count = 0;
+	for (TElementList::iterator i=ElementList->begin(); i!=ElementList->end(); i++)
+	{
+		if (Debug && Count % 10000 == 0)	write_fortschritt("%d von %d Elementen bearbeitert, %d Kanten erzeugt.\n", Count, ElementList->size(), EdgeList->Anz);
+		else if (Count % 100000 == 0)		write_fortschritt("%d von %d Elementen bearbeitert, %d Kanten erzeugt.\n", Count, ElementList->size(), EdgeList->Anz);
+
+		TElement *Element = *i;
+
+		TNodeList::iterator N3 = Element->NodeList->begin();
+		TNodeList::iterator N1 = N3++;
+		TNodeList::iterator N2 = N3++;
+
+		AntiEdge = EdgeList->Find((*N2)->Nr, (*N1)->Nr);
+		if (AntiEdge == 0)
+		{
+			// Im moment gehe ich mal davon aus, dass es könnte eine neue Randkante ist
+			NewEdge = EdgeList->Add(*N1, *N2);
+			NewEdge->IsBoundary = true;
+		}
+		else
+		{
+			// Mal sehen welche ich behalte
+			if ((*N1)->Nr > (*N2)->Nr)
+			{
+				// die alte ist besser, aber keine Randkante
+				AntiEdge->IsBoundary = false;
+			}
+			else
+			{
+				// Die neue ist besser, aber keine Randkante
+				EdgeList->Erase(AntiEdge);
+				NewEdge = EdgeList->Add(*N1, *N2);
+				NewEdge->IsBoundary = false;
+			}
+		}
+
+		AntiEdge = EdgeList->Find((*N3)->Nr, (*N2)->Nr);
+		if (AntiEdge == 0)
+		{
+			// Im moment gehe ich mal davon aus, dass es könnte eine neue Randkante ist
+			NewEdge = EdgeList->Add(*N2, *N3);
+			NewEdge->IsBoundary = true;
+		}
+		else
+		{
+			// Mal sehen welche ich behalte
+			if ((*N2)->Nr > (*N3)->Nr)
+			{
+				// die alte ist besser, aber keine Randkante
+				AntiEdge->IsBoundary = false;
+			}
+			else
+			{
+				// Die neue ist besser, aber keine Randkante
+				EdgeList->Erase(AntiEdge);
+				NewEdge = EdgeList->Add(*N2, *N3);
+				NewEdge->IsBoundary = false;
+			}
+		}
+
+		if (Element->Typ == TRI)
+		{
+			AntiEdge = EdgeList->Find((*N1)->Nr, (*N3)->Nr);
+			if (AntiEdge == 0)
+			{
+				// Im moment gehe ich mal davon aus, dass es könnte eine neue Randkante ist
+				NewEdge = EdgeList->Add(*N3, *N1);
+				NewEdge->IsBoundary = true;
+			}
+			else
+			{
+				// Mal sehen welche ich behalte
+				if ((*N3)->Nr > (*N1)->Nr)
+				{
+					// die alte ist besser, aber keine Randkante
+					AntiEdge->IsBoundary = false;
+				}
+				else
+				{
+					// Die neue ist besser, aber keine Randkante
+					EdgeList->Erase(AntiEdge);
+					NewEdge = EdgeList->Add(*N3, *N1);
+					NewEdge->IsBoundary = false;
+				}
+			}
+		}
+		else
+		{
+			TNodeList::iterator N4 = N3;
+			N4++;
+
+			AntiEdge = EdgeList->Find((*N4)->Nr, (*N3)->Nr);
+			if (AntiEdge == 0)
+			{
+				// Im moment gehe ich mal davon aus, dass es könnte eine neue Randkante ist
+				NewEdge = EdgeList->Add(*N3, *N4);
+				NewEdge->IsBoundary = true;
+			}
+			else
+			{
+				// Mal sehen welche ich behalte
+				if ((*N3)->Nr > (*N4)->Nr)
+				{
+					// die alte ist besser, aber keine Randkante
+					AntiEdge->IsBoundary = false;
+				}
+				else
+				{
+					// Die neue ist besser, aber keine Randkante
+					EdgeList->Erase(AntiEdge);
+					NewEdge = EdgeList->Add(*N3, *N4);
+					NewEdge->IsBoundary = false;
+				}
+			}
+
+			AntiEdge = EdgeList->Find((*N1)->Nr, (*N4)->Nr);
+			if (AntiEdge == 0)
+			{
+				// Im moment gehe ich mal davon aus, dass es könnte eine neue Randkante ist
+				NewEdge = EdgeList->Add(*N4, *N1);
+				NewEdge->IsBoundary = true;
+			}
+			else
+			{
+				// Mal sehen welche ich behalte
+				if ((*N4)->Nr > (*N1)->Nr)
+				{
+					// die alte ist besser, aber keine Randkante
+					AntiEdge->IsBoundary = false;
+				}
+				else
+				{
+					// Die neue ist besser, aber keine Randkante
+					EdgeList->Erase(AntiEdge);
+					NewEdge = EdgeList->Add(*N4, *N1);
+					NewEdge->IsBoundary = false;
+				}
+			}
+		}
+		Count++;
+	}
+	write_fortschritt("%d von %d Elementen bearbeitert, %d Kanten erzeugt.\n", Count, ElementList->size(), EdgeList->Anz);
+
+	if (Debug)
+	{
+		Count = 0;
+		TEdgeListNrSorted::iterator i = EdgeList->EdgeListNrSorted.begin();
+		while (i != EdgeList->EdgeListNrSorted.end())
+		{
+			if (Debug && Count % 10000 == 0)	write_fortschritt("%d Kanten getestet\n", Count);
+			else if (Count % 100000 == 0)		write_fortschritt("%d Kanten getestet\n", Count);
+
+			TEdge *Edge = *i++;
+
+			TNode* Node1 = Edge->Node1;
+			TNode* Node2 = Edge->Node2;
+
+			int Nr1 = Node1->Nr;
+			int Nr2 = Node2->Nr;
+
+			TEdge* AntiEdge = EdgeList->Find(Nr2, Nr1);
+
+			if (0 != AntiEdge)
+			{
+				dump_error(__FILE__, __LINE__, "Diese Kante dürfte es nicht geben");
+			}
+
+			Count++;
+		}
+		write_fortschritt("%d Kanten getestet\n", Count);
+	}
+
+	write_fortschritt ("Kanten wurden erzeugt<-\n");
+}
+
+//---------------------------------------------------------------------------
+void BuildProfilNodeList(TProfilList *ProfilList, TNodeList *NodeList, TGewaesserAchseList *GewaesserAchseList, TNodeList *ProfilNodeList, double AvgDistance, bool Sperre, bool Debug)
+{
+	write_fortschritt ("->Knotenliste wird aus den Profilspuren generiert\n");
+
+	NodeList->SortByXY();
+
+	ProfilNodeList->Clear();
+
+	int NodeNr = 0;
+
+	int Count = 0;
+	for (TProfilList::iterator i = ProfilList->begin(); i != ProfilList->end(); i++)
+	{
+		if (Debug && Count % 100 == 0)	write_fortschritt("%d Profile getestet %d Knoten erzeugt\n", Count, NodeNr);
+		else if (Count % 1000 == 0)		write_fortschritt("%d Profile getestet %d Knoten erzeugt\n", Count, NodeNr);
+
+		TProfil* Profil = *i;
+
+		std::string Gewaesser = Profil->Gewaesser;
+		int Station = Profil->Station;
+		double Wsp = Profil->Wsp;
+
+		double Meter = 0.0;
+
+		if (Sperre)
+		{
+			Meter = Profil->CalcSchnitt(GewaesserAchseList);
+
+			if (Meter < 0)
+			{
+				write_error(3206, "Die Gewässerachse für das Gewässer '%s' schneidet die Profilspur %.4f nicht\n", Gewaesser.c_str(), Station / 10000.0);
+			}
+		}
+
+		for (TPointList::reverse_iterator v = Profil->PointList->rbegin(); v != Profil->PointList->rend(); v++)
+		{
+			TPoint* Point = *v;
+
+			if (Point->Meter > Meter)	continue;
+
+			double X = Point->X;
+			double Y = Point->Y;
+
+			double Z = 0.0;
+			double WspDummy = 0.0;
+			bool Found = NodeList->Interpolate(X, Y, AvgDistance, &Z, &WspDummy);
+
+			if (false == Found)
+			{
+				// Dies bedeutet, die Profile ragen aus dem DGM raus oder die Punkte sind lokal sehr weit auseinander
+
+				// if (Debug) write_warning(9999, "Es konnte für einen Profilpunkt keine Höhe interpoliert werden\n");
+				continue;
+			}
+
+			if (Z < Wsp)
+			{
+				NodeNr++;
+				TNode* Node = new TNode(NodeNr, X, Y, Z, Wsp);
+				ProfilNodeList->push_back(Node);
+			}
+			else if (Sperre)
+			{
+				// Wenn das aktuelle Überschwemmungsgebiet ermittelt werden soll
+				// so wird nicht über Geländekanten hinaus der Wasserstand übertragen
+				break;
+			}
+		}
+
+		for (TPointList::iterator n = Profil->PointList->begin(); n != Profil->PointList->end(); n++)
+		{
+			TPoint* Point = *n;
+
+			if (Point->Meter < Meter)	continue;
+
+			double X = Point->X;
+			double Y = Point->Y;
+
+			double Z = 0.0;
+			double WspDummy = 0.0;
+			bool Found = NodeList->Interpolate(X, Y, AvgDistance, &Z, &WspDummy);
+
+			if (false == Found)
+			{
+				// Dies bedeutet, die Profile ragen aus dem DGM raus oder die Punkte sind lokal sehr weit auseinander
+
+				// if (Debug) write_warning(9999, "Es konnte für einen Profilpunkt keine Höhe interpoliert werden");
+				continue;
+			}
+
+			if (Z < Wsp)
+			{
+				NodeNr++;
+				TNode* Node = new TNode(NodeNr, X, Y, Z, Wsp);
+				ProfilNodeList->push_back(Node);
+			}
+			else if (Sperre)
+			{
+				// Wenn das aktuelle Überschwemmungsgebiet ermittelt werden soll
+				// so wird nicht über Geländekanten hinaus der Wasserstand übertragen
+				break;
+			}
+		}
+		Count++;
+	}
+	write_fortschritt("%d Profile getestet %d Knoten erzeugt\n", Count, NodeNr);
+
+	write_fortschritt ("Knotenliste wurde aus den Profilspuren generiert<-\n");
+}
+
+//---------------------------------------------------------------------------
+void TransferWsp(TNodeList *ProfilNodeList, TNodeList *NodeList, double AvgDistance, bool Debug)
+{
+	write_fortschritt ("->Wasserstände werden übertragen\n");
+
+	ProfilNodeList->SortByXY();
+
+	int WspCount = 0;
+	int Count = 0;
+	for (TNodeList::iterator i = NodeList->begin(); i != NodeList->end(); i++)
+	{
+		if (Debug && Count % 1000 == 0)	write_fortschritt("%d Knoten getestet, %d Wasserstände übertragen\n", Count, WspCount);
+		else if (Count % 10000 == 0)		write_fortschritt("%d Knoten getestet, %d Wasserstände übertragen\n", Count, WspCount);
+
+		TNode* Node = *i;
+
+		double X = Node->X;
+		double Y = Node->Y;
+
+		double ZDummy = 0.0;
+		double Wsp = 0.0;
+		bool Found = ProfilNodeList->Interpolate(X, Y, AvgDistance, &ZDummy, &Wsp);
+
+		if (Found)
+		{
+			if (Node->Z < Wsp)
+			{
+				Node->Wsp = Wsp;
+				WspCount++;
+			}
+		}
+		Count++;
+	}
+	write_fortschritt("%d Knoten getestet, %d Wasserstände übertragen\n", Count, WspCount);
+
+	write_fortschritt ("Wasserstände wurden übertragen<-\n");
+}
+
+//---------------------------------------------------------------------------
+double TwoToWin (double x0, double y0, double x1, double y1)
+{
+	double  Win;
+
+	if (fabs (x1-x0) < 0.0001)
+	{
+		if (y1 - y0 > 0.0)  return (90.0);
+		else                return (270.0);
+	}
+
+	Win = atan ( (y1-y0) / (x1-x0) );
+	Win = Win * 180.0 / M_PI;
+	if (x1 - x0 < 0.0)  Win = Win + 180;
+	if (Win < 0.0)      Win = Win + 360.0;
+	if (Win >= 360.0)   Win = Win - 360.0;
+
+	return (Win);
+}
+
+//---------------------------------------------------------------------------
+double ThreeToWin (double x0, double y0, double x1, double y1, double x2, double y2, int turn)
+{
+	double  W0, W1, Win;
+
+	W0 = TwoToWin(x1, y1, x0, y0);
+	W1 = TwoToWin (x1, y1, x2, y2);
+	Win = W1 - W0;
+	if (Win < 0.0)  Win = 360.0 + Win;
+	if (turn == 1)  Win = 360.0 - Win;
+
+	return (Win);
+}
+
+//---------------------------------------------------------------------------
+bool Calc2Schnitt (double P0x, double P0y, double P1x, double P1y, double S0x, double S0y, double S1x, double S1y, double *x, double *y, double *lambdap, double *lambdas)
+{
+	double PDx = P1x - P0x;
+	double PDy = P1y - P0y;
+
+	double SDx = S1x - S0x;
+	double SDy = S1y - S0y;
+
+	double  LambdaP = 0.0;
+	double  LambdaS = 0.0;
+
+	if (fabs(PDx) < 0.00001 && fabs(PDy) < 0.00001)
+	{
+		write_error(3207, "Profil-Punktabstand (%.3f %.3f) - (%.3f %.3f) ist zu klein\n", P0x, P0y, P1x, P1y);
+	}
+	else if (fabs(SDx) < 0.00001 && fabs(SDy) < 0.00001)
+	{
+		write_error(3208, "GewaesserAchse-Punktabstand (%.3f %.3f) - (%.3f %.3f) ist zu klein\n", S0x, S0y, S1x, S1y);
+	}
+	else if (fabs(PDx) < 0.00001 && fabs(SDx) < 0.00001)
+	{
+		// S-Segment und P->Abschnitt sind beide senkrecht (parallel)
+		return (false);
+	}
+	else if (fabs(PDy) < 0.00001 && fabs(SDy) < 0.00001)
+	{
+		// S-Segment und P->Abschnitt sind beide waagerecht (parallel)
+		return (false);
+	}
+	else if (fabs(PDx) < 0.00001)
+	{
+		// P-Abschnitt senkrecht aber Spur-Abschnitt nicht
+		LambdaS = (P0x - S0x) / SDx;
+		LambdaP = ((S0y + LambdaS * SDy) - P0y) / PDy;
+	}
+	else if (fabs(PDy) < 0.00001)
+	{
+		// P-Abschnitt waagerecht aber Spur-Abschnitt nicht
+		LambdaS = (P0y - S0y) / SDy;
+		LambdaP = ((S0x + LambdaS * SDx) - P0x) / PDx;
+	}
+	else if (fabs((SDy / PDy) - (SDx / PDx)) < 0.00001)
+	{
+		// Spur-Segment und PaPe->Abschnitt sind parallel
+		// fabs((SDy / PDy) - (SDx / PDx)) < 0.00001 entspricht
+		// SDy / PDy = SDx / PDx entspricht
+		// SDy / SDx = PDy / PDx (P-Steigung gleich S-Steigung) entspricht
+		// SDy / SDx = PDy / PDx (P-Steigung gleich S-Steigung) entspricht
+		// SDy / SDx = PDy / PDx entspricht
+		// SDy / PDy = SDx / PDx entspricht
+		// SDy / PDy * PDx = SDx entspricht
+		// 0 = SDx - SDy / PDy * PDx (siehe unten !!!!)
+
+		return (false);
+	}
+	else
+	{
+		LambdaS = (P0x + (S0y - P0y) / PDy * PDx - S0x) / (SDx - SDy / PDy * PDx); // !!!!
+		LambdaP = (S0y + LambdaS * SDy - P0y) / PDy;
+	}
+
+	double Px = P0x + LambdaP * PDx;
+	double Py = P0y + LambdaP * PDy;
+
+	double Sx = S0x + LambdaS * SDx;
+	double Sy = S0y + LambdaS * SDy;
+
+	if (fabs(Px-Sx) > 0.0001 || fabs(Py-Sy) > 0.0001)
+	{
+		dump_error (__FILE__, __LINE__, "Errechnete Punkte sind nicht identisch (%10.5f,%10.5f) und (%10.5f,%10.5f)\n", Px, Py, Sx, Sy);
+	}
+
+	*x = Px;
+	*y = Py;
+	*lambdap = LambdaP;
+	*lambdas = LambdaS;
+
+	if (LambdaP < 0.0 || LambdaP > 1.0) return (false);
+	if (LambdaS < 0.0 || LambdaS > 1.0) return (false);
+
+	return (true);
+}
+
+//---------------------------------------------------------------------------
+const double Eps =0.01;
+
+//---------------------------------------------------------------------------
+TEdge *FindNextAntiClockwiseEdge(TEdge **edge, TNode **node)
+{
+	double ThisArc = (*edge)->Arc;
+
+	if ((*edge)->Node2->Nr == (*node)->Nr)
+	{
+		if (ThisArc < 180.0)    ThisArc = ThisArc + 180.0;
+		else                    ThisArc = ThisArc - 180.0;
+	}
+
+	TEdge *MaxEdge = 0;
+	double  MaxArc = -9999.9;
+
+	TEdgeIndex *AktEdgeIndex = (*node)->EdgeIndex;
+
+	while (AktEdgeIndex)
+	{
+		TEdgeIndex *NextEdgeIndex = AktEdgeIndex->NextEdgeIndex;
+
+		TEdge *Edge = AktEdgeIndex->Edge;
+
+		if (Edge != *edge)
+		{
+			double Arc = Edge->Arc;
+			if (Edge->Node2->Nr == (*node)->Nr)
+			{
+				if (Arc < 180.0)    Arc = Arc + 180.0;
+				else                Arc = Arc - 180.0;
+			}
+			if (Arc < ThisArc)  Arc = Arc + 360.0;
+			if (Arc > MaxArc)
+			{
+				MaxArc = Arc;
+				MaxEdge = Edge;
+			}
+		}
+
+		AktEdgeIndex = NextEdgeIndex;
+	}
+
+	if (MaxEdge == 0)
+	{
+		dump_error(__FILE__, __LINE__, "Kante: %d (%.3f, %.3f) nach %d (%.3f, %.3f) von %d\nKeine weitere Kante gefunden", (*edge)->Node1->Nr, (*edge)->Node1->X, (*edge)->Node1->Y, (*edge)->Node2->Nr, (*edge)->Node2->X, (*edge)->Node2->Y, (*node)->Nr);
+	}
+
+	return (MaxEdge);
+}
+
+//---------------------------------------------------------------------------
+bool FindFirstChangeEdge(TEdgeListNrSorted::iterator *Start, TEdgeList *EdgeList, TEdge **edge, TNode **node)
+{
+	for (TEdgeListNrSorted::iterator i = *Start; i != EdgeList->EdgeListNrSorted.end(); i++)
+	{
+		TEdge *Edge = *i;
+
+		if (Edge->Ready == false && Edge->X > 0.0 && Edge->Y > 0.0)
+		{
+			if (Edge->Node1->Wsp - Edge->Node1->Z > Eps)
+			{
+				Edge->Ready = true;
+				*edge = Edge;
+				*node = Edge->Node1;
+				*Start = i;
+				return (true);
+			}
+			if (Edge->Node2->Wsp - Edge->Node2->Z > Eps)
+			{
+				Edge->Ready = true;
+				*edge = Edge;
+				*node = Edge->Node2;
+				*Start = i;
+				return (true);
+			}
+		}
+	}
+	*Start = EdgeList->EdgeListNrSorted.end();
+
+	return (false);
+}
+//---------------------------------------------------------------------------
+bool FindNextChangeEdge(TEdge **edge, TNode **node, TXYList *PunktList)
+{
+	do
+	{
+		TEdge *Edge = FindNextAntiClockwiseEdge (edge, node);
+
+		if ((*edge)->IsBoundary && Edge->IsBoundary)
+		{
+			(*edge)->Ready = true;
+
+			double X = (*node)->X;
+			double Y = (*node)->Y;
+
+			TXY *XY = new TXY(X, Y);
+			PunktList->Add(XY);
+		}
+
+		if (Edge->X > 0.0 && Edge->Y > 0.0)
+		{
+			if (Edge->Ready)	return(false);
+
+			Edge->Ready = true;
+			*edge = Edge;
+
+			if (Edge->Node1->Nr == (*node)->Nr)
+			{
+				*node = Edge->Node1;
+
+				if (Edge->Node1->Wsp - Edge->Node1->Z < -Eps)
+				{
+					dump_error(__FILE__, __LINE__, "Der eigentlich nasse erste Knoten (Nr %d) einer Kanter  (%d - %d) ist trocken", Edge->Node1->Nr, Edge->Node1->Nr, Edge->Node2->Nr);
+				}
+				return (true);
+			}
+			else if (Edge->Node2->Nr == (*node)->Nr)
+			{
+				*node = Edge->Node2;
+
+				if (Edge->Node2->Wsp - Edge->Node2->Z < -Eps)
+				{
+					dump_error(__FILE__, __LINE__, "Der eigentlich nasse zweite Knoten (Nr %d) einer Kanter  (%d - %d) ist trocken", Edge->Node2->Nr, Edge->Node1->Nr, Edge->Node2->Nr);
+				}
+
+				return (true);
+			}
+			else
+			{
+				dump_error(__FILE__, __LINE__, "Die Betrachtungsseite hat gewechselt");
+			}
+		}
+		else
+		{
+			*edge = Edge;
+
+			if (Edge->Node1->Nr == (*node)->Nr)
+			{
+				*node = Edge->Node2;
+			}
+			else
+			{
+				*node = Edge->Node1;
+			}
+		}
+	} while (true);
+}
+//---------------------------------------------------------------------------
+bool FindFirstWetBoundaryEdge(TEdgeListNrSorted::iterator *Start, TEdgeList *EdgeList, TEdge **edge, TNode **node)
+{
+	for (TEdgeListNrSorted::iterator i = *Start; i != EdgeList->EdgeListNrSorted.end(); i++)
+	{
+		TEdge *Edge = *i;
+
+		if (Edge->Ready)	continue;
+
+		if (Edge->IsBoundary && Edge->Node1->Wsp - Edge->Node1->Z > Eps && Edge->Node2->Wsp - Edge->Node2->Z > Eps)
+		{
+			Edge->Ready = true;
+			*edge = Edge;
+			*node = Edge->Node1;
+			*Start = i;
+			return (true);
+		}
+	}
+
+	*Start = EdgeList->EdgeListNrSorted.end();
+
+	return (false);
+}
+//---------------------------------------------------------------------------
+bool FindNextWetBoundaryEdge(TEdge **edge, TNode **node)
+{
+	do
+	{
+		TEdge *Edge = FindNextAntiClockwiseEdge (edge, node);
+
+		if (Edge->Ready)	return (false);
+
+		if (Edge->IsBoundary && Edge->Node1->Wsp - Edge->Node1->Z > Eps && Edge->Node2->Wsp - Edge->Node2->Z > Eps)
+		{
+			if (Edge->Node1 == *node)
+			{
+				Edge->Ready = true;
+				*edge = Edge;
+				*node = Edge->Node2;
+			}
+			else
+			{
+				Edge->Ready = true;
+				*edge = Edge;
+				*node = Edge->Node1;
+			}
+			return (true);
+		}
+		else
+		{
+			*edge = Edge;
+		}
+	} while (true);
+}
+
+//---------------------------------------------------------------------------
+void NassTrockenBerechnung(std::string FileName, TNodeList *NodeList, TEdgeList *EdgeList, TErgebnisPolygonList* ErgebnisPolygone, double Von, double Bis, double Diff, bool Debug)
+{
+	TNodeList *SaveNodeList = new TNodeList;
+	SaveNodeList = NodeList->Copy();
+
+	if (Diff <= 0.0)
+	{
+		dump_error(__FILE__, __LINE__, "Diff ist kleiner gleich Null");
+	}
+
+	for (double DeltaTopo = Von; DeltaTopo <= Bis; DeltaTopo = DeltaTopo + Diff)
+	{
+		// Zuerst alles wieder wie gehabt einstellen
+		// Bloss das die Topographie etwas angehoben wird
+		TNodeList::iterator n = NodeList->begin();
+		TNodeList::iterator s = SaveNodeList->begin();
+		for (unsigned int i=0; i<NodeList->size(); i++)
+		{
+			TNode *Node = *n++;
+			TNode *SaveNode = *s++;
+			Node->Z = SaveNode->Z + DeltaTopo;
+			if (SaveNode->Wsp > Node->Z + Eps)
+			{
+				Node->Wsp = SaveNode->Wsp;
+			}
+			else
+			{
+				Node->Wsp = SaveNode->Wsp;
+			}
+		}
+
+		// Alle trockenen Werte in der Topographie etwas verändert
+/*
+		for (int i=0; i<Net2->AnzNodes(); i++)
+		{
+			TNode *NodeNeu = Net2->FindNodeByIndex(i);
+
+			TNode *NodeAlt = Net->FindNodeByXY(NodeNeu->X, NodeNeu->Y);
+
+			if (NodeAlt->Wsp <= EPS)
+			{
+				NodeNeu->Z = NodeNeu->Z + OptionenTopoDiff;
+				NodeNeu->Vx = 0.0;
+				NodeNeu->Vy = 0.0;
+				NodeNeu->Wsp = -9999.9;
+			}
+			else
+			{
+				NodeNeu->Wsp = NodeAlt->Wsp;
+				NodeNeu->Vx = NodeAlt->Vx;
+				NodeNeu->Vy = NodeAlt->Vy;
+			}
+		}
+*/
+
+		// Maximalen Wasserstand ermitteln
+		double  MaxWsp = 0.0;
+		for (TNodeList::iterator i = NodeList->begin(); i != NodeList->end(); i++)
+		{
+			TNode *Node = *i;
+
+			if (i == NodeList->begin() || MaxWsp < Node->Wsp)   MaxWsp = Node->Wsp;
+		}
+
+		// Anzahl der Knoten bestimmen, die höher als der maximale Wassrstand sind
+		// oder die schon einen Wasserstand haben
+		int Ready = 0;
+		for (TNodeList::iterator i = NodeList->begin(); i != NodeList->end(); i++)
+		{
+			TNode *Node = *i;
+
+			if (Node->Wsp > -9999 || Node->Z > MaxWsp)  Ready++;
+		}
+
+		// Die Kanten bestimmen, die an einem Ende einen nassen und am anderen Ende einen trockenen Knoten haben
+		// Dies ist die Anfangskanten
+		TEdgeList *Temp2EdgeList = new TEdgeList();
+		for (TEdgeListNrSorted::iterator i = EdgeList->EdgeListNrSorted.begin(); i != EdgeList->EdgeListNrSorted.end(); i++)
+		{
+			TEdge *Edge = *i;
+
+			if (Edge->Node1->Wsp < -9999 && Edge->Node2->Wsp > -9999 && Edge->Node2->Wsp > Edge->Node2->Z + Eps)
+			{
+				Temp2EdgeList->Add(Edge);
+			}
+			else if (Edge->Node2->Wsp < -9999 && Edge->Node1->Wsp > -9999 && Edge->Node1->Wsp > Edge->Node1->Z + Eps)
+			{
+				Temp2EdgeList->Add(Edge);
+			}
+		}
+
+		TEdgeList *TempEdgeList = new TEdgeList();
+		int Changed = 0;
+		do
+		{
+			// Hier nur die Verwaltungsinformationen, aber nicht die richtigen Kanten löschen
+			// Es waren nur geliehene Kanten
+			TempEdgeList->Empty();
+
+			// Alle bisher ermittelten Wechsel-Kanten übertragen
+			for (TEdgeListNrSorted::iterator i = Temp2EdgeList->EdgeListNrSorted.begin(); i != Temp2EdgeList->EdgeListNrSorted.end(); i++)
+			{
+				TEdge *Edge = *i;
+
+				if (Edge->Node1->Wsp < -9999 && Edge->Node2->Wsp > -9999 && Edge->Node2->Wsp > Edge->Node2->Z + Eps)
+				{
+					TempEdgeList->Add(Edge);
+				}
+				else if (Edge->Node2->Wsp < -9999 && Edge->Node1->Wsp > -9999 && Edge->Node1->Wsp > Edge->Node1->Z + Eps)
+				{
+					TempEdgeList->Add(Edge);
+				}
+			}
+
+			// Hier nur die Verwaltungsinformationen, aber nicht die richtigen Kanten löschen
+			// Es waren nur geliehene Kanten
+			Temp2EdgeList->Empty();
+
+			Changed = 0;
+			for (TEdgeListDistanceSorted::iterator i = TempEdgeList->EdgeListDistanceSorted.begin(); i != TempEdgeList->EdgeListDistanceSorted.end(); i++)
+			{
+				TEdge *Edge = *i;
+
+				if (Edge->Node1->Wsp < -9999 && Edge->Node2->Wsp > -9999)
+				{
+					if (Edge->Node2->Wsp <= Edge->Node2->Z + Eps)
+					{
+						dump_error(__FILE__, __LINE__, "Ein Knoten Kantenendknoten %d ist unter Gelände aber nass", Edge->Node2->Nr);
+					}
+
+// !!! hier war früher ein negativ setzen
+					Edge->Node1->Wsp = Edge->Node2->Wsp;
+
+					// Hier jetzt neue potentielle Kanten aufnehmen
+					TEdgeIndex *AktEdgeIndex = Edge->Node1->EdgeIndex;
+					while (AktEdgeIndex)
+					{
+						TEdgeIndex *NextEdgeIndex = AktEdgeIndex->NextEdgeIndex;
+
+//						Temp2EdgeList->Add(new TEdge(AktEdgeIndex->Edge));
+						if (0 == Temp2EdgeList->Find(AktEdgeIndex->Edge)) Temp2EdgeList->Add(AktEdgeIndex->Edge);
+
+						AktEdgeIndex = NextEdgeIndex;
+					}
+
+					Changed++;
+				}
+				else if (Edge->Node2->Wsp < -9999.0 && Edge->Node1->Wsp > -9999)
+				{
+					if (Edge->Node1->Wsp <= Edge->Node1->Z + Eps)
+					{
+						dump_error(__FILE__, __LINE__, "Ein Knoten Kantenstartknoten %d ist unter Gelände aber nass", Edge->Node1->Nr);
+					}
+
+// !!! hier war früher ein negativ setzen
+					Edge->Node2->Wsp = Edge->Node1->Wsp;
+
+					// Hier jetzt neue potentielle Kanten aufnehmen
+					TEdgeIndex *AktEdgeIndex = Edge->Node2->EdgeIndex;
+					while (AktEdgeIndex)
+					{
+						TEdgeIndex *NextEdgeIndex = AktEdgeIndex->NextEdgeIndex;
+
+//						Temp2EdgeList->Add(new TEdge(AktEdgeIndex->Edge));
+						if (0 == Temp2EdgeList->Find(AktEdgeIndex->Edge)) Temp2EdgeList->Add(AktEdgeIndex->Edge);
+
+						AktEdgeIndex = NextEdgeIndex;
+					}
+
+					Changed++;
+				}
+			}
+
+/*
+			Hier musste man früher die negativen umdrehen
+			for (TEdgeListDistanceSorted::iterator i = TempEdgeList->EdgeListDistanceSorted.begin(); i != TempEdgeList->EdgeListDistanceSorted.end(); i++)
+			{
+				TEdge *Edge = *i;
+
+				if (Edge->Node1->Wsp > -9999 && Edge->Node1->Wsp < -9999)
+				{
+					Edge->Node1->Wsp = -Edge->Node1->Wsp;
+				}
+				if (Edge->Node2->Wsp > -9999 && Edge->Node2->Wsp < -9999)
+				{
+					Edge->Node2->Wsp = -Edge->Node2->Wsp;
+				}
+			}
+*/
+
+			Ready = Ready + Changed;
+
+		} while (Changed > 0);
+
+		// Hier nur die Verwaltungsinformationen, aber nicht die richtigen Kanten löschen
+		// Es waren nur geliehene Kanten
+		TempEdgeList->Empty();
+		delete TempEdgeList;
+
+		// Hier nur die Verwaltungsinformationen, aber nicht die richtigen Kanten löschen
+		// Es waren nur geliehene Kanten
+		Temp2EdgeList->Empty();
+		delete Temp2EdgeList;
+
+
+		// Jetzt sind alle Knoten nass, die Nass sein sollen
+
+
+		//Zuerst die Übergangspunkt der Kanten löschen
+		for (TEdgeListNrSorted::iterator i = EdgeList->EdgeListNrSorted.begin(); i != EdgeList->EdgeListNrSorted.end(); i++)
+		{
+			TEdge *Edge = *i;
+
+			Edge->X = 0.0;
+			Edge->Y = 0.0;
+			Edge->Ready = false;
+		}
+
+		// Jetzt die Nass/Trocken Übergänge bestimmen
+		int FoundWetDry = 0;
+		for (TEdgeListNrSorted::iterator i = EdgeList->EdgeListNrSorted.begin(); i != EdgeList->EdgeListNrSorted.end(); i++)
+		{
+			TEdge *Edge = *i;
+
+			double Z1 = Edge->Node1->Z;
+			double Wsp1 = Edge->Node1->Wsp;
+
+			double Z2 = Edge->Node2->Z;
+			double Wsp2 = Edge->Node2->Wsp;
+
+
+			// Testen wir mal, ob es hier einen Übergang gibt
+			if (Wsp1 - Z1 <= 0.0 && Wsp2 - Z2 > 0.0 ||
+				Wsp1 - Z1 > 0.0 &&  Wsp2 - Z2 <= 0.0)
+			{
+				double Dx = Edge->Node1->X - Edge->Node2->X;
+				double Dy = Edge->Node1->Y - Edge->Node2->Y;
+				double D1 = 0.0;
+				double D2 = 0.0;
+
+				if (Wsp1 - Z1 <= 0.0 && Wsp2 - Z2 > 0.0)
+				{
+					D1 = Z1 - Wsp1;
+					D2 = Wsp2 - Z2;
+				}
+				else
+				{
+					D1 = Wsp1 - Z1;
+					D2 = Z2 - Wsp2;
+				}
+
+				if (D1 < 0.0 || D2 < 0.0)
+				{
+					dump_error(__FILE__, __LINE__, "Zwei Knoten sind trocken, aber einer sollte nass sein: Kante %d - %d Differenzen %lf %lf\n", Edge->Node1->Nr, Edge->Node2->Nr, D1, D2);
+				}
+
+				double Faktor;
+
+				if (fabs(D2) < 0.0001)  Faktor = 0;
+				else                    Faktor = 1 / (1 + D1/D2);
+
+				double X = Edge->Node2->X + Dx * Faktor;
+				double Y = Edge->Node2->Y + Dy * Faktor;
+
+				Edge->X = X;
+				Edge->Y = Y;
+
+				FoundWetDry++;
+			}
+		}
+
+		// Jetzt sind alle Nass/Trockenübergänge bestimmt
+
+
+		// Jetzt muss man sie nur noch verbinden
+
+		bool FoundStartChangeEdge = false;
+		TEdgeListNrSorted::iterator StartChange = EdgeList->EdgeListNrSorted.begin();
+		do
+		{
+			TEdge   *Edge = 0;
+			TNode   *Node = 0;
+
+			FoundStartChangeEdge = FindFirstChangeEdge (&StartChange, EdgeList, &Edge, &Node);
+
+			if (FoundStartChangeEdge)
+			{
+				TErgebnisPolygon* ErgebnisPolygon = new TErgebnisPolygon(DeltaTopo);
+
+				double X = Edge->X;
+				double Y = Edge->Y;
+
+				TXY *XY = new TXY(X, Y);
+				ErgebnisPolygon->Add(XY);
+
+				double Ox = X;
+				double Oy = Y;
+
+				bool FoundChangeEdge = FindNextChangeEdge (&Edge, &Node, ErgebnisPolygon);
+
+				while (FoundChangeEdge)
+				{
+					X = Edge->X;
+					Y = Edge->Y;
+
+					TXY *XY = new TXY(X, Y);
+					ErgebnisPolygon->Add(XY);
+
+					FoundChangeEdge = FindNextChangeEdge (&Edge, &Node, ErgebnisPolygon);
+				}
+
+				XY = new TXY(Ox, Oy);
+				ErgebnisPolygon->Add(XY);
+
+				ErgebnisPolygone->push_back(ErgebnisPolygon);
+			}
+
+		} while (FoundStartChangeEdge);
+	}
+}
+

Modified: trunk/src/tools.h
===================================================================
--- trunk/src/tools.h	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/tools.h	2006-03-13 23:53:00 UTC (rev 37)
@@ -16,9 +16,9 @@
 
 //----------------------------------------------------------------------------
 #include <string>
-
 #include <math.h>
 
+#include "shape.h"
 #include "xy.h"
 
 
@@ -47,6 +47,7 @@
 void    				Swap2Bytes(byte *Bytes);
 void    				Swap4Bytes(byte *Bytes);
 void    				Swap8Bytes(byte *Bytes);
+void* 					SfRealloc(void *pMem, int nNewSize);
 std::string				GetFileExt(std::string FileName);
 std::string				ExchangeFileExt(std::string FileName, std::string Ext);
 std::string				GetFilePath(std::string FileName);
@@ -55,6 +56,22 @@
 bool 					CircumCircle(TNode *n1, TNode *n2, TNode *n3, double *x, double *y, double *r);
 size_t					CheckMemory(bool IsDebug);
 long 					CheckSpeed(bool IsDebug);
+const char*				ShapeTypeName(TShpType ShapeType);
+const char*				ShapePartTypeName(TPartType PartType);
+char*					SkipSpaces(char* P);
+char*					GetCol(char* P);
+void 					InterpolateWsp(TProfilList *ProfilList, TProfilList *WspProfilList, bool Debug);
+TProfilMap 				BuildGewaesserListen(TProfilList *ProfilList, bool Debug);
+void 					BuildPolygon(TProfilList *ProfilList, TXYList *XyList, bool Debug);
+void 					EqualizeProfil(TProfil *ProfilOne, TProfil *ProfilTwo);
+void 					CheckForDuplicates(TNodeList *NodeList, bool Debug);
+void 					BuildEdgeList(TEdgeList* EdgeList, TElementList* ElementList, bool Debug);
+void 					BuildProfilNodeList(TProfilList *ProfilList, TNodeList *NodeList, TGewaesserAchseList *GewaesserAchseList, TNodeList *ProfilNodeList, double AvgDistance, bool Sperre, bool Debug);
+void					TransferWsp(TNodeList *ProfilNodeList, TNodeList *NodeList, double AvgDistance, bool Debug);
+void 					NassTrockenBerechnung(std::string FileName, TNodeList *NodeList, TEdgeList *edgelist, TErgebnisPolygonList* ErgebnisPolygone, double Von, double Bis, double Diff, bool Debug);
+double 					TwoToWin (double x0, double y0, double x1, double y1);
+double 					ThreeToWin (double x0, double y0, double x1, double y1, double x2, double y2, int turn);
+bool 					Calc2Schnitt (double P0x, double P0y, double P1x, double P1y, double S0x, double S0y, double S1x, double S1y, double *x, double *y, double *lambdap, double *lambdas);
 
 //---------------------------------------------------------------------------
 template<class TClass> int IsInside(TClass *p, double x, double y)
@@ -67,6 +84,7 @@
 	{
 		// Wenn keine Punkte da sind, um das Polygon zu bilden
 		// kann der Punkt nicht innerhalb oder auf dem Rand liegen.
+		// Also 0 -> Outside
 		return (0);
 	}
 
@@ -96,16 +114,34 @@
 		else if (bx <= x && by > y)	bQ = 3;
 		else	return (-1);  // Der Polygonpunkt und der gesuchte sind identisch
 
-		if (bQ == aQ)	continue;
+		if (bQ == aQ)
+		{
+		}
+		else if (bQ == (aQ + 1) % 4)
+		{
+			alpha++;
+		}
+		else if (bQ == (aQ + 3) % 4)
+		{
+			alpha--;
+		}
+		else if (bQ == (aQ + 2) % 4)
+		{
+			if (fabs(by - ay) < 0.005)
+			{
+				// der Punkt liegt auf der waagerechten Verbindung zwischen
+				// den beiden Polygonpunkte -1 -> online
+				return (-1);
+			}
 
-		if (bQ == (aQ + 1) % 4)	alpha++;
-		if (bQ == (aQ + 3) % 4)	alpha--;
-
-		if (bQ == (aQ + 2) % 4)
-		{
 			double zx = (bx - ax) * (y - ay) / (by - ay) + ax;
 
-			if (fabs(x - zx) < 0.005)	return (-1);
+			if (fabs(x - zx) < 0.005)
+			{
+				// der Punkt liegt auf der senkrechten Verbindung zwischen
+				// den beiden Polygonpunkte -1 -> online
+				return (-1);
+			}
 
 			if ((x > zx) == (by > ay)) 	alpha = alpha - 2;
 			else                       	alpha = alpha + 2;

Modified: trunk/src/tri.cpp
===================================================================
--- trunk/src/tri.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/tri.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,7 +10,9 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------
 #include <sys/timeb.h>
@@ -18,6 +20,13 @@
 #include "tools.h"
 #include "tri.h"
 
+TNodeList* FoundNodeList = new TNodeList();
+TNode* TestNode = new TNode(1, 0.0, 0.0, 0.0);
+double cx = 0;
+double cy = 0;
+double cr = 0;
+TEdge *Edge = 0;
+
 //---------------------------------------------------------------------
 void FindLeftMostNeighbours(TNodeList* NodeList, TNode* *Node1, TNode* *Node2)
 {
@@ -35,7 +44,7 @@
 		}
 		else if	(*Node2 == 0)
 		{
-			if (Min1 < Node->X)
+			if (Min1 > Node->X)
 			{
 				Min2 = Min1;
 				*Node2 = *Node1;
@@ -49,7 +58,7 @@
 				*Node2 = Node;
 			}
 		}
-		else if (Min1 < Node->X)
+		else if (Min1 > Node->X)
 		{
 			Min2 = Min1;
 			*Node2 = *Node1;
@@ -57,7 +66,7 @@
 			Min1 = Node->X;
 			*Node1 = Node;
 		}
-		else if (Min2 < Node->X)
+		else if (Min2 > Node->X)
 		{
 			Min2 = Node->X;
 			*Node2 = Node;
@@ -93,9 +102,8 @@
 	TNode *Node1 = AktEdge->Node1;
 	TNode *Node2 = AktEdge->Node2;
 
-	TNode *NewNode = 0;
+	TNode* NewNode = 0;
 
-
 	double X1 = Node1->X;
 	double Y1 = Node1->Y;
 	double X2 = Node2->X;
@@ -107,90 +115,148 @@
 	double X = (X1 + X2) / 2;
 	double Y = (Y1 + Y2) / 2;
 
-	X = X - 1.1 * Dy;
-	Y = Y + 1.1 * Dx;
-	double R = sqrt(Dx * Dx + Dy * Dy);
-
-	TNode* TestNode = NodeList->FindByXY(X, Y, R);
-	if (TestNode != 0 && TestNode->Nr != Node1->Nr && TestNode->Nr != Node2->Nr)
+	int TestAnz = 0;
+	do
 	{
-		double CP = CrossProduct(Node1, Node2, TestNode);
-		if (CP > 0.0001)
-		{
-			NewNode = TestNode;
+		TestAnz++;
 
-			double cx = 0;
-			double cy = 0;
-			double cr = 0;
+		double SX = X - TestAnz * Dy;
+		double SY = Y + TestAnz * Dx;
 
-			CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
+		TestNode->X = SX;
+		TestNode->Y = SY;
 
-			TestNode = NodeList->FindByXY(cx, cy, sqrt(cr - 0.0001));
+		CircumCircle(Node1, Node2, TestNode, &cx, &cy, &cr);
 
-			if (TestNode != 0)
+		NodeList->FindAllByXY(FoundNodeList, cx, cy, sqrt(cr)+0.01);
+
+/*
+		if (FoundNodeList->size() <= 2)
+		{
+			// Da waren nur die beiden KantenKnoten drin
+			FoundNodeList->clear();
+		}
+*/
+
+		TNodeList::iterator i = FoundNodeList->begin();
+		while (i != FoundNodeList->end())
+		{
+			TNode* Node = *i;
+
+			if (Node->Nr == Node1->Nr)
 			{
-				NewNode = 0;
+				FoundNodeList->erase(i);
+				i = FoundNodeList->begin();
+				continue;
 			}
-			else
+			if (Node->Nr == Node2->Nr)
 			{
-				bool Stop = true;
+				FoundNodeList->erase(i);
+				i = FoundNodeList->begin();
+				continue;
 			}
+
+			double CP = CrossProduct(Node1, Node2, Node);
+			if (CP < 0.000001)
+			{
+				FoundNodeList->erase(i);
+				i = FoundNodeList->begin();
+				continue;
+			}
+			i++;
 		}
-	}
+	} while (TestAnz < 9 && FoundNodeList->size() == 0);
 
-	unsigned int i = 0;
 
-	if (NewNode == 0)
+	// Dann versuche ich es noch mal allen
+	if (FoundNodeList->size() == 0)
 	{
-		// Find a point to form a triangle
-		for (i = 0; i < NodeList->size(); i++)
+		for (TNodeList::iterator i = NodeList->begin(); i != NodeList->end(); i++)
 		{
-			TNode *TestNode = (*NodeList)[i];
+			TNode* Node = *i;
+			if (Node->Nr == Node1->Nr || Node->Nr == Node2->Nr) continue;
+			FoundNodeList->push_back(Node);
+		}
+	}
 
-			if (TestNode->Nr == Node1->Nr || TestNode->Nr == Node2->Nr) continue;
+	NewNode = 0;
+	TNodeList::iterator i = FoundNodeList->begin();
 
-			double CP = CrossProduct(Node1, Node2, TestNode);
+	while (i != FoundNodeList->end())
+	{
+		TNode* Node = *i++;
 
-			if (CP > 0.0001)
+		double CP = CrossProduct(Node1, Node2, Node);
+
+		if (CP > 0.0000001)
+		{
+			NewNode = Node;
+
+			if (NewNode->Nr == Node1->Nr || NewNode->Nr == Node2->Nr)
 			{
-				NewNode = TestNode;
-				break;
+				dump_error(__FILE__, __LINE__, "Der erste gefundene Knoten ist einer der Kanteknoten");
 			}
+
+			break;
 		}
+	}
 
+	if (NewNode != 0)
+	{
 		// Find best point to form a triangle
-		if (NewNode)
+
+		CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
+
+		while (i != FoundNodeList->end())
 		{
-			double cx = 0;
-			double cy = 0;
-			double cr = 0;
+			TNode* Node = *i;
 
-			CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
+			if (Node->Nr == Node1->Nr || Node->Nr == Node2->Nr)
+			{
+				dump_error(__FILE__, __LINE__, "Einer der gefundenen Knoten ist einer der Kanteknoten");
+			}
 
-			for (unsigned int j = i+1; j < NodeList->size(); j++)
+			if (Node->Nr != NewNode->Nr)
 			{
-				TNode* TestNode = (*NodeList)[j];
+				double CP = CrossProduct(Node1, Node2, Node);
 
-				if (TestNode->Nr == Node1->Nr || TestNode->Nr == Node2->Nr || TestNode->Nr == NewNode->Nr) continue;
-
-				double CP = CrossProduct(Node1, Node2, TestNode);
-
-				if (CP > 0.0001)
+				if (CP > 0.0000001)
 				{
-					double x = TestNode->X;
-					double y = TestNode->Y;
+					double X = Node->X;
+					double Y = Node->Y;
 
-					double dx = cx - x;
-					double dy = cy - y;
+					double Dx = cx - X;
+					double Dy = cy - Y;
 
-					if (dx * dx + dy * dy < cr)
+					if (Dx * Dx + Dy * Dy < cr)
 					{
-						NewNode = TestNode;
-
+						NewNode = Node;
 						CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
 					}
+					else if (Dx * Dx + Dy * Dy <= cr)
+					{
+						Edge = FindEdge(TodoEdgeList, Node, Node1);
+
+						if (Edge)
+						{
+							NewNode = Node;
+							CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
+						}
+						else
+						{
+							Edge = FindEdge(TodoEdgeList, Node2, Node);
+
+							if (Edge)
+							{
+								NewNode = Node;
+								CircumCircle(Node1, Node2, NewNode, &cx, &cy, &cr);
+							}
+						}
+					}
+
 				}
 			}
+			i++;
 		}
 	}
 
@@ -201,8 +267,6 @@
 		Element = new TElement(Node1, Node2, NewNode);
 		ElementList->push_back(Element);
 
-		TEdge *Edge;
-
 		// Richtung: Ist schon fertig
 		Edge = FindEdge(TodoEdgeList, Node2, NewNode);
 		if (Edge)
@@ -237,10 +301,15 @@
 }
 
 //---------------------------------------------------------------------
-bool	Triangulate(TNodeList *NodeList, TElementList *ElementList)
+bool	Triangulate(TNodeList *NodeList, TElementList *ElementList, bool Debug)
 {
 	write_fortschritt("->Netz wird trianguliert\n");
 
+	if (NodeList->size() < 3)
+	{
+		write_error(1234, "Es sind im DGM nur %d Knoten vorhanden.\nEs werden aber mindestens 3 Knoten benötigt\n", NodeList->size());
+	}
+
 	NodeList->SortByXY();
 
 	TEdgeList *TodoEdgeList = new TEdgeList;
@@ -269,15 +338,29 @@
 	{
 		CompleteFacet(NodeList, ElementList, TodoEdgeList);
 
+
+
+if (Debug)
+{
+	#include "file.h"
+	if (ElementList->size() % 50000 == 49999)
+	{
+/*
+		SaveNet("tmp.2dm", NodeList, ElementList);
+*/
+	}
+}
+
+
 		Anz++;
 
-		if (Anz % 500 == 0)
+		if (Anz % 5000 == 0)
 		{
 			ftime (&Now);
 			int NowMSec = Now.time * 1000 + Now.millitm;
 			int DiffMSec = NowMSec - StartMSec;
-			write_fortschritt("%d Done %d Todo %d Elemente)\n", Anz, TodoEdgeList->Anz, ElementList->size());
-			write_fortschritt("%.2f sec -> %.4f sec pro Kante\n", DiffMSec / 1000.0, DiffMSec / 1000.0 / Anz);
+			write_fortschritt("%d Kanten bearbeitet\n%d Kanten in der Warteschlange\n%d Elemente erzeugt\n", Anz, TodoEdgeList->Anz, ElementList->size());
+			if (Debug) write_fortschritt("%.2f sec -> %.4f sec pro Kante\n", DiffMSec / 1000.0, DiffMSec / 1000.0 / Anz);
 		}
 	}
 

Modified: trunk/src/tri.h
===================================================================
--- trunk/src/tri.h	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/tri.h	2006-03-13 23:53:00 UTC (rev 37)
@@ -22,7 +22,7 @@
 typedef enum { SUNDEFINED, SLEFT, SRIGHT, SUNIVERSE } TSide;
 
 //---------------------------------------------------------------------------
-bool	Triangulate(TNodeList* NodeList, TElementList *ElementList);
+bool	Triangulate(TNodeList* NodeList, TElementList *ElementList, bool Debug);
 
 //---------------------------------------------------------------------------
 #endif

Modified: trunk/src/wsplgen.cpp
===================================================================
--- trunk/src/wsplgen.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/wsplgen.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,7 +10,9 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
 //---------------------------------------------------------------------------
 #include <sys/stat.h>
@@ -24,12 +26,14 @@
 #include "tools.h"
 #include "xy.h"
 #include "file.h"
+#include "tri.h"
 
 int ReturnCode = 0;
 
 //---------------------------------------------------------------------------
 int main(int argc, char **argv)
 {
+/*
 	char StaFileName[] = "C:\\WSPLGEN\\WSPLGEN.STA";
 	char LogFileName[] = "C:\\WSPLGEN\\WSPLGEN.LOG";
 
@@ -41,49 +45,315 @@
 
 	close (newstdout);
 	close (newstderr);
+*/
 
 	write_fortschritt ("->WSPLGEN wurde gestartet\n");
 
+
+	// Hier werden alle Profile drin verwaltet
+	TProfilList ProfilList;
+
+	// Hier wird das aktuelle Begrenzungspolygon für den aktuellen Bereich drin verwaltet
+	TXYList Bereichspolygon;
+
+	// Hier werden dir Knoten des DGM drin verwaltet
+	// (und an andere Klassen in Form von Pointern ausgeliehen)
+	TNodeList NodeList;
+
+	// Hier werden die Elemente drin verwaltet
+	// Die Elemente werden aus ausgeliehenen Knoten gebildet
+	// Daher muss man immer erst die Knoten einlesen und dann die Elemente
+	// Eigentlich braucht man die Elemente nicht
+	TElementList ElementList;
+
+	// Hier werden die Gewaesserachsen drin verwaltet
+	TGewaesserAchseList GewaesserAchseList;
+
+	// Hier werden die Knoten verwaltet, die aus den Profilen generiert werden
+	TNodeList ProfilNodeList;
+
+	// Hier drin werden die Ergebnis Polygone drin verwaltet
+	TErgebnisPolygonList ErgebnisPolygonList;
+
+/*
+	LoadDGM("test_daten\\dgm_ziemlich_riesig.shp", NodeList, ElementList, 0, 99999999, true);
+	Triangulate (NodeList, ElementList, true);
+	SaveNet("test_daten\\dgm_ziemlich_riesig.2dm", NodeList, ElementList, true);
+*/
+
 	try
 	{
+		// Zuerst Parameter auswerten
+		// Die ausgewerteten Parameter stehen dann in dem Objekt Parameter bereit
 		TParameter Parameter(argc, argv);
 
-		TProfilList *ProfilList = new TProfilList;
+		// Jetzt die Profile einlesen
+		// Dabei wird die Stationierung in km in cm umgerechnet
+		LoadProfile(Parameter.FileNamePro, &ProfilList);
 
-		LoadProfile(Parameter.FileNamePro, ProfilList);
+		if (ProfilList.size() < 2)
+		{
+			write_error(3204, "Es liegen nur %d Querprofilspuren vor\nEs werden aber mindestens 2 Querprofilspuren benötigt.", ProfilList.size());
+		}
 
-		LoadWsp(Parameter.FileNameWsp, ProfilList);
+		// Jetzt die Waserstände einlesen und
+		// anschliessend gleich auf die Profile interpolieren
+		// Dabei wird die Stationierung von km in cm umgerechnet
 
+		TProfilList *WspProfilList = new TProfilList; // (ja, die Klasse TProfile wird jier kurz zweckentfremdet)
+		LoadWsp(Parameter.FileNameWsp, WspProfilList);
+		InterpolateWsp(&ProfilList, WspProfilList, Parameter.IsDebug);
+		delete WspProfilList;
+		WspProfilList = 0;
+
+		// Jetzt die Gewässerachse einlesen, wenn es notwendig ist
+		if (Parameter.Sperre)
+		{
+			LoadAchse(Parameter.FileNameAchse, &GewaesserAchseList);
+		}
+		else if (false == Parameter.Sperre)
+		{
+			write_warning(1123, "Parameter -ACHSE wird ignoriert, da der Parameter -SPERRE den Wert NOSPERRE hat\n");
+		}
+
+
+		// Jetzt die Profile nach Gewaessern trennen
+		TProfilMap ProfilMap = BuildGewaesserListen(&ProfilList, Parameter.IsDebug);
+
+		// Ungefähren Speicher ermitteln, als Grundlage für die Entscheidung
+		// Ob in Scheiben gearbeitet werden soll
 		size_t MaxMem = CheckMemory(Parameter.IsDebug);
 
-		long Flops = CheckSpeed(Parameter.IsDebug);
+		// Ungefähre Geschwindigkeit ermitteln, als Grundlage für die Entscheidung
+		// ob in Scheiben gearbeitet werden soll
+		int KFlops = CheckSpeed(Parameter.IsDebug) / 1000;
 
+		// Eine rein empirische Formel
+		// geteilt durch 2 Man bracht auch Speicher für was anderes
+		// geteilt durch 8 Byte per double
+		// geteilt durch x, y, z, und wsp
+		// geteilt durch 4, da man auch mal was anderes im Speicher braucht.
+		// ein Wert von 10000 ist ok, wenn Flops kleiner ist so sollten weniger Knoten verarbeitet werden ->
+		// geteilt durch (10000 / KFlops).
 
+		write_fortschritt("->Ermitteln der maximalen DGM-Knotenanzahl\n");
+		int MaxNodesPerSlice = (MaxMem / 2) / (8 * 4 * 4) / (10000 / KFlops);
+		write_fortschritt("Es können nur ca. %d DGM-Punkte eingelesen werden\n", MaxNodesPerSlice);
+		write_fortschritt("Ermitteln der maximalen DGM-Knotenanzahl beendet<-\n");
+
+		// Jetzt die Gewasser der Reihe nach bearbeiten
+		// Für jedes Gewaesser gibt es eine Profilliste in der ProfilMap
+		for (TProfilMap::iterator GewaesserIter = ProfilMap.begin(); GewaesserIter != ProfilMap.end(); GewaesserIter++)
+		{
+			std::string Gewaesser = GewaesserIter->first;
+
+			write_fortschritt("Gewässer '%s' wird bearbeitet\n", Gewaesser.c_str());
+
+			TProfilList *GewProfilList = GewaesserIter->second;
+
+			TProfil *FirstProfil = *GewProfilList->begin();
+			TProfil *LastProfil = *GewProfilList->rbegin();
+
+			if (GewProfilList->size() < 100)
+			{
+				double SollAbstand = (LastProfil->Station - FirstProfil->Station) / 100.0;
+				SollAbstand = (int)(SollAbstand * 10000.0 + 0.5) / 10000.0;
+
+				GewProfilList->InterpoliereProfile(SollAbstand);
+			}
+
+			// Mal wieder Zwischenergebnisse produzieren
+if (Parameter.IsDebug) SaveProfile("test_daten\\Profile_100_" + Gewaesser + ".shp", GewProfilList, Parameter.IsDebug);
+
+			// Jetzt ein Polygon bilden, das die Profile begrenzt
+			BuildPolygon(GewProfilList, &Bereichspolygon, Parameter.IsDebug);
+
+if (Parameter.IsDebug) SavePolygon("test_daten\\Polygon_" + Gewaesser + ".shp", Gewaesser, 0, 0, &Bereichspolygon);
+
+			unsigned int AnzScheiben = LoadDGM(Parameter.FileNameDgm, &NodeList, &ElementList, &Bereichspolygon, MaxNodesPerSlice, Parameter.IsDebug);
+
+			// Wenn LoadDGM eine Scheibenanzahl von mehr als 1 ergeben hat, ist das DGM nicht geladen,
+			// es muss jetzt mit Scheiben gearbeitet werden.
+			if (GewProfilList->size() < AnzScheiben + 1)
+			{
+				write_warning(3103, "Die Anzahl der gewünschten Bearbeitungsscheiben ist kleiner als die Anzahl der Profile");
+				AnzScheiben = GewProfilList->size() - 1;
+			}
+
+			TBereichsList BereichsList(GewProfilList, AnzScheiben);
+
+			for (TBereichsList::iterator i=BereichsList.begin(); i != BereichsList.end(); i++)
+			{
+				TProfilList::iterator Von = i->first;
+				TProfilList::iterator Bis = i->second;
+
+				TProfil *VonProfil = *Von;
+				TProfil *BisProfil = *Bis;
+
+char VC[100];
+char NC[100];
+
+sprintf (VC, "_Von%d", VonProfil->Station);
+sprintf (NC, "_Bis%d", BisProfil->Station);
+
+				write_fortschritt("->Bei Gewaesser %s wird der Bereich von %.4f bis %.4f bearbeitet\n", Gewaesser.c_str(), VonProfil->Station / 10000.0, BisProfil->Station / 10000.0);
+
+				// Als Endemarkierung
+				Bis++;
+
+				if (AnzScheiben > 1)
+				{
+					TProfilList *TempProfilList = new TProfilList;
+					for (TProfilList::iterator P = Von; P != Bis; P++)
+					{
+						TProfil *TempProfil = new TProfil(*P);
+						TempProfilList->insert(TempProfil);
+					}
+
+					// Jetzt das Polygon bilden, das die Profile begrenzen
+					BuildPolygon(TempProfilList, &Bereichspolygon, Parameter.IsDebug);
+
+if (Parameter.IsDebug) SavePolygon("test_daten\\Polygon_" + Gewaesser + VC + NC + ".shp", Gewaesser, 0, 0, &Bereichspolygon);
+
+					LoadDGM(Parameter.FileNameDgm, &NodeList, &ElementList, &Bereichspolygon, 99999999, Parameter.IsDebug);
+
+					delete TempProfilList;
+				}
+
+				// Wenn die Elementliste noch leer ist, müssen die Knoten noch trianguliert werden.
+				if (ElementList.size() == 0)
+				{
+					if (false == Triangulate (&NodeList, &ElementList, Parameter.IsDebug))	return (false);
+				}
+
+				NodeList.SortByNr();
+
+if (Parameter.IsDebug) SaveNet("test_daten\\Net_" + Gewaesser + VC + NC + ".2dm", &NodeList, &ElementList, true);
+if (Parameter.IsDebug) SaveNodes("test_daten\\Nodes_" + Gewaesser + VC + NC + ".shp", &NodeList, true);
+if (Parameter.IsDebug) SaveElements("test_daten\\Elements_" + Gewaesser + VC + NC + ".shp", &ElementList, true);
+
+				// Aus den Elementen werden nun die Kanten gebildet
+				// Hier ist noch Optimierungspotential
+				// Man kann auch gleich die Kanten erzeugen statt der Elemente
+				// Der durchschnittliche Abstand der Knoten (bzw. die Kantenlänge) wird dabei mit ermittelt.
+				// Das DGM sollte einigermassen homogen sein
+
+				// Hier werden die Kanten drin verwaltet
+				// Die Kanten werden im Moment noch aus den Elementen generiert
+				// Dieser Umweg ist eingetlich nocht notwendig
+				TEdgeList* EdgeList = new TEdgeList;
+				BuildEdgeList(EdgeList, &ElementList, Parameter.IsDebug);
+
+				// Die Elemete werden nun nicht mehr gebraucht
+				ElementList.Clear();
+
+if (Parameter.IsDebug) SaveEdges("test_daten\\Edges_" + Gewaesser + VC + NC + ".shp", EdgeList, Parameter.IsDebug);
+
+				// Nachdem die durchschnittliche Kantenlänge bekannt ist,
+				// wird sie für die spätere Verwendung zwischengespeichert
+				double AvgDistance = EdgeList->AvgDistance;
+
+				if (Parameter.IsDebug)	write_fortschritt("Die mittlere Kantenlänge beträgt %.2f.\n", AvgDistance);
+
+				// Nachdem die durchschnittliche Kantenlänge bekannt ist,
+				// werden die Profile entsprechend fein interpoliert
+				// Dabei muss der Faktor zwischen Kantenlänge in Metern
+				// und Station in Centimetern beachtet werden
+				GewProfilList->InterpoliereProfile(AvgDistance * 10);
+
+				// Mal wieder Zwischenergebnisse produzieren
+if (Parameter.IsDebug) SaveProfile("test_daten\\Profile_all_" + Gewaesser + VC + NC + ".shp", GewProfilList, Parameter.IsDebug);
+
+				// Jetzt die Stützstellen auffüllen
+				GewProfilList->FillProfile(AvgDistance, Parameter.IsDebug);
+
+				// Mal wieder Zwischenergebnisse produzieren
+if (Parameter.IsDebug) SaveProfile("test_daten\\Profile_fill_" + Gewaesser + VC + NC + ".shp", GewProfilList, Parameter.IsDebug);
+
+				// Jetzt eine neue Knotenliste aus den Profilen generienen
+				BuildProfilNodeList(GewProfilList, &NodeList, &GewaesserAchseList, &ProfilNodeList, AvgDistance, Parameter.Sperre, Parameter.IsDebug);
+
+if (Parameter.IsDebug) SaveNodes("test_daten\\ProfilNodes_" + Gewaesser + VC + NC + ".shp", &ProfilNodeList, true);
+
+				// Jetzt die Wasserstände übertragen
+				TransferWsp(&ProfilNodeList, &NodeList, AvgDistance, Parameter.IsDebug);
+
+				ProfilNodeList.Clear();
+
+if (Parameter.IsDebug) SaveNodes("test_daten\\Nodes_mitWSP_" + Gewaesser + VC + NC + ".shp", &NodeList, true);
+
+				// Den alten Knoten Kanten Index löschen
+				NodeList.ClearEdgeIndex();
+
+				// Einen neuen Knoten Kanten Index aufbauen
+				EdgeList->BuildEdgeIndex();
+
+				TErgebnisPolygonList* TempErgebnisPolygone = new TErgebnisPolygonList;
+				NassTrockenBerechnung(Parameter.FileNameAusgabe + Gewaesser + VC + NC + ".shp", &NodeList, EdgeList, TempErgebnisPolygone, Parameter.Von, Parameter.Bis, Parameter.Diff, Parameter.IsDebug);
+
+				for (TErgebnisPolygonList::iterator i = TempErgebnisPolygone->begin(); i != TempErgebnisPolygone->end(); i++)
+				{
+					TErgebnisPolygon* ErgebnisPolygon = *i;
+
+					ErgebnisPolygon->Gewaesser = Gewaesser;
+					ErgebnisPolygon->VonKm = VonProfil->Station / 10000.0;
+					ErgebnisPolygon->BisKm = BisProfil->Station / 10000.0;
+				}
+
+				ErgebnisPolygonList.Append(TempErgebnisPolygone);
+
+				TempErgebnisPolygone->clear();
+				delete TempErgebnisPolygone;
+
+if (Parameter.IsDebug) SavePolygone(Parameter.FileNameAusgabe, &ErgebnisPolygonList, Parameter.IsDebug);
+
+				// Löscht nur die Verwaltung und nicht die Knoten der Kanten,
+				// die Knoten waren nur geliehen
+				EdgeList->Empty();
+
+				write_fortschritt("Der Bereich von %.4f bis %.4f wurde bei Gewässer %s bearbeitet\n", VonProfil->Station / 10000.0, BisProfil->Station / 10000.0, Gewaesser.c_str());
+			}
+		}
+
+		// Speichern der Ergenispolygone
+		SavePolygone(Parameter.FileNameAusgabe, &ErgebnisPolygonList, Parameter.IsDebug);
+
+		for (TProfilMap::iterator i = ProfilMap.begin(); i != ProfilMap.end(); i++)
+		{
+			TProfilList* GewProfilList = i->second;
+			// Hier muss ich das kleingeschriebene clear benutzen, da ich sonst die
+			// Profile selbst mit löschen würde
+			// Sie sind aber nur geliehen, um sie anders zu sortieren.
+			// Der Speicher darf nicht freigegeben werden.
+			// Der Speicher für die Verwaltung der ProfilList muss aber freigegeben werden !
+			// Deshalb erst alle Profile rausschmeissen (clear) und DANN ProfilList löschen (delete)
+			// Das ProfilMap wird automatisch am Ende zerstört, da es nur lokal war
+			GewProfilList->clear();
+			delete GewProfilList;
+		}
 	}
 	catch (TFehler fehler)
 	{
-		close (fileno(stdout));
-		close (fileno(stderr));
-
-		return (ReturnCode);
+		printf ("Unbekannter Fehler wurde korrekt abgefangen\n");
+		printf ("Programmabbruch\n");
 	}
 	catch (...)
 	{
 		printf ("Unbekannter Fehler nicht korrekt abgefangen\n");
 		printf ("Programmabbruch\n");
 
-		close (fileno(stdout));
-		close (fileno(stderr));
-
-		return (9299);
+		ReturnCode = 9299;
 	}
 
 	write_fortschritt ("WSPLGEN wird beendet<-\n");
 
+/*
 	close (fileno(stdout));
 	close (fileno(stderr));
+*/
 
 	return (ReturnCode);
 }
 //---------------------------------------------------------------------------
 
+

Deleted: trunk/src/wsplgen.h
===================================================================

Modified: trunk/src/xy.cpp
===================================================================
--- trunk/src/xy.cpp	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/xy.cpp	2006-03-13 23:53:00 UTC (rev 37)
@@ -10,8 +10,11 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
+#ifdef __BORLANDC__
 #pragma hdrstop
+#endif
 
+//---------------------------------------------------------------------------
 #include <algorithm>
 #include <math.h>
 #include "tools.h"
@@ -89,11 +92,19 @@
 TNode::TNode(int nr, double x, double y, double z) : TXYZ (x, y, z)
 {
 	Nr = nr;
-	Wsp = 0.0;
+	Wsp = -9999.9;
 	EdgeIndex = 0;
 }
 
 //---------------------------------------------------------------------
+TNode::TNode(int nr, double x, double y, double z, double wsp) : TXYZ (x, y, z)
+{
+	Nr = nr;
+	Wsp = wsp;
+	EdgeIndex = 0;
+}
+
+//---------------------------------------------------------------------
 TNode::TNode(TNode *node) : TXYZ (node->X, node->Y, node->Z)
 {
 	Nr = node->Nr;
@@ -121,6 +132,19 @@
 }
 
 //---------------------------------------------------------------------
+struct TNodeSortByX
+{
+	 bool operator()(TNode* const &Node1, TNode* const &Node2)
+	 {
+		  if (Node1->X < Node2->X)	return (true);
+		  if (Node1->X > Node2->X)	return (false);
+		  if (Node1->Y < Node2->Y)	return (true);
+		  if (Node1->Y > Node2->Y)	return (false);
+		  return (false);
+	 }
+};
+
+//---------------------------------------------------------------------
 struct TNodeSortByXY
 {
 	 bool operator()(TNode* const &Node1, TNode* const &Node2)
@@ -143,26 +167,24 @@
 //---------------------------------------------------------------------
 
 //---------------------------------------------------------------------
-TPoint::TPoint(double x, double y, double meter) : TXY (x, y)
+TPoint::TPoint(double x, double y, double meter) : TXYZ (x, y)
 {
 	Meter = meter;
 }
 
 //---------------------------------------------------------------------
-TPoint::TPoint(TPoint *point) : TXY (point->X, point->Y)
+TPoint::TPoint(double x, double y, double z, double meter) : TXYZ (x, y, z)
 {
-	Meter = point->Meter;
+	Meter = meter;
 }
 
 //---------------------------------------------------------------------
-struct TPointSortByMeter
+TPoint::TPoint(TPoint *point) : TXYZ (point->X, point->Y, point->Z)
 {
-	 bool operator()(TPoint* const &Point1, TPoint* const &Point2)
-	 {
-		  return(Point1->Meter < Point2->Meter);
-	 }
-};
+	Meter = point->Meter;
+}
 
+
 //---------------------------------------------------------------------
 // TElement
 //---------------------------------------------------------------------
@@ -174,9 +196,9 @@
 
 	NodeList = new TNodeList();
 
-	NodeList->push_back(new TNode(Node1));
-	NodeList->push_back(new TNode(Node2));
-	NodeList->push_back(new TNode(Node3));
+	NodeList->push_back(Node1);
+	NodeList->push_back(Node2);
+	NodeList->push_back(Node3);
 }
 
 //---------------------------------------------------------------------
@@ -186,10 +208,10 @@
 
 	NodeList = new TNodeList();
 
-	NodeList->push_back(new TNode(Node1));
-	NodeList->push_back(new TNode(Node2));
-	NodeList->push_back(new TNode(Node3));
-	NodeList->push_back(new TNode(Node4));
+	NodeList->push_back(Node1);
+	NodeList->push_back(Node2);
+	NodeList->push_back(Node3);
+	NodeList->push_back(Node4);
 }
 
 //---------------------------------------------------------------------
@@ -197,23 +219,24 @@
 {
 	Typ = element->Typ;
 
-	for (unsigned int i = 0; i < NodeList->size(); i++)
+	for (TNodeList::iterator i = element->NodeList->begin(); i != element->NodeList->end(); i++)
 	{
-		TNodeList *NL = element->NodeList;
-		TNode* Node = new TNode((*NL)[i]);
-
-		NodeList->push_back(Node);
+		NodeList->push_back(*i);
 	}
 }
 
 //---------------------------------------------------------------------
 TElement::~TElement(void)
 {
+	// Hier muss man das kleine clear verwenden da
+	// die Knoten alle nur geliehen sind
+	// und sonst mit zerstört würden
+	NodeList->clear();
 	delete NodeList;
 }
 
 //---------------------------------------------------------------------
-TInsideTyp TElement::IsInElement(double X, double Y)
+TInsideTyp TElement::IsInsideElement(double X, double Y)
 {
 
 	int alpha = IsInside(NodeList, X, Y);
@@ -236,6 +259,10 @@
 TXYList::TXYList(void)
 {
 	XYKombiIndex = 0;
+	MinX = 0.0;
+	MaxX = 0.0;
+	MinY = 0.0;
+	MaxY = 0.0;
 }
 
 //---------------------------------------------------------------------------
@@ -256,6 +283,11 @@
 		delete Xy;
 	}
 	clear();
+
+	MinX = 0.0;
+	MaxX = 0.0;
+	MinY = 0.0;
+	MaxY = 0.0;
 }
 
 //---------------------------------------------------------------------
@@ -269,6 +301,11 @@
 		TXY *NewXy = new TXY(OldXy);
 		NewXyList->push_back(NewXy);
 	}
+	NewXyList->MinX = MinX;
+	NewXyList->MaxX = MaxX;
+	NewXyList->MinY = MinY;
+	NewXyList->MaxY = MaxY;
+
 	return(NewXyList);
 }
 
@@ -289,9 +326,6 @@
 
 	int Index = XYKombiIndex->Search(this, X, Y, Eps);
 
-
-
-
 	if (Index >= 0)
 	{
 		TXY *Xy = (* this)[Index];
@@ -335,6 +369,61 @@
 }
 
 //---------------------------------------------------------------------
+TInsideTyp TXYList::IsInsideXYList(double X, double Y)
+{
+	if (X < MinX || X > MaxX || Y < MinY || Y > MaxY)	return (NOT_INSIDE);
+
+	int alpha = IsInside(this, X, Y);
+
+	if (alpha == 0)		return (NOT_INSIDE);  // not inside
+	if (alpha == 4)		return (INSIDE);   // inside
+	if (alpha == -4)	return (INSIDE);   // inside
+	if (alpha == -1)	return (ON_LINE);   // on line
+	if (alpha == 2)	    return (ON_LINE);   // on line twisted
+	if (alpha == -2)    return (ON_LINE);   // on line twisted
+
+	dump_error(__FILE__, __LINE__, "Alpha (%d) ungültig\n", alpha);
+
+	return (UNDEFINED);
+}
+
+//---------------------------------------------------------------------
+void TXYList::Add(TXY *Xy)
+{
+	push_back(Xy);
+
+	if (size() == 1)
+	{
+		MinX = Xy->X;
+		MaxX = Xy->X;
+		MinY = Xy->Y;
+		MaxY = Xy->Y;
+	}
+	else
+	{
+		if (MinX > Xy->X) MinX = Xy->X;
+		if (MaxX < Xy->X) MaxX = Xy->X;
+		if (MinY > Xy->Y) MinY = Xy->Y;
+		if (MaxY < Xy->Y) MaxY = Xy->Y;
+	}
+}
+
+//---------------------------------------------------------------------
+void TXYList::Add(double X, double Y)
+{
+	TXY *Xy = new TXY(X, Y);
+	Add(Xy);
+}
+
+TErgebnisPolygon::TErgebnisPolygon(double diff)
+{
+	Gewaesser = "dummy";
+	VonKm = 0.0;
+	BisKm = 0.0;
+	Diff = diff;
+}
+
+//---------------------------------------------------------------------
 // TXYZList
 //---------------------------------------------------------------------
 
@@ -342,6 +431,10 @@
 TXYZList::TXYZList(void)
 {
 	XYKombiIndex = 0;
+	MinX = 0.0;
+	MaxX = 0.0;
+	MinY = 0.0;
+	MaxY = 0.0;
 }
 
 //---------------------------------------------------------------------------
@@ -362,6 +455,11 @@
 		delete Xyz;
 	}
 	clear();
+
+	MinX = 0.0;
+	MaxX = 0.0;
+	MinY = 0.0;
+	MaxY = 0.0;
 }
 
 //---------------------------------------------------------------------
@@ -375,6 +473,12 @@
 		TXYZ *NewXyz = new TXYZ(OldXyz);
 		NewXyzList->push_back(NewXyz);
 	}
+
+	NewXyzList->MinX = MinX;
+	NewXyzList->MaxX = MaxX;
+	NewXyzList->MinY = MinY;
+	NewXyzList->MaxY = MaxY;
+
 	return(NewXyzList);
 }
 
@@ -438,6 +542,34 @@
 }
 
 //---------------------------------------------------------------------
+void TXYZList::Add(TXYZ *Xyz)
+{
+	push_back(Xyz);
+
+	if (size() == 1)
+	{
+		MinX = Xyz->X;
+		MaxX = Xyz->X;
+		MinY = Xyz->Y;
+		MaxY = Xyz->Y;
+	}
+	else
+	{
+		if (MinX > Xyz->X) MinX = Xyz->X;
+		if (MaxX < Xyz->X) MaxX = Xyz->X;
+		if (MinY > Xyz->Y) MinY = Xyz->Y;
+		if (MaxY < Xyz->Y) MaxY = Xyz->Y;
+	}
+}
+
+//---------------------------------------------------------------------
+void TXYZList::Add(double X, double Y, double Z)
+{
+	TXYZ *Xyz = new TXYZ(X, Y, Z);
+	Add(Xyz);
+}
+
+//---------------------------------------------------------------------
 // TNodeList
 //---------------------------------------------------------------------
 
@@ -482,6 +614,12 @@
 }
 
 //---------------------------------------------------------------------
+void TNodeList::SortByX(void)
+{
+	std::sort(this->begin(), this->end(), TNodeSortByX());
+}
+
+//---------------------------------------------------------------------
 void TNodeList::SortByXY(void)
 {
 	std::sort(this->begin(), this->end(), TNodeSortByXY());
@@ -526,6 +664,7 @@
 
 	return (0);
 }
+
 //---------------------------------------------------------------------
 TNode* TNodeList::FindByXY(double X, double Y, double R)
 {
@@ -536,17 +675,9 @@
 
 	if (size() <= 0) return (0);
 
-/*
-	if (X - R <= 0) R = X;
-	if (Y - R <= 0) R = Y;
-*/
-
 	int Index = XYKombiIndex->Search(this, X, Y, R);
 
-
-
-
-
+/*
 	if (Index >= 0)
 	{
 		TNode *Node = (* this)[Index];
@@ -579,9 +710,8 @@
 		}
 		return (0);
 	}
-
-
-
+*/
+  
 	if (Index < 0)  return (0);
 
 	TNode *Node = (* this)[Index];
@@ -590,6 +720,243 @@
 }
 
 //---------------------------------------------------------------------
+void TNodeList::FindAllByXY(TNodeList *SearchNodeList, double X, double Y, double R)
+{
+	// Wichtig ist das kleingeschriebene clear
+	// In dieser Nodelist sind villeicht Knoten drin, die nur geliehen sind.
+	// Die Knoten selbst sollen nicht gelöscht werden
+
+	SearchNodeList->clear();
+
+	if (size() != XYKombiIndex->Anzahl)
+	{
+		dump_error(__FILE__, __LINE__, "Knotenanzahl (%d) und XYKombiIndex-Anzahl (%d) stimmen nicht überein", size(), XYKombiIndex->Anzahl);
+	}
+
+	if (size() <= 0) return;
+
+	std::vector<int> NodeIndexList;
+
+	XYKombiIndex->SearchAll(&NodeIndexList, this, X, Y, R);
+
+	for (unsigned int i = 0; i<NodeIndexList.size(); i++)
+	{
+		int Index = NodeIndexList[i];
+		TNode *Node = (* this)[Index];
+
+		SearchNodeList->push_back(Node);
+	}
+}
+
+//---------------------------------------------------------------------
+bool TNodeList::Interpolate(double X, double Y, double R, double *ZWert, double *WspWert)
+{
+	TNodeList *SearchNodeList = new TNodeList;
+
+	if (size() != XYKombiIndex->Anzahl)
+	{
+		dump_error(__FILE__, __LINE__, "Knotenanzahl (%d) und XYKombiIndex-Anzahl (%d) stimmen nicht überein", size(), XYKombiIndex->Anzahl);
+	}
+
+	FindAllByXY(SearchNodeList, X, Y, R);
+
+	TNode* TLNode = 0;
+	double TLD = 0.0;
+
+	TNode* BLNode = 0;
+	double BLD = 0.0;
+
+	TNode* TRNode = 0;
+	double TRD = 0.0;
+
+	TNode* BRNode = 0;
+	double BRD = 0.0;
+
+	for (TNodeList::iterator i = SearchNodeList->begin(); i != SearchNodeList->end(); i++)
+	{
+		TNode* Node = *i;
+
+		if (Node->X == X && Node->Y == Y)
+		{
+			*ZWert = Node->Z;
+			*WspWert = Node->Wsp;
+
+			return (true);
+		}
+
+		if (Node->X >= X && Node->Y > Y)
+		{
+			if (0 == TRNode)
+			{
+				TRNode = Node;
+				double Dx = TRNode->X - X;
+				double Dy = TRNode->Y - Y;
+
+				TRD = Dx*Dx + Dy*Dy;
+				continue;
+			}
+			else
+			{
+				double Dx = Node->X - X;
+				double Dy = Node->Y - Y;
+
+				double D = Dx*Dx + Dy*Dy;
+
+				if (D < TRD)
+				{
+					TRNode = Node;
+					TRD = D;
+				}
+			}
+			continue;
+		}
+
+		if (Node->X < X && Node->Y >= Y)
+		{
+			if (0 == TLNode)
+			{
+				TLNode = Node;
+				double Dx = TLNode->X - X;
+				double Dy = TLNode->Y - Y;
+
+				TLD = Dx*Dx + Dy*Dy;
+				continue;
+			}
+			else
+			{
+				double Dx = Node->X - X;
+				double Dy = Node->Y - Y;
+
+				double D = Dx*Dx + Dy*Dy;
+
+				if (D < TLD)
+				{
+					TLNode = Node;
+					TLD = D;
+				}
+			}
+			continue;
+		}
+
+		if (Node->X <= X && Node->Y < Y)
+		{
+			if (0 == BLNode)
+			{
+				BLNode = Node;
+				double Dx = BLNode->X - X;
+				double Dy = BLNode->Y - Y;
+
+				BLD = Dx*Dx + Dy*Dy;
+				continue;
+			}
+			else
+			{
+				double Dx = Node->X - X;
+				double Dy = Node->Y - Y;
+
+				double D = Dx*Dx + Dy*Dy;
+
+				if (D < BLD)
+				{
+					BLNode = Node;
+					BLD = D;
+				}
+			}
+			continue;
+		}
+
+		if (Node->X > X && Node->Y <= Y)
+		{
+			if (0 == BRNode)
+			{
+				BRNode = Node;
+				double Dx = BRNode->X - X;
+				double Dy = BRNode->Y - Y;
+
+				BRD = Dx*Dx + Dy*Dy;
+				continue;
+			}
+			else
+			{
+				double Dx = Node->X - X;
+				double Dy = Node->Y - Y;
+
+				double D = Dx*Dx + Dy*Dy;
+
+				if (D < BRD)
+				{
+					BRNode = Node;
+					BRD = D;
+				}
+			}
+			continue;
+		}
+	}
+
+	int Anzahl = 0;
+	double Summe = 0.0;
+	if (TLNode != 0)
+	{
+		TLD = sqrt(TLD);
+		Summe = Summe + 1 / TLD;
+		Anzahl++;
+	}
+	if (TRNode != 0)
+	{
+		TRD = sqrt(TRD);
+		Summe = Summe + 1 / TRD;
+		Anzahl++;
+	}
+	if (BLNode != 0)
+	{
+		BLD = sqrt(BLD);
+		Summe = Summe + 1 / BLD;
+		Anzahl++;
+	}
+	if (BRNode != 0)
+	{
+		BRD = sqrt(BRD);
+		Summe = Summe + 1 / BRD;
+		Anzahl++;
+	}
+
+	if (Anzahl > 0)
+	{
+		double Z = 0.0;
+
+		if (TLNode != 0) Z = Z +  1 / TLD / Summe * TLNode->Z;
+		if (TRNode != 0) Z = Z +  1 / TRD / Summe * TRNode->Z;
+		if (BLNode != 0) Z = Z +  1 / BLD / Summe * BLNode->Z;
+		if (BRNode != 0) Z = Z +  1 / BRD / Summe * BRNode->Z;
+
+		*ZWert = Z;
+
+		double Wsp = 0.0;
+
+		if (TLNode != 0) Wsp = Wsp +  1 / TLD / Summe * TLNode->Wsp;
+		if (TRNode != 0) Wsp = Wsp +  1 / TRD / Summe * TRNode->Wsp;
+		if (BLNode != 0) Wsp = Wsp +  1 / BLD / Summe * BLNode->Wsp;
+		if (BRNode != 0) Wsp = Wsp +  1 / BRD / Summe * BRNode->Wsp;
+
+		*WspWert = Wsp;
+
+		return (true);
+	}
+
+	return (false);
+}
+
+//---------------------------------------------------------------------
+void TNodeList::ClearEdgeIndex(void)
+{
+	for (iterator i = begin(); i != end(); i++)
+	{
+		TNode *Node = *i;
+		Node->ClearEdgeIndex();
+	}
+}
+
+//---------------------------------------------------------------------
 // TElementList
 //---------------------------------------------------------------------
 
@@ -602,9 +969,9 @@
 //---------------------------------------------------------------------
 void TElementList::Clear(void)
 {
-	for (unsigned int i=0; i<size(); i++)
+	for (TElementList::iterator i=begin(); i != end(); i++)
 	{
-		TElement *Element = (*this)[i];
+		TElement *Element = *i;
 		delete Element;
 	}
 	clear();
@@ -615,64 +982,105 @@
 //---------------------------------------------------------------------
 
 //---------------------------------------------------------------------------
-TPolygonList::~TPolygonList(void)
+TErgebnisPolygonList::~TErgebnisPolygonList(void)
 {
 	Clear();
 }
 
 //---------------------------------------------------------------------
-void TPolygonList::Clear(void)
+void TErgebnisPolygonList::Clear(void)
 {
-	for (unsigned int i=0; i<size(); i++)
+	for (TErgebnisPolygonList::iterator i=begin(); i!=end(); i++)
 	{
-		TXYList *XyList = (*this)[i];
-		XyList->Clear();
-		delete XyList;
+		TErgebnisPolygon *ErgebnisPolygon = *i;
+		delete ErgebnisPolygon;
 	}
 	clear();
 }
 
 //---------------------------------------------------------------------
-TPolygonList* TPolygonList::Copy(void)
+TErgebnisPolygonList* TErgebnisPolygonList::Copy(void)
 {
-	TPolygonList *NewPolygonList = new TPolygonList;
+	TErgebnisPolygonList *NewErgebnisPolygonList = new TErgebnisPolygonList;
 
 	for (unsigned int i=0; i<size(); i++)
 	{
-		TXYList *OldXyList = (*this)[i];
+		TErgebnisPolygon *OldErgebnisPolygon = (*this)[i];
 
-		TXYList *NewXyList = new TXYList();
+		TErgebnisPolygon *NewErgebnisPolygon = new TErgebnisPolygon(OldErgebnisPolygon->Diff);
 
-		for (unsigned int j=0; j<OldXyList->size(); j++)
+		NewErgebnisPolygon->Gewaesser = OldErgebnisPolygon->Gewaesser;
+		NewErgebnisPolygon->VonKm = OldErgebnisPolygon->VonKm;
+		NewErgebnisPolygon->BisKm = OldErgebnisPolygon->BisKm;
+
+		for (unsigned int j=0; j<OldErgebnisPolygon->size(); j++)
 		{
-			TXY *OldXy = (*OldXyList)[j];
+			TXY *OldXy = (*OldErgebnisPolygon)[j];
 			TXY *NewXy = new TXY(OldXy);
 
-			NewXyList->push_back(NewXy);
+			NewErgebnisPolygon->push_back(NewXy);
 		}
 
-		NewPolygonList->push_back(NewXyList);
+		NewErgebnisPolygon->MinX = OldErgebnisPolygon->MinX;
+		NewErgebnisPolygon->MaxX = OldErgebnisPolygon->MaxX;
+		NewErgebnisPolygon->MinY = OldErgebnisPolygon->MinY;
+		NewErgebnisPolygon->MaxY = OldErgebnisPolygon->MaxY;
+
+		NewErgebnisPolygonList->push_back(NewErgebnisPolygon);
 	}
 
-	return(NewPolygonList);
+	return(NewErgebnisPolygonList);
 }
 
 //---------------------------------------------------------------------
-TXYList* TPolygonList::First(void)
+void TErgebnisPolygonList::Append(TErgebnisPolygonList *AddErgebnisPolygonList)
 {
+	for (TErgebnisPolygonList::iterator i = AddErgebnisPolygonList->begin(); i != AddErgebnisPolygonList->end(); i++)
+	{
+		TErgebnisPolygon *AddErgebnisPolygon = *i;
+		push_back(AddErgebnisPolygon);
+	}
+}
+
+//---------------------------------------------------------------------
+TErgebnisPolygon* TErgebnisPolygonList::First(void)
+{
 	if (size() <= 0) return (0);
 
-	TXYList *XYList = this->front();
+	TErgebnisPolygon *ErgebnisPolygon = this->front();
 
-	return (XYList);
+	return (ErgebnisPolygon);
 }
 
 //---------------------------------------------------------------------
+TInsideTyp TErgebnisPolygonList::IsInsidePolygonList(double X, double Y)
+{
+
+	for (TErgebnisPolygonList::iterator i = begin(); i != end(); i++)
+	{
+		TErgebnisPolygon* Polygon = *i;
+
+		int alpha = IsInside(Polygon, X, Y);
+
+		if (alpha == 0)		continue;  			// not inside -> versuche das nächste Polygon
+		if (alpha == 4)		return (INSIDE);    // inside
+		if (alpha == -4)	return (INSIDE);    // inside
+		if (alpha == -1)	return (ON_LINE);   // on line
+		if (alpha == 2)	    return (ON_LINE);   // on line twisted
+		if (alpha == -2)    return (ON_LINE);   // on line twisted
+
+		dump_error(__FILE__, __LINE__, "Alpha (%d) ungültig\n", alpha);
+	}
+
+	return (NOT_INSIDE);
+}
+
+//---------------------------------------------------------------------
 // TEdge
 //---------------------------------------------------------------------
 
 //---------------------------------------------------------------------
-TEdge::TEdge(TNode *node1, TNode *node2, TNode *triNode)
+TEdge::TEdge(TNode *node1, TNode *node2)
 {
 	if (node1->Nr < 0)
 	{
@@ -716,8 +1124,6 @@
 	Y = 0.0;
 	Ready = false;
 	IsBoundary = false;
-
-	TriNode = triNode;
 }
 
 //---------------------------------------------------------------------
@@ -731,36 +1137,11 @@
 	Y = Edge->Y;
 	Ready = Edge->Ready;
 	IsBoundary = Edge->IsBoundary;
-
-	TriNode = Edge->TriNode;
 }
 
 //---------------------------------------------------------------------
-struct TEdgeSortByNr
-{
-	 bool operator()(TEdge* const &Edge1, TEdge* const &Edge2)
-	 {
-		if      (Edge1->Node1->Nr < Edge2->Node1->Nr)   return(true);
-		else if (Edge1->Node1->Nr > Edge2->Node1->Nr)   return(false);
-		else if (Edge1->Node2->Nr < Edge2->Node2->Nr)   return(true);
-		else if (Edge1->Node2->Nr > Edge2->Node2->Nr)   return(false);
 
-		return (0);
-	 }
-};
-
 //---------------------------------------------------------------------
-struct TEdgeSortByDistance
-{
-	 bool operator()(TEdge* const &Edge1, TEdge* const &Edge2)
-	 {
-		return (Edge1->Distance < Edge2->Distance);
-	 }
-};
-
-//---------------------------------------------------------------------
-
-//---------------------------------------------------------------------
 // TEdgeList
 //---------------------------------------------------------------------
 
@@ -768,12 +1149,22 @@
 TEdgeList::TEdgeList(void)
 {
 	Anz = 0;
+	AvgDistance = 0.0;
+
+	// Nur als Hüllen für das Suchen nach Kanten
+	SearchNode1 = new TNode(0, 1, 1, 1);
+	SearchNode2 = new TNode(0, 2, 2, 2);
+	SearchEdge = new TEdge(SearchNode1, SearchNode2);
 }
 
 //---------------------------------------------------------------------
 TEdgeList::~TEdgeList(void)
 {
 	Clear();
+
+	delete SearchEdge;
+	delete SearchNode1;
+	delete SearchNode2;
 }
 
 //---------------------------------------------------------------------
@@ -789,32 +1180,51 @@
 	{
 		dump_error(__FILE__, __LINE__, "Anz der Kanten ist nicht 0");
 	}
+
+	AvgDistance = 0.0;
+
 	EdgeListNrSorted.clear();
 	EdgeListDistanceSorted.clear();
 }
 
 //---------------------------------------------------------------------
-TEdge* TEdgeList::First(void)
+void TEdgeList::Empty(void)
 {
-	if (Anz == 0)
+	for (TEdgeListNrSorted::const_iterator i = EdgeListNrSorted.begin(); i != EdgeListNrSorted.end(); i++)
 	{
-		return(0);
+		Anz--;
 	}
 
-	if (EdgeListNrSorted.size() == 0)
+	if (Anz != 0)
 	{
+		dump_error(__FILE__, __LINE__, "Anz der Kanten ist nicht 0");
+	}
+
+	AvgDistance = 0.0;
+
+	EdgeListNrSorted.clear();
+	EdgeListDistanceSorted.clear();
+}
+
+//---------------------------------------------------------------------
+TEdge* TEdgeList::First(void)
+{
+	if (Anz == 0) return(0);
+
+//	if (EdgeListNrSorted.size() == 0)
+	if (EdgeListDistanceSorted.size() == 0)
+	{
 		dump_error(__FILE__, __LINE__, "Da ist nichts mehr drin");
 	}
 
-	TEdgeListNrSorted::iterator NrIt = EdgeListNrSorted.begin();
+//	TEdgeListNrSorted::iterator It = EdgeListNrSorted.begin();
+	TEdgeListDistanceSorted::iterator It = EdgeListDistanceSorted.begin();
 
 	TEdge *Edge = 0;
-	if (NrIt != EdgeListNrSorted.end())	Edge = *NrIt;
+//	if (It != EdgeListNrSorted.end())	Edge = *It;
+	if (It != EdgeListDistanceSorted.end())	Edge = *It;
 
-	if (Edge == 0)
-	{
-		dump_error(__FILE__, __LINE__, "Erste Kante ist 0");
-	}
+	if (Edge == 0) dump_error(__FILE__, __LINE__, "Erste Kante ist 0");
 	return (Edge);
 }
 
@@ -822,7 +1232,9 @@
 void TEdgeList::Add(TEdge *edge)
 {
 	EdgeListNrSorted.insert(edge);
+	AvgDistance = AvgDistance * Anz;
 	Anz++;
+	AvgDistance = (AvgDistance + edge->Distance) / Anz;
 
 	if (Anz != EdgeListNrSorted.size())
 	{
@@ -834,6 +1246,16 @@
 }
 
 //---------------------------------------------------------------------
+TEdge* TEdgeList::Add(TNode *Node1, TNode *Node2)
+{
+	TEdge *NewEdge = new TEdge(Node1, Node2);
+
+	Add(NewEdge);
+
+	return (NewEdge);
+}
+
+//---------------------------------------------------------------------
 void TEdgeList::Erase(TEdge *edge)
 {
 	if (Anz == 0)
@@ -843,7 +1265,7 @@
 
 	TEdgeListNrSorted::iterator NrIt = EdgeListNrSorted.find(edge);
 
-	
+
 	TEdgeListDistanceSorted::iterator DistanceIt = EdgeListDistanceSorted.find(edge);
 
 	TEdge *Edge1 = *NrIt;
@@ -854,12 +1276,14 @@
 		dump_error(__FILE__, __LINE__, "Es werden zwei verschiedene Kanten gelöscht");
 	}
 
-
 	if (NrIt == EdgeListNrSorted.end())
 	{
 		dump_error(__FILE__, __LINE__, "Konnte Kante nicht löschen da sie nicht gefunden wurde");
 	}
 
+	AvgDistance = AvgDistance * Anz;
+	AvgDistance = AvgDistance - edge->Distance;
+
 	TEdge *Edge = *NrIt;
 	delete Edge;
 
@@ -868,6 +1292,9 @@
 	EdgeListDistanceSorted.erase(DistanceIt);
 	Anz--;
 
+	if (Anz == 0)	AvgDistance = 0.0;
+	else			AvgDistance = AvgDistance / Anz;
+
 	if (Anz != EdgeListNrSorted.size())
 	{
 		dump_error(__FILE__, __LINE__, "Anz = %d size() = %d A\n", Anz, EdgeListNrSorted.size());
@@ -893,11 +1320,27 @@
 }
 
 //---------------------------------------------------------------------
+TEdge* TEdgeList::Find(int NodeNr1, int NodeNr2)
+{
+	if (Anz == 0)	return(0);
+
+	SearchNode1->Nr = NodeNr1;
+	SearchNode2->Nr = NodeNr2;
+
+	TEdgeListNrSorted::iterator NrIt = EdgeListNrSorted.find(SearchEdge);
+
+	TEdge *Edge = 0;
+	if (NrIt != EdgeListNrSorted.end())	Edge = *NrIt;
+
+	return (Edge);
+}
+
+//---------------------------------------------------------------------
 void TEdgeList::BuildEdgeIndex(void)
 {
 	for (TEdgeListNrSorted::const_iterator i=EdgeListNrSorted.begin(); i != EdgeListNrSorted.end(); i++)
 	{
-		TEdge *Edge = (*i);
+		TEdge *Edge = *i;
 
 		TNode *Node1 = Edge->Node1;
 		Node1->EdgeIndex = new TEdgeIndex (Node1->EdgeIndex, Edge);
@@ -923,7 +1366,7 @@
 //---------------------------------------------------------------------
 
 //---------------------------------------------------------------------
-TProfil::TProfil(std::string gewaesser, double station, double wsp)
+TProfil::TProfil(std::string gewaesser, int station, double wsp)
 {
 	Gewaesser = gewaesser;
 	Station = station;
@@ -940,7 +1383,7 @@
 	Wsp = profil->Wsp;
 
 	PointList = new TPointList;
-	for (TPointList::iterator i=PointList->begin(); i != PointList->end(); i++)
+	for (TPointList::iterator i=profil->PointList->begin(); i != profil->PointList->end(); i++)
 	{
 		TPoint *OldPoint = *i;
 
@@ -953,18 +1396,35 @@
 //---------------------------------------------------------------------
 TProfil::~TProfil(void)
 {
-	for (TPointList::iterator i=PointList->begin(); i != PointList->end(); i++)
+	if (PointList)
 	{
-		TPoint *Point = *i;
+		for (TPointList::iterator i=PointList->begin(); i != PointList->end(); i++)
+		{
+			TPoint *Point = *i;
 
-		delete Point;
+			delete Point;
+		}
+
+		delete PointList;
 	}
+}
 
-	delete PointList;
+//---------------------------------------------------------------------
+void TProfil::AddPoint(double meter)
+{
+	if (0 == PointList || PointList->size() < 2)	dump_error(__FILE__, __LINE__, "Weniger als 2 Punkte im Profil vorhanden");
+
+	double X = 0.0;
+	double Y = 0.0;
+	GetXY(meter, &X, &Y);
+
+	TPoint* NewPoint = new TPoint(X, Y, 0.0, meter);
+
+	PointList->insert(NewPoint);
 }
 
 //---------------------------------------------------------------------
-void TProfil::AddPoint(double x, double y)
+void TProfil::AddPoint(double x, double y, double z)
 {
 	if (0 == PointList)	PointList = new TPointList;
 
@@ -993,7 +1453,7 @@
 		Meter = M + D;
 	}
 
-	TPoint* NewPoint = new TPoint(x, y, Meter);
+	TPoint* NewPoint = new TPoint(x, y, z, Meter);
 
 	PointList->insert(NewPoint);
 }
@@ -1001,6 +1461,8 @@
 //---------------------------------------------------------------------
 bool TProfil::GetXY(double meter, double *x, double *y)
 {
+	if (0 == PointList || PointList->size() < 2)	dump_error(__FILE__, __LINE__, "Weniger als 2 Punkte im Profil vorhanden");
+
 	TPointList::iterator i = PointList->begin();
 
 	TPoint *LastPoint = 0;
@@ -1082,18 +1544,177 @@
 	return (false);
 }
 
+//---------------------------------------------------------------------------
+void TProfil::EqualizeProfil(TProfil *Profil)
+{
+	TPointList::iterator OneVon = PointList->begin();
+	TPointList::reverse_iterator OneBis = PointList->rbegin();
+	TPointList::iterator TwoVon = Profil->PointList->begin();
+	TPointList::reverse_iterator TwoBis = Profil->PointList->rbegin();
+
+	TPoint *PointOneVon = *OneVon;
+	TPoint *PointOneBis = *OneBis;
+	TPoint *PointTwoVon = *TwoVon;
+	TPoint *PointTwoBis = *TwoBis;
+
+	double MeterOneVon = PointOneVon->Meter;
+	double MeterOneBis = PointOneBis->Meter;
+	double MeterTwoVon = PointTwoVon->Meter;
+	double MeterTwoBis = PointTwoBis->Meter;
+
+	double LaengeOne  = MeterOneBis - MeterOneVon;
+	double LaengeTwo  = MeterTwoBis - MeterTwoVon;
+
+
+	TPointList::iterator i = ++TwoVon;
+	for (unsigned int Anz = 0; Anz < Profil->PointList->size()-2; Anz++)
+	{
+		TPoint *PointTwoI = *i++;
+		double MeterTwoI = PointTwoI->Meter;
+
+		double Prozent = (MeterTwoI - MeterTwoVon) / LaengeTwo;
+		double Meter = MeterOneVon + LaengeOne * Prozent;
+
+		int OldAnz = PointList->size();
+		int NewAnz = PointList->size();
+		while (OldAnz == NewAnz)
+		{
+			AddPoint(Meter);
+			NewAnz = PointList->size();
+			Meter = Meter + 0.1;
+		}
+	}
+}
+
+//---------------------------------------------------------------------------
+void TProfil::InterpolateProfil(TProfil *vorprofil, TProfil *nachprofil, double Prozent)
+{
+	if (vorprofil->PointList->size() != nachprofil->PointList->size())
+	{
+		dump_error(__FILE__, __LINE__, "Angeglichene Profile ('%.2f' und '%.2f') haben verschiedenviel Stützstellen", vorprofil->Station / 10000.0, nachprofil->Station / 10000.0);
+	}
+
+	TPointList::iterator V = vorprofil->PointList->begin();
+	TPointList::iterator N = nachprofil->PointList->begin();
+
+	for (unsigned int i=0; i<vorprofil->PointList->size(); i++)
+	{
+		TPoint *VPoint = *V++;
+		TPoint *NPoint = *N++;
+
+		double VX = VPoint->X;
+		double NX = NPoint->X;
+		double X = VX + Prozent * (NX - VX);
+
+		double VY = VPoint->Y;
+		double NY = NPoint->Y;
+		double Y = VY + Prozent * (NY - VY);
+
+		AddPoint(X, Y);
+	}
+}
+
+//---------------------------------------------------------------------------
+double TProfil::CalcSchnitt(TGewaesserAchseList *GewaesserAchseList)
+{
+	for (TGewaesserAchseList::iterator g=GewaesserAchseList->begin(); g != GewaesserAchseList->end(); g++)
+	{
+		TGewaesserAchse* GewaesserAchse = *g;
+
+		if (Gewaesser != GewaesserAchse->Gewaesser)	continue;
+
+		TPoint* P0 = 0;
+		TPoint* P1 = 0;
+		for (TPointList::iterator p = PointList->begin(); p != PointList->end(); p++)
+		{
+			if (P1 == 0)
+			{
+				P1 = *p;
+				continue;
+			}
+			else
+			{
+				P0 = P1;
+				P1 = *p;
+			}
+
+			double P0x = P0->X;
+			double P0y = P0->Y;
+			double P1x = P1->X;
+			double P1y = P1->Y;
+
+			// Es heisst hier s für spur und nicht g für gewässerachse
+
+			TPoint*S0 = 0;
+			TPoint*S1 = 0;
+			for (TPointList::iterator s = GewaesserAchse->PointList->begin(); s != GewaesserAchse->PointList->end(); s++)
+			{
+				if (S1 == 0)
+				{
+					S1 = *s;
+					continue;
+				}
+				else
+				{
+					S0 = S1;
+					S1 = *s;
+				}
+
+				double S0x = S0->X;
+				double S0y = S0->Y;
+				double S1x = S1->X;
+				double S1y = S1->Y;
+
+				double X, Y, LambdaP, LambdaS;
+				bool Found = Calc2Schnitt(P0x, P0y, P1x, P1y, S0x, S0y, S1x, S1y, &X, &Y, &LambdaP, &LambdaS);
+
+				if (Found)
+				{
+					double Meter = (P0->Meter + P1->Meter) / 2;
+
+					return (Meter);
+				}
+			}
+		}
+	}
+
+	// Das ist ein wenig gefährlich
+	// Eigentlich sollte es keine negativen Meter geben
+	// Daher bedeutet -1.0 nicht gefunden
+	return (-1.0);
+}
+
 //---------------------------------------------------------------------
 // TProfilList
 //---------------------------------------------------------------------
 
 //---------------------------------------------------------------------
-TProfil* TProfilList::FindStation(double Station, double Eps)
+TProfilList::~TProfilList(void)
 {
+	Clear();
+}
+
+//---------------------------------------------------------------------
+void TProfilList::Clear(void)
+{
+	for (TProfilList::iterator i=begin(); i != end(); i++)
+	{
+		TProfil *Profil = *i;
+
+		delete Profil;
+	}
+
+	clear();
+}
+
+//---------------------------------------------------------------------
+TProfil* TProfilList::Find(std::string Gewaesser, int Station)
+{
 	for (iterator i = begin(); i != end(); i++)
 	{
 		TProfil *Profil = *i;
 
-		if (Station >= Profil->Station - Eps && Station <= Profil->Station + Eps)
+		if (Gewaesser == Profil->Gewaesser && Station == Profil->Station)
 		{
 			return (Profil);
 		}
@@ -1101,3 +1722,378 @@
 	return (0);
 }
 
+//---------------------------------------------------------------------
+void TProfilList::InterpoliereProfile(double SollAbstand)
+{
+	write_fortschritt("->Interpoliere Profile\n");
+
+	TProfil *FirstProfil = 0;
+	TProfil *NextProfil = 0;
+
+	TProfilList* NewProfilList = new TProfilList();
+
+	for (iterator i = begin(); i != end(); i++)
+	{
+		if (NextProfil == 0)
+		{
+			NextProfil = *i;
+			continue;
+		}
+		else
+		{
+			FirstProfil = NextProfil;
+			NextProfil = *i;
+		}
+
+		TProfil *FirstProfilNeu = new TProfil(FirstProfil);
+		TProfil *NextProfilNeu = new TProfil(NextProfil);
+
+		FirstProfilNeu->EqualizeProfil(NextProfil);
+		NextProfilNeu->EqualizeProfil(FirstProfil);
+
+		double Diff = NextProfil->Station - FirstProfil->Station;
+		int Anz = (int)(Diff / SollAbstand + 0.5) - 1;
+		if (Anz < 0) Anz = 0;
+		double Abstand = Diff / (Anz + 1);
+
+		for (int j=1; j<=Anz; j++)
+		{
+			double Prozent = j * Abstand / Diff;
+			int NewStation = (int)(FirstProfil->Station + j * Abstand + 0.5);
+			double NewWsp = FirstProfil->Wsp + Prozent * (NextProfil->Wsp - FirstProfil->Wsp);
+
+			TProfil* NewProfil = new TProfil(FirstProfil->Gewaesser, NewStation, NewWsp);
+			NewProfil->InterpolateProfil(FirstProfilNeu, NextProfilNeu, Prozent);
+
+			NewProfilList->insert(NewProfil);
+
+		}
+
+		delete FirstProfilNeu;
+		delete NextProfilNeu;
+	}
+
+	for (TProfilList::iterator i = NewProfilList->begin(); i != NewProfilList->end(); i++)
+	{
+		insert(*i);
+	}
+
+	NewProfilList->clear();
+	delete NewProfilList;
+
+	write_fortschritt("Profile interpoliert<-\n");
+}
+
+//---------------------------------------------------------------------
+void TProfilList::FillProfile(double SollAbstand, bool Debug)
+{
+	write_fortschritt("->Die Profile werden mit Stützstellen aufgefüllt\n");
+
+	int Count = 0;
+	for (iterator i = begin(); i != end(); i++)
+	{
+		if (Debug && Count % 100 == 0)	write_fortschritt("Profil %d von %d wird aufgefüllt.\n", Count, size());
+		else if (Count % 1000 == 0)		write_fortschritt("Profil %d von %d wird aufgefüllt.\n", Count, size());
+
+		TProfil* Profil = *i;
+
+		TPoint* FirstPoint = 0;
+		TPoint* NextPoint = 0;
+		for (TPointList::iterator j = Profil->PointList->begin(); j != Profil->PointList->end(); j++)
+		{
+			if (NextPoint == 0)
+			{
+				NextPoint = *j;
+				continue;
+			}
+			else
+			{
+				FirstPoint = NextPoint;
+				NextPoint = *j;
+			}
+
+			double Diff = NextPoint->Meter - FirstPoint->Meter;
+			int Anz = (int)(Diff / SollAbstand + 0.5) - 1;
+			if (Anz < 0) Anz = 0;
+			double Abstand = Diff / (Anz + 1);
+
+			for (int k=1; k<=Anz; k++)
+			{
+				double Meter = FirstPoint->Meter + k * Abstand;
+
+				Profil->AddPoint(Meter);
+
+				// Jetzt wieder von vorne
+				j = Profil->PointList->begin();
+			}
+		}
+		Count++;
+	}
+
+	write_fortschritt("Profil %d von %d wurde aufgefüllt.\n", Count, size());
+
+	write_fortschritt("Die Profile wurden mit Stützstellen aufgefüllt<-\n");
+}
+
+//---------------------------------------------------------------------
+TBereichsList::TBereichsList(TProfilList* ProfilList, int AnzBereiche)
+{
+	// An dieser Stelle wird bereits davon ausgegangen das es mindestens 2 Querprofilspuren gibt und
+	// das alle Profile zum selben Gewaesser gehören
+
+	int Anfang = (*ProfilList->begin())->Station;
+	int Ende = (*ProfilList->rbegin())->Station;
+
+	double Diff = (Ende - Anfang) / AnzBereiche;
+
+	TProfilList::iterator Start = ProfilList->begin();
+	TProfilList::iterator P = ProfilList->begin();
+	for (int i=1; i<=AnzBereiche; i++)
+	{
+		int SollStation = (int)(Anfang + i * Diff + 0.5);
+
+		TProfilList::iterator T = P;
+		T++;
+		while (T != ProfilList->end() && (*T)->Station < SollStation)
+		{
+			P++;
+			T++;
+		}
+
+		if (T == ProfilList->end()) dump_error(__FILE__, __LINE__, "Konnte nicht alle Bereiche generieren");
+
+		if (P == Start) dump_error(__FILE__, __LINE__, "Bin nicht von der Stelle gekommen");
+
+		if ((*T)->Station - SollStation < SollStation - (*P)->Station)
+		{
+			(*this)[Start] = T;
+			Start = T;
+		}
+		else
+		{
+			(*this)[Start] = P;
+			Start = P;
+		}
+	}
+}
+
+//---------------------------------------------------------------------
+// TGewaesserAchse
+//---------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+TGewaesserAchse::TGewaesserAchse(std::string gewaesser, int id)
+{
+	Gewaesser = gewaesser;
+	ID = id;
+
+	PointList = 0;
+}
+
+//---------------------------------------------------------------------
+TGewaesserAchse::TGewaesserAchse(TGewaesserAchse *gewaesserAchse)
+{
+	Gewaesser = gewaesserAchse->Gewaesser;
+	ID = gewaesserAchse->ID;
+
+	PointList = new TPointList;
+	for (TPointList::iterator i=gewaesserAchse->PointList->begin(); i != gewaesserAchse->PointList->end(); i++)
+	{
+		TPoint *OldPoint = *i;
+
+		TPoint *NewPoint = new TPoint(OldPoint);
+
+		PointList->insert(NewPoint);
+	}
+}
+
+//---------------------------------------------------------------------
+TGewaesserAchse::~TGewaesserAchse(void)
+{
+	if (PointList)
+	{
+		for (TPointList::iterator i=PointList->begin(); i != PointList->end(); i++)
+		{
+			TPoint *Point = *i;
+
+			delete Point;
+		}
+
+		delete PointList;
+	}
+}
+
+//---------------------------------------------------------------------
+void TGewaesserAchse::AddPoint(double meter)
+{
+	if (0 == PointList || PointList->size() < 2)	dump_error(__FILE__, __LINE__, "Weniger als 2 Punkte im Gewässerachse vorhanden");
+
+	double X = 0.0;
+	double Y = 0.0;
+	GetXY(meter, &X, &Y);
+
+	TPoint* NewPoint = new TPoint(X, Y, 0.0, meter);
+
+	PointList->insert(NewPoint);
+}
+
+//---------------------------------------------------------------------
+void TGewaesserAchse::AddPoint(double x, double y, double z)
+{
+	if (0 == PointList)	PointList = new TPointList;
+
+	TPointList::iterator i = PointList->begin();
+
+	TPoint *LastPoint = 0;
+	while (i != PointList->end())
+	{
+		LastPoint = *i;
+		i++;
+	}
+
+	double Meter = 0.0;
+
+	if (LastPoint)
+	{
+		double X = LastPoint->X;
+		double Y = LastPoint->Y;
+		double M = LastPoint->Meter;
+
+		double Dx = X - x;
+		double Dy = Y - y;
+
+		double D = sqrt(Dx * Dx + Dy * Dy);
+
+		Meter = M + D;
+	}
+
+	TPoint* NewPoint = new TPoint(x, y, z, Meter);
+
+	PointList->insert(NewPoint);
+}
+
+//---------------------------------------------------------------------
+bool TGewaesserAchse::GetXY(double meter, double *x, double *y)
+{
+	if (0 == PointList || PointList->size() < 2)	dump_error(__FILE__, __LINE__, "Weniger als 2 Punkte im Gewässerachse vorhanden");
+
+	TPointList::iterator i = PointList->begin();
+
+	TPoint *LastPoint = 0;
+	TPoint *Point = 0;
+	while (i != PointList->end())
+	{
+		Point = *i;
+
+		if (Point->Meter == meter)
+		{
+			*x = Point->X;
+			*y = Point->Y;
+			return(true);
+		}
+
+		if (LastPoint != 0)
+		{
+			if (meter < LastPoint->Meter)
+			{
+				// Der gesuchte Punkt liegt vor dem ersten Punkt des Profils
+				double Dx = Point->X - LastPoint->X;
+				double Dy = Point->Y - LastPoint->Y;
+				double Dm = Point->Meter - LastPoint->Meter;
+
+				double Faktor = (meter - LastPoint->Meter) / Dm;
+
+				*x = LastPoint->X + Dx * Faktor;
+				*y = LastPoint->Y + Dy * Faktor;
+
+				if (Faktor >= 0.0)
+				{
+					dump_error(__FILE__, __LINE__,  "Faktor ist nicht negativ, aber der gesuchte Punkt liegt vor dem Profil");
+				}
+
+				return (false);
+			}
+			else if (meter > LastPoint->Meter && meter < Point->Meter)
+			{
+				// Der gesuchte Punkt liegt zwischen Punkten des Profils
+				double Dx = Point->X - LastPoint->X;
+				double Dy = Point->Y - LastPoint->Y;
+				double Dm = Point->Meter - LastPoint->Meter;
+
+				double Faktor = (meter - LastPoint->Meter) / Dm;
+
+				*x = LastPoint->X + Dx * Faktor;
+				*y = LastPoint->Y + Dy * Faktor;
+
+				if (Faktor <= 0.0 || Faktor >= 1.0)
+				{
+					dump_error(__FILE__, __LINE__,  "Faktor ist nicht zwischen 0 und 1, aber der gesuchte Punkt liegt im Profil");
+				}
+
+				return (true);
+			}
+
+		}
+
+		LastPoint = Point;
+
+		i++;
+	}
+
+	// Der gesuchte Punkt liegt hinter dem letzten Punkt des Profils
+	double Dx = Point->X - LastPoint->X;
+	double Dy = Point->Y - LastPoint->Y;
+	double Dm = Point->Meter - LastPoint->Meter;
+
+	double Faktor = (meter - LastPoint->Meter) / Dm;
+
+	*x = LastPoint->X + Dx * Faktor;
+	*y = LastPoint->Y + Dy * Faktor;
+
+	if (Faktor <= 1.0)
+	{
+		dump_error(__FILE__, __LINE__,  "Faktor ist nicht größer als 1, aber der gesuchte Punkt liegt hinter dem Profil");
+	}
+
+	return (false);
+}
+
+//---------------------------------------------------------------------
+// TGewaesserAchseList
+//---------------------------------------------------------------------
+
+//---------------------------------------------------------------------
+TGewaesserAchseList::~TGewaesserAchseList(void)
+{
+	Clear();
+}
+
+//---------------------------------------------------------------------
+void TGewaesserAchseList::Clear(void)
+{
+	for (TGewaesserAchseList::iterator i=begin(); i != end(); i++)
+	{
+		TGewaesserAchse *GewaesserAchse = *i;
+
+		delete GewaesserAchse;
+	}
+
+	clear();
+}
+
+//---------------------------------------------------------------------
+TGewaesserAchse* TGewaesserAchseList::Find(std::string Gewaesser, int ID)
+{
+	for (iterator i = begin(); i != end(); i++)
+	{
+		TGewaesserAchse *GewaesserAchse = *i;
+
+		if (Gewaesser == GewaesserAchse->Gewaesser && ID == GewaesserAchse->ID)
+		{
+			return (GewaesserAchse);
+		}
+	}
+	return (0);
+}
+
+

Modified: trunk/src/xy.h
===================================================================
--- trunk/src/xy.h	2006-03-12 14:42:43 UTC (rev 36)
+++ trunk/src/xy.h	2006-03-13 23:53:00 UTC (rev 37)
@@ -27,6 +27,7 @@
 #include <vector>
 #include <list>
 #include <set>
+#include <map>
 
 #include <math.h>
 
@@ -39,6 +40,7 @@
 class TXYList;
 class TXYZList;
 class TNodeList;
+class TGewaesserAchseList;
 
 //----------------------------------------------------------------------------
 static const unsigned int 	MaxXYKombiIndexAnzahlKonst = 10;
@@ -51,8 +53,8 @@
 		double  		Y;
 
 		// Dieser Wert ist eine abwechselt Bitweise Kombination des (long)(X * 100) und (long)(Y * 100) Wertes.
-		// X = 1.2345 -> (long)(X*100) = 123 = 001111011
-		// Y = 2.654  -> (long)(Y*100) = 265 = 100001001
+		// X = 1.2345 -> (long)(X*100) = 123 = 0 0 1 1 1 1 0 1 1
+		// Y = 2.654  -> (long)(Y*100) = 265 = 1 0 0 0 0 1 0 0 1
 		// XYKombi = 0...0 01 00 10 10 10 11 00 10 11 = 0000000000000000000000000000000000000000000000010010101011001011
 		unsigned INT64	XYKombi;
 
@@ -75,28 +77,28 @@
 //----------------------------------------------------------------------------
 class TNode : public TXYZ
 {
-	private:
-		void 		ClearEdgeIndex(void);
-
 	public:
 		int			Nr;
 		double  	Wsp;
 		TEdgeIndex 	*EdgeIndex;
 
-		TNode(int Nr, double X, double Y, double Z);
-		TNode(int Nr, double X, double Y, double Z, int Wsp);
-		TNode(TNode *Node);
-		~TNode(void);
+					TNode(int Nr, double X, double Y, double Z);
+					TNode(int Nr, double X, double Y, double Z, double Wsp);
+					TNode(TNode *Node);
+					~TNode(void);
+
+		void 		ClearEdgeIndex(void);
 };
 
 
 //----------------------------------------------------------------------------
-class TPoint : public TXY
+class TPoint : public TXYZ
 {
 	public:
 		double  	Meter;
 
 		TPoint(double X, double Y, double Meter);
+		TPoint(double X, double Y, double Z, double Meter);
 		TPoint(TPoint *Point);
 };
 
@@ -125,7 +127,7 @@
 						TElement(TElement *Element);
 						~TElement(void);
 
-		TInsideTyp		IsInElement(double X, double Y);
+		TInsideTyp		IsInsideElement(double X, double Y);
 };
 
 //----------------------------------------------------------------------------
@@ -141,9 +143,7 @@
 		bool	Ready;
 		bool	IsBoundary;
 
-		TNode*		TriNode;
-
-		TEdge(TNode *Node1, TNode *Node2, TNode* TriNode = 0);
+		TEdge(TNode *Node1, TNode *Node2);
 		TEdge(TEdge *Edge);
 };
 
@@ -284,6 +284,92 @@
 			}
 			return (-1);
 		}
+
+		//----------------------------------------------------------------------------
+		void SearchAll(std::vector<int> *NodeIndexList, TXyList *XyList, double SX, double SY, double SR, bool LeftRight = true, unsigned INT64 XUnLi = INT64SUFF(0x00000000), unsigned INT64 YUnLi = INT64SUFF(0x00000000), unsigned INT64 XObRe = INT64SUFF(0xFFFFFFFF), unsigned INT64 YObRe = INT64SUFF(0xFFFFFFFF))
+		{
+			if (Zero == 0 && One == 0)
+			{
+				for (unsigned int i=0; i<Anzahl; i++)
+				{
+					TXy *Xy = (*XyList)[Start + i];
+
+					double Dx = Xy->X - SX;
+					double Dy = Xy->Y - SY;
+
+					if (sqrt(Dx * Dx + Dy * Dy) <=  SR)
+					{
+						NodeIndexList->push_back(Start + i);
+					}
+				}
+				return;
+			}
+
+			double DxUnLi = SX - XUnLi;
+			double DxObRe = SX - XObRe;
+			double DyUnLi = SY - YUnLi;
+			double DyObRe = SY - YObRe;
+
+			if (sqrt(DxUnLi * DxUnLi + DyUnLi * DyUnLi) <= SR &&
+				sqrt(DxObRe * DxObRe + DyUnLi * DyUnLi) <= SR &&
+				sqrt(DxUnLi * DxUnLi + DyObRe * DyObRe) <= SR &&
+				sqrt(DxObRe * DxObRe + DyObRe * DyObRe) <= SR)
+			{
+				for (unsigned int i=0; i<Anzahl; i++)
+				{
+//					TXy *Xy = (*XyList)[Start + i];
+
+//					double Dx = Xy->X - SX;
+//					double Dy = Xy->Y - SY;
+
+//					if (sqrt(Dx * Dx + Dy * Dy) <  SR)
+					{
+						NodeIndexList->push_back(Start + i);
+					}
+				}
+				return;
+			}
+
+			if (LeftRight)
+			{
+				unsigned INT64 X = XUnLi / 2 + XObRe / 2;
+				double Left = SX - SR;
+				if (Left < 0)	Left = 0;
+				if ((unsigned INT64)(Left) <= X && Zero)
+				{
+					Zero->SearchAll(NodeIndexList, XyList, SX, SY, SR, !LeftRight, XUnLi, YUnLi, X, YObRe);
+				}
+
+				X = X + 1;
+
+				double Right = SX + SR;
+				if (Right > (double)0x7FFFFFFFL)	Right = (double)0x7FFFFFFFL;
+				if ((unsigned INT64)(Right) >= X && One)
+				{
+					One->SearchAll(NodeIndexList, XyList, SX, SY, SR, !LeftRight, X, YUnLi, XObRe, YObRe);
+				}
+			}
+			else
+			{
+				unsigned INT64 Y = YUnLi / 2 + YObRe / 2;
+				double Bottom = SY - SR;
+				if (Bottom < 0)	Bottom = 0;
+				if ((unsigned INT64)(Bottom) <= Y && Zero)
+				{
+					Zero->SearchAll(NodeIndexList, XyList, SX, SY, SR, !LeftRight, XUnLi, YUnLi, XObRe, Y);
+				}
+
+				Y = Y + 1;
+
+				double Top = SY + SR;
+				if (Top > (double)0x7FFFFFFFL)	Top = (double)0x7FFFFFFFL;
+				if ((unsigned INT64)(Top) >= Y && One)
+				{
+					One->SearchAll(NodeIndexList, XyList, SX, SY, SR, !LeftRight, XUnLi, Y, XObRe, YObRe);
+				}
+			}
+			return;
+		}
 };
 
 //----------------------------------------------------------------------------
@@ -293,29 +379,57 @@
 		TXYKombiIndex<TXYList, TXY>	*XYKombiIndex;
 
 	public:
+		double		 	MinX;
+		double		 	MaxX;
+		double		 	MinY;
+		double		 	MaxY;
+
 						TXYList(void);
 						~TXYList(void);
 		void 			Clear(void);
 		TXYList* 		Copy(void);
 
+		void 			Add(TXY *Xy);
+		void 			Add(double X, double Y);
 		void 			SortByXY(void);
 		TXY* 			FindByXY(double X, double Y, double Eps = 0.01);
+		TInsideTyp		IsInsideXYList(double X, double Y);
 };
 
 //----------------------------------------------------------------------------
+class TErgebnisPolygon : public TXYList
+{
+	public:
+		std::string	Gewaesser;
+		double		VonKm;
+		double		BisKm;
+		double		Diff;
+
+					TErgebnisPolygon(double Diff);
+};
+
+//----------------------------------------------------------------------------
 class TXYZList : public std::vector<TXYZ *>
 {
 	private:
 		TXYKombiIndex<TXYZList, TXYZ>	*XYKombiIndex;
 
 	public:
+		double		   	MinX;
+		double		   	MaxX;
+		double		   	MinY;
+		double		   	MaxY;
+
 						TXYZList(void);
 						~TXYZList(void);
 		void 			Clear(void);
 		TXYZList* 		Copy(void);
 
+		void 			Add(TXYZ *Xyz);
+		void 			Add(double X, double Y, double Z);
 		void 			SortByXY(void);
 		TXYZ*			FindByXY(double X, double Y, double Eps = 0.01);
+		TInsideTyp		IsInsideXYZList(double X, double Y);
 };
 
 //----------------------------------------------------------------------------
@@ -330,11 +444,14 @@
 		void 			Clear(void);
 		TNodeList* 		Copy(void);
 
+		void			SortByX(void);
 		void			SortByXY(void);
 		void			SortByNr(void);
 		TNode*			FindByXY(double X, double Y, double Eps = 0.01);
-		TNodeList*		FindAllByXY(double X, double Y, double Eps = 0.01);
+		void			FindAllByXY(TNodeList *NodeList, double X, double Y, double Eps = 0.01);
 		TNode*			FindByNr(int Nr);
+		bool			Interpolate(double X, double Y, double R, double *Z, double *Wsp); 
+		void			ClearEdgeIndex(void);
 };
 
 //----------------------------------------------------------------------------
@@ -385,6 +502,12 @@
 //----------------------------------------------------------------------------
 class TEdgeList
 {
+	private:
+		// Diese beiden Knoten und die Kante dienen nur als Hüllen für das Suchen
+		TNode *SearchNode1;
+		TNode *SearchNode2;
+		TEdge *SearchEdge;
+
 	public:
 									TEdgeList(void);
 									~TEdgeList(void);
@@ -393,11 +516,15 @@
 		TEdgeListDistanceSorted		EdgeListDistanceSorted;
 
 		unsigned int				Anz;
+		double						AvgDistance;
 
-		void 						Clear(void);
+		void 						Clear(void); // Wird verwendet, wenn auch die Kanten selbst gelöscht werden sollen
+		void 						Empty(void); // Wird verwendet, wenn es es nur geliehene Kanten waren
 		TEdge* 						First(void);
 		void 						Add(TEdge *Edge);
+		TEdge* 						Add(TNode* Node1, TNode* Node2);
 		TEdge* 						Find(TEdge *Edge);
+		TEdge* 						Find(int NodeNr1, int NodeNr2);
 		void 						Erase(TEdge *Edge);
 
 		void 						BuildDistanceSortedList(void);
@@ -405,13 +532,15 @@
 };
 
 //----------------------------------------------------------------------------
-class TPolygonList : public std::vector<TXYList *>
+class TErgebnisPolygonList : public std::vector<TErgebnisPolygon *>
 {
 	public:
-						~TPolygonList(void);
-		void 			Clear(void);
-		TXYList* 	  	First(void);
-		TPolygonList* 	Copy(void);
+								~TErgebnisPolygonList(void);
+		void 					Clear(void);
+		TErgebnisPolygon*		First(void);
+		TErgebnisPolygonList* 	Copy(void);
+		void 					Append(TErgebnisPolygonList *AddErgebnisPolygonList);
+		TInsideTyp				IsInsidePolygonList(double X, double Y);
 };
 
 //----------------------------------------------------------------------------
@@ -429,18 +558,22 @@
 {
 	public:
 		std::string		Gewaesser;
-		double			Station;
+		int				Station;
 
 		TPointList*		PointList;
 
 		double			Wsp;
 
-						TProfil(std::string Gewaesser, double Station, double Wsp = 0.0);
+						TProfil(std::string Gewaesser, int Station, double Wsp = 0.0);
 						TProfil(TProfil *Profil);
 						~TProfil(void);
 
-		void  			AddPoint(double X, double Y);
+		void  			AddPoint(double Meter);
+		void  			AddPoint(double X, double Y, double Z = 0.0);
 		bool			GetXY(double Meter, double *X, double *Y);
+		void 			EqualizeProfil(TProfil *Profil);
+		void			InterpolateProfil(TProfil *VorProfil, TProfil *NachProfil, double Prozent);
+		double			CalcSchnitt(TGewaesserAchseList *GewaesserAchseList);
 		double  		Length(TPoint *Point1, TPoint *Point2);
 		double  		Length(double X1, double Y1, double X2, double Y2);
 		TPoint*			FindNearest(double X, double Y);
@@ -452,6 +585,8 @@
 	public:
 		bool operator()(TProfil* const &Profil1, TProfil* const &Profil2) const
 		{
+			if (Profil1->Gewaesser < Profil2->Gewaesser)	return (true);
+			if (Profil2->Gewaesser > Profil2->Gewaesser)	return (false);
 			return (Profil1->Station < Profil2->Station);
 		}
 };
@@ -460,7 +595,80 @@
 class TProfilList : public std::set<TProfil *, TProfilCompStation>
 {
 	public:
-		TProfil* 	FindStation(double Station, double Eps = 0.01);
+					~TProfilList(void);
+
+		void		Clear(void);
+		TProfil* 	Find(std::string Gewaesser, int Station);
+		void		InterpoliereProfile(double SollAbstand);
+		void		FillProfile(double SollAbstand, bool Debug);
 };
 
+typedef std::map<std::string, TProfilList *> TProfilMap;
+
+//----------------------------------------------------------------------------
+class TBereichCompStation
+{
+	public:
+		bool operator()(TProfilList::iterator const &Profil1Iter, TProfilList::iterator const &Profil2Iter) const
+		{
+			if ((*Profil1Iter)->Gewaesser < (*Profil2Iter)->Gewaesser)	return (true);
+			if ((*Profil2Iter)->Gewaesser > (*Profil2Iter)->Gewaesser)	return (false);
+			return ((*Profil1Iter)->Station < (*Profil2Iter)->Station);
+		}
+};
+
+//----------------------------------------------------------------------------
+class TBereichsList : public std::map<TProfilList::iterator, TProfilList::iterator, TBereichCompStation>
+{
+	private:
+		TProfilList::iterator FindBestBereich(TProfilList* ProfilList, TProfilList::iterator StartIterator, int AnzBereiche);
+
+	public:
+		TBereichsList(TProfilList* ProfilList, int AnzBereiche);
+};
+
+//----------------------------------------------------------------------------
+class TGewaesserAchse
+{
+	public:
+		std::string		Gewaesser;
+		int				ID;
+
+		TPointList*		PointList;
+
+						TGewaesserAchse(std::string Gewaesser, int ID);
+						TGewaesserAchse(TGewaesserAchse *GewaesserAchse);
+						~TGewaesserAchse(void);
+
+		void  			AddPoint(double Meter);
+		void  			AddPoint(double X, double Y, double Z = 0.0);
+		bool			GetXY(double Meter, double *X, double *Y);
+		double  		Length(TPoint *Point1, TPoint *Point2);
+		double  		Length(double X1, double Y1, double X2, double Y2);
+		TPoint*			FindNearest(double X, double Y);
+};
+
+//----------------------------------------------------------------------------
+class TGewaesserAchseComp
+{
+	public:
+		bool operator()(TGewaesserAchse* const &GewaesserAchse1, TGewaesserAchse* const &GewaesserAchse2) const
+		{
+			if (GewaesserAchse1->Gewaesser < GewaesserAchse2->Gewaesser)	return (true);
+			if (GewaesserAchse2->Gewaesser > GewaesserAchse2->Gewaesser)	return (false);
+			return (GewaesserAchse1->ID < GewaesserAchse2->ID);
+		}
+};
+
+//----------------------------------------------------------------------------
+class TGewaesserAchseList : public std::set<TGewaesserAchse *, TGewaesserAchseComp>
+{
+	public:
+							~TGewaesserAchseList(void);
+
+		void				Clear(void);
+		TGewaesserAchse* 	Find(std::string Gewaesser, int ID);
+};
+
 #endif
+



More information about the Wsplgen-commits mailing list