/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}] //[TOC] [\tableofcontents] [1] Header file of the LineFunctionAlgebra April 2015 - Rene Steinbrueck 1 Overview With LineFunctionAlgebra , it is possible to describe the height depending on the distance traveled. [TOC] 2 Defines, includes, and constants */ #ifndef LINEFUNCTION_ALGEBRA_H #define LINEFUNCTION_ALGEBRA_H #include "LMapping.h" # include "ConstLengthUnit.h" #include "LUReal.h" #include "./../Raster2/sbool.h" #include "./../Raster2/sint.h" #include "./../Raster2/sstring.h" #include "./../Raster2/sreal.h" #include "./../Raster2/util/types.h" #include "./../Raster2/Operators/CellIterator.h" #include "./../Spatial/Point.h" #include "./../Spatial/HalfSegment.h" #include "./../Spatial/SpatialAlgebra.h" #include "./../FText/FTextAlgebra.h" double DistanceWithHeight(const Point&,const Point&, CcReal&, LReal&, const Geoid*); double HeightDifference(LReal) ; /* 0 Functions for Operators 0.1 getHeightAtPosition */ template double getHeightAtPosition (const double xcoord, const double ycoord, const T& raster) { Point P, TL, TC, TR, CL, CC, CR, BL, BC, BR; double glength = raster.getGrid().getLength(); double ox = raster.getGrid().getOriginX(); double oy = raster.getGrid().getOriginY(); P.Set (xcoord, ycoord); CC.Set (floor((xcoord-ox)/glength) * glength + ox + glength/2, floor((ycoord-oy)/glength) * glength + oy + glength/2); CL.Set (CC.GetX () - glength, CC.GetY ()); CR.Set (CC.GetX () + glength, CC.GetY ()); TL.Set (CC.GetX () - glength, CC.GetY () + glength); TC.Set (CC.GetX (), CC.GetY () + glength); TR.Set (CC.GetX () + glength, CC.GetY () + glength); BL.Set (CC.GetX () - glength, CC.GetY () - glength); BC.Set (CC.GetX (), CC.GetY () - glength); BR.Set (CC.GetX () + glength, CC.GetY () - glength); if (P==CC) { double res = raster.atlocation(P.GetX (), P.GetY ()); return (raster.isUndefined(res) ? raster2::UNDEFINED_REAL() : res); } Point A = CC; Point B = CL; Point C = BC; double DistA = P.Distance(A); double DistB = P.Distance(B); double DistC = P.Distance(C); double DistTmp = P.Distance(TL); bool undefined = raster.isUndefined(raster.atlocation(TL.GetX(), TL.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = TL; } else if (DistTmp < DistC) { DistC = DistTmp; C = TL; } } DistTmp = P.Distance(TC); undefined = raster.isUndefined(raster.atlocation(TC.GetX(), TC.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = TC; } else if (DistTmp < DistC) { DistC = DistTmp; C = TC; } } DistTmp = P.Distance(TR); undefined = raster.isUndefined(raster.atlocation(TR.GetX(), TR.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = TR; } else if (DistTmp < DistC) { DistC = DistTmp; C = TR; } } DistTmp = P.Distance(BL); undefined = raster.isUndefined(raster.atlocation(BL.GetX(),BL.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = BL; } else if (DistTmp < DistC) { DistC = DistTmp; C = BL; } } DistTmp = P.Distance(BR); undefined = raster.isUndefined(raster.atlocation(BR.GetX(), BR.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = BR; } else if (DistTmp < DistC) { DistC = DistTmp; C = BR; } } DistTmp = P.Distance(CR); undefined = raster.isUndefined(raster.atlocation(CR.GetX(), CR.GetY())); if (!undefined) { if (DistTmp < DistB) { if (DistB < DistC) { DistC=DistB; C=B; } DistB = DistTmp; B = CR; } else if (DistTmp < DistC) { DistC = DistTmp; C = CR; } } double DistAB = A.Distance(B); double DistAC = A.Distance(C); double DistBC = B.Distance(C); //http://www.arndt-bruenner.de/mathe/9/herondreieck.htm // whole triangle double s = (DistAB + DistAC + DistBC) / 2; double A_whole = sqrt (s * (s - DistAB)*(s - DistAC)*(s - DistBC)); //alpha s = (DistB + DistC + DistBC) / 2; double A_alpha = sqrt (s * (s - DistB)*(s - DistC)*(s - DistBC)); double alpha = A_alpha / A_whole; //beta s = (DistA + DistC + DistAC) / 2; double A_beta = sqrt (s * (s - DistA)*(s - DistC)*(s - DistAC)); double beta = A_beta / A_whole; //gamma s = (DistA + DistB + DistAB) / 2; double A_gamma = sqrt (s * (s - DistA)*(s - DistB)*(s - DistAB)); double gamma = A_gamma / A_whole; double valueA = raster.atlocation(A.GetX (), A.GetY ()); double valueB = raster.atlocation(B.GetX (), B.GetY ()); double valueC = raster.atlocation(C.GetX (), C.GetY ()); bool undefinedA = raster.isUndefined(raster.atlocation(A.GetX (), A.GetY ())); bool undefinedB = raster.isUndefined(raster.atlocation(B.GetX (), B.GetY ())); bool undefinedC = raster.isUndefined(raster.atlocation(C.GetX (), C.GetY ())); if (undefinedA && !undefinedB && !undefinedC) return (beta/(beta+gamma)*valueB+gamma/(beta+gamma)*valueC); if (!undefinedA && undefinedB && !undefinedC) return (alpha/(alpha+gamma)*valueA+gamma/(alpha+gamma)*valueC); if (!undefinedA && !undefinedB && undefinedC) return (alpha/(alpha+beta)*valueA+beta/(alpha+beta)*valueB); if (undefinedA && undefinedB && !undefinedC) return (valueC); if (undefinedA && !undefinedB && undefinedC) return (valueB); if (!undefinedA && undefinedB && undefinedC) return (valueA); if (undefinedA && undefinedB && undefinedC) return (raster2::UNDEFINED_REAL()); return ((alpha * valueA) + (beta * valueB) + (gamma * valueC)); } /* 1 Operators 1.1 Operator ~heightatposition~ */ struct heightatpositionInfo : OperatorInfo { heightatpositionInfo () { name = "heightatposition"; signature = raster2::sint::BasicType () + " heightatposition " + Point::BasicType () + " -> real"; appendSignature ( raster2::sreal::BasicType () + " heightatposition " + Point::BasicType () + " -> real"); syntax = "_ heightatposition _ "; meaning = "This function returns the interpolated " "height at the raster position."; } }; template int heightatpositionFun(Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); CcReal* pResult = static_cast(result.addr); Point* pPoint = static_cast(args[1].addr); T* praster = static_cast(args[0].addr); if(!pPoint->IsDefined() || !praster->isDefined()) { pResult->SetDefined(false); } else { (*pResult) = raster2::sreal::wrap(getHeightAtPosition(pPoint->GetX(), pPoint->GetY(), *praster)); } return 0; } #endif // LINEFUNCTION_ALGEBRA_H