/* ---- 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}}] //paragraph [10] Footnote: [{\footnote{] [}}] //[TOC] [\tableofcontents] //[bl] [\\] [1] Implementation of Module April 2015 Rene Steinbrueck [TOC] 1 Overview 2 Inclusion of the Header File */ #include "LineFunctionAlgebra.h" //#include #include "Algebras/Geoid/Geoid.h" /* 3.1 Type Constructor ~lubool~ Type ~lubool~ represents an (linterval, boolvalue)-pair. 3.1.1 List Representation The list representation of an ~lubool~ is ---- ( lengthInterval bool-value ) ---- For example: ---- ( 1.0 5.2 TRUE FALSE) TRUE ) ---- 3.1.2 function Describing the Signature of the Type Constructor */ ListExpr LUBoolProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LUNIT"), nl->StringAtom("(lubool) "), nl->StringAtom("(lengthInterval bool) "), nl->StringAtom("((1.3 5.2 FALSE FALSE) TRUE)")))); } /* 3.1.3 Kind Checking Function */ bool CheckLUBool( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LUBool::BasicType() )); } /* 3.1.4 Creation of the type constructor ~lubool~ */ TypeConstructor lunitbool( LUBool::BasicType(), //name LUBoolProperty, //property function describing signature OutConstLengthUnit, InConstLengthUnit, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateConstLengthUnit, DeleteConstLengthUnit, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseConstLengthUnit, CloneConstLengthUnit, //object close and clone CastConstLengthUnit, //cast function SizeOfConstLengthUnit, //sizeof function CheckLUBool ); //kind checking function /* 3.2 Type Constructor ~luint~ Type ~luint~ represents an (linterval, intvalue)-pair. 3.2.1 List Representation The list representation of an ~luint~ is ---- ( lengthInterval int-value ) ---- For example: ---- ( ( 1.0 5.7 TRUE FALSE) 5 ) ---- 3.2.2 function Describing the Signature of the Type Constructor */ ListExpr LUIntProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LUNIT"), nl->StringAtom("(luint) "), nl->StringAtom("(lengthInterval int) "), nl->StringAtom("((1.3 5.2 FALSE FALSE) 1)")))); } /* 3.2.3 Kind Checking Function */ bool CheckLUInt( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LUInt::BasicType() )); } /* 3.2.4 Creation of the type constructor ~luint~ */ TypeConstructor lunitint( LUInt::BasicType(), //name LUIntProperty, //property function describing signature OutConstLengthUnit, InConstLengthUnit, //Out and In functions 0, 0,//SaveToList and RestoreFromList functions CreateConstLengthUnit, DeleteConstLengthUnit, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseConstLengthUnit, CloneConstLengthUnit, //object close and clone CastConstLengthUnit, //cast function SizeOfConstLengthUnit, //sizeof function CheckLUInt ); //kind checking function /* 3.3 Type Constructor ~lustring~ Type ~lustring~ represents an (linterval, intvalue)-pair. 3.3.1 List Representation The list representation of an ~lustring~ is ---- ( lengthInterval string-value ) ---- For example: ---- ( ( 1.0 5.7 TRUE FALSE) "Hello" ) ---- 3.3.2 function Describing the Signature of the Type Constructor */ ListExpr LUStringProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LUNIT"), nl->StringAtom("(lustring) "), nl->StringAtom("(lengthInterval string) "), nl->StringAtom("((1.3 5.2 FALSE FALSE) 'Hello')")))); } /* 3.3.3 Kind Checking Function */ bool CheckLUString( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LUString::BasicType() )); } /* 3.3.4 Creation of the type constructor ~lustring~ */ TypeConstructor lunitstring( LUString::BasicType(), //name LUStringProperty, //property function describing signature OutConstLengthUnit, InConstLengthUnit, //Out and In functions 0, 0,//SaveToList and RestoreFromList functions CreateConstLengthUnit, DeleteConstLengthUnit, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseConstLengthUnit, CloneConstLengthUnit, //object close and clone CastConstLengthUnit, //cast function SizeOfConstLengthUnit, //sizeof function CheckLUString ); /* 3.4 Type Constructor ~lureal~ Type ~lureal~ represents an (linterval, (m,n))-pair, where m and n are real numbers. 3.4.1 List Representation The list representation of an ~lureal~ is ---- ( lengthInterval m n ) ---- For example: ---- ( (1.0 5.7 TRUE FALSE) (3.2 4.5) ) ---- 3.4.2 Function Describing the Signature of the Type Constructor */ ListExpr LURealProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LUNIT"), nl->StringAtom("("+LUReal::BasicType()+") "), nl->StringAtom("( lengthInterval (real1 real2)) "), nl->StringAtom("((1.3 5.2 TRUE FALSE) (1.0 2.2))")))); } /* 3.4.3 Kind Checking Function */ bool CheckLUReal( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LUReal::BasicType() )); } /* 3.4.4 ~Out~-function */ ListExpr OutLUReal( ListExpr typeInfo, Word value ) { LUReal* lureal = (LUReal*)(value.addr); if ( !lureal->IsDefined() ) return (nl->SymbolAtom(Symbol::UNDEFINED())); else { ListExpr lengthIntervalList = nl->FourElemList( OutCcReal( nl->TheEmptyList(), SetWord(&lureal->lengthInterval.start) ), OutCcReal( nl->TheEmptyList(), SetWord(&lureal->lengthInterval.end) ), nl->BoolAtom( lureal->lengthInterval.lc ), nl->BoolAtom( lureal->lengthInterval.rc)); ListExpr realfunList = nl->TwoElemList( nl->RealAtom( lureal->m), nl->RealAtom( lureal->n)); return nl->TwoElemList(lengthIntervalList, realfunList ); } } /* 3.4.5 ~In~-function */ Word InLUReal( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { std::string errmsg; correct = true; if ( nl->ListLength( instance ) == 2 ) { ListExpr first = nl->First( instance ); if( nl->ListLength( first ) == 4 && nl->IsAtom( nl->Third( first ) ) && nl->AtomType( nl->Third( first ) ) == BoolType && nl->IsAtom( nl->Fourth( first ) ) && nl->AtomType( nl->Fourth( first ) ) == BoolType ) { CcReal *start = (CcReal *)InCcReal( nl->TheEmptyList(), nl->First( first ), errorPos, errorInfo, correct ).addr; if( !correct || !start->IsDefined() ) { errmsg = "InLUReal(): Error in first instant (Must be defined!)."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; return SetWord( Address(0) ); } CcReal *end = (CcReal *)InCcReal( nl->TheEmptyList(), nl->Second( first ), errorPos, errorInfo, correct ).addr; if( !correct || !end->IsDefined() ) { errmsg = "InLUReal(): Error in second instant (Must be defined!)."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; delete end; return SetWord( Address(0) ); } LInterval linterval( *start, *end, nl->BoolValue( nl->Third( first ) ), nl->BoolValue( nl->Fourth( first ) ) ); delete start; delete end; correct = linterval.IsValid(); if ( !correct ) { errmsg = "InLUReal(): Non valid length interval."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } ListExpr second = nl->Second( instance ); if( nl->ListLength( second ) == 2 && nl->IsAtom( nl->First( second ) ) && nl->AtomType( nl->First( second ) ) == RealType && nl->IsAtom( nl->Second( second ) ) && nl->AtomType( nl->Second( second ) ) == RealType ) { LUReal *lureal = new LUReal( linterval, nl->RealValue( nl->First( second ) ), nl->RealValue( nl->Second( second ) )); if( lureal->IsValid() ) { correct = true; return SetWord( lureal ); } delete lureal; } } } else if ( listutils::isSymbolUndefined(instance) ) { LUReal *lureal = new LUReal(); lureal->SetDefined(false); lureal->lengthInterval=LInterval(true); correct = lureal->lengthInterval.IsValid(); if ( correct ) return (SetWord( lureal )); } errmsg = "InLUReal(): Non valid representation."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); correct = false; return SetWord( Address(0) ); } /* 3.4.6 ~Create~-function */ Word CreateLUReal( const ListExpr typeInfo ) { return (SetWord( new LUReal(false) )); } /* 3.4.7 ~Delete~-function */ void DeleteLUReal( const ListExpr typeInfo, Word& w ) { delete (LUReal *)w.addr; w.addr = 0; } /* 3.4.8 ~Close~-function */ void CloseLUReal( const ListExpr typeInfo, Word& w ) { delete (LUReal *)w.addr; w.addr = 0; } /* 3.4.9 ~Clone~-function */ Word CloneLUReal( const ListExpr typeInfo, const Word& w ) { LUReal *lureal = (LUReal *)w.addr; return SetWord( new LUReal( *lureal ) ); } /* 3.4.10 ~Sizeof~-function */ int SizeOfLUReal() { return sizeof(LUReal); } /* 3.4.11 ~Cast~-function */ void* CastLUReal(void* addr) { return new (addr) LUReal; } /* 3.4.12 Creation of the type constructor ~lureal~ */ TypeConstructor lunitreal( LUReal::BasicType(), //name LURealProperty, //property function describing signature OutLUReal, InLUReal, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateLUReal, DeleteLUReal, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseLUReal, CloneLUReal, //object close and clone CastLUReal, //cast function SizeOfLUReal, //sizeof function CheckLUReal ); //kind checking function /* 3.5 Type Constructor ~lbool~ Type ~lbool~ represents a length boolean. 3.5.1 List Representation The list representation of a ~lbool~ is ---- ( u1 ... un ) ---- ,where u1, ..., un are units of type ~lubool~. For example: ---- ( ( (1.0 5.4 TRUE FALSE) TRUE ) ( (5.5 6.8 FALSE FALSE) FALSE ) ) ---- 3.5.2 function Describing the Signature of the Type Constructor */ ListExpr LBoolProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LMAPPING"), nl->StringAtom("(lbool) "), nl->StringAtom("( u1 ... un)"), nl->StringAtom("(((1.3 5.2 TRUE TRUE) TRUE) ...)")))); } /* 3.5.3 Kind Checking Function This function checks whether the type constructor is applied correctly. */ bool CheckLBool( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LBool::BasicType() )); } /* 3.5.4 Creation of the type constructor ~lbool~ */ TypeConstructor lengthbool( LBool::BasicType(), //name LBoolProperty, //property function describing signature OutLMapping >, InLMapping >, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateLMapping, DeleteLMapping, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseLMapping, CloneLMapping, //object close and clone CastLMapping, //cast function SizeOfLMapping, //sizeof function CheckLBool ); //kind checking function /* 3.6 Type Constructor ~lint~ Type ~lint~ represents a length integer. 3.6.1 List Representation The list representation of a ~lint~ is ---- ( u1 ... un ) ---- ,where u1, ..., un are units of type ~lint~. For example: ---- ( ( 1.0 5.4 TRUE FALSE) 1 ) ( 5.5 8.2 FALSE FALSE) 4 ) ) ---- 3.6.2 function Describing the Signature of the Type Constructor */ ListExpr LIntProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LMAPPING"), nl->StringAtom("(lint) "), nl->StringAtom("( u1 ... un)"), nl->StringAtom("(((1.3 5.2 TRUE TRUE) 1) ...)")))); } /* 3.6.3 Kind Checking Function This function checks whether the type constructor is applied correctly. */ bool CheckLInt( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LInt::BasicType() )); } /* 3.6.4 Creation of the type constructor ~lint~ */ TypeConstructor lengthint( LInt::BasicType(), //name LIntProperty, //property function describing signature OutLMapping >, InLMapping >, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateLMapping, DeleteLMapping, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseLMapping, CloneLMapping, //object close and clone CastLMapping, //cast function SizeOfLMapping, //sizeof function CheckLInt ); //kind checking function /* 3.7 Type Constructor ~lstring~ Type ~lstring~ represents a length string. 3.7.1 List Representation The list representation of a ~lstring~ is ---- ( u1 ... un ) ---- ,where u1, ..., un are units of type ~lstring~. For example: ---- ( ( 1.0 5.4 TRUE FALSE) 1 ) ( 5.5 8.2 FALSE FALSE) 4 ) ) ---- 3.7.2 function Describing the Signature of the Type Constructor */ ListExpr LStringProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LMAPPING"), nl->StringAtom("(lstring) "), nl->StringAtom("( u1 ... un)"), nl->StringAtom("(((1.3 5.2 TRUE TRUE) 1) ...)")))); } /* 3.7.3 Kind Checking Function This function checks whether the type constructor is applied correctly. */ bool CheckLString( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LString::BasicType() )); } /* 3.7.4 Creation of the type constructor ~lstring~ */ TypeConstructor lengthstring( LString::BasicType(), //name LStringProperty, //property function describing signature OutLMapping >, InLMapping >, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateLMapping, DeleteLMapping, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseLMapping, CloneLMapping, //object close and clone CastLMapping, //cast function SizeOfLMapping, //sizeof function CheckLString ); //kind checking function /* 3.8 Type Constructor ~lreal~ Type ~lreal~ represents a length real. 3.8.1 List Representation The list representation of a ~lreal~ is ---- ( u1 ... un ) ---- ,where u1, ..., un are units of type ~lureal~. For example: ---- ( ( 6.37 9.9 TRUE FALSE) (1.0 2.3) ) ( 11.4 13.9 FALSE FALSE) (2.0 2.8) ) ) ---- 3.8.2 function Describing the Signature of the Type Constructor */ ListExpr LRealProperty() { return (nl->TwoElemList( nl->FourElemList(nl->StringAtom("Signature"), nl->StringAtom("Example Type List"), nl->StringAtom("List Rep"), nl->StringAtom("Example List")), nl->FourElemList(nl->StringAtom("-> LMAPPING"), nl->StringAtom("(lreal) "), nl->StringAtom("( u1 ... un) "), nl->StringAtom("(((1.3 5.2 TRUE FALSE) (1.0 2.2)) ...)")))); } /* 3.8.3 Kind Checking Function */ bool CheckLReal( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, LReal::BasicType() )); } /* 3.8.4 Creation of the type constructor ~lreal~ */ TypeConstructor lengthreal( LReal::BasicType(), //name LRealProperty, //property function describing signature OutLMapping, InLMapping, //Out and In functions 0, 0, //SaveToList and RestoreFromList functions CreateLMapping, DeleteLMapping, //object creation and deletion OpenAttribute, SaveAttribute, // object open and save CloseLMapping, CloneLMapping, //object close and clone CastLMapping, //cast function SizeOfLMapping, //sizeof function CheckLReal ); //kind checking function /* 4 Operators */ double DistanceWithHeight(const Point& pointSource, const Point& pointTarget, CcReal& weight, LReal& heightfunction, const Geoid* geoid ) { assert( pointSource.IsDefined() ); assert( pointTarget.IsDefined() ); assert( !geoid || geoid->IsDefined() ); assert( weight.IsDefined() ); const Geoid mygeoid(Geoid::WGS1984); bool ok = false; double bearInitial = 0, bearFinal = 0; // std::cout << "LineFunctionA.cpp mygeoid: \t Address: " << mygeoid ; // std::cout << "\t Content: " << mygeoid << "\n"; double distance = pointSource.DistanceOrthodromePrecise(pointTarget, mygeoid,ok,bearInitial,bearFinal); /*hier muesste das Gewicht pro Steigung uebergeben werden und die HeightDifference Methode angepasst werden, wenn es diese Tabellenfunktion geben soll*/ double height= HeightDifference(heightfunction); //distance und height sind hier in koordinateneinheiten, nicht in metern double distanceWithHeigt= distance + (height * weight.GetValue()); return distanceWithHeigt; } double HeightDifference(LReal heightfunction) { double heightDiff=0; if(!heightfunction.IsDefined()){ return heightDiff; } heightfunction.Print(cout); // cout << heightfunction.GetNoComponents() << "\n"; for (int i = 0; i < heightfunction.GetNoComponents(); i++) { LUReal unit; // cout << "LFA.cpp Line " << __LINE__ << ", i: " << i << "\n"; heightfunction.Get(i,unit); //Steigung des Intervals double steigung=unit.m; double intervStart=unit.getLengthInterval().start.GetRealval(); double intervEnd=unit.getLengthInterval().end.GetRealval(); //Laenge des Intervals double intervalLength= intervEnd-intervStart; if(steigung>0){ heightDiff=heightDiff + steigung*intervalLength; } //cout<< "m:" << steigung <<"\t istart:"<, heightatpositionFun, 0 }; int heightatpositionSelectFun(ListExpr args) { NList type(args); if (type.first().isSymbol(raster2::sint::BasicType())) { return (0); }; if (type.first().isSymbol(raster2::sreal::BasicType())) { return (1); }; return (-1); } ListExpr heightatpositionTypeMap(ListExpr args) { if(!nl->HasLength(args,2)) { return (listutils::typeError("2 arguments expected")); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); std::string err = "stype x point expected"; if(!raster2::util::isSType(arg1)) return (listutils::typeError(err + " (first arg is not an stype)")); if(!Point::checkType(arg2)) return (listutils::typeError(err + " (second arg is not an point)")); return (nl->SymbolAtom(CcReal::BasicType())); } /* 1.2 Operator ~lcompose~ */ struct lcomposeInfo : OperatorInfo { lcomposeInfo() { name = "lcompose"; signature = raster2::sbool::BasicType() + " lcompose " + SimpleLine::BasicType() + " , " + CcBool::BasicType() + "-> lbool"; appendSignature(raster2::sreal::BasicType() + " lcompose " + SimpleLine::BasicType() + " , " + CcBool::BasicType() + "-> lreal"); appendSignature(raster2::sint::BasicType() + " lcompose " + SimpleLine::BasicType() + " , " + CcBool::BasicType() + "-> lint"); appendSignature(raster2::sstring::BasicType() + " lcompose " + SimpleLine::BasicType() + " , " + CcBool::BasicType() + "-> lstring"); syntax = "_ lcompose [_,_]"; meaning = "This function merges sline, sT and boolean into lT. " "If the bool parameter is TRUE, the Distance between " "two points on the line is calculated by orthodrome " "distance, otherwise by the euclidean distance."; } }; template int constlcomposeFun (Word* args, Word& result, int message, Word& local, Supplier s) { // storage for the result result = qp->ResultStorage(s); // the sT object ST* raster = static_cast(args[0].addr); // the simple Line SimpleLine* simpleLine = static_cast(args[1].addr); // the computation method for distance //(true = Distance Orthodrome, false = Euclidean Distance) CcBool* distCalc = static_cast(args[2].addr); // The result of the lcompose RT* pResult = static_cast(result.addr); if (!simpleLine->IsDefined() || !raster->isDefined()) { pResult->SetDefined(false); return 0; } pResult->Clear(); pResult->StartBulkLoad(); // get the number of components int num = simpleLine->Size(); HalfSegment unit; raster2::grid2 grid = raster->getGrid(); raster2::grid2::index_type cell1; raster2::grid2::index_type cell2; double start = 0.0; double end = 0.0; bool definedGeoID; bool distOrthodrome = distCalc->GetBoolval(); if (simpleLine->StartsSmaller()) { for (int i = 0; i < num; i++) { simpleLine->Get(i,unit); if (unit.IsLeftDomPoint()) { // get the coordinates double xStart = unit.GetLeftPoint().GetX(); double yStart = unit.GetLeftPoint().GetY(); double xEnd = unit.GetRightPoint().GetX(); double yEnd = unit.GetRightPoint().GetY(); start = end; double distance = distOrthodrome ? unit.GetLeftPoint().DistanceOrthodrome( unit.GetRightPoint(),Geoid(true),definedGeoID)/1000 : unit.GetLeftPoint().Distance(unit.GetRightPoint()); end = start + distance; cell1 = grid.getIndex(xStart,yStart); cell2 = grid.getIndex(xEnd, yEnd); if(cell1==cell2) { // only a constant unit in result LInterval linterval(CcReal(start), CcReal(end),true, (i==(num-2))?true:false); typename ST::cell_type v1 = raster->atlocation( (xEnd-xStart)/2,(yEnd-yStart)/2); if(!raster->isUndefined(v1)) { typename ST::wrapper_type v(v1); pResult->MergeAdd(UT(linterval,v)); } } else { CellIterator it(grid,xStart,yStart,xEnd,yEnd); double dx = xEnd - xStart; double dy = yEnd - yStart; while(it.hasNext()) { std::pair p = it.next(); double s = start + (distance*p.first); double e = start + (distance*p.second); if(e>s) { LInterval linterval(CcReal(s), CcReal(e),true,(i==(num-2))?true:false); double delta =(p.first + p.second) / 2.0; double x = xStart + delta*dx; double y = yStart + delta*dy; typename ST::cell_type v1 = raster->atlocation(x,y); if(!raster->isUndefined(v1)) { typename ST::wrapper_type v(v1); pResult->MergeAdd(UT(linterval,v)); } } else assert(e==s); } } } } } else { for (int i = num-1; i >=0; i--) { simpleLine->Get(i,unit); if (!unit.IsLeftDomPoint()) { // get the coordinates double xStart = unit.GetRightPoint().GetX(); double yStart = unit.GetRightPoint().GetY(); double xEnd = unit.GetLeftPoint().GetX(); double yEnd = unit.GetLeftPoint().GetY(); start = end; double distance = distOrthodrome ? unit.GetRightPoint().DistanceOrthodrome( unit.GetLeftPoint(),Geoid(true),definedGeoID)/1000 : unit.GetRightPoint().Distance(unit.GetLeftPoint()); end = start + distance; cell1 = grid.getIndex(xStart,yStart); cell2 = grid.getIndex(xEnd, yEnd); if(cell1==cell2) { // only a constant unit in result LInterval linterval(CcReal(start), CcReal(end),true, (i==0)?true:false); typename ST::cell_type v1 = raster->atlocation((xEnd-xStart)/2,(yEnd-yStart)/2); if(!raster->isUndefined(v1)) { typename ST::wrapper_type v(v1); pResult->MergeAdd(UT(linterval,v)); } } else { CellIterator it(grid,xStart,yStart,xEnd,yEnd); double dx = xEnd - xStart; double dy = yEnd - yStart; while(it.hasNext()) { std::pair p = it.next(); double s = start + (distance*p.first); double e = start + (distance*p.second); if(e>s) { LInterval linterval(CcReal(s), CcReal(e),true,(i==0)?true:false); double delta =(p.first + p.second) / 2.0; double x = xStart + delta*dx; double y = yStart + delta*dy; typename ST::cell_type v1 = raster->atlocation(x,y); if(!raster->isUndefined(v1)) { typename ST::wrapper_type v(v1); pResult->MergeAdd(UT(linterval,v)); } } else assert(e==s); } } } } } pResult->EndBulkLoad(); return 0; } template int reallcomposeFun (Word* args, Word& result, int message, Word& local, Supplier s) { // storage for the result result = qp->ResultStorage(s); // the sT object ST* raster = static_cast(args[0].addr); // the simple Line SimpleLine* simpleLine = static_cast(args[1].addr); // the computation method for distance //(true = Distance Orthodrome, false = Euclidean Distance) CcBool* distCalc = static_cast(args[2].addr); // The result of the lcompose LReal* pResult = static_cast(result.addr); if (!simpleLine->IsDefined() || !raster->isDefined()) { pResult->SetDefined(false); return 0; } pResult->Clear(); pResult->StartBulkLoad(); // get the number of components int num = simpleLine->Size(); HalfSegment unit; raster2::grid2 grid = raster->getGrid(); raster2::grid2::index_type cell1; raster2::grid2::index_type cell2; double start = 0.0; double end = 0.0; bool definedGeoID; bool distOrthodrome = distCalc->GetBoolval(); if (simpleLine->StartsSmaller()) { for (int i = 0; i < num; i++) { simpleLine->Get(i,unit); if (unit.IsLeftDomPoint()) { // get the coordinates double xStart = unit.GetLeftPoint().GetX(); double yStart = unit.GetLeftPoint().GetY(); double xEnd = unit.GetRightPoint().GetX(); double yEnd = unit.GetRightPoint().GetY(); start = end; double distance = distOrthodrome ? unit.GetLeftPoint().DistanceOrthodrome( unit.GetRightPoint(),Geoid(true),definedGeoID)/1000 : unit.GetLeftPoint().Distance(unit.GetRightPoint()); end = start + distance; cell1 = grid.getIndex(xStart,yStart); cell2 = grid.getIndex(xEnd, yEnd); if(cell1==cell2) { // only a constant unit in result LInterval linterval(CcReal(start), CcReal(end), true, (i==(num-2))?true:false); double v1 = getHeightAtPosition(xStart,yStart,*raster); double v2 = getHeightAtPosition(xEnd,yEnd,*raster); if(!raster->isUndefined(v1) && !raster->isUndefined(v2)) pResult->MergeAdd(LUReal(linterval,v1,v2,false)); } else { CellIterator it(grid,xStart,yStart,xEnd,yEnd); double dx = xEnd - xStart; double dy = yEnd - yStart; while(it.hasNext()) { std::pair p = it.next(); double s = start + (distance*p.first); double e = start + (distance*p.second); if(e>s) { LInterval linterval(CcReal(s), CcReal(e),true,(i==(num-2))?true:false); double xs = xStart + p.first * dx; double ys = yStart + p.first * dy; double xe = xStart + p.second * dx; double ye = yStart + p.second * dy; double v1 = getHeightAtPosition(xs,ys,*raster); double v2 = getHeightAtPosition(xe,ye,*raster); if(!raster->isUndefined(v1) && !raster->isUndefined(v2)) pResult->MergeAdd( LUReal(linterval,v1,v2,false)); } else assert(e==s); } } } } } else { for (int i = num-1; i >=0; i--) { simpleLine->Get(i,unit); if (!unit.IsLeftDomPoint()) { // get the coordinates double xStart = unit.GetLeftPoint().GetX(); double yStart = unit.GetLeftPoint().GetY(); double xEnd = unit.GetRightPoint().GetX(); double yEnd = unit.GetRightPoint().GetY(); start = end; double distance = distOrthodrome ? unit.GetLeftPoint().DistanceOrthodrome( unit.GetRightPoint(),Geoid(true),definedGeoID)/1000 : unit.GetLeftPoint().Distance(unit.GetRightPoint()); end = start + distance; cell1 = grid.getIndex(xStart,yStart); cell2 = grid.getIndex(xEnd, yEnd); if(cell1==cell2) { // only a constant unit in result LInterval linterval(CcReal(start), CcReal(end), true, (i==0)?true:false); double v1 = getHeightAtPosition(xStart,yStart,*raster); double v2 = getHeightAtPosition(xEnd,yEnd,*raster); if(!raster->isUndefined(v1) && !raster->isUndefined(v2)) pResult->MergeAdd(LUReal(linterval,v1,v2,false)); } else { CellIterator it(grid,xStart,yStart,xEnd,yEnd); double dx = xEnd - xStart; double dy = yEnd - yStart; while(it.hasNext()) { std::pair p = it.next(); double s = start + (distance*p.first); double e = start + (distance*p.second); if(e>s) { LInterval linterval( CcReal(s),CcReal(e),true,(i==0)?true:false); double xs = xStart + p.first * dx; double ys = yStart + p.first * dy; double xe = xStart + p.second * dx; double ye = yStart + p.second * dy; double v1 = getHeightAtPosition(xs,ys,*raster); double v2 = getHeightAtPosition(xe,ye,*raster); if(!raster->isUndefined(v1) && !raster->isUndefined(v2)) pResult->MergeAdd( LUReal(linterval,v1,v2,false)); } else assert(e==s); } } } } } pResult->EndBulkLoad(); return 0; } ValueMapping lcomposeFuns[] = { constlcomposeFun, constlcomposeFun, reallcomposeFun, reallcomposeFun, 0 }; int lcomposeSelectFun(ListExpr args) { std::string errmsg = "lcomposeSelectFun started"; NList type(args); if (type.first().isSymbol(raster2::sbool::BasicType())) return 0; if (type.first().isSymbol(raster2::sstring::BasicType())) return 1; if (type.first().isSymbol(raster2::sint::BasicType())) return 2; if(type.first().isSymbol(raster2::sreal::BasicType())) return 3; return -1; //this point should never be reached } ListExpr lcomposeTypeMap(ListExpr args) { std::string errmsg = "lcomposeTypeMap started"; if(!nl->HasLength(args,3)) return listutils::typeError("3 arguments expected"); ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); std::string err = "stype x sline x bool expected"; if(!raster2::util::isSType(arg1)) return listutils::typeError(err + " (first arg is not an stype)"); if(!SimpleLine::checkType(arg2)) return listutils::typeError(err + " (second arg is not an sline)"); if(!CcBool::checkType(arg3)) return listutils::typeError(err + " (third arg is not an bool)"); std::string sname = nl->SymbolValue(arg1); if (sname==raster2::sbool::BasicType()) return (nl->SymbolAtom(LBool::BasicType())); if (sname==raster2::sstring::BasicType()) return (nl->SymbolAtom(LString::BasicType())); if (sname==raster2::sreal::BasicType()) return (nl->SymbolAtom(LReal::BasicType())); if (sname==raster2::sint::BasicType()) return (nl->SymbolAtom(LReal::BasicType())); return listutils::typeError(); } /* 1.3 Operator ~lfdistance~ */ struct lfdistanceInfo : OperatorInfo { lfdistanceInfo() { name = "lfdistance"; signature = "lfdistance (" + Point::BasicType() + " , " + Point::BasicType() + ", " + raster2::sint::BasicType() + " , " + CcInt::BasicType() + "-> Real"; appendSignature("lfdistance (" + Point::BasicType() + " , " + Point::BasicType() + " , " + raster2::sreal::BasicType() + " , " + CcInt::BasicType() + "-> Real"); syntax = "lfdistance ( _ , _ , _ , _ )"; meaning = "This function computes the distance " "between two points including their height. " "The First two parameters are " "the two points, between the distance " "should be calculated " "and the third parameter is a raster, " "from which the height " "could be get. " "The fourth parameter is 1 or 2: " "1 for computing the pure " "driving distance or " "2 for computing the driving distance, " "depending on the gradient."; } }; template int lfdistanceFun (Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); Point* a = static_cast(args[0].addr); Point* b = static_cast(args[1].addr); Raster* raster = static_cast(args[2].addr); CcInt* suchart = static_cast(args[3].addr); CcReal* res = static_cast(result.addr); bool checkCoord; if(!a->IsDefined() || !b->IsDefined() || a->IsEmpty() || b->IsEmpty() || !suchart->IsDefined() || !( suchart->GetIntval() == 1 || suchart->GetIntval() == 2 ) ) { res->SetDefined(false); } else { if (suchart->GetIntval() == 1) { double airDistance = a->DistanceOrthodrome(*b,Geoid(true),checkCoord); double heightA=getHeightAtPosition(a->GetX(),a->GetY(),*raster); double heightB=getHeightAtPosition(b->GetX(),b->GetY(),*raster); double dheight=heightB-heightA; double drivingDistance=sqrt(pow(dheight,2)+pow(airDistance,2)); res->Set(true, drivingDistance); } if (suchart->GetIntval() == 2) { double airDistance = a->DistanceOrthodrome(*b,Geoid(true),checkCoord); double heightA=getHeightAtPosition(a->GetX(),a->GetY(),*raster); double heightB=getHeightAtPosition(b->GetX(),b->GetY(),*raster); double dheight=heightB-heightA; double drivingDistance=sqrt(pow(dheight,2)+pow(airDistance,2)); double climb = dheight/airDistance; double dist=0.0; if ((climb < (-1.0))||(climb > 1.0)) res->SetDefined(false); else if ((climb >= -1.00)&&(climb <= -0.10)) dist = drivingDistance * 0.30; else if ((climb > -0.10)&&(climb < -0.01)) dist = drivingDistance * 0.60; else if ((climb >= -0.01)&&(climb <= 0.01)) dist = drivingDistance * 1.00; else if ((climb > 0.01)&&(climb < 0.02)) dist = drivingDistance * 1.25; else if ((climb >= 0.02)&&(climb < 0.05)) dist = drivingDistance * 1.75; else if ((climb >= 0.05)&&(climb < 0.10)) dist = drivingDistance * 2.75; else if ((climb >= 0.10)&&(climb <= 1.00)) dist = drivingDistance * 20.00; res->Set(true,dist); } } return (0); } ValueMapping lfdistanceFuns[] = { lfdistanceFun, lfdistanceFun, 0 }; int lfdistanceSelectFun(ListExpr args) { NList type(args); if (type.third().isSymbol(raster2::sint::BasicType())) { return (0); } if(type.third().isSymbol(raster2::sreal::BasicType())) { return (1); } return (-1); } ListExpr lfdistanceTypeMap(ListExpr args) { if(!nl->HasLength(args,4)){ return (listutils::typeError("4 arguments expected")); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); ListExpr arg4 = nl->Fourth(args); std::string err = "Point x Point x stype x int expected"; if(!Point::checkType(arg1)) { return (listutils::typeError(err + " (first arg is not an point)")); } if(!Point::checkType(arg2)) { return (listutils::typeError(err + " (second arg is not an point)")); } if(!raster2::util::isSType(arg3)){ return (listutils::typeError(err + " (third arg is not an stype)")); } if(!CcInt::checkType(arg4)) { return (listutils::typeError(err + " (fourth arg is not an int)")); } return (listutils::basicSymbol()); } /* 1.4 Operator ~lfdistanceparam~ */ struct lfdistanceparamInfo : OperatorInfo { lfdistanceparamInfo() { name = "lfdistanceparam"; signature = "lfdistanceparam (" + Point::BasicType() + " , " + Point::BasicType() + " , " + raster2::sint::BasicType() + " , " + CcString::BasicType() + " , " + CcString::BasicType() + " , " + CcString::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + "-> Real )"; appendSignature("lfdistanceparam (" + Point::BasicType() + " , " + Point::BasicType() + " , " + raster2::sreal::BasicType() + " , " + CcString::BasicType() + " , " + CcString::BasicType() + " , " + CcString::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + " , " + CcReal::BasicType() + "-> Real )"); syntax = "lfdistanceparam ( _ , _ , _ , _ , _ , _ , " "_ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ )"; meaning = "This function computes the distance " "between two points including their height. " "The First two parameters are the two points, " "between the distance should be calculated " "and the third parameter is a raster, " "from which the height could be get. " "Parameter fith, six and seven is used " "to pass the sort of way, the dependence to " "a cycle route and the surface. " "With the last parameters the dependence " "on the sort of way, " "the gradient and the surface can be set. " "Put in Zero for default value."; } }; template int lfdistanceparamFun (Word* args, Word& result, int message, Word& local, Supplier s) { result = qp->ResultStorage(s); Point* a = static_cast(args[0].addr); Point* b = static_cast(args[1].addr); Raster* raster = static_cast(args[2].addr); CcString* roadType = static_cast(args[3].addr); CcString* routePart = static_cast(args[4].addr); CcString* surface = static_cast(args[5].addr); CcReal* w1 = static_cast(args[6].addr); CcReal* w2 = static_cast(args[7].addr); CcReal* w3 = static_cast(args[8].addr); CcReal* w4 = static_cast(args[9].addr); CcReal* s1 = static_cast(args[10].addr); CcReal* s2 = static_cast(args[11].addr); CcReal* s3 = static_cast(args[12].addr); CcReal* s4 = static_cast(args[13].addr); CcReal* s5 = static_cast(args[14].addr); CcReal* s6 = static_cast(args[15].addr); CcReal* s7 = static_cast(args[16].addr); CcReal* o1 = static_cast(args[17].addr); CcReal* o2 = static_cast(args[18].addr); CcReal* o3 = static_cast(args[19].addr); CcReal* o4 = static_cast(args[20].addr); CcReal* res = static_cast(result.addr); bool checkCoord; double wayFactor; if ((routePart->toText()=="yes") && (w1->GetRealval()!=0.0)) wayFactor = w1->GetRealval(); else if ((routePart->toText()=="yes") && (w1->GetRealval()==0.0)) wayFactor = 0.5; else if ((roadType->toText()=="cycleway") && (w2->GetRealval()!=0.0)) wayFactor = w2->GetRealval(); else if ((roadType->toText()=="cycleway") && (w2->GetRealval()==0.0)) wayFactor = 0.5; else if ((roadType->toText()=="track" || roadType->toText() == "path") && (w3->GetRealval()!=0.0)) wayFactor = w3->GetRealval(); else if ((roadType->toText()=="trunk" || roadType->toText()=="primary" || roadType->toText()=="secondary" || roadType->toText()=="tertiary" || roadType->toText()=="unclassified" || roadType->toText()=="residential" || roadType->toText()=="trunk") && (w4->GetRealval()!=0.0)) wayFactor = w4->GetRealval(); else if ((roadType->toText()=="trunk" || roadType->toText()=="primary" || roadType->toText()=="secondary" || roadType->toText()=="tertiary" || roadType->toText()=="unclassified" || roadType->toText()=="residential" || roadType->toText()=="trunk") && (w4->GetRealval()==0.0)) wayFactor = 2.0; else wayFactor = 1.0; double surfaceFactor; if ((surface->toText()=="paved" || surface->toText()=="asphalt" || surface->toText()=="concrete") && (o1->GetRealval() != 0.0)) surfaceFactor = o1->GetRealval(); else if ((surface->toText()=="cobblestone" || surface->toText()=="cobblestone:flattened" || surface->toText()=="sett" || surface->toText()=="concrete:lanes" || surface->toText()=="concrete:plates" || surface->toText()=="paving_stones" || surface->toText()=="metal" || surface->toText()=="wood" || surface->toText()=="paving_stones:30" || surface->toText()=="paving_stones:20" ) && (o2->GetRealval()!=0.0)) surfaceFactor = o2->GetRealval(); else if ((surface->toText()=="unpaved" || surface->toText()=="compacted" || surface->toText()=="dirt" || surface->toText()=="earth" || surface->toText()=="grass" || surface->toText() == "grass_paver" || surface->toText()=="ground" || surface->toText()=="mud" || surface->toText()=="ice" || surface->toText()=="salt" || surface->toText()=="sand" || surface->toText()=="snow"|| surface->toText()=="woodchips" ) && (o3->GetRealval()!=0.0)) surfaceFactor = o3->GetRealval(); else if ((surface->toText()=="gravel" || surface->toText()=="pebblestone" ) && (o4->GetRealval()!=0.0)) surfaceFactor = o4->GetRealval(); else if ((surface->toText()=="gravel" || surface->toText()=="pebblestone" ) && (o4->GetRealval()==0.0)) surfaceFactor = 3.0; else surfaceFactor = 1.0; if(!a->IsDefined() || !b->IsDefined() || a->IsEmpty() || b->IsEmpty() ) { res->SetDefined(false); } else { double airDistance = a->DistanceOrthodrome(*b,Geoid(true),checkCoord); double heightA=getHeightAtPosition(a->GetX(),a->GetY(),*raster); double heightB=getHeightAtPosition(b->GetX(),b->GetY(),*raster); double dheight=heightB-heightA; double drivingDistance=sqrt(pow(dheight,2)+pow(airDistance,2)); double climb = dheight/airDistance; double dist=0; if ((climb < (-1.0))||(climb > 1.0)) res->SetDefined(false); else if ((climb >= -1.00)&&(climb <= -0.10)) dist = drivingDistance * (s1->GetRealval()!=0 ? s1->GetRealval() : 0.30); else if ((climb > -0.10)&&(climb < -0.01)) dist = drivingDistance * (s2->GetRealval()!=0 ? s2->GetRealval() : 0.60); else if ((climb >= -0.01)&&(climb <= 0.01)) dist = drivingDistance * (s3->GetRealval()!=0 ? s3->GetRealval() : 1.00); else if ((climb > 0.01)&&(climb < 0.02)) dist = drivingDistance * (s4->GetRealval()!=0 ? s4->GetRealval() : 1.25); else if ((climb >= 0.02)&&(climb < 0.05)) dist = drivingDistance * (s5->GetRealval()!=0 ? s5->GetRealval() : 1.75); else if ((climb >= 0.05)&&(climb < 0.10)) dist = drivingDistance * (s6->GetRealval()!=0 ? s6->GetRealval() : 2.75); else if ((climb >= 0.10)&&(climb <= 1.00)) dist = drivingDistance * (s7->GetRealval()!=0 ? s7->GetRealval() : 20.00); dist = dist * wayFactor * surfaceFactor; res->Set(true,dist); } return (0); } ValueMapping lfdistanceparamFuns[] = { lfdistanceparamFun, lfdistanceparamFun, 0 }; int lfdistanceparamSelectFun(ListExpr args) { NList type(args); if (type.third().isSymbol(raster2::sint::BasicType())) { return (0); } if(type.third().isSymbol(raster2::sreal::BasicType())) { return (1); } return (-1); } ListExpr lfdistanceparamTypeMap(ListExpr args) { if(!nl->HasLength(args,21)){ return (listutils::typeError("21 arguments expected")); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); ListExpr arg4 = nl->Fourth(args); ListExpr arg5 = nl->Fifth(args); ListExpr arg6 = nl->Sixth(args); std::string err = "Point x Point x stype x 3 string x 15 real expected "; if(!Point::checkType(arg1)) { return (listutils::typeError(err + " (arg 1 is not an point)")); } if(!Point::checkType(arg2)) { return (listutils::typeError(err + " (arg 2 is not an point)")); } if(!raster2::util::isSType(arg3)) { return (listutils::typeError(err + " (arg 3 is not an stype)")); } if(!CcString::checkType(arg4)) { return (listutils::typeError(err + " (arg 4 arg is not an string)")); } if(!CcString::checkType(arg5)) { return (listutils::typeError(err + " (arg 5 is not an string)")); } if(!CcString::checkType(arg6)) { return (listutils::typeError(err + " (arg 6 is not an string)")); } NList type(args); if(!CcReal::checkType(type.elem(7).listExpr())) { return (listutils::typeError(err + "arg 7 is not an real ")); } if(!CcReal::checkType(type.elem(8).listExpr())) { return (listutils::typeError(err + "arg 8 is not an real ")); } if(!CcReal::checkType(type.elem(9).listExpr())) { return (listutils::typeError(err + "arg 9 is not an real ")); } if(!CcReal::checkType(type.elem(10).listExpr())) { return (listutils::typeError(err + "arg 10 is not an real ")); } if(!CcReal::checkType(type.elem(11).listExpr())) { return (listutils::typeError(err + "arg 11 is not an real ")); } if(!CcReal::checkType(type.elem(12).listExpr())) { return (listutils::typeError(err + "arg 12 is not an real ")); } if(!CcReal::checkType(type.elem(13).listExpr())) { return (listutils::typeError(err + "arg 13 is not an real ")); } if(!CcReal::checkType(type.elem(14).listExpr())) { return (listutils::typeError(err + "arg 14 is not an real ")); } if(!CcReal::checkType(type.elem(15).listExpr())) { return (listutils::typeError(err + "arg 15 is not an real ")); } if(!CcReal::checkType(type.elem(16).listExpr())) { return (listutils::typeError(err + "arg 16 is not an real ")); } if(!CcReal::checkType(type.elem(17).listExpr())) { return (listutils::typeError(err + "arg 17 is not an real ")); } if(!CcReal::checkType(type.elem(18).listExpr())) { return (listutils::typeError(err + "arg 18 is not an real ")); } if(!CcReal::checkType(type.elem(19).listExpr())) { return (listutils::typeError(err + "arg 19 is not an real ")); } if(!CcReal::checkType(type.elem(20).listExpr())) { return (listutils::typeError(err + "arg 20 is not an real ")); } if(!CcReal::checkType(type.elem(21).listExpr())) { return (listutils::typeError(err + "arg 21 is not an real ")); } return (listutils::basicSymbol()); } /* 1.5 Operator ~distanceWithGradient~ */ struct distanceWithGradientInfo : OperatorInfo { distanceWithGradientInfo() {//Point,Point,CcReal, LReal> name = "distanceWithGradient"; signature = "distanceWithGradient (" + Point::BasicType() + " , " + Point::BasicType() + " , " + CcReal::BasicType() + " , " + LReal::BasicType() + "-> Real"; appendSignature("distanceWithGradient (" + Point::BasicType() + " , " + Point::BasicType() + " , " + CcReal::BasicType() + " , " + LReal::BasicType() + "-> Real"); syntax = "distanceWithGradient ( _ , _ , _ , _ )"; meaning = "This function computes the distance " "between two points including their height. " "The First two parameters are " "the two points, between the distance " "should be calculated. " "The third parameter gives the weight for the gradient." "The fourth parameter is a lreal with linear functions " "from which the height could be get. " ; } }; int distanceWithGradientFun( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage( s ); CcReal* res = static_cast(result.addr); // const Geoid* geoid =0; const Geoid geoid(Geoid::WGS1984); //Argumente auseinander nehmen und casten Point* pointSource = static_cast(args[0].addr); Point* pointTarget = static_cast(args[1].addr); CcReal* weight = static_cast(args[2].addr); LReal* heightfunction = static_cast(args[3].addr); double distance=DistanceWithHeight(*pointSource,*pointTarget,*weight, *heightfunction,&geoid); res->Set(true,distance); return 0; } ListExpr distanceWithGradientTypeMap(ListExpr args) { if(!nl->HasLength(args,4)){ return (listutils::typeError("4 arguments expected")); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); ListExpr arg4 = nl->Fourth(args); std::string err = "Point x Point x CcReal x LReal expected"; if(!Point::checkType(arg1)) { return (listutils::typeError(err + " (first arg is not a point)")); } if(!Point::checkType(arg2)) { return (listutils::typeError(err + " (second arg is not a point)")); } if(!CcReal::checkType(arg3)){ return (listutils::typeError(err + " (third arg is not a ccreal)")); } if(!LReal::checkType(arg4)) { return (listutils::typeError(err + " (fourth arg is not a LReal)")); } //return listutils::typeError(); return (listutils::basicSymbol()); } /* 1.5 Operator ~lfResult~ */ struct lfResultInfo : OperatorInfo { lfResultInfo() { name = "lfResult"; signature = "lfResult (Real,LReal)->Real"; appendSignature("lfResult (Real,LReal)->Real"); syntax = "lfResult ( _ , _ )"; meaning = "A LReal is a datatype which consists of " "multiple linear functions for given intervals" "This function computes the result at a given position of a LReal. " "The first parameter is the value for x in a linear function " "like (y=m*x +n). " "The second parameter is the LReal which includes all linear functions" "with interval." "The result is the y of the linear function " ; } }; int lfResultFun( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage( s ); CcReal* res = static_cast(result.addr); //Argumente auseinander nehmen und casten CcReal* xValue = static_cast(args[0].addr); LReal* heightfunction = static_cast(args[1].addr); double x = xValue->GetRealval(); double y; res->Set(false,0.0); for (int i = 0; i < heightfunction->GetNoComponents(); i++) { LUReal unit; heightfunction->Get(i,unit); double intervStart=unit.getLengthInterval().start.GetRealval(); double intervEnd=unit.getLengthInterval().end.GetRealval(); if ((intervStart <= x) && (x <= intervEnd)){ //Steigung und Anfangshoehe der Funktion double m=unit.m; double n=unit.n; //Lineare Funktion ausrechnen y= (m * x) + n; res->Set(true,y); break; } } return 0; } ListExpr lfResultTypeMap(ListExpr args) { if(!nl->HasLength(args,2)){ return (listutils::typeError("2 arguments expected")); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); std::string err = "CcReal x LReal expected"; if(!CcReal::checkType(arg1)){ return (listutils::typeError(err + " (first arg is not a ccreal)")); } if(!LReal::checkType(arg2)) { return (listutils::typeError(err + " (second arg is not a LReal)")); } //return listutils::typeError(); return (listutils::basicSymbol()); } Operator distanceWithGradient ( distanceWithGradientInfo(), distanceWithGradientFun, distanceWithGradientTypeMap ); Operator lfResult ( lfResultInfo(), lfResultFun, lfResultTypeMap ); Operator lcompose ( lcomposeInfo(), lcomposeFuns, lcomposeSelectFun, lcomposeTypeMap ); Operator heightatposition ( heightatpositionInfo(), heightatpositionFuns, heightatpositionSelectFun, heightatpositionTypeMap ); Operator lfdistance ( lfdistanceInfo(), lfdistanceFuns, lfdistanceSelectFun, lfdistanceTypeMap ); Operator lfdistanceparam ( lfdistanceparamInfo(), lfdistanceparamFuns, lfdistanceparamSelectFun, lfdistanceparamTypeMap ); /* 5 Creating the Algebra */ class LineFunctionAlgebra : public Algebra { public: LineFunctionAlgebra() : Algebra() { AddTypeConstructor( &lunitbool ); AddTypeConstructor( &lunitint ); AddTypeConstructor( &lunitstring ); AddTypeConstructor( &lunitreal ); AddTypeConstructor( &lengthbool ); AddTypeConstructor( &lengthint ); AddTypeConstructor( &lengthstring ); AddTypeConstructor( &lengthreal ); lunitbool.AssociateKind( Kind::DATA() ); lunitint.AssociateKind( Kind::DATA() ); lunitstring.AssociateKind( Kind::DATA() ); lunitreal.AssociateKind( Kind::DATA() ); lengthbool.AssociateKind( Kind::DATA() ); lengthint.AssociateKind( Kind::DATA() ); lengthstring.AssociateKind( Kind::DATA() ); lengthreal.AssociateKind( Kind::DATA() ); AddOperator( &lcompose ); AddOperator( &heightatposition ); AddOperator( &lfdistance ); AddOperator( &lfdistanceparam); AddOperator( &distanceWithGradient); AddOperator( &lfResult); } ~LineFunctionAlgebra() {}; }; /* 6 Initialization Each algebra module needs an initialization function. The algebra manager has a reference to this function if this algebra is included in the list of required algebras, thus forcing the linker to include this module. The algebra manager invokes this function to get a reference to the instance of the algebra class and to provide references to the global nested list container (used to store constructor, type, operator and object information) and to the query processor. The function has a C interface to make it possible to load the algebra dynamically at runtime. */ extern "C" Algebra* InitializeLineFunctionAlgebra( NestedList* nlRef, QueryProcessor* qpRef ) { nl = nlRef; qp = qpRef; return (new LineFunctionAlgebra()); }