[Wsplgen-commits] r79 - trunk/src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Nov 21 07:38:11 CET 2006


Author: mrchip
Date: 2006-11-21 07:38:11 +0100 (Tue, 21 Nov 2006)
New Revision: 79

Modified:
   trunk/src/file.cpp
   trunk/src/wsplgen.h
   trunk/src/xy.cpp
Log:
Jetzt ist das Beschneiden des Begrenzungspolgons hoffentlich wirklich fertig.

Modified: trunk/src/file.cpp
===================================================================
--- trunk/src/file.cpp	2006-11-19 13:27:36 UTC (rev 78)
+++ trunk/src/file.cpp	2006-11-21 06:38:11 UTC (rev 79)
@@ -979,15 +979,15 @@
 }
 
 //---------------------------------------------------------------------
-bool LoadProfile(std::string FileName, TProfilList* ProfilList, double VonKm, double BisKm, int DebugLevel)
+bool LoadProfile(std::string FileName, TProfilList* ProfilList, double VonKmD, double BisKmD, int DebugLevel)
 {
 	write_fortschritt("->Laden der Profilspuren gestartet\n");
 
 	LoadPRJ(FileName, DebugLevel);
 
-	if (VonKm > -9999 && BisKm > -9999)	write_fortschritt("Nur Profile von Station %.4f bis %.4f werden geladen\n", VonKm, BisKm);
-	else if (VonKm > -9999)	write_fortschritt("Nur Profile mit einer Station größer als %.4f werden geladen\n", VonKm);
-	else if (BisKm > -9999)	write_fortschritt("Nur Profile mit einer Station kleiner als %.4f werden geladen\n", BisKm);
+	if (VonKmD > -9999 && BisKmD > -9999)	write_fortschritt("Nur Profile von Station %.4f bis %.4f werden geladen\n", VonKmD, BisKmD);
+	else if (VonKmD > -9999)	write_fortschritt("Nur Profile mit einer Station größer als %.4f werden geladen\n", VonKmD);
+	else if (BisKmD > -9999)	write_fortschritt("Nur Profile mit einer Station kleiner als %.4f werden geladen\n", BisKmD);
 
 	if (ProfilList == 0)
 	{
@@ -1118,19 +1118,22 @@
 		write_error(2210, "In der DBF-Datei '%s' ist der Attribut-Typ des Attributes '%s' nicht Fliesskommazahl.\n", DBFFileName.c_str(), StationName.c_str());
 	}
 
+	int VonKmI = (int)(VonKmD * 10000.0 + 0.5);
+	int BisKmI = (int)(BisKmD * 10000.0 + 0.5);
+
 	int Count = 0;
 	for (int i = 0; i<RecordCount; i++)
 	{
 		double StationD = DBFReadDoubleAttribute(hDBF, i, StationFieldIndex);
 
-		int Station = (int)(StationD * 10000.0 + 0.5);
-		if (StationD < 0)	Station = (int)(StationD * 10000.0 - 0.5);
+		int StationI = (int)(StationD * 10000.0 + 0.5);
+		if (StationD < 0)	StationI = (int)(StationD * 10000.0 - 0.5);
 
-		if (Station >= VonKm * 10000 && Station <= BisKm * 10000)
+		if (StationI >= VonKmI && StationI <= BisKmI)
 		{
-			if (ProfilList->Find(Station))
+			if (ProfilList->Find(StationI))
 			{
-				write_warning(2111, "In der DBF-Datei '%s' kommt das Profil (%.4f) mehrfach vor.\nEs wird nur die erste Definition berücksichtigt.\n", DBFFileName.c_str(), Station / 10000.0);
+				write_warning(2111, "In der DBF-Datei '%s' kommt das Profil (%.4f) mehrfach vor.\nEs wird nur die erste Definition berücksichtigt.\n", DBFFileName.c_str(), StationI / 10000.0);
 				continue;
 			}
 
@@ -1140,11 +1143,11 @@
 
 			if (AnzVert <= 0)
 			{
-				write_warning(2112, "In der DBF-Datei '%s' hat das Profil (%.4f) keine Stützstellen.\nEs wird ignoriert.\n", DBFFileName.c_str(), Station / 10000.0);
+				write_warning(2112, "In der DBF-Datei '%s' hat das Profil (%.4f) keine Stützstellen.\nEs wird ignoriert.\n", DBFFileName.c_str(), StationI / 10000.0);
 				continue;
 			}
 
-			TProfil* Profil = new TProfil(Station);
+			TProfil* Profil = new TProfil(StationI);
 
 			ProfilList->insert(Profil);
 
@@ -2235,8 +2238,22 @@
 
 	SHPObject *psCShape = SHPReadObject(hSHP, 0);
 
+	int AnzPart = psCShape->nParts;
+
+	if (psCShape->panPartType[0] != SHPP_RING)
+	{
+		write_error(2225, "Der erste Teil des Begrenzungpolygon '%s' ist keine äußerer Ring.\n", SHPFileName.c_str());
+	}
+
 	int AnzVert = psCShape->nVertices;
 
+	if (AnzPart > 1)
+	{
+		write_warning(2124, "Das Begrenzungpolygon '%s' besteht aus mehreren Teilen.\nEs wird nur der erste Teil verwendet.\n", SHPFileName.c_str());
+
+		AnzVert = psCShape->panPartStart[1];
+	}
+
 	if (AnzVert < 3)
 	{
 		write_error(2223, "In der SHP-Datei '%s' hat die hydraulische Grenze weniger als 3 Stützstellen.\n", SHPFileName.c_str());

Modified: trunk/src/wsplgen.h
===================================================================
--- trunk/src/wsplgen.h	2006-11-19 13:27:36 UTC (rev 78)
+++ trunk/src/wsplgen.h	2006-11-21 06:38:11 UTC (rev 79)
@@ -10,8 +10,16 @@
 // Read the file COPYING coming with WSPLGEN for details.
 //
 
-const char Version[] = "1.0.0 rc3";
+const char Version[] = "1.0.0 rc4";
 
+// Bei Beschneiden des Begrenzungspolygon wurde die Methodik komplett verändert
+
+// Bei Laden von Begrenzungspolygonen wird jetzt nur noch der äußere Ring geladen
+
+// Einige Meldungen wurden etwas verbesssert
+
+// const char Version[] = "1.0.0 rc3";
+
 // Die Koordinaten der Elemente waren um den Faktor 100 zu gross
 
 // Das Dateiformat für die Elemente war völlig kaputt

Modified: trunk/src/xy.cpp
===================================================================
--- trunk/src/xy.cpp	2006-11-19 13:27:36 UTC (rev 78)
+++ trunk/src/xy.cpp	2006-11-21 06:38:11 UTC (rev 79)
@@ -388,42 +388,55 @@
 //---------------------------------------------------------------------
 TXYList* TXYList::Cut(TXYList* ProfilPolygon, TProfil* CutProfil)
 {
-	TXYList* CutXyList = new TXYList();
-
 	// Zuerst (wenn notwendig )den ersten Punkt am Ende hinzufügen
 	TXY* XyFirst = *begin();
 	TXY* XyLast = *rbegin();
 
-    if (XyFirst->X != XyLast->X || XyFirst->Y != XyLast->Y)
-    {
+	if (XyFirst->X != XyLast->X || XyFirst->Y != XyLast->Y)
+	{
 		Add(XyFirst->X, XyFirst->Y);
-    }
+	}
 
-    // Jetzt das CutProfil verlängern, damit es wirklich zwei Schnittpunkte gibt
+	// Jetzt das CutProfil verlängern, damit es wirklich zwei Schnittpunkte gibt
+	TXYList* CutXyList = new TXYList();
+
 	long X = 0;
 	long Y = 0;
 
+	TPoint*	FPoint = *CutProfil->PointList->begin();
+	TPoint*	LPoint = *CutProfil->PointList->rbegin();
+
 	CutProfil->GetXY(-999999, &X, &Y);
 	CutXyList->Add(X, Y);
-    for	(TPointList::iterator i=CutProfil->PointList->begin(); i != CutProfil->PointList->end(); i++)
-    {
+	for	(TPointList::iterator i=CutProfil->PointList->begin(); i != CutProfil->PointList->end(); i++)
+	{
 		TPoint*	Point =	*i;
 
 		CutXyList->Add(Point->X, Point->Y);
-    }
+	}
 	CutProfil->GetXY(999999, &X, &Y);
 	CutXyList->Add(X, Y);
 
+	int 	After0 = -1;
+	long	X0 = FPoint->X;
+	long	Y0 = FPoint->Y;
+	double	SX0 = 0;
+	double	SY0 = 0;
+	double	D00 = 0.0;
+	double	D01 = 0.0;
 
+	int 	After1 = -1;
+	long	X1 = LPoint->X;
+	long	Y1 = LPoint->Y;
+	double  SX1 = 0;
+	double  SY1 = 0;
+	double	D10 = 0.0;
+	double	D11 = 0.0;
 
-	TXYList* SideZero = new	TXYList();
-	TXYList* SideOne = new TXYList();
-
-	int Side = 0;
-
 	TXY* Xy0 = 0;
 	TXY* Xy1 = 0;
-	for (TXYList::iterator i=begin(); i	!= end(); i++)
+	int Index = 0;
+	for (TXYList::iterator i=begin(); i	!= end(); i++, Index++)
 	{
 		Xy0 = Xy1;
 		Xy1 = *i;
@@ -434,9 +447,9 @@
 		}
 
 		if (Xy0->X == Xy1->X && Xy0->Y == Xy1->Y)
-        {
-	        continue;
-        }
+		{
+			continue;
+		}
 
 		TXY* CutXy0 = 0;
 		TXY* CutXy1 = 0;
@@ -452,97 +465,294 @@
 
 			Schnitt	= Calc2Schnitt(Xy0->X, Xy0->Y, Xy1->X, Xy1->Y, CutXy0->X, CutXy0->Y, CutXy1->X,	CutXy1->Y, &SX,	&SY);
 
-			if (Schnitt)	break;
+			if (Schnitt)
+			{
+				double D0 = (SX - X0) * (SX - X0) + (SY - Y0) * (SY - Y0);
+				double D1 = (SX - X1) * (SX - X1) + (SY - Y1) * (SY - Y1);
+
+				if (After0 == -1 && After1 == -1)
+				{
+					if (D0 < D1)
+					{
+						After0 = Index;
+						SX0 = SX;
+						SY0 = SY;
+						D00 = D0;
+						D01 = D1;
+					}
+					else
+					{
+						After1 = Index;
+						SX1 = SX;
+						SY1 = SY;
+						D10 = D0;
+						D11 = D1;
+					}
+					break;
+				}
+				else if (After1 == -1) // -> Also After0 != -1
+				{
+					if (SX == SX0 && SY == SY0)	continue;
+
+					if (D0 + D01 < D00 + D1)
+					{
+						After1 = After0;
+						SX1 = SX1;
+						SY1 = SY1;
+						D10 = D00;
+						D11 = D01;
+
+						After0 = Index;
+						SX0 = SX;
+						SY0 = SY;
+						D00 = D0;
+						D01 = D1;
+					}
+					else
+					{
+						After1 = Index;
+						SX1 = SX;
+						SY1 = SY;
+						D10 = D0;
+						D11 = D1;
+					}
+					break;
+				}
+				else if (After0 == -1) // -> Also After1 != -1
+				{
+					if (SX == SX1 && SY == SY1)	continue;
+
+					if (D0 + D11 < D10 + D1)
+					{
+						After0 = Index;
+						SX0 = SX;
+						SY0 = SY;
+						D00 = D0;
+						D01 = D1;
+					}
+					else
+					{
+						After0 = After0;
+						SX0 = SX1;
+						SY0 = SY1;
+						D00 = D10;
+						D01 = D11;
+
+						After1 = Index;
+						SX1 = SX;
+						SY1 = SY;
+						D10 = D0;
+						D11 = D1;
+					}
+					break;
+				}
+				else
+				{
+					if (SX == SX0 && SY == SY0)	continue;
+					if (SX == SX1 && SY == SY1)	continue;
+
+					if (D0 + D01 < D00 + D11 && D0 + D01 < D00 + D1 && D0 + D01 < D0 + D11 && D0 + D01 < D10 + D1)
+					{
+						After1 = After0;
+						SX1 = SX0;
+						SY1 = SY0;
+						D10 = D00;
+						D11 = D01;
+
+						After0 = Index;
+						SX0 = SX;
+						SY0 = SY;
+						D00 = D0;
+						D01 = D1;
+					}
+					else if (D0 + D11 < D00 + D11 && D0 + D11 < D00 + D1 && D0 + D11 < D0 + D01 && D0 + D11 < D10 + D1)
+					{
+						After0 = Index;
+						SX0 = SX;
+						SY0 = SY;
+						D00 = D0;
+						D01 = D1;
+					}
+					else if (D00 + D1 < D00 + D11 && D00 + D1 < D0 + D01 && D00 + D1 < D0 + D11 && D00 + D1 < D10 + D1)
+					{
+						After1 = Index;
+						SX1 = SX;
+						SY1 = SY;
+						D10 = D0;
+						D11 = D1;
+					}
+					else if (D10 + D1 < D00 + D11 && D10 + D1 < D00 + D1 && D10 + D1 < D0 + D11 && D10 + D1 < D0 + D01)
+					{
+						After0 = After1;
+						SX0 = SX1;
+						SY0 = SY1;
+						D00 = D10;
+						D01 = D11;
+
+						After1 = Index;
+						SX1 = SX;
+						SY1 = SY;
+						D10 = D0;
+						D11 = D1;
+					}
+					break;
+				}
+			}
 		}
+	}
 
-		if (Schnitt)
+	if (After0 == -1 && After1 == -1)
+	{
+		TXYList* SideZero = new TXYList();
+
+		TXYList::iterator iter=begin();
+		unsigned int i = 0;
+		while (i < size())
 		{
-			long LSX = (long)(SX + 0.5);
-			long LSY = (long)(SY + 0.5);
-			SideZero->Add(LSX, LSY);
-			SideOne->Add(LSX, LSY);
-			Side = 1 - Side;    // Wechsel von 0 zu	1 oder von 1 zu	0
+			TXY *Xy = *iter++;
+
+			SideZero->Add(Xy->X, Xy->Y);
+
+			i++;
 		}
 
-		if (Side == 0)
+		return (SideZero);
+	}
+	else if (After0 == -1 || After1 == -1)
+	{
+		dump_error(__FILE__, __LINE__, "Es wurden keine zwei Schnittpunkte gefunden.\n");
+
+		return (0);
+	}
+	else
+	{
+		// Damit die Reihenfolge stimmt evtl. vertauschen
+		if (After0 > After1)
 		{
-			SideZero->Add(Xy1->X, Xy1->Y);
+			int TempAfter = After0;
+			double TempSX = SX0;
+			double TempSY = SY0;
+
+			After0 = After1;
+			SX0 = SX1;
+			SY0 = SY1;
+
+			After1 = TempAfter;
+			SX1 = TempSX;
+			SY1 = TempSY;
 		}
-		else
+
+		TXYList* SideZero = new TXYList();
+		TXYList* SideOne = new TXYList();
+
+		TXYList::iterator iter=begin();
+		unsigned int i = 0;
+		while (i < (unsigned int)After0)
 		{
-			SideOne->Add(Xy1->X, Xy1->Y);
+			TXY *Xy = *iter++;
+
+			SideZero->Add(Xy->X, Xy->Y);
+
+			i++;
 		}
-    }
 
+		long LSX0 = (long)(SX0 + 0.5);
+		long LSY0 = (long)(SY0 + 0.5);
+		SideZero->Add(LSX0, LSY0);
 
-/*
-    write_fortschritt("\n");
+		SideOne->Add(LSX0, LSY0);
 
-	int Count = 0;
-    for	(TXYList::iterator i=SideZero->begin();	i != SideZero->end(); i++)
-	{
-		TXY* Xy	= *i;
+		while (i < (unsigned int)After1)
+		{
+			TXY *Xy = *iter++;
 
-		write_fortschritt("%d %d %d\n",	++Count, Xy->X,	Xy->Y);
-    }
+			SideOne->Add(Xy->X, Xy->Y);
 
-    write_fortschritt("\n");
+			i++;
+		}
 
-    Count = 0;
-    for	(TXYList::iterator i=SideOne->begin(); i != SideOne->end(); i++)
-    {
-		TXY* Xy	= *i;
+		long LSX1 = (long)(SX1 + 0.5);
+		long LSY1 = (long)(SY1 + 0.5);
+		SideOne->Add(LSX1, LSY1);
 
-		write_fortschritt("%d %d %d\n",	++Count, Xy->X,	Xy->Y);
-    }
+		SideZero->Add(LSX1, LSY1);
 
-    write_fortschritt("\n");
+		while (i < size())
+		{
+			TXY *Xy = *iter++;
+
+			SideZero->Add(Xy->X, Xy->Y);
+
+			i++;
+		}
+
+/*
+		write_fortschritt("\n");
+
+		int Count = 0;
+		for	(TXYList::iterator i=SideZero->begin();	i != SideZero->end(); i++)
+		{
+			TXY* Xy	= *i;
+
+			write_fortschritt("%d %d %d\n",	++Count, Xy->X,	Xy->Y);
+		}
+		write_fortschritt("\n");
+
+		Count = 0;
+		for	(TXYList::iterator i=SideOne->begin(); i != SideOne->end(); i++)
+		{
+			TXY* Xy	= *i;
+
+			write_fortschritt("%d %d %d\n",	++Count, Xy->X,	Xy->Y);
+		}
+		write_fortschritt("\n");
 */
 
-	// Nun haben wir 2 Polygone
-	// Als nächstes	wird getestet, welches das richtige ist.
+		// Nun haben wir 2 Polygone
+		// Als nächstes	wird getestet, welches das richtige ist.
 
 
-	// Falls das ProfilPolygon größer als das Begrenzungspolygon ist,
-    // werden hier die Punkte innerhalb	gezählt
-	int IsInsideZeroCount =	0;
-    for	(TXYList::iterator i=SideZero->begin();	i != SideZero->end(); i++)
-    {
-		TXY* Xy	= *i;
+		// Falls das ProfilPolygon größer als das Begrenzungspolygon ist,
+		// werden hier die Punkte innerhalb	gezählt
+		int IsInsideZeroCount =	0;
+		for	(TXYList::iterator i=SideZero->begin(); i != SideZero->end(); i++)
+		{
+			TXY* Xy	= *i;
 
-		if (ProfilPolygon->IsInsideXYList(Xy->X, Xy->Y))	IsInsideZeroCount++;
-    }
+			if (ProfilPolygon->IsInsideXYList(Xy->X, Xy->Y))	IsInsideZeroCount++;
+		}
 
-	int IsInsideOneCount = 0;
-    for	(TXYList::iterator i=SideOne->begin(); i != SideOne->end(); i++)
-    {
-		TXY* Xy	= *i;
+		int IsInsideOneCount = 0;
+		for	(TXYList::iterator i=SideOne->begin(); i != SideOne->end(); i++)
+		{
+			TXY* Xy	= *i;
 
-		if (ProfilPolygon->IsInsideXYList(Xy->X, Xy->Y))	IsInsideOneCount++;
-    }
+			if (ProfilPolygon->IsInsideXYList(Xy->X, Xy->Y))	IsInsideOneCount++;
+		}
 
-	// Falls das ProfilPolygon kleiner als das Begrenzungspolygon ist,
-    // werden hier die Punkte innerhalb	gezählt
-    for	(TXYList::iterator i=ProfilPolygon->begin(); i != ProfilPolygon->end();	i++)
-    {
-		TXY* Xy	= *i;
+		// Falls das ProfilPolygon kleiner als das Begrenzungspolygon ist,
+		// werden hier die Punkte innerhalb	gezählt
+		for	(TXYList::iterator i=ProfilPolygon->begin(); i != ProfilPolygon->end();	i++)
+		{
+			TXY* Xy	= *i;
 
-		if (SideZero->IsInsideXYList(Xy->X, Xy->Y))	IsInsideZeroCount++;
-		if (SideOne->IsInsideXYList(Xy->X, Xy->Y))	IsInsideOneCount++;
-    }
+			if (SideZero->IsInsideXYList(Xy->X, Xy->Y))	IsInsideZeroCount++;
+			if (SideOne->IsInsideXYList(Xy->X, Xy->Y))	IsInsideOneCount++;
+		}
 
-	delete CutXyList;
+		delete CutXyList;
 
-    if (IsInsideZeroCount > IsInsideOneCount)
-    {
-		delete SideOne;
-	    return (SideZero);
-    }
-    else
-    {
-		delete SideZero;
-		return (SideOne);
-    }
+		if (IsInsideZeroCount > IsInsideOneCount)
+		{
+			delete SideOne;
+			return (SideZero);
+		}
+		else
+		{
+			delete SideZero;
+			return (SideOne);
+		}
+	}
 }
 
 //---------------------------------------------------------------------



More information about the Wsplgen-commits mailing list