[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