/* ---- 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] Source File of the Transportation Mode Algebra Dec, 2010 Jianqiu Xu [TOC] 1 Overview This source file essentially contains the necessary implementations for indoor environment */ #include "Indoor.h" #include "GeneralType.h" #include "PaveGraph.h" #include "SecParser.h" using namespace std; using namespace temporalalgebra; using namespace datetime; extern NestedList *nl; extern QueryProcessor *qp; extern AlgebraManager *am; //////////////////////////////////////////////////////////////////////// /////////////////////////// Point3D //////////////////////////////////// ////////////////////////////////////////////////////////////////////////// Point3D::Point3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { valueRecord.Read(&x, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&y, sizeof(double), offset); offset += sizeof(double); valueRecord.Read(&z, sizeof(double), offset); offset += sizeof(double); SetDefined(true); } bool Point3D::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { // cout<<"Point3D::Save()"<IsDefined()){ return nl->ThreeElemList( nl->RealAtom(p3d->GetX()), nl->RealAtom(p3d->GetY()), nl->RealAtom(p3d->GetZ()) ); }else return nl->SymbolAtom("undef"); } /* input function for data type point3d */ Word InPoint3D(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct) { correct = true; if( nl->ListLength( instance ) == 3 ) { ListExpr first = nl->First(instance); ListExpr second = nl->Second(instance); ListExpr third = nl->Third(instance); correct = listutils::isNumeric(first) && listutils::isNumeric(second) && listutils::isNumeric(third); if(!correct){ return SetWord( Address(0) ); } else { return SetWord(new Point3D(true, listutils::getNumValue(first), listutils::getNumValue(second), listutils::getNumValue(third))); } } else if( listutils::isSymbol( instance, "undef" ) ){ return SetWord(new Point3D(false)); } correct = false; return SetWord( Address(0) ); } /* Creation of the type constructor instance for point3d */ ListExpr Point3DProperty() { 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("-> DATA"), nl->StringAtom("point3d"), nl->StringAtom("(x y z)"), nl->StringAtom("(10 5 2)"))); } Word CreatePoint3D(const ListExpr typeInfo) { return SetWord (new Point3D(false)); } void DeletePoint3D(const ListExpr typeInfo, Word& w) { // ((Point3D*)w.addr)->DeleteIfAllowed(); Point3D* p3d = (Point3D*)w.addr; delete p3d; w.addr = NULL; } void ClosePoint3D(const ListExpr typeInfo, Word& w) { // ((Point3D*)w.addr)->DeleteIfAllowed(); Point3D* p3d = (Point3D*)w.addr; delete p3d; w.addr = NULL; } Word ClonePoint3D(const ListExpr typeInfo, const Word& w) { Point3D* p3d = new Point3D(*(Point3D*)w.addr); return SetWord(p3d); } void* CastPoint3D(void* addr) { return new (addr)Point3D(); } int SizeOfPoint3D() { return sizeof(Point3D); } bool CheckPoint3D(ListExpr type, ListExpr& errorInfo) { return nl->IsEqual(type, "point3d"); } /* save function for point3d */ bool SavePoint3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { Point3D* p3d = (Point3D*)value.addr; return p3d->Save(valueRecord, offset, typeInfo); } bool OpenPoint3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { value.addr = new Point3D(valueRecord, offset, typeInfo); return value.addr != NULL; } ostream& operator<<(ostream& o, const Point3D& loc) { if(loc.IsDefined()){ o<<"( "<(true), points( initsize ) { // cout<<"constructor1 "<(ps.IsDefined()), points( ps.Size() ) { // cout<<"constructor2"<= 0 && i < NumOfFLOBs() ); return &points; } inline size_t Line3D::Sizeof() const { return sizeof( *this ); } inline void Line3D::Resize(const int newSize){ if(newSize>Size()){ points.resize(newSize); } } inline void Line3D::TrimToSize(){ points.TrimToSize(); } void Line3D::RemoveDuplicates() { } /* sort 3d points in a line */ void Line3D::Sort(const bool exact /*= true*/) { } void Line3D::Clear() { points.clean(); } void Line3D::StartBulkLoad() { } Line3D& Line3D::operator+=( const Point3D& p ) { if(!IsDefined()){ return *this; } points.Append(p); return *this; } bool Line3D::IsValid() const { return true; } size_t Line3D::HashValue() const { return (size_t)0.0; } void Line3D::CopyFrom( const Attribute* right ) { // cout<<"Line3D CopyFrom"<IsOrdered() ); *this = *ps; } /* end bulkload for a line3d */ void Line3D::EndBulkLoad( bool sort, bool remDup, bool trim ) { if( !IsDefined() ) { Clear(); SetDefined( false ); } if( sort ){ Sort(); } if( remDup ){ RemoveDuplicates(); } if(trim){ points.TrimToSize(); } } Line3D& Line3D::operator=( const Line3D& ps ) { // cout<<"Line3D = "<(&ps); for(int i = 0;i < l->Size();i++){ Point3D p; l->Get(i, p); points.Append(p); } SetDefined(ps.IsDefined()); return *this; } bool Line3D::operator==( const Line3D& l) const { vector ps_list1; vector ps_list2; if(Size() != l.Size()) return false; for(int i = 0;i < points.Size();i++){ Point3D p; points.Get(i, p); ps_list1.push_back(p); } for(int i = 0;i < l.Size();i++){ Point3D p; l.Get(i, p); ps_list2.push_back(p); } sort(ps_list1.begin(), ps_list1.end()); sort(ps_list2.begin(), ps_list2.end()); for(unsigned int i = 0;i < ps_list1.size();i++){ if(!(ps_list1[i] == ps_list2[i])) return false; } return true; } bool Line3D::Adjacent( const Attribute* arg ) const { return 0; } int Line3D::Compare( const Attribute* arg ) const { return 0; } int Line3D::CompareAlmost( const Attribute* arg ) const { return 0; } double Line3D::Distance( const Rectangle<3>& r,const Geoid* geoid) const { return 0.0; } double Line3D::Length() { double length = 0.0; for(int i = 0;i < points.Size() - 1;i++){ Point3D p1; points.Get(i, p1); Point3D p2; points.Get(i + 1, p2); length += p1.Distance(p2); } return length; } ostream& Line3D::Print(ostream& o) const { for(int i = 0;i < points.Size();i++){ Point3D p; points.Get(i , p); p.Print(o); } return o; } const Rectangle<3> Line3D::BoundingBox(const Geoid* geoid) const { // return new Rectangle<3>(true,0.0,0.0,0.0,0.0,0.0,0.0); // cout<<"Rectangle<3> BoundingBox "<::max(); max[i] = numeric_limits::min(); } for(int i = 0;i < points.Size();i++){ Point3D p; points.Get(i, p); min[0] = MIN(p.GetX(), min[0]); min[1] = MIN(p.GetY(), min[1]); min[2] = MIN(p.GetZ(), min[2]); max[0] = MAX(p.GetX(), max[0]); max[1] = MAX(p.GetY(), max[1]); max[2] = MAX(p.GetZ(), max[2]); } Rectangle<3> bbox3d(true, min, max); return bbox3d; } /* List Representation The list representation of a point is ---- (x y) ---- ~Out~-function */ ListExpr OutLine3D( ListExpr typeInfo, Word value ) { Line3D* points = (Line3D*)(value.addr); if(!points->IsDefined()){ return nl->SymbolAtom("undef"); } if( points->IsEmpty() ) return nl->TheEmptyList(); // Point p; Point3D p; assert( points->Get( 0, p ) ); /* ListExpr result = nl->OneElemList( OutPoint( nl->TheEmptyList(), SetWord( (void*)&p ) ) );*/ ListExpr result = nl->OneElemList( OutPoint3D( nl->TheEmptyList(), SetWord( (void*)&p ) ) ); ListExpr last = result; for( int i = 1; i < points->Size(); i++ ) { assert( points->Get( i, p ) ); /* last = nl->Append( last, OutPoint( nl->TheEmptyList(), SetWord( (void*)&p ) ) );*/ last = nl->Append( last, OutPoint3D( nl->TheEmptyList(), SetWord( (void*)&p))); } return result; } /* In function */ Word InLine3D( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { if(nl->IsEqual(instance,"undef")) { Points* points = new Points(0); points->Clear(); points->SetDefined(false); correct=true; return SetWord( Address(points) ); } Line3D* points = new Line3D( max(0,nl->ListLength( instance) ) ); points->SetDefined( true ); if(nl->AtomType(instance)!=NoAtom) { points->DeleteIfAllowed(); correct = false; cout << __PRETTY_FUNCTION__ << ": Unexpected Atom!" << endl; return SetWord( Address(points) ); } ListExpr rest = instance; points->StartBulkLoad(); while( !nl->IsEmpty( rest ) ) { ListExpr first = nl->First( rest ); rest = nl->Rest( rest ); /* Point *p = (Point*)InPoint( nl->TheEmptyList(), first, 0, errorInfo, correct ).addr;*/ Point3D *p = (Point3D*)InPoint3D( nl->TheEmptyList(), first, 0, errorInfo, correct ).addr; if( correct && p->IsDefined() ) { (*points) += (*p); delete p; } else { if(p) { delete p; } cout << __PRETTY_FUNCTION__ << ": Incorrect or undefined point!" << endl; points->DeleteIfAllowed(); correct = false; return SetWord( Address(0) ); } } points->EndBulkLoad(); if( points->IsValid() ) { correct = true; return SetWord( points ); } points->DeleteIfAllowed(); correct = false; cout << __PRETTY_FUNCTION__ << ": Invalid points value!" << endl; return SetWord( Address(0) ); } /* Create function */ Word CreateLine3D( const ListExpr typeInfo ) { // cout<<"CreateLine3D "<Destroy(); ps->DeleteIfAllowed(false); w.addr = 0; } /* Close function */ void CloseLine3D( const ListExpr typeInfo, Word& w ) { // cout<<"CloseLine3D "<DeleteIfAllowed(); w.addr = 0; } /* Clone function */ Word CloneLine3D( const ListExpr typeInfo, const Word& w ) { return SetWord( new Line3D( *((Line3D *)w.addr) ) ); } /* Open function */ bool OpenLine3D( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { Line3D *ps = (Line3D*)Attribute::Open( valueRecord, offset, typeInfo ); value = SetWord( ps ); return true; } /* Save function */ bool SaveLine3D( SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value ) { Line3D *ps = (Line3D*)value.addr; Attribute::Save( valueRecord, offset, typeInfo, ps ); return true; } /* SizeOf function */ int SizeOfLine3D() { return sizeof(Line3D); } ListExpr Line3DProperty() { 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("-> DATA"), nl->StringAtom("line3d"), nl->StringAtom("(*) where point3d is ()"), nl->StringAtom("( (10 1 2)(4 5 3) )")))); } bool CheckLine3D( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, "line3d" )); } ////////////////////////////////////////////////////////////////////////// ////////////////////////// Floor3D ///////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /* Constructor function for Floor3D */ Floor3D::Floor3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo): StandardSpatialAttribute<2>(true),reg(0) { // cout<<"Floor3D(SmiRecord& , size_t& , const ListExpr) here"<SymbolAtom("region"); ListExpr xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); Region* r = (Region*)Attribute::Open(valueRecord,offset,xNumericType); reg = *r; // cout<<*r<DeleteIfAllowed(); SetDefined(true); } bool Floor3D::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { // cout<<"Save()"<SymbolAtom("region"); ListExpr xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); Attribute::Save(valueRecord, offset, xNumericType, ®); return true; } /* Creation of the type constructor instance for floor3d */ ListExpr Floor3DProperty() { // cout<<"Floor3DProperty()"<TextAtom(); nl->AppendText(examplelist,"thefloor(floor_height, polygon)"); return nl->TwoElemList( nl->TwoElemList(nl->StringAtom("Creation"), nl->StringAtom("Example Creation")), nl->TwoElemList(examplelist, nl->StringAtom("(let room1=thefloor(0, r))")) ); } /* OutPut function for floor3d */ ListExpr OutFloor3D(ListExpr typeInfo, Word value) { // cout<<"OutFloor3D()"<IsDefined()){ return nl->SymbolAtom("undef"); } if( fl->IsEmpty() ){ return (nl->TheEmptyList()); } else{ Region* cr = const_cast(fl->GetRegion()); ListExpr regionNL = OutRegion(nl->TheEmptyList(), SetWord(cr)); return nl->TwoElemList(nl->RealAtom(fl->GetHeight()), regionNL); } } /* input function for data type floor3d a float value for ground height and a region for space covered */ Word InFloor3D(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct) { // cout<<"InFloor3D()"<ListLength(instance) != 2){ string strErrorMessage = "floor3d(): List length must be 2"; errorInfo = nl->Append(errorInfo,nl->StringAtom(strErrorMessage)); correct = false; return SetWord(Address(0)); } if (nl->IsAtom(instance)){ correct=false; return SetWord( Address(0) ); } if(nl->IsEqual(instance,"undef")){ correct=false; return SetWord(Address(0)); } ListExpr height_list = nl->First(instance); if(!nl->IsAtom(height_list) || nl->AtomType(height_list) != RealType){ string strErrorMessage = "floor3d(): height must be float type"; errorInfo = nl->Append(errorInfo,nl->StringAtom(strErrorMessage)); correct = false; return SetWord(Address(0)); } float height = nl->RealValue(height_list); // cout<<"height "<Second(instance),errorPos, errorInfo,correct); Region* cr = (Region*)reg_addr.addr; Floor3D* fl = new Floor3D(height, *cr); cr->DeleteIfAllowed(); return SetWord(fl); } void CloseFloor3D(const ListExpr typeInfo, Word& w) { // cout<<"CloseFloor3D()"<DeleteIfAllowed(); delete static_cast (w.addr); w.addr = NULL; } Word CloneFloor3D(const ListExpr typeInfo, const Word& w) { // cout<<"CloneFloor3D()"<IsEqual(type, "floor3d"); } /* open function for floor3d */ bool OpenFloor3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenFloor3D()"<Save(valueRecord, offset, typeInfo); } /////////////////////////////////////////////////////////////////////////// ///////////////////////////// Door3D ///////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /* Constructor function for Door3D */ Door3D::Door3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo):StandardSpatialAttribute<2>(true), door_pos1(0),door_pos2(0), tpstate(0) { valueRecord.Read(&oid1, sizeof(unsigned int), offset); offset += sizeof(unsigned int); ListExpr xType = nl->SymbolAtom("line"); ListExpr xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); Line* l1 = (Line*)Attribute::Open(valueRecord,offset,xNumericType); door_pos1 = *l1; l1->DeleteIfAllowed(); valueRecord.Read(&oid2, sizeof(unsigned int), offset); offset += sizeof(unsigned int); Line* l2 = (Line*)Attribute::Open(valueRecord,offset,xNumericType); door_pos2 = *l2; l2->DeleteIfAllowed(); xType = nl->SymbolAtom("mbool"); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); MBool* mb = (MBool*)Attribute::Open(valueRecord,offset,xNumericType); tpstate = *mb; // cout<SymbolAtom("line"); ListExpr xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); Attribute::Save(valueRecord, offset, xNumericType, &door_pos1); valueRecord.Write(&oid2, sizeof(unsigned int),offset); offset += sizeof(unsigned int); Attribute::Save(valueRecord, offset, xNumericType, &door_pos2); xType = nl->SymbolAtom("mbool"); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); Attribute::Save(valueRecord, offset, xNumericType, &tpstate); valueRecord.Write(&lift_door, sizeof(bool), offset); offset += sizeof(bool); return true; } /* Door3D Property function */ ListExpr Door3DProperty() { 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("-> DATA"), nl->StringAtom("door3d"), nl->StringAtom("() (int line int line mbool bool)"), nl->StringAtom("(oid1 l1 oid2 l2 doorstat type)")))); } ListExpr OutDoor3D( ListExpr typeInfo, Word value ) { // cout<<"OutDoor3D()"<IsDefined()){ return nl->SymbolAtom("undef"); } if( dr->IsEmpty() ){ return nl->TheEmptyList(); } ListExpr l1 = OutLine(nl->TheEmptyList(), SetWord(dr->GetLoc(1))); ListExpr l2 = OutLine(nl->TheEmptyList(), SetWord(dr->GetLoc(2))); ListExpr tempstate = OutMapping >(nl->TheEmptyList(), SetWord(dr->GetTState())); ListExpr list1 = nl->TwoElemList(nl->IntAtom(dr->GetOid(1)), l1); ListExpr list2 = nl->TwoElemList(nl->IntAtom(dr->GetOid(2)), l2); return nl->FourElemList(list1, list2, tempstate, nl->BoolAtom(dr->GetDoorType())); } /* In function for door3d */ Word InDoor3D( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { if(nl->IsEqual(instance,"undef")) { Door3D* dr = new Door3D(); dr->SetDefined(false); correct=true; return SetWord(Address(dr)); } //////////////////////////////////////////////////////////////////////// /////////////////////// get the first genrange ///////////////////////// /////////////////////////////////////////////////////////////////////// ListExpr first_instance = nl->First(instance); ListExpr oid_list1 = nl->First(first_instance); if(!nl->IsAtom(oid_list1) || nl->AtomType(oid_list1) != IntType){ string strErrorMessage = "genrange(): obj id must be int type"; errorInfo = nl->Append(errorInfo,nl->StringAtom(strErrorMessage)); correct = false; return SetWord(Address(0)); } unsigned int oid1 = nl->IntValue(oid_list1); ListExpr rest = nl->Second(first_instance); Line* l1 = (Line*)(InLine(typeInfo,rest,errorPos,errorInfo,correct).addr); /////////////////////////////////////////////////////////////////////////// //////////////////////// get the second oid and line ////////////////////// /////////////////////////////////////////////////////////////////////////// ListExpr second_instance = nl->Second(instance); ListExpr oid_list2 = nl->First(second_instance); if(!nl->IsAtom(oid_list2) || nl->AtomType(oid_list2) != IntType){ string strErrorMessage = "genrange(): obj id must be int type"; errorInfo = nl->Append(errorInfo,nl->StringAtom(strErrorMessage)); correct = false; return SetWord(Address(0)); } unsigned int oid2 = nl->IntValue(oid_list2); rest = nl->Second(second_instance); Line* l2 = (Line*)(InLine(typeInfo,rest,errorPos,errorInfo,correct).addr); //////////////////////////////////////////////////////////////////////// ///////////// time-dependent state mbool ////////////////////////////// /////////////////////////////////////////////////////////////////////// ListExpr temporal_state = nl->Third(instance); int numUnits = 0; if(nl->AtomType(temporal_state)==NoAtom){ numUnits = nl->ListLength(temporal_state); } MBool* m = new MBool( numUnits ); correct = true; int unitcounter = 0; string errmsg; m->StartBulkLoad(); rest = temporal_state; if (nl->AtomType( rest ) != NoAtom) { if(nl->IsEqual(rest,"undef")){ m->EndBulkLoad(); m->SetDefined(false); return SetWord( Address( m ) ); } else { correct = false; m->Destroy(); m->DeleteIfAllowed(); return SetWord( Address( 0 ) ); } } else while( !nl->IsEmpty( rest ) ) { ListExpr first = nl->First( rest ); rest = nl->Rest( rest ); // UBool *unit = (UBool*)InUnit( nl->TheEmptyList(), first, // errorPos, errorInfo, correct ).addr; UBool *unit = (UBool*)InConstTemporalUnit( nl->TheEmptyList(), first, errorPos, errorInfo, correct ).addr; if ( !correct ) { errmsg = "InMapping(): Representation of Unit " + int2string(unitcounter) + " is wrong."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); m->Destroy(); delete m; return SetWord( Address(0) ); } if( !unit->IsDefined() || !unit->IsValid() ) { errmsg = "InMapping(): Unit " + int2string(unitcounter) + " is undef."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); correct = false; delete unit; m->Destroy(); delete m; return SetWord( Address(0) ); } m->Add( *unit ); unitcounter++; delete unit; } m->EndBulkLoad( true ); // cout<<*m<Fourth(instance); if(!nl->IsAtom(door_type) || nl->AtomType(door_type) != BoolType){ cout<< "door3d(): type must be bool type"<BoolValue(door_type); /////////////////////////////////////////////////////////////////////// Door3D* dr = new Door3D(oid1, oid2,*l1,*l2, *m, dr_type); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); m->DeleteIfAllowed(); return SetWord(dr); } Word CreateDoor3D(const ListExpr typeInfo) { // cout<<"CreateDoor3D()"<Save(valueRecord, offset, typeInfo); } void CloseDoor3D( const ListExpr typeInfo, Word& w ) { ((Door3D*)w.addr)->DeleteIfAllowed(); w.addr = 0; } Word CloneDoor3D( const ListExpr typeInfo, const Word& w ) { return SetWord( new Door3D( *((Door3D *)w.addr) ) ); } void* CastDoor3D(void* addr) { return (new (addr) Door3D()); } int SizeOfDoor3D() { return sizeof(Door3D); } bool CheckDoor3D( ListExpr type, ListExpr& errorInfo ) { return (nl->IsEqual( type, "door3d" )); } //////////////////////////////////////////////////////////////////////////// ///////////////////////////// GRoom ////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /* old version of region input pointlist is to store the point in such a way that it is the same as for the input. 1) Outercycle in a clock-wise and holes in a counter-clock wise 2) index list stores the start position of the first point for the outercycle and the hole */ Word MyInRegion(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct, int& cycno) { Region* cr = new Region( 0 ); cr->StartBulkLoad(); ListExpr RegionNL = instance; ListExpr FaceNL, CycleNL; int fcno = -1; int ccno = -1; int edno = -1; int partnerno = 0; if(nl->ListLength(RegionNL) > 1){ correct = false; return SetWord(Address(0)); } FaceNL = nl->First( RegionNL ); bool isCycle = true; //A face is composed by 1 cycle, and can have holes. //All the holes must be inside the face. (TO BE IMPLEMENTED0) //Region *faceCycle; fcno++; ccno=-1; edno=-1; if (nl->IsAtom( FaceNL )){ correct=false; return SetWord( Address(0) ); } while (!nl->IsEmpty( FaceNL) ){ //several cycles (outer and hole) CycleNL = nl->First( FaceNL ); FaceNL = nl->Rest( FaceNL ); ccno++; edno=-1; if (nl->IsAtom( CycleNL )){ correct=false; return SetWord( Address(0) ); } if (nl->ListLength( CycleNL) <3){ cerr << __PRETTY_FUNCTION__ << ": A cycle must have at least 3 edges!" << endl; correct=false; return SetWord( Address(0) ); }else{ ListExpr firstPoint = nl->First( CycleNL ); ListExpr prevPoint = nl->First( CycleNL ); ListExpr flagedSeg, currPoint; CycleNL = nl->Rest( CycleNL ); //Starting to compute a new cycle Points *cyclepoints= new Points( 8 ); // in memory Point *currvertex,p1,p2,firstP; //This function has the goal to store the half segments of //the cycle that is been treated. When the cycle's computation //is terminated the region rDir will be used to compute the //insideAbove //attribute of the half segments of this cycle. Region *rDir = new Region(32); rDir->StartBulkLoad(); currvertex = (Point*) InPoint ( nl->TheEmptyList(), firstPoint, 0, errorInfo, correct ).addr; if (!correct) { // todo: delete temp objects return SetWord( Address(0) ); } cyclepoints->StartBulkLoad(); (*cyclepoints) += (*currvertex); p1 = *currvertex; firstP = p1; cyclepoints->EndBulkLoad(); /////////////////////////////////////////////////////////////// ////////////////////////one cycle ///////////////////////////// //////////////////////////////////////////////////////////////// delete currvertex; cycno++; while ( !nl->IsEmpty( CycleNL) ){ // cout<<"cycle "<First( CycleNL ); CycleNL = nl->Rest( CycleNL ); currvertex = (Point*) InPoint( nl->TheEmptyList(), currPoint, 0, errorInfo, correct ).addr; // cout<<"curvertex "<<*currvertex<Contains(*currvertex)){ cerr<< __PRETTY_FUNCTION__ << ": The same vertex: " <<(*currvertex) <<" appears repeatedly within the current cycle!"<StartBulkLoad(); (*cyclepoints) += (*currvertex); cyclepoints->EndBulkLoad(true,false,false); } delete currvertex; flagedSeg = nl->TwoElemList (nl-> BoolAtom(true), nl->TwoElemList(prevPoint, currPoint)); prevPoint=currPoint; edno++; //Create left dominating half segment HalfSegment * hs = (HalfSegment*)InHalfSegment ( nl->TheEmptyList(), flagedSeg, 0, errorInfo, correct ).addr; if(!correct){ if(hs){ cerr << __PRETTY_FUNCTION__ << ": Creation of left dominating " << "half segment (1) failed!" << endl; delete hs; } cr->DeleteIfAllowed(); return SetWord( Address(0) ); } hs->attr.faceno=fcno; hs->attr.cycleno=ccno; hs->attr.edgeno=edno; hs->attr.partnerno=partnerno; partnerno++; hs->attr.insideAbove = (hs->GetLeftPoint() == p1); //true (L-->R ),false (R--L) p1 = p2; if (( correct )&&( cr->InsertOk(*hs) )){ (*cr) += (*hs); // cout<<"cr+1 "<<*hs<IsLeftDomPoint() ){ (*rDir) += (*hs); // cout<<"rDr+1 "<<*hs<SetLeftDomPoint( false ); }else{ hs->SetLeftDomPoint( true ); // cout<<"rDr+2 "<<*hs<DeleteIfAllowed(); edno++; flagedSeg= nl->TwoElemList (nl-> BoolAtom(true), nl->TwoElemList(firstPoint, currPoint)); HalfSegment * hs = (HalfSegment*)InHalfSegment ( nl->TheEmptyList(), flagedSeg, 0, errorInfo, correct ).addr; if(!correct){ if(hs){ cerr << __PRETTY_FUNCTION__ << ": Creation of " << "half segment (2) failed!" << endl; delete hs; } cr->DeleteIfAllowed(); return SetWord( Address(0) ); } hs->attr.faceno=fcno; hs->attr.cycleno=ccno; hs->attr.edgeno=edno; hs->attr.partnerno=partnerno; hs->attr.insideAbove = (hs->GetRightPoint() == firstP); //true (L-->R ),false (R--L), //the order of typing is last point than first point. partnerno++; //The last half segment of the region if (( correct )&&( cr->InsertOk(*hs) )){ (*cr) += (*hs); // cout<<"cr+3 "<<*hs<IsLeftDomPoint() ){ (*rDir) += (*hs); // cout<<"rDr+3 "<<*hs<SetLeftDomPoint( false ); }else{ hs->SetLeftDomPoint( true ); // cout<<"rDr+4 "<<*hs<EndBulkLoad(true, false, false, false); //To calculate the inside above attribute bool direction = rDir->GetCycleDirection(); int h = cr->Size() - ( rDir->Size() * 2 ); while ( h < cr->Size()){ //after each left half segment of the region is its //correspondig right half segment HalfSegment hsIA; bool insideAbove; cr->Get(h,hsIA); if (direction == hsIA.attr.insideAbove) insideAbove = false; else insideAbove = true; if (!isCycle) insideAbove = !insideAbove; HalfSegment auxhsIA( hsIA ); auxhsIA.attr.insideAbove = insideAbove; cr->UpdateAttr(h,auxhsIA.attr); //Get right half segment cr->Get(h+1,hsIA); auxhsIA = hsIA; auxhsIA.attr.insideAbove = insideAbove; cr->UpdateAttr(h+1,auxhsIA.attr); h+=2; } rDir->DeleteIfAllowed(); isCycle = false; } else{ correct=false; return SetWord( Address(0) ); } } } cr->SetNoComponents( fcno+1 ); cr->EndBulkLoad( true, true, true, false ); ////////////////////////////////////////////////////////////////////////// // cout<<"Area "<Area()<& hs_list) { // cout<<"GRoom::Add()"< felem_list; for(int j = 0;j < elem_list.Size();j++){ FloorElem elem; elem_list.Get(j, elem); if(elem.id == i){ felem_list.push_back(elem); h = elem.h; } } /////////////////////////////////////////////////////////////////// r.StartBulkLoad(); // cout<<"elem size "<DeleteIfAllowed(); } } std::ostream& GRoom::Print(std::ostream& o) const { for( int i = 0; i < Size(); i++ ){ Region r(0); float h; Get( i, h, r); o<<"elem "<::max(); for( int i = 0; i < elem_list.Size(); i++ ){ FloorElem felem; elem_list.Get(i, felem); if(felem.h < h) h = felem.h; } return h; } /* return the highest height of a groom */ float GRoom::GetHighHeight() { // float h = numeric_limits::min(); //returns a positive value float h = MIN_FLOOR_HEIGHT; for( int i = 0; i < elem_list.Size(); i++ ){ FloorElem felem; elem_list.Get(i, felem); assert(felem.h > MIN_FLOOR_HEIGHT); if(felem.h > h) h = felem.h; } return h; } /* get the 3D box of a groom */ const Rectangle<3> GRoom::BoundingBox3D() const { Rectangle<3> bbox; for( int i = 0; i < Size(); i++ ){ Region r(0); float h; Get( i, h, r); if( i == 0 ){ Rectangle<2> reg_box = r.BoundingBox(); double minMax[] = { reg_box.MinD(0), reg_box.MaxD(0), reg_box.MinD(1), reg_box.MaxD(1), h, h + ApplyFactor(h)}; bbox = Rectangle<3>(true,minMax); }else{ Rectangle<2> reg_box = r.BoundingBox(); double minMax[] = {reg_box.MinD(0), reg_box.MaxD(0), reg_box.MinD(1), reg_box.MaxD(1), h, h + ApplyFactor(h)}; Rectangle<3> bbox1 = Rectangle<3>(true,minMax ); bbox = bbox.Union(bbox1); } } return bbox; } /* Groom Property function */ ListExpr GRoomProperty() { 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("-> DATA"), nl->StringAtom("groom"), nl->StringAtom("(*) ((f1 floor3d)(f2 floor3d))"), nl->StringAtom("((f1)(f2))")))); } /* output the list expression for Staircase3D */ ListExpr OutGRoom( ListExpr typeInfo, Word value ) { // cout<<"OutGRoom()"<IsDefined()){ return nl->SymbolAtom("undef"); } if( gr->IsEmpty() ){ return nl->TheEmptyList(); } // cout<<"stair size "<Size()<TheEmptyList(); ListExpr last = result; ListExpr sb_list; for( int i = 0; i < gr->Size(); i++ ){ Region r(0); float h; gr->Get( i, h, r); sb_list = nl->TwoElemList(nl->RealAtom(h), OutRegion(nl->TheEmptyList(), SetWord(&r))); if( first == true ){ result = nl->OneElemList( sb_list ); last = result; first = false; }else last = nl->Append( last, sb_list); } return result; } /* In function */ Word InGRoom( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { if(nl->IsEqual(instance,"undef")) { correct = false; return SetWord(Address(0)); } GRoom* gr = new GRoom(0); // cout<<"length "<ListLength(instance)<IsEmpty(floor_nl)){ ListExpr first = nl->First(floor_nl); floor_nl = nl->Rest(floor_nl); ListExpr height_nl = nl->First(first); if(!(nl->IsAtom(height_nl) && nl->AtomType(height_nl) == RealType)){ cout<<"real value expected for height"<RealValue(height_nl); // cout<<"height "<Second(first), errorPos, errorInfo, correct, cycleno).addr; ///////////////////////////////////////////////////////////////////// ///////////////temporally/////////////////////////////////////////// // Region* temp = new Region(0); // reg->Translate(10.0, 0.0, *temp); // *reg = *temp; // delete temp; //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// // cout<<"Area "<Area()<NoComponents() != 1 || cycleno == 0){//only one face is allowed cout<<"invalid region input "< hs_list; for(int j = 0;j < reg->Size();j++){ HalfSegment hs; reg->Get(j, hs); if(hs.attr.cycleno == i){ hs_list.push_back(hs); } } // cout<Add(count, height, hs_list); else gr->Add(count, height, hs_list); } count++; } ////////////////very important //////////////////////////////// correct = true; //////////////////////////////////////////////////////// return SetWord(gr); } /* Open a GRoom object */ bool OpenGRoom(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenGRoom()"<ElemSize()<<" "<SegSize()<ElemSize()<<" "<SegSize()<DeleteIfAllowed(); w.addr = 0; } Word CloneGRoom( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneGRoom"<IsEqual( type, "groom" )); } ////////////////////////////////////////////////////////////////////////////// /////////////////////////////Indoor Navigation/////////////////////////////// //////////////////////////////////////////////////////////////////////////// string IndoorNav::Indoor_GRoom_Door = "(rel(tuple((Oid int)(Name string)(Type string)(Room groom)(Door line))))"; /* create a 3d line for the door. We use RTree to find doors that their locations are the same in space. Because for the data type door3d, we have to know the relative position in each room. */ void IndoorNav::CreateDoor3D() { // cout<<"CreateDoor3D()"< floor_height; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* indoor_tuple = rel1->GetTuple(i, false); string s = ((CcString*)indoor_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(s) == EL){ GRoom* groom = (GRoom*)indoor_tuple->GetAttribute(I_Room); float h = groom->GetLowHeight(); if(floor_height.size() == 0) floor_height.push_back(h); else{ unsigned int j = 0; for(;j < floor_height.size();j++){ if(AlmostEqual(floor_height[j], h))break; } if(j == floor_height.size()) floor_height.push_back(h); } } indoor_tuple->DeleteIfAllowed(); } sort(floor_height.begin(), floor_height.end()); // cout<<"rel1 no "<GetNoTuples()<GetNoTuples();i++){ Tuple* indoor_tuple = rel1->GetTuple(i, false); GRoom* groom = (GRoom*)indoor_tuple->GetAttribute(I_Room); Line* l = (Line*)indoor_tuple->GetAttribute(I_Door); int oid = ((CcInt*)indoor_tuple->GetAttribute(I_OID))->GetIntval(); string s = ((CcString*)indoor_tuple->GetAttribute(I_Type))->GetValue(); // groom->Print(); // cout<<*l<GetLowHeight(); CreateLine3D(oid, l, h); /////////////////3D box x,y,z //////////////////////// if(GetRoomEnum(s) == ST){//Staircase // cout<<"one more box needed"<GetHighHeight(); CreateLine3D(oid, l, h); } if(GetRoomEnum(s) == EL){//Elevator // cout<<"one more box needed"< 0.0){ if(flag_h){ CreateLine3D(oid, l, h); } } indoor_tuple->DeleteIfAllowed(); } } /* create a 3d line */ void IndoorNav::CreateLine3D(int oid, Line* l, float h) { // cout<<"oid "<Size();i++){ HalfSegment hs; l->Get(i, hs); if(hs.IsLeftDomPoint() == false) continue; Point lp = hs.GetLeftPoint(); Point rp = hs.GetRightPoint(); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); Point3D q1(true, lp.GetX(), lp.GetY(), h); *l3d += q1; Point3D q2(true, rp.GetX(), rp.GetY(), h); *l3d += q2; l3d->EndBulkLoad(); groom_oid_list.push_back(oid); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); } } /* create a 3D box for each door. return (oid, tid, box3d) for staircase and elevator. In the original data, it only stores the door for each floor, but in fact the staircase and elevator builds the connection between two floors. so, we create one more door for staircase and elevator If a groom has several 3D regions, the door normally is located at the lowest level The result is: for each groom, we create its doors. so usually, the door (spatial locatin in space) will be represented twice because it connects two rooms. */ void IndoorNav::CreateDoorBox() { /////////////// collect the height value for each floor/////////////////// //////////////// for staircase and elevator ////////////////////////////// vector floor_height; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* indoor_tuple = rel1->GetTuple(i, false); string s = ((CcString*)indoor_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(s) == EL){ GRoom* groom = (GRoom*)indoor_tuple->GetAttribute(I_Room); float h = groom->GetLowHeight(); if(floor_height.size() == 0) floor_height.push_back(h); else{ unsigned int j = 0; for(;j < floor_height.size();j++){ if(AlmostEqual(floor_height[j], h))break; } if(j == floor_height.size()) floor_height.push_back(h); } } indoor_tuple->DeleteIfAllowed(); } sort(floor_height.begin(), floor_height.end()); // for(unsigned int i = 0;i < floor_height.size();i++) // cout<<"floor "<GetNoTuples()<GetNoTuples();i++){ Tuple* indoor_tuple = rel1->GetTuple(i, false); GRoom* groom = (GRoom*)indoor_tuple->GetAttribute(I_Room); Line* l = (Line*)indoor_tuple->GetAttribute(I_Door); int oid = ((CcInt*)indoor_tuple->GetAttribute(I_OID))->GetIntval(); int tid = indoor_tuple->GetTupleId(); string s = ((CcString*)indoor_tuple->GetAttribute(I_Type))->GetValue(); // groom->Print(); // cout<<*l<GetLowHeight(); CreateBox3D(oid, tid, l, h); /////////////////3D box x,y,z //////////////////////// if(GetRoomEnum(s) == ST){//Staircase // cout<<"one more box needed"<GetHighHeight(); CreateBox3D(oid, tid, l, h); } if(GetRoomEnum(s) == EL){// Elevator // cout<<"one more box needed"< 0.0){ if(flag_h){ CreateBox3D(oid, tid, l, h); } } indoor_tuple->DeleteIfAllowed(); } } /* get the floor height in the next higher level */ float IndoorNav::NextFloorHeight(float h, vector& floor_height, bool& flag_h) { for(unsigned int i = 0;i < floor_height.size();i++){ if(AlmostEqual(h, floor_height[i])){ if(i != floor_height.size() - 1){ flag_h = true; return floor_height[ i + 1]; } else{ flag_h = false; return -1.0; } } } assert(false); // return -1.0; } void IndoorNav::CreateBox3D(int oid, int tid, Line* l, float h) { // const double delta_h = 0.01; // cout<<"oid "<Size();i++){ HalfSegment hs; l->Get(i, hs); if(hs.IsLeftDomPoint() == false) continue; double min[3]; double max[3]; Point lp = hs.GetLeftPoint(); Point rp = hs.GetRightPoint(); min[0] = MIN(lp.GetX(), rp.GetX()); min[1] = MIN(lp.GetY(), rp.GetY()); min[2] = h; max[0] = MAX(lp.GetX(), rp.GetX()); max[1] = MAX(lp.GetY(), rp.GetY()); // max[2] = h + delta_h; max[2] = h + ApplyFactor(h); Rectangle<3> bbox3d(true, min, max); oid_list.push_back(oid); tid_list.push_back(tid); box_list.push_back(bbox3d); // cout<<"i "<* rtree, int attr1, int attr2, int attr3) { ///////////// minimum and maximum height of the building//////////////// vector height_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); height_list.push_back(groom->GetLowHeight()); groom_tuple->DeleteIfAllowed(); } sort(height_list.begin(), height_list.end()); /////////////////////////////////////////////////////////////////////// float max_height = height_list[ height_list.size() - 1]; // cout<<"max_height "<RootRecordId(); for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* door_tuple = rel2->GetTuple(i, false); int oid = ((CcInt*)door_tuple->GetAttribute(attr1))->GetIntval(); int tid = ((CcInt*)door_tuple->GetAttribute(attr2))->GetIntval(); Rectangle<3>* bbox3d = (Rectangle<3>*)door_tuple->GetAttribute(attr3); unsigned int id = door_tuple->GetTupleId(); /* if(oid != 81){ door_tuple->DeleteIfAllowed(); continue; }*/ vector id_list; // cout<<"oid "<MinD(2))){ // cout<<"find "<MinD(2), 0.0)){//height 0 = underground level ///////////////////////////////////////////////////////////////// ////////////////////we define 0.0 for the first level//////////// /////////////////where the building entrance is located////////// ////////////////this is for buildings have underground level///// //////////////////////trainstation, hospital///////////////////// ///////////////////// mall ///////////////////////////////////// ///////////////////////////////////////////////////////////////// // cout<<"underground here"<DeleteIfAllowed(); } } /* check whether the room is OR or CO. excludes BR, ST, EL */ bool IndoorNav::IsGRoom(int tid, Relation* rel) { assert(1 <= tid && tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == OR || GetRoomEnum(type) == CO) return true; else return false; } /* create the result for door relation: door3d line groomid1 groomid2 for data type line, region, mbool, the function operator=() is not correctly impelmented. it should copy the value from the dbarray instead of calling copyfrom. It is no problem in memory, but has problems in disk for storage */ void IndoorNav::CreateResDoor(int id, int oid, int tid, vector id_list, int attr1, int attr2, int attr3) { for(unsigned int i = 0;i < id_list.size();i++){ /////////////// first door in one groom //////////////////// Tuple* indoor_tuple1 = rel1->GetTuple(tid, false); int oid1 = ((CcInt*)indoor_tuple1->GetAttribute(I_OID))->GetIntval(); assert(oid1 == oid); string type1 = ((CcString*)indoor_tuple1->GetAttribute(I_Type))->GetValue(); GRoom* groom1 = (GRoom*)indoor_tuple1->GetAttribute(I_Room); Tuple* box_tuple1 = rel2->GetTuple(id, false); Rectangle<3>* bbox3d_1 = (Rectangle<3>*)box_tuple1->GetAttribute(attr3); // cout<<"bbox3d 1 "<<*bbox3d_1< groom_box1 = groom1->BoundingBox(); /////////////// second door in one groom //////////////////// Tuple* box_tuple2 = rel2->GetTuple(id_list[i], false); int oid2 = ((CcInt*)box_tuple2->GetAttribute(attr1))->GetIntval(); int groom_tid = ((CcInt*)box_tuple2->GetAttribute(attr2))->GetIntval(); /* if(oid2 != 385){ indoor_tuple1->DeleteIfAllowed(); box_tuple1->DeleteIfAllowed(); box_tuple2->DeleteIfAllowed(); continue; }*/ assert(1 <= groom_tid && groom_tid <= rel1->GetNoTuples()); Tuple* indoor_tuple2 = rel1->GetTuple(groom_tid, false); string type2 = ((CcString*)indoor_tuple2->GetAttribute(I_Type))->GetValue(); GRoom* groom2 = (GRoom*)indoor_tuple2->GetAttribute(I_Room); Rectangle<3>* bbox3d_2 = (Rectangle<3>*)box_tuple2->GetAttribute(attr3); Rectangle<2> groom_box2 = groom2->BoundingBox(); // cout<<"bbox3d 2 "<<*bbox3d_2<MinD(2)); ///////////////////// create the door ////////////////////////////// Door3D* door_obj1 = new Door3D(oid1, oid2, *l1, *l2, *mb1, lift_door); ////////////////////// result /////////////////////////////// door_list.push_back(*door_obj1); line_list.push_back(*l3); groom_id_list1.push_back(oid1); groom_id_list2.push_back(oid2); path_list.push_back(*l3d_1); door_heights.push_back(bbox3d_1->MinD(2)); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); l3->DeleteIfAllowed(); delete door_obj1; l3d_1->DeleteIfAllowed(); mb1->DeleteIfAllowed(); ///////////////////////////////////////////////////////////// box_tuple1->DeleteIfAllowed(); box_tuple2->DeleteIfAllowed(); indoor_tuple2->DeleteIfAllowed(); indoor_tuple1->DeleteIfAllowed(); } } /* create the time-dependent state for the door */ void IndoorNav::CreateDoorState(MBool* mb) { Instant start_time(instanttype); start_time.ReadFrom("2010-12-5-0:0:0"); Instant end_time(instanttype); end_time.ReadFrom("2010-12-6-0:0:0"); Instant begin_time(instanttype); begin_time.ReadFrom("begin of time"); Instant finish_time(instanttype); finish_time.ReadFrom("end of time"); mb->StartBulkLoad(); UBool ub1; ub1.timeInterval.start = begin_time; ub1.timeInterval.end = start_time; ub1.timeInterval.lc = true; ub1.timeInterval.rc = false; ub1.constValue.Set(true, true); ub1.SetDefined(true); UBool ub2; ub2.timeInterval.start = start_time; ub2.timeInterval.end = end_time; ub2.timeInterval.lc = true; ub2.timeInterval.rc = false; ub2.constValue.Set(true, true); ub2.SetDefined(true); UBool ub3; ub3.timeInterval.start = end_time; ub3.timeInterval.end = finish_time; ub3.timeInterval.lc = true; ub3.timeInterval.rc = false; ub3.constValue.Set(true, true); ub3.SetDefined(true); // ub1.Print(cout); // ub2.Print(cout); // ub3.Print(cout); mb->Add(ub1); mb->Add(ub2); mb->Add(ub3); mb->EndBulkLoad(); } /* depth-first traverse the Rtree to find the element (line3d) intersects the bbox3d */ void IndoorNav::DFTraverse(R_Tree<3,TupleId>* rtree, SmiRecordId adr, unsigned int id, Rectangle<3>* bbox3d, int attr1, int attr2, int attr3, vector& id_list) { R_TreeNode<3,TupleId>* node = rtree->GetMyNode(adr,false, rtree->MinEntries(0), rtree->MaxEntries(0)); for(int j = 0;j < node->EntryCount();j++){ if(node->IsLeaf()){ R_TreeLeafEntry<3,TupleId> e = (R_TreeLeafEntry<3,TupleId>&)(*node)[j]; Tuple* box_tuple = rel2->GetTuple(e.info,false); Rectangle<3>* b = (Rectangle<3>*)box_tuple->GetAttribute(attr3); if(b->Intersects(*bbox3d) && id != e.info){ Tuple* box_tuple = rel2->GetTuple(e.info, false); Rectangle<3>* bbox_3d = (Rectangle<3>*)box_tuple->GetAttribute(attr3); if(BBox3DEqual(bbox3d, bbox_3d)) id_list.push_back(e.info); box_tuple->DeleteIfAllowed(); } box_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<3> e = (R_TreeInternalEntry<3>&)(*node)[j]; if(bbox3d->Intersects(e.box)){ DFTraverse(rtree, e.pointer, id, bbox3d, attr1, attr2, attr3, id_list); } } } delete node; } /* create entrance door of the building if it is the entrance of the building, we set groom oid1: oid1, groom oid2:-1 */ void IndoorNav::CreateEntranceDoor(int id, int oid, int tid, int attr1, int attr2, int attr3) { /////////////// first door in one groom //////////////////// Tuple* indoor_tuple1 = rel1->GetTuple(tid, false); int oid1 = ((CcInt*)indoor_tuple1->GetAttribute(I_OID))->GetIntval(); assert(oid1 == oid); string type1 = ((CcString*)indoor_tuple1->GetAttribute(I_Type))->GetValue(); GRoom* groom1 = (GRoom*)indoor_tuple1->GetAttribute(I_Room); Tuple* box_tuple1 = rel2->GetTuple(id, false); Rectangle<3>* bbox3d_1 = (Rectangle<3>*)box_tuple1->GetAttribute(attr3); // cout<<"bbox3d 1 "<<*bbox3d_1< groom_box1 = groom1->BoundingBox(); /////////////// second door in one groom //////////////////// Tuple* box_tuple2 = rel2->GetTuple(tid, false); int oid2 = ((CcInt*)box_tuple2->GetAttribute(attr1))->GetIntval(); int groom_tid = ((CcInt*)box_tuple2->GetAttribute(attr2))->GetIntval(); assert(1 <= groom_tid && groom_tid <= rel1->GetNoTuples()); Tuple* indoor_tuple2 = rel1->GetTuple(groom_tid, false); string type2 = ((CcString*)indoor_tuple2->GetAttribute(I_Type))->GetValue(); GRoom* groom2 = (GRoom*)indoor_tuple2->GetAttribute(I_Room); Rectangle<3>* bbox3d_2 = (Rectangle<3>*)box_tuple2->GetAttribute(attr3); Rectangle<2> groom_box2 = groom2->BoundingBox(); // cout<<"bbox3d 2 "<<*bbox3d_2<MinD(2)); ///////////////////// create the door ////////////////////////////// Door3D* door_obj1 = new Door3D(oid1, oid2, *l1, *l2, *mb1, lift_door); ////////////////////// result /////////////////////////////////// door_list.push_back(*door_obj1); line_list.push_back(*l3); groom_id_list1.push_back(oid1);//the room oid // groom_id_list2.push_back(-1);//-1 for entrance door groom_id_list2.push_back((int)UNDEFVAL);//UNDEFVAL for entrance door path_list.push_back(*l3d_1); door_heights.push_back(bbox3d_1->MinD(2)); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); l3->DeleteIfAllowed(); delete door_obj1; l3d_1->DeleteIfAllowed(); mb1->DeleteIfAllowed(); ///////////////////////////////////////////////////////////// box_tuple1->DeleteIfAllowed(); box_tuple2->DeleteIfAllowed(); indoor_tuple2->DeleteIfAllowed(); indoor_tuple1->DeleteIfAllowed(); } /* Compare two 3D box */ bool IndoorNav::BBox3DEqual(Rectangle<3>* bbox3d, Rectangle<3>* bbox_3d) { for(unsigned int i = 0;i < 3;i ++){ if(!AlmostEqual(bbox3d->MinD(i), bbox_3d->MinD(i)))return false; if(!AlmostEqual(bbox3d->MaxD(i), bbox_3d->MaxD(i)))return false; } return true; } /* create virtual doors for the staircase. The position is the place of the first footstep (higher than the ground level) which is the place for entering the staircase */ void IndoorNav::CreateDoor2() { for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(!(GetRoomEnum(type) == ST)){ groom_tuple->DeleteIfAllowed(); continue; } int oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<2> groom_box = groom->BoundingBox(); Line* l1 = new Line(0); Line* l2 = new Line(0); Line* l3 = new Line(0); Line* l4 = new Line(0); Line3D* l3d1 = new Line3D(0); Line3D* l3d2 = new Line3D(0); float h1 = GetVirtualDoor1(groom, l1, l2, l3d1); float h2 = GetVirtualDoor2(groom, l3, l4, l3d2); MBool* mb1 = new MBool(0); CreateDoorState(mb1); MBool* mb2 = new MBool(0); CreateDoorState(mb2); Door3D* door_obj1 = new Door3D(oid, oid, *l1, *l1, *mb1, false); Door3D* door_obj2 = new Door3D(oid, oid, *l3, *l3, *mb2, false); door_list.push_back(*door_obj1); line_list.push_back(*l2); groom_id_list1.push_back(oid); groom_id_list2.push_back(oid); path_list.push_back(*l3d1); door_heights.push_back(h1); door_list.push_back(*door_obj2); line_list.push_back(*l4); groom_id_list1.push_back(oid); groom_id_list2.push_back(oid); path_list.push_back(*l3d2); door_heights.push_back(h2); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); l3->DeleteIfAllowed(); l4->DeleteIfAllowed(); l3d1->DeleteIfAllowed(); l3d2->DeleteIfAllowed(); mb1->DeleteIfAllowed(); mb2->DeleteIfAllowed(); delete door_obj1; delete door_obj2; groom_tuple->DeleteIfAllowed(); } } /* constuct a middle path in the staircase the middle path does not include the lowest and highest level */ bool Floor3DCompare1(const Floor3D& f1, const Floor3D& f2) { return f1.GetHeight() < f2.GetHeight(); } bool Floor3DCompare2(const Floor3D& f1, const Floor3D& f2) { return f1.GetHeight() > f2.GetHeight(); } /* Create a virtual door, relative position in a groom, absolute position 2D, absolute position 3D. low level height. Note: the height for the foorsteps in the input data is set in the reverse way */ float IndoorNav::GetVirtualDoor1(GRoom* groom, Line* l1, Line* l2, Line3D* l3d) { vector floors; for(int i = 0;i < groom->Size();i++){ float h; Region r(0); groom->Get(i, h, r); Floor3D floor(h, r); floors.push_back(floor); } sort(floors.begin(), floors.end(), Floor3DCompare2); Region* r1 = const_cast(floors[0].GetRegion()); Region* r2 = const_cast(floors[1].GetRegion()); Line* boundary = new Line(0); r1->Boundary(boundary); r2->Intersection(*boundary, *l2); assert(l2->Size() == 2); HalfSegment hs; l2->Get(0, hs); boundary->DeleteIfAllowed(); Rectangle<2> groom_box = groom->BoundingBox(); double x1 = hs.GetLeftPoint().GetX() - groom_box.MinD(0); double y1 = hs.GetLeftPoint().GetY() - groom_box.MinD(1); Point p1(true, x1, y1); double x2 = hs.GetRightPoint().GetX() - groom_box.MinD(0); double y2 = hs.GetRightPoint().GetY() - groom_box.MinD(1); Point p2(true, x2, y2); //////////////////relative position in the groom//////////////////////// l1->StartBulkLoad(); int edgeno = 0; HalfSegment temp_hs(true, p1, p2); temp_hs.attr.edgeno = edgeno++; *l1 += temp_hs; temp_hs.SetLeftDomPoint(!temp_hs.IsLeftDomPoint()); *l1 += temp_hs; l1->EndBulkLoad(); ////////////////////////////////////////////////////////////////////////// ////////////////absolute position in 3D space///////////////////////////// ////////////////////////////////////////////////////////////////////////// float h = floors[0].GetHeight(); l3d->StartBulkLoad(); Point3D q1(true, hs.GetLeftPoint().GetX(), hs.GetLeftPoint().GetY(), h); Point3D q2(true, hs.GetRightPoint().GetX(), hs.GetRightPoint().GetY(), h); *l3d += q1; *l3d += q2; l3d->EndBulkLoad(); return h; ////////////////////////////////////////////////////////////////////////// } /* Create a virtual door, relative position in a groom, absolute position 2D, absolute position 3D. high level height Note: the height for the foorsteps in the input data is set in the reverse way */ float IndoorNav::GetVirtualDoor2(GRoom* groom, Line* l1, Line* l2, Line3D* l3d) { vector floors; for(int i = 0;i < groom->Size();i++){ float h; Region r(0); groom->Get(i, h, r); Floor3D floor(h, r); floors.push_back(floor); } sort(floors.begin(), floors.end(), Floor3DCompare2); Region* r1 = const_cast(floors[0].GetRegion()); Region* r2 = const_cast(floors[1].GetRegion()); Line* boundary = new Line(0); r1->Boundary(boundary); r2->Intersection(*boundary, *l2); assert(l2->Size() == 2); HalfSegment hs; l2->Get(0, hs); boundary->DeleteIfAllowed(); Rectangle<2> groom_box = groom->BoundingBox(); double x1 = hs.GetLeftPoint().GetX() - groom_box.MinD(0); double y1 = hs.GetLeftPoint().GetY() - groom_box.MinD(1); Point p1(true, x1, y1); double x2 = hs.GetRightPoint().GetX() - groom_box.MinD(0); double y2 = hs.GetRightPoint().GetY() - groom_box.MinD(1); Point p2(true, x2, y2); //////////////////relative position in the groom//////////////////////// l1->StartBulkLoad(); int edgeno = 0; HalfSegment temp_hs(true, p1, p2); temp_hs.attr.edgeno = edgeno++; *l1 += temp_hs; temp_hs.SetLeftDomPoint(!temp_hs.IsLeftDomPoint()); *l1 += temp_hs; l1->EndBulkLoad(); ////////////////////////////////////////////////////////////////////////// ////////////////absolute position in 3D space///////////////////////////// ////////////////////////////////////////////////////////////////////////// float h = floors[floors.size() - 1].GetHeight(); l3d->StartBulkLoad(); Point3D q1(true, hs.GetLeftPoint().GetX(), hs.GetLeftPoint().GetY(), h); Point3D q2(true, hs.GetRightPoint().GetX(), hs.GetRightPoint().GetY(), h); *l3d += q1; *l3d += q2; l3d->EndBulkLoad(); return h; ////////////////////////////////////////////////////////////////////////// } /* create a line denoting the positio of a door. we record the relative position according to the groom */ void IndoorNav::GRoomDoorLine(Rectangle<3>* bbox3d_1, Rectangle<3>* bbox3d_2, Line* l1, Line* l2, Line* l3, const Rectangle<2>* groom_box1, const Rectangle<2>* groom_box2, Line3D* l3d, float h) { // cout<<"door box1 "<<*bbox3d_1<MinD(0) - groom_box1->MinD(0); double min_y1 = bbox3d_1->MinD(1) - groom_box1->MinD(1); double max_x1 = bbox3d_1->MaxD(0) - groom_box1->MinD(0); double max_y1 = bbox3d_1->MaxD(1) - groom_box1->MinD(1); double min_x2 = bbox3d_2->MinD(0) - groom_box2->MinD(0); double min_y2 = bbox3d_2->MinD(1) - groom_box2->MinD(1); double max_x2 = bbox3d_2->MaxD(0) - groom_box2->MinD(0); double max_y2 = bbox3d_2->MaxD(1) - groom_box2->MinD(1); // cout<<" x1 "<StartBulkLoad(); Point lp1(true, min_x1, min_y1); Point rp1(true, max_x1, max_y1); HalfSegment hs1(true, lp1, rp1); int edgeno1 = 0; hs1.attr.edgeno = edgeno1++; *l1 += hs1; hs1.SetLeftDomPoint(!hs1.IsLeftDomPoint()); *l1 += hs1; l1->EndBulkLoad(); l2->StartBulkLoad(); Point lp2(true, min_x2, min_y2); Point rp2(true, max_x2, max_y2); HalfSegment hs2(true, lp2, rp2); int edgeno2 = 0; hs2.attr.edgeno = edgeno2++; *l2 += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *l2 += hs2; l2->EndBulkLoad(); l3->StartBulkLoad(); Point lp3(true, bbox3d_1->MinD(0), bbox3d_1->MinD(1)); Point rp3(true, bbox3d_1->MaxD(0), bbox3d_1->MaxD(1)); HalfSegment hs3(true, lp3, rp3); int edgeno3 = 0; hs3.attr.edgeno = edgeno3++; *l3 += hs3; hs3.SetLeftDomPoint(!hs3.IsLeftDomPoint()); *l3 += hs3; l3->EndBulkLoad(); l3d->StartBulkLoad(); Point3D lq(true, bbox3d_1->MinD(0), bbox3d_1->MinD(1), h); Point3D rq(true, bbox3d_1->MaxD(0), bbox3d_1->MaxD(1), h); *l3d += lq; *l3d += rq; l3d->EndBulkLoad(); } /* create the edges connecting two doors inside one room */ void IndoorNav::CreateAdjDoor1(BTree* btree,int attr1, int attr2, int attr3, int attr4) { // cout<<"CreateAdjDoor() "<GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); ////////////////////////////////////////////////////////////////////////// /////////////find all doors belong to this groom///////////////////////// ///////////////////////////////////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); vector tid_list; while(btree_iter->Next()){ Tuple* tuple = rel2->GetTuple(btree_iter->GetId(), false); tid_list.push_back(tuple->GetTupleId()); tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; // cout<<"groom_oid "< 1){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); string groom_type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); // cout<<"groom type"<DeleteIfAllowed(); return; } } } groom_tuple->DeleteIfAllowed(); } } ///////////////////////////////////////////////////////////////////////////// //////////// compute the path for each pair of doors inside one room ////// //////////// The rooms needs to be considered: OR, CO, ST, EL ///////////// //////////////// BR (bath room) is excluded ////////////////////////////// /* the path for an elevator, a straight line connecting two floors */ void IndoorNav::BuildPathEL(int groom_oid, GRoom* groom, vector tid_list, int attr1, int attr2, int attr3, int attr4) { // cout<<"BuildPathEL() tid_lise size "<GetLowHeight()<GetTuple(tid_list[i], false); float h1 = ((CcReal*)door_tuple1->GetAttribute(attr4))->GetRealval(); for(unsigned int j = 0;j < tid_list.size();j++){ if(tid_list[i] == tid_list[j])continue; Tuple* door_tuple2 = rel2->GetTuple(tid_list[j], false); float h2 = ((CcReal*)door_tuple2->GetAttribute(attr4))->GetRealval(); if(AlmostEqual(h1, h2)) { door_tuple2->DeleteIfAllowed(); continue; //ignore the doors on the same level } Line* l = (Line*)door_tuple1->GetAttribute(attr2); assert(l->Size() == 2); HalfSegment hs; l->Get(0, hs); double x = (hs.GetLeftPoint().GetX() + hs.GetRightPoint().GetX())/2; double y = (hs.GetLeftPoint().GetY() + hs.GetRightPoint().GetY())/2; Point3D p1(true, x, y, h1); Point3D p2(true, x, y, h2); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); *l3d += p1; *l3d += p2; l3d->EndBulkLoad(); ////////////////////// result //////////////////////////////////////// groom_oid_list.push_back(groom_oid); door_tid_list1.push_back(tid_list[i]); door_tid_list2.push_back(tid_list[j]); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); // cout<<"groom_oid "<DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } } /* the path for the staircase */ void IndoorNav::BuildPathST(int groom_oid, GRoom* groom, vector tid_list, int attr1, int attr2, int attr3, int attr4) { const double dist_delta = 0.001; // cout<<"BuildPathST()"< middle_path; ConstructMiddlePath(groom, middle_path); // cout<<"low height "<GetLowHeight()<GetTuple(tid_list[i], false); float h1 = ((CcReal*)door_tuple1->GetAttribute(attr4))->GetRealval(); Line* l1 = (Line*)door_tuple1->GetAttribute(attr2); for(unsigned int j = 0;j < tid_list.size();j++){ if(tid_list[j] == tid_list[i]) continue; Tuple* door_tuple2 = rel2->GetTuple(tid_list[j], false); float h2 = ((CcReal*)door_tuple2->GetAttribute(attr4))->GetRealval(); Line* l2 = (Line*)door_tuple2->GetAttribute(attr2); if(fabs(h1-h2) < dist_delta){ // on the same floor ST_ConnectOneFloor(groom_oid, groom, l1, l2, tid_list[i], tid_list[j], h1); }else{ //not on the same floor ST_ConnectFloors(groom_oid, groom, l1, l2, tid_list[i], tid_list[j], h1, h2, middle_path); // return; } door_tuple2->DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } } /* build the connection for two doors of a staircase at the same level */ void IndoorNav::ST_ConnectOneFloor(int groom_oid, GRoom* groom, Line* l1, Line* l2, int tid1, int tid2, float h) { // cout<<" ST_ConnectOneFloor "<Size() == 2); l1->Get(0, hs1); HalfSegment hs2; assert(l2->Size() == 2); l2->Get(0, hs2); double x1 = (hs1.GetLeftPoint().GetX() + hs1.GetRightPoint().GetX())/2; double y1 = (hs1.GetLeftPoint().GetY() + hs1.GetRightPoint().GetY())/2; Point p1(true, x1, y1); double x2 = (hs2.GetLeftPoint().GetX() + hs2.GetRightPoint().GetX())/2; double y2 = (hs2.GetLeftPoint().GetY() + hs2.GetRightPoint().GetY())/2; Point p2(true, x2, y2); if(p1.Distance(p2) < dist_delta) return; vector mhs; FindPathInRegion(groom, h, mhs, &p1, &p2); ///////////////// conver to 3D line ////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point p1 = mhs[i].to; Point3D q1(true, p1.GetX(), p1.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); groom_oid_list.push_back(groom_oid); door_tid_list1.push_back(tid1); door_tid_list2.push_back(tid2); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); } /* find the path in one floor vector MyHalfSegment store the result */ void IndoorNav::FindPathInRegion(GRoom* groom, float h, vector& mhs, Point* p1, Point* p2) { const double dist_delta = 0.001; Region* r = new Region(0); int i = 0; for(;i < groom->Size();i++){ float temp_h; groom->Get(i, temp_h, *r); if(fabs(h - temp_h) < dist_delta){ break; } r->Clear(); } if(i == groom->Size()){ cout<<" such height " <Size() == 0) { r->DeleteIfAllowed(); l->DeleteIfAllowed(); return; } SimpleLine* sl = new SimpleLine(0); sl->fromLine(*l); l->DeleteIfAllowed(); SpacePartition* sp = new SpacePartition(); sp->ReorderLine(sl, mhs); delete sp; sl->DeleteIfAllowed(); r->DeleteIfAllowed(); if(mhs[0].from.Distance(*p1) < dist_delta && mhs[mhs.size() - 1].to.Distance(*p2) < dist_delta) return; assert(mhs[mhs.size() - 1].to.Distance(*p1) < dist_delta && mhs[0].from.Distance(*p2) < dist_delta); vector temp_mhs; for(int i = mhs.size() - 1;i >= 0;i--){ MyHalfSegment seg = mhs[i]; Point p = seg.from; seg.from = seg.to; seg.to = p; temp_mhs.push_back(seg); } mhs.clear(); for(unsigned int i = 0;i < temp_mhs.size();i++) mhs.push_back(temp_mhs[i]); if(mhs[0].from.Distance(*p1) < dist_delta && mhs[mhs.size() - 1].to.Distance(*p2) < dist_delta) return; assert(false); } /* build a path inside a staircase and it connects from the second footstep to the last second footstep. */ void IndoorNav::ConstructMiddlePath(GRoom* groom, vector& middle_path) { vector floors; for(int i = 0;i < groom->Size();i++){ float h; Region r(0); groom->Get(i, h, r); Floor3D floor(h, r); floors.push_back(floor); } sort(floors.begin(), floors.end(), Floor3DCompare1); ///////// from low height to high height //////////////////// for(unsigned int i = 0; i < floors.size();i++){ // cout<<"height "<(floors[i].GetRegion()); Region* r1 = const_cast(floors[i - 1].GetRegion()); Region* r2 = const_cast(floors[i + 1].GetRegion()); // cout<<"cur "<<*cur_r<<" r1 "<<*r1<<" r2 "<<*r2<Boundary(l1); Line* l2 = new Line(0); r2->Boundary(l2); Line* il1 = new Line(0); Line* il2 = new Line(0); cur_r->Intersection(*l1, *il1); cur_r->Intersection(*l2, *il2); assert(il1->Size() == 2 && il2->Size() == 2); HalfSegment hs1; HalfSegment hs2; il1->Get(0, hs1); il2->Get(0, hs2); il1->DeleteIfAllowed(); il2->DeleteIfAllowed(); l1->DeleteIfAllowed(); l2->DeleteIfAllowed(); double x1 = (hs1.GetLeftPoint().GetX() + hs1.GetRightPoint().GetX())/2; double y1 = (hs1.GetLeftPoint().GetY() + hs1.GetRightPoint().GetY())/2; Point p1(true, x1, y1); double x2 = (hs2.GetLeftPoint().GetX() + hs2.GetRightPoint().GetX())/2; double y2 = (hs2.GetLeftPoint().GetY() + hs2.GetRightPoint().GetY())/2; Point p2(true, x2, y2); MySegHeight mysegh(true, p1, p2, floors[i].GetHeight()); middle_path.push_back(mysegh); } ////////////////////////////////////////////////////////////////////// ///////////////////for debuging/////////////////////////////////////// ///////////////////////////////////////////////////////////////////// /* float low_h = floors[0].GetHeight(); float high_h = floors[floors.size() - 1].GetHeight(); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0 ;i < middle_path.size();i++){ if(i == 0){ Point3D p(true, middle_path[i].from.GetX(), middle_path[i].from.GetY(), low_h); *l3d += p; } Point3D p1(true, middle_path[i].from.GetX(), middle_path[i].from.GetY(), middle_path[i].h); Point3D p2(true, middle_path[i].to.GetX(), middle_path[i].to.GetY(), middle_path[i].h); *l3d += p1; *l3d += p2; if(i == middle_path.size() - 1){ Point3D p(true, middle_path[i].to.GetX(), middle_path[i].to.GetY(), high_h); *l3d += p; } } l3d->EndBulkLoad(); groom_oid_list.push_back(1); door_tid_list1.push_back(1); door_tid_list2.push_back(1); path_list.push_back(*l3d); delete l3d; */ } /* build a path inside a staircase and it connects from height h1 to height h2 */ void IndoorNav::ConstructMiddlePath2(GRoom* groom, vector& middle_path, float h1, float h2) { assert(h1 < h2); const double delta_dist = 0.001; vector floors; for(int i = 0;i < groom->Size();i++){ float h; Region r(0); groom->Get(i, h, r); if(fabs(h - h1) < delta_dist || fabs(h - h2) < delta_dist){ Floor3D floor(h, r); floors.push_back(floor); }else if(h1 < h && h < h2){ Floor3D floor(h, r); floors.push_back(floor); } } sort(floors.begin(), floors.end(), Floor3DCompare1); ///////// from low height to high height //////////////////// for(unsigned int i = 0; i < floors.size();i++){ // cout<<"height "<(floors[i].GetRegion()); Region* r1 = const_cast(floors[i - 1].GetRegion()); // cout<<"cur "<<*cur_r<<" r1 "<<*r1<<" r2 "<<*r2<Boundary(l1); Line* il1 = new Line(0); cur_r->Intersection(*l1, *il1); assert(il1->Size() == 2); HalfSegment hs1; il1->Get(0, hs1); il1->DeleteIfAllowed(); l1->DeleteIfAllowed(); double x = (hs1.GetLeftPoint().GetX() + hs1.GetRightPoint().GetX())/2; double y = (hs1.GetLeftPoint().GetY() + hs1.GetRightPoint().GetY())/2; Point3D q1(true, x, y, floors[i - 1].GetHeight()); Point3D q2(true, x, y, floors[i].GetHeight()); middle_path.push_back(q1); middle_path.push_back(q2); } } /* build the connection for two doors of a staircase at different levels middle path from low height to heigh height */ void IndoorNav::ST_ConnectFloors(int groom_oid, GRoom* groom, Line* l1, Line* l2, int tid1, int tid2, float h1, float h2, vector& middle_path) { // cout<<" ST_ConnectFloorS "<Size() == 2); l1->Get(0, hs1); HalfSegment hs2; assert(l2->Size() == 2); l2->Get(0, hs2); double x1 = (hs1.GetLeftPoint().GetX() + hs1.GetRightPoint().GetX())/2; double y1 = (hs1.GetLeftPoint().GetY() + hs1.GetRightPoint().GetY())/2; Point p1(true, x1, y1); double x2 = (hs2.GetLeftPoint().GetX() + hs2.GetRightPoint().GetX())/2; double y2 = (hs2.GetLeftPoint().GetY() + hs2.GetRightPoint().GetY())/2; Point p2(true, x2, y2); // cout<<"p1 "< floors; for(int i = 0;i < groom->Size();i++){ float h; Region r(0); groom->Get(i, h, r); Floor3D floor(h, r); floors.push_back(floor); } sort(floors.begin(), floors.end(), Floor3DCompare1); if(h1 < h2){ Point q1 = middle_path[0].from; Point q2 = middle_path[middle_path.size() - 1].to; vector mhs1; FindPathInRegion(groom, h1, mhs1, &p1, &q1); vector mhs2; FindPathInRegion(groom, h2, mhs2, &q2, &p2); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0 ;i < mhs1.size();i++){ Point p = mhs1[i].from; Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } for(unsigned int i = 0 ;i < middle_path.size();i++){ Point p = middle_path[i].from; if(i == 0){ Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } Point3D q1(true, p.GetX(), p.GetY(), middle_path[i].h); *l3d += q1; p = middle_path[i].to; Point3D q2(true, p.GetX(), p.GetY(), middle_path[i].h); *l3d += q2; } // cout<<"mhs2 size "<EndBulkLoad(); groom_oid_list.push_back(groom_oid); door_tid_list1.push_back(tid1); door_tid_list2.push_back(tid2); path_list.push_back(*l3d); }else{ //h1 > h2 Point q1 = middle_path[middle_path.size() - 1].to; Point q2 = middle_path[0].from; vector mhs1; FindPathInRegion(groom, h1, mhs1, &p1, &q1); vector mhs2; FindPathInRegion(groom, h2, mhs2, &q2, &p2); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0 ;i < mhs1.size();i++){ Point p = mhs1[i].from; Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } for(int i = middle_path.size() - 1;i >= 0; i--){ Point p = middle_path[i].to; if(i == (int)(middle_path.size() - 1)){ Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } Point3D q1(true, p.GetX(), p.GetY(), middle_path[i].h); *l3d += q1; p = middle_path[i].from; Point3D q2(true, p.GetX(), p.GetY(), middle_path[i].h); *l3d += q2; } for(unsigned int i = 0 ;i < mhs2.size();i++){ Point p = mhs2[i].from; Point3D q(true, p.GetX(), p.GetY(), h2); *l3d += q; if(i == mhs2.size() - 1){ Point p = mhs2[i].to; Point3D q(true, p.GetX(), p.GetY(), h2); *l3d += q; } } l3d->EndBulkLoad(); groom_oid_list.push_back(groom_oid); door_tid_list1.push_back(tid1); door_tid_list2.push_back(tid2); path_list.push_back(*l3d); } } /* compute the path for each pair of doors inside one room The rooms needs to be considered: OR, CO BR (bath room) is excluded Note: in the original data. !!! the position of the door should be covered by the room !!! otherwise, it can not find the shorest path connecting two doors inside one room */ void IndoorNav::BuildPathOR(int groom_oid, GRoom* groom, vector tid_list, int attr1, int attr2, int attr3, int attr4) { if(groom->Size() > 1){ cout<<"groom has several levels"<GetTuple(tid_list[i], false); float h1 = ((CcReal*)door_tuple1->GetAttribute(attr4))->GetRealval(); Line* l1 = (Line*)door_tuple1->GetAttribute(attr2); // cout<<"i "<GetTuple(tid_list[j], false); float h2 = ((CcReal*)door_tuple2->GetAttribute(attr4))->GetRealval(); Line* l2 = (Line*)door_tuple2->GetAttribute(attr2); // cout<<"j "<DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } } /* compute the path for each pair of doors inside one room The rooms needs to be considered: CO BR (bath room) is excluded Note: in the original data. !!! the position of the door should be covered by the room !!! otherwise, it can not find the shorest path connecting two doors inside one room. The function is different from the function for OR. if the corridor is complex which has many vertices and holes inside, the simple method needs too much time to compute the shortest path between each pair of doors. So, we use the method for trip planning for pedestrian. it builds dual graph and visual graph. */ bool IndoorNav::BuildPathCO(int groom_oid, GRoom* groom, vector tid_list, int attr1, int attr2, int attr3, int attr4) { if(groom->Size() > 1){ cout<<"groom has several levels"<GetLowHeight(); // cout<<"low h "<Size();index++){ float temp_h; groom->Get(index, temp_h, *groom_reg); if(fabs(h - temp_h) < dist_delta){ break; } groom_reg->Clear(); } if(index == groom->Size()){ cout<<" such height " <Area()<ComplexRegion(); delete ct; assert(complex_reg >= 0); vector obj_name; DualGraph* dg = NULL; VisualGraph* vg = NULL; Relation* tri_rel = NULL; if(complex_reg == 1){ ///complex region, we build dual graph and visual graph // cout<<"complex corridor "<GetObject(obj_name[0], dg_addr, dg_def); ctlg->GetObject(obj_name[1], vg_addr, vg_def); ctlg->GetObject(obj_name[2], rel_addr, rel_def); if(dg_def && vg_def && rel_def){ dg = (DualGraph*)dg_addr.addr; vg = (VisualGraph*)vg_addr.addr; tri_rel = (Relation*)rel_addr.addr; assert(dg != NULL); assert(vg != NULL); assert(tri_rel != NULL); }else{ cout<<"open dual graph or visual graph error"<GetTuple(tid_list[i], false); float h1 = ((CcReal*)door_tuple1->GetAttribute(attr4))->GetRealval(); Line* l1 = (Line*)door_tuple1->GetAttribute(attr2); for(unsigned int j = 0;j < tid_list.size();j++){ if(tid_list[j] == tid_list[i]) continue; Tuple* door_tuple2 = rel2->GetTuple(tid_list[j], false); float h2 = ((CcReal*)door_tuple2->GetAttribute(attr4))->GetRealval(); Line* l2 = (Line*)door_tuple2->GetAttribute(attr2); if(fabs(h1-h2) < dist_delta){ // on the same floor if(complex_reg == 0){//////////simple region ST_ConnectOneFloor(groom_oid, groom, l1, l2, tid_list[i], tid_list[j], h1); }else if(complex_reg == 1){//////complex region ConnectComplexRegion(groom_oid, l1, l2, tid_list[i], tid_list[j], h1, dg, vg, tri_rel, groom_reg); }else assert(false); }else assert(false); door_tuple2->DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } /////////////////////////////////////////////////////////////////////// delete groom_reg; if(complex_reg == 1)DeleteSecondoObj(obj_name); return true; } /* build the connection of two doors in a complex corrdior region it uses dual graph, visual graph. */ void IndoorNav::ConnectComplexRegion(int groom_oid, Line* l1, Line* l2, int tid1, int tid2, float h, DualGraph* dg, VisualGraph* vg, Relation* tri_rel, Region* groom_reg) { // if(tid1 != 135 ) return; assert(dg != NULL); assert(vg != NULL); assert(tri_rel != NULL); const double dist_delta = 0.001; ///////////////////////////////////////////////////////////////////////// //////////////////get the position of two doors////////////////////////// ///////////////////////////////////////////////////////////////////////// HalfSegment hs1; assert(l1->Size() == 2); l1->Get(0, hs1); HalfSegment hs2; assert(l2->Size() == 2); l2->Get(0, hs2); double x1 = (hs1.GetLeftPoint().GetX() + hs1.GetRightPoint().GetX())/2; double y1 = (hs1.GetLeftPoint().GetY() + hs1.GetRightPoint().GetY())/2; Point p1(true, x1, y1); double x2 = (hs2.GetLeftPoint().GetX() + hs2.GetRightPoint().GetX())/2; double y2 = (hs2.GetLeftPoint().GetY() + hs2.GetRightPoint().GetY())/2; Point p2(true, x2, y2); if(p1.Distance(p2) < dist_delta) return; ///////////////////////////////////////////////////////////////////////// ///////////////////compute the shortest path///////////////////////////// ///////////////////////////////////////////////////////////////////////// int oid1 = 0; int oid2 = 0; // cout<<"tri no "<node_rel->GetNoTuples()<node_rel->GetNoTuples()); FindPointInDG1(dg, &p2, oid2); assert(1 <= oid2 && oid2 <= dg->node_rel->GetNoTuples()); Walk_SP* wsp = new Walk_SP(dg, vg, NULL, NULL); wsp->rel3 = tri_rel; Line* sp_path = new Line(0); if(EuclideanConnection(groom_reg, &p1, &p2, sp_path)){ }else{ // cout<<"p1 "<WalkShortestPath2(oid1, oid2, p1, p2, sp_path); } delete wsp; if(sp_path->Size() == 0){ sp_path->DeleteIfAllowed(); return; } vector mhs; SimpleLine* sl = new SimpleLine(0); sl->fromLine(*sp_path); SpacePartition* sp = new SpacePartition(); sp->ReorderLine(sl, mhs); delete sp; sl->DeleteIfAllowed(); sp_path->DeleteIfAllowed(); if(mhs[0].from.Distance(p1) < dist_delta && mhs[mhs.size() - 1].to.Distance(p2) < dist_delta){ }else{ assert(mhs[mhs.size() - 1].to.Distance(p1) < dist_delta && mhs[0].from.Distance(p2) < dist_delta); vector temp_mhs; for(int i = mhs.size() - 1;i >= 0;i--){ MyHalfSegment seg = mhs[i]; Point p = seg.from; seg.from = seg.to; seg.to = p; temp_mhs.push_back(seg); } mhs.clear(); for(unsigned int i = 0;i < temp_mhs.size();i++) mhs.push_back(temp_mhs[i]); assert(mhs[0].from.Distance(p1) < dist_delta && mhs[mhs.size() - 1].to.Distance(p2) < dist_delta); } /////////////////////////////////////////////////////////////////// ///////////////// conver to 3D line ////////////////////////////// /////////////////////////////////////////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point p1 = mhs[i].to; Point3D q1(true, p1.GetX(), p1.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); groom_oid_list.push_back(groom_oid); door_tid_list1.push_back(tid1); door_tid_list2.push_back(tid2); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); } /* create the edges connecting the same door but belong to two rooms */ void IndoorNav::CreateAdjDoor2(R_Tree<3,TupleId>* rtree) { SmiRecordId adr = rtree->RootRecordId(); for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* door_tuple = rel1->GetTuple(i, false); int groom_oid = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); Line3D* l = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); vector id_list; // l->Print(); ////// the number of neighbor should be 2 or 3 ////////////////// DFTraverse(rtree, adr, i, l, id_list, groom_oid); // assert(id_list.size() > 0); // cout<<"door tid "<DeleteIfAllowed(); } door_tuple->DeleteIfAllowed(); } } /* traverse the RTree to find the same door but belongs to two rooms */ void IndoorNav::DFTraverse(R_Tree<3,TupleId>* rtree, SmiRecordId adr, unsigned int id, Line3D* l, vector& id_list, int groom_oid) { R_TreeNode<3,TupleId>* node = rtree->GetMyNode(adr,false, rtree->MinEntries(0), rtree->MaxEntries(0)); Rectangle<3> bbox3d_1 = l->BoundingBox(); for(int j = 0;j < node->EntryCount();j++){ if(node->IsLeaf()){ R_TreeLeafEntry<3,TupleId> e = (R_TreeLeafEntry<3,TupleId>&)(*node)[j]; Tuple* door_tuple = rel1->GetTuple(e.info,false); Line3D* l3d = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); if(l3d->BoundingBox().Intersects(bbox3d_1) && id != e.info){ if(*l == *l3d)id_list.push_back(e.info); } /* if(l3d->BoundingBox().Intersects(bbox3d_1)){ cout<<"l2 "; l3d->Print(); if(*l == *l3d)id_list.push_back(e.info); }*/ door_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<3> e = (R_TreeInternalEntry<3>&)(*node)[j]; if(l->BoundingBox().Intersects(e.box)){ DFTraverse(rtree, e.pointer, id, l, id_list, groom_oid); } } } delete node; } ///////////////////////////////////////////////////////////////////////////// ////////// shortest path inside a polygon (convex, concave, holes) ///////// //////////////////////////////////////////////////////////////////////////// string PointsTypeInfo = "(rel(tuple((v point)(neighbor1 point)(neighbor2 point)(regid int))))"; void ShortestPath_InRegion(Region* reg, Point* s, Point* d, Line* pResult) { const double dist_delta = 0.001; if(reg->Contains(*s) == false){ cout<<"region "<<*reg<<"start point "<<*s<<" end point "<<*d<Contains(*d) == false){ cout<<"region "<<*reg<<"start point "<<*s<<" end point "<<*d<NoComponents() > 1){ cout<<"only one face is allowed"<Distance(*d) < dist_delta){ // cout<<"start location equals to the end locaton"< ps_list; Points* ps = new Points(0); reg->Vertices(ps); vector visit_flag; for(int i = 0;i < ps->Size();i++){ Point p; ps->Get(i, p); PointAndID* paid = new PointAndID(i + 1, p); ps_list.push_back(*paid); // paid->Print(); delete paid; visit_flag.push_back(true); } ps->DeleteIfAllowed(); ////////////////////collec all segments//////////////////////////////////// vector seg_list; for(int i = 0;i < reg->Size();i++){ HalfSegment hs; reg->Get(i, hs); if(!hs.IsLeftDomPoint())continue; seg_list.push_back(hs); } //////////////////create start and end point ///////////////////////////// PointAndID start_loc; PointAndID end_loc; bool start = false; bool end = false; for(unsigned int i = 0;i < ps_list.size();i++){ Point loc = ps_list[i].loc; if(s->Distance(loc) < dist_delta){ start_loc = ps_list[i]; start = true; } if(d->Distance(loc) < dist_delta){ end_loc = ps_list[i]; end = true; } if(start && end) break; } if(start == false){ start_loc.pid = 0; start_loc.loc = *s; }else visit_flag[start_loc.pid - 1] = false; if(end == false){ end_loc.pid = ps_list.size() + 1; end_loc.loc = *d; ps_list.push_back(end_loc); visit_flag.push_back(true); } ///////////////////////////////////////////////////////////////////////// ////////////first check whether Euclidean distance between s and d////// HalfSegment temp_hs(true, start_loc.loc, end_loc.loc); if(SegAvailable(temp_hs, seg_list) && RegContainHS(reg, temp_hs)){ // cout<<"find the path"<StartBulkLoad(); int edgeno = 0; HalfSegment hs(true, start_loc.loc, end_loc.loc); hs.attr.edgeno = edgeno++; *pResult += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *pResult += hs; pResult->EndBulkLoad(); return; } //////////////searching inside the region////////////////////////////// // for(unsigned int i = 0;i < pslist.size();i++) // pslist[i].Print(); priority_queue path_queue; vector expand_path; InitializeQueue(reg, path_queue, expand_path, start_loc, end_loc, ps_list, seg_list); // cout<<" initialize size "< adj_list; FindAdj(reg, cur_loc, visit_flag, adj_list, ps_list, seg_list); int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ // cout<<" neighbor "; int expand_path_size = expand_path.size(); double w = cur_loc.loc.Distance(ps_list[adj_list[i] - 1].loc); double hw = ps_list[adj_list[i] - 1].loc.Distance(end_loc.loc); path_queue.push(RPath_elem(pos_expand_path, expand_path_size, adj_list[i], top.real_w + w + hw, top.real_w + w)); expand_path.push_back(RPath_elem(pos_expand_path, expand_path_size, adj_list[i], top.real_w + w + hw, top.real_w + w)); } visit_flag[top.tri_index - 1] = false; // cout< points; while(dest.prev_index != -1){ points.push_back(ps_list[dest.tri_index - 1].loc); dest = expand_path[dest.prev_index]; } points.push_back(ps_list[dest.tri_index - 1].loc); points.push_back(start_loc.loc); pResult->StartBulkLoad(); int edgeno = 0; for(unsigned int i = 0;i < points.size() - 1;i++){ HalfSegment hs(true, points[i], points[i + 1]); hs.attr.edgeno = edgeno++; *pResult += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *pResult += hs; } pResult->EndBulkLoad(); } } /* Initialize the queue for searching, put all points which are reachable to the start point */ void InitializeQueue(Region* reg, priority_queue& path_queue, vector& expand_queue, PointAndID start_loc, PointAndID end_loc, vector& ps_list, vector& seg_list) { // cout<<"Initialize Queue "< candidate; for(unsigned int i = 0;i < ps_list.size();i++){ if(start_loc.pid != ps_list[i].pid){ HalfSegment hs(true, start_loc.loc, ps_list[i].loc); if(SegAvailable(hs, seg_list)){ candidate.push_back(i); } } } for(unsigned int i = 0;i < candidate.size();i++){ unsigned int j = candidate[i]; HalfSegment hs(true, start_loc.loc, ps_list[j].loc); if(RegContainHS(reg, hs)){ int cur_size = expand_queue.size(); double w = start_loc.loc.Distance(ps_list[j].loc); double hw = ps_list[j].loc.Distance(end_loc.loc); RPath_elem elem(-1, cur_size, ps_list[j].pid, w + hw, w); path_queue.push(elem); expand_queue.push_back(elem); } } } /* find points which are available */ void FindAdj(Region* reg, PointAndID top, vector& visit_flag, vector& adj_list, vector& ps_list, vector& seg_list) { vector candidate; for(unsigned int i = 0;i < ps_list.size();i++){ if(top.pid != ps_list[i].pid && visit_flag[i]){ HalfSegment hs(true, top.loc, ps_list[i].loc); if(SegAvailable(hs, seg_list)){ candidate.push_back(i); } } } for(unsigned int i = 0;i < candidate.size();i++){ unsigned int j = candidate[i]; HalfSegment hs(true, top.loc, ps_list[j].loc); if(RegContainHS(reg, hs)) adj_list.push_back(ps_list[j].pid); } } /* check whether the segment middle intersects another one */ bool SegAvailable(HalfSegment hs, vector& seg_list) { const double dist_delta = 0.001; for(unsigned int i = 0;i < seg_list.size();i++){ HalfSegment seg = seg_list[i]; if( (hs.GetLeftPoint().Distance(seg.GetLeftPoint()) < dist_delta && hs.GetRightPoint().Distance(seg.GetRightPoint()) < dist_delta )|| (hs.GetLeftPoint().Distance(seg.GetRightPoint()) < dist_delta && hs.GetRightPoint().Distance(seg.GetLeftPoint()) < dist_delta )) return true; HalfSegment iseg; if(hs.Intersection(seg, iseg) && iseg.Length() > dist_delta){ if(fabs(iseg.Length() - hs.Length()) < dist_delta) return true; return false; } Point ip; if(hs.Intersection(seg, ip)){ if( hs.GetLeftPoint().Distance(ip) < dist_delta || hs.GetRightPoint().Distance(ip) < dist_delta) continue; else return false; } } return true; } /* collect the boundary points of a region cycle */ void GetBoundaryPoints(Region* reg, vector& ps, unsigned int i) { SimpleLine* sl = new SimpleLine(0); sl->StartBulkLoad(); int edgeno = 0; for(int j = 0;j < reg->Size();j++){ HalfSegment hs1; reg->Get(j, hs1); if(!hs1.IsLeftDomPoint()) continue; HalfSegment hs2; hs2.Set(true, hs1.GetLeftPoint(), hs1.GetRightPoint()); hs2.attr.edgeno = edgeno++; *sl += hs2; hs2.SetLeftDomPoint(!hs2.IsLeftDomPoint()); *sl += hs2; } sl->EndBulkLoad(); SpacePartition* sp = new SpacePartition(); vector mhs; sp->ReorderLine(sl, mhs); for(unsigned int j = 0;j < mhs.size();j++) ps.push_back(mhs[j].from); delete sp; sl->DeleteIfAllowed(); CompTriangle* ct = new CompTriangle(); bool clock; if(0.0f < ct->Area(ps)){//points counter-clockwise order clock = false; }else{// points clockwise clock = true; } vector temp_ps1; //clockwise vector temp_ps2; //counter-clockwise if(clock){ for(unsigned int i = 0;i < ps.size();i++){ temp_ps1.push_back(ps[i]); temp_ps2.push_back(ps[ps.size() - 1 - i]); } }else{ for(unsigned int i = 0;i < ps.size();i++){ temp_ps2.push_back(ps[i]); temp_ps1.push_back(ps[ps.size() - 1 - i]); } } if(i == 0){ ps.clear(); for(unsigned int i = 0;i < temp_ps1.size();i++) ps.push_back(temp_ps1[i]); }else{ ps.clear(); for(unsigned int i = 0;i < temp_ps2.size();i++) ps.push_back(temp_ps2[i]); } delete ct; } /* create the dual graph and visual graph for finding the shortest path between two points inside a region. not use the simple method for complex region */ void ShortestPath_InRegionNew(Region* reg, Point* s, Point* d, Line* pResult) { const double dist_delta = 0.001; if(reg->Contains(*s) == false){ cout<<"region "<<*reg<<"start point "<<*s<<" end point "<<*d<Contains(*d) == false){ cout<<"region "<<*reg<<"start point "<<*s<<" end point "<<*d<NoComponents() > 1){ cout<<"only one face is allowed"<Distance(*d) < dist_delta){ cout<<"start location equals to the end locaton"< obj_name; GetSecondoObj(reg, obj_name); assert(obj_name.size() == 3); /////////////////////////////////////////////////////// SecondoCatalog* ctlg = SecondoSystem::GetCatalog(); bool dg_def, vg_def, rel_def; Word dg_addr, vg_addr, rel_addr; ctlg->GetObject(obj_name[0], dg_addr, dg_def); ctlg->GetObject(obj_name[1], vg_addr, vg_def); ctlg->GetObject(obj_name[2], rel_addr, rel_def); if(dg_def && vg_def && rel_def){ DualGraph* dg = (DualGraph*)dg_addr.addr; VisualGraph* vg = (VisualGraph*)vg_addr.addr; Relation* rel = (Relation*)rel_addr.addr; assert(dg != NULL); assert(vg != NULL); assert(rel != NULL); Walk_SP* wsp = new Walk_SP(dg, vg, NULL, NULL); wsp->rel3 = rel; int oid1 = 0; int oid2 = 0; FindPointInDG(dg, s, d, oid1, oid2); assert(1 <= oid1 && oid1 <= dg->node_rel->GetNoTuples()); assert(1 <= oid2 && oid2 <= dg->node_rel->GetNoTuples()); wsp->WalkShortestPath2(oid1, oid2, *s, *d, pResult); delete wsp; }else{ cout<<"open dual graph or visual graph error"< seg_list; for(int i = 0;i < reg->Size();i++){ HalfSegment hs; reg->Get(i, hs); if(!hs.IsLeftDomPoint())continue; seg_list.push_back(hs); } HalfSegment temp_hs(true, *s, *d); if(SegAvailable(temp_hs, seg_list) && RegContainHS(reg, temp_hs)){ pResult->StartBulkLoad(); HalfSegment hs(true, *s, *d); hs.attr.edgeno = 0; *pResult += hs; hs.SetLeftDomPoint(!hs.IsLeftDomPoint()); *pResult += hs; pResult->EndBulkLoad(); return true; } return false; } /* find which triangle the point is located inside */ void FindPointInDG(DualGraph* dg, Point* loc1, Point* loc2, int& id1, int& id2) { for(int i = 1;i <= dg->node_rel->GetNoTuples();i++){ Tuple* dg_tuple = dg->node_rel->GetTuple(i, false); Region* reg = (Region*)dg_tuple->GetAttribute(DualGraph::PAVEMENT); if(loc1->Inside(*reg))id1 = i; if(loc2->Inside(*reg))id2 = i; dg_tuple->DeleteIfAllowed(); } // cout<<"oid1 "<node_rel->GetNoTuples();i++){ Tuple* dg_tuple = dg->node_rel->GetTuple(i, false); Region* reg = (Region*)dg_tuple->GetAttribute(DualGraph::PAVEMENT); if(loc1->Inside(*reg))id1 = i; dg_tuple->DeleteIfAllowed(); } // cout<<"oid1 "<& obj_name) { ////////1. create a second object from the memory region////////////// string ObjName_Reg = "xu_region"; SecondoCatalog* ctlg = SecondoSystem::GetCatalog(); if ( ctlg->IsSystemObject(ObjName_Reg) ) { cout<< "ERROR: Object name identifier is a reseverved identifier."; return; } else if (ctlg->IsObjectName(ObjName_Reg) ) { cout<< "ERROR: Object name identifier " + ObjName_Reg + " is already used."; return; } ListExpr resultType1 = nl->SymbolAtom("region"); ctlg->CreateObject(ObjName_Reg, "", resultType1, 0); ctlg->CloneObject( ObjName_Reg, SetWord( reg ) ); //////////////////////////////////////////////////////////////////// /////////////////////2. dual graph///////////////////////////////// /////////////////////////////////////////////////////////////////// ///////////////// 1) dual graph nodes ////////////////////////////// string ObjName_DG_Node = "xu_dg_node"; string command1 = "triangulation(" + ObjName_Reg + ") transformstream \ addcounter[Oid, 1] extend[Rid:.Oid] extend[Pavement:.Elem] \ project[Oid,Rid,Pavement] consume"; string querystringParsed = ""; ListExpr parsedCommand1; if(CheckCommand(command1, querystringParsed, parsedCommand1) == false)return; // cout<DeleteObject(ObjName_Reg)); assert( ctlg->DeleteObject(ObjName_DG_Node)); assert( ctlg->DeleteObject(ObjName_REGNODES)); assert( ctlg->DeleteObject(ObjName_TRIREG)); assert( ctlg->DeleteObject(ObjName_TRIREGSORT)); assert( ctlg->DeleteObject(ObjName_DG_Edge)); assert( ctlg->DeleteObject(ObjName_DG)); assert( ctlg->DeleteObject(ObjName_VG_Node)); return; } RunCommand(ctlg, parsedCommand8, ObjName_VG_TRI); string ObjName_VG_TRI_BTREE = "xu_btr_vid"; string command9 = ObjName_VG_TRI + " createbtree[Vid]"; querystringParsed = ""; ListExpr parsedCommand9; if(CheckCommand(command9, querystringParsed, parsedCommand9) == false){ assert( ctlg->DeleteObject(ObjName_Reg)); assert( ctlg->DeleteObject(ObjName_DG_Node)); assert( ctlg->DeleteObject(ObjName_REGNODES)); assert( ctlg->DeleteObject(ObjName_TRIREG)); assert( ctlg->DeleteObject(ObjName_TRIREGSORT)); assert( ctlg->DeleteObject(ObjName_DG_Edge)); assert( ctlg->DeleteObject(ObjName_DG)); assert( ctlg->DeleteObject(ObjName_VG_Node)); assert( ctlg->DeleteObject(ObjName_VG_TRI)); return; } RunCommand(ctlg, parsedCommand9, ObjName_VG_TRI_BTREE); ////////////////// 2) edges ///////////////////////////////////////// string ObjName_VG_Edge = "xu_vg_edge"; string command10 = "getvgedge(" + ObjName_DG + "," + ObjName_VG_Node + "," + ObjName_TRIREG + ", " + ObjName_VG_TRI + ", " + ObjName_VG_TRI_BTREE + ") consume"; querystringParsed = ""; ListExpr parsedCommand10; if(CheckCommand(command10, querystringParsed, parsedCommand10) == false){ return; } RunCommand(ctlg, parsedCommand10, ObjName_VG_Edge); //////////////////////3) graph ////////////////////////////////// string ObjName_VG = "xu_vg"; string command11 = "createvgraph( 1000, " + ObjName_VG_Node + "," + ObjName_VG_Edge + ")"; querystringParsed = ""; ListExpr parsedCommand11; if(CheckCommand(command11, querystringParsed, parsedCommand11) == false){ return; } RunCommand(ctlg, parsedCommand11, ObjName_VG); ///////////////////////////////////////////////////////////////////////// ///////////////delete all objects///////////////////////////////// assert( ctlg->DeleteObject(ObjName_Reg)); assert( ctlg->DeleteObject(ObjName_DG_Node)); assert( ctlg->DeleteObject(ObjName_REGNODES)); // assert( ctlg->DeleteObject(ObjName_TRIREG)); //we need this assert( ctlg->DeleteObject(ObjName_TRIREGSORT)); assert( ctlg->DeleteObject(ObjName_DG_Edge)); // assert( ctlg->DeleteObject(ObjName_DG)); //we need dual graph assert( ctlg->DeleteObject(ObjName_VG_Node)); assert( ctlg->DeleteObject(ObjName_VG_TRI)); assert( ctlg->DeleteObject(ObjName_VG_TRI_BTREE)); assert( ctlg->DeleteObject(ObjName_VG_Edge)); // assert( ctlg->DeleteObject(ObjName_VG)); //we need visual graph obj_name.push_back(ObjName_DG); obj_name.push_back(ObjName_VG); obj_name.push_back(ObjName_TRIREG); } bool CheckCommand(string& str1, string& str2, ListExpr& parsedCommand) { SecParser mySecParser; if(mySecParser.Text2List( "query " + str1, str2 ) != 0){ cout<< "ERROR: Value text does not contain a \ parsable value expression."; return false; } if (!nl->ReadFromString(str2, parsedCommand) ) { cout<< "ERROR: Value text does not produce a \ valid nested list expression."; return false; } if ( (nl->ListLength(parsedCommand) == 2) ){ parsedCommand = nl->Second(parsedCommand); } else { cout<< "ERROR: Value text does not produce a \ valid nested list expression."; return false; } return true; } /* run the commond to create second object */ bool RunCommand(SecondoCatalog* ctlg, ListExpr parsedCommand, string ObjNameString) { // cout<<"object name "<Construct( parsedCommand, correct, evaluable, defined, isFunction, tree, resultType ); if ( !correct ){ cout<<"ERROR: Value text yields a TYPEERROR."; // Do not need to destroy tree here! delete qpp; return false; } string typestring = nl->ToString(resultType); if ( evaluable){ string typeName = ""; ctlg->CreateObject(ObjNameString, typeName, resultType, 0); } if ( evaluable ){ qpp->EvalS( tree, qresult, 1 ); if( IsRootObject( tree ) && !IsConstantObject( tree ) ){ // ctlg->CloneObject( ObjNameString, qresult ); // qpp->Destroy( tree, true ); } else { ctlg->UpdateObject( ObjNameString, qresult ); // qpp->Destroy( tree, false); } } delete qpp; return true; } /* delete the dual graph, visual graph and the relation */ void DeleteSecondoObj(vector obj_name) { SecondoCatalog* ctlg = SecondoSystem::GetCatalog(); for(unsigned int i = 0;i < obj_name.size();i++){ assert( ctlg->DeleteObject(obj_name[i])); } } ////////////////////////////////////////////////////////////////////////// ///////////////////Indoor Graph for Navigation////////////////////////// ///////////////////////////////////////////////////////////////////////// string IndoorGraph::NodeTypeInfo = "(rel (tuple ((Door door3d) (Door_loc line) (Groom_oid1 int) (Groom_oid2 int)\ (Door_loc3d line3d) (Doorheight real))))"; string IndoorGraph::EdgeTypeInfo = "(rel (tuple ((Groom_oid int) (Door_tid1 int) (Door_tid2 int) (Path line3d))))"; string IndoorGraph::NodeBTreeTypeInfo = "(btree (tuple ((Door door3d) (Door_loc line) (Groom_oid1 int) (Groom_oid2 int)\ (Door_loc3d line3d) (Doorheight real))) int)"; string IndoorGraph::EntranceTidTypeInfo = "(rel (tuple ((Entrance int))))"; IndoorGraph::~IndoorGraph() { // cout<<"~IndoorGraph()"<Close(); } IndoorGraph::IndoorGraph():btree_node(NULL), entrance_list(NULL), graph_type(0) { // cout<<"IndoorGraph::IndoorGraph()"<IsEqual(type, "indoorgraph"); } void IndoorGraph::CloseIndoorGraph(const ListExpr typeInfo, Word& w) { // cout<<"CloseIndoorGraph()"< (w.addr); w.addr = NULL; } void IndoorGraph::DeleteIndoorGraph(const ListExpr typeInfo, Word& w) { // cout<<"DeleteIndoorGraph()"<Out(typeInfo); } /* Output the indoor graph */ ListExpr IndoorGraph::Out(ListExpr typeInfo) { // cout<<"Out()"<TheEmptyList(); ListExpr xLast = nl->TheEmptyList(); ListExpr xNext = nl->TheEmptyList(); bool bFirst = true; for(int i = 1;i <= edge_rel->GetNoTuples();i++){ Tuple* edge_tuple = edge_rel->GetTuple(i, false); CcInt* groom_oid = (CcInt*)edge_tuple->GetAttribute(I_GROOM_OID); CcInt* oid1 = (CcInt*)edge_tuple->GetAttribute(I_DOOR_TID1); CcInt* oid2 = (CcInt*)edge_tuple->GetAttribute(I_DOOR_TID2); Line* connection = (Line*)edge_tuple->GetAttribute(I_PATH); ListExpr xline = OutLine3D(nl->TheEmptyList(),SetWord(connection)); xNext = nl->FourElemList(nl->IntAtom(groom_oid->GetIntval()), nl->IntAtom(oid1->GetIntval()), nl->IntAtom(oid2->GetIntval()), xline); if(bFirst){ xNode = nl->OneElemList(xNext); xLast = xNode; bFirst = false; }else xLast = nl->Append(xLast,xNext); edge_tuple->DeleteIfAllowed(); } ListExpr xtype = nl->TwoElemList( nl->StringAtom("Graph Type: "), nl->StringAtom(GetBuildingStr(graph_type))); // return nl->TwoElemList(nl->IntAtom(g_id),xNode); return nl->ThreeElemList(nl->IntAtom(g_id), xtype, xNode); } IndoorGraph::IndoorGraph(SmiRecord& in_xValueRecord, size_t& inout_iOffset, const ListExpr in_xTypeInfo) { // cout<<"IndoorGraph::IndoorGraph(SmiRecord)"<ReadFromString(NodeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); node_rel = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType); if(!node_rel) { return; } /***********************Open relation for edge*********************/ nl->ReadFromString(EdgeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); edge_rel = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType); if(!edge_rel) { node_rel->Delete(); return; } ////////////////////adjaency list//////////////////////////////// size_t bufsize = DbArray::headerSize(); SmiSize offset = 0; char* buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; assert(buf != NULL); adj_list.restoreHeader(buf,offset); free(buf); offset = 0; buf = (char*) malloc(bufsize); in_xValueRecord.Read(buf, bufsize, inout_iOffset); assert(buf != NULL); entry_adj_list.restoreHeader(buf,offset); inout_iOffset += bufsize; free(buf); /////////////////////////////////////////////////////////////////// /////////////////btree on node///////////////////////////////////// /////////////////////////////////////////////////////////////////// nl->ReadFromString(NodeBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_node = BTree::Open(in_xValueRecord, inout_iOffset, xNumericType); if(!btree_node) { node_rel->Delete(); edge_rel->Delete(); return; } /////////////////////////////////////////////////////////////// ////////////relation for door tid for entrance//////////////// ////////////////////////////////////////////////////////////// nl->ReadFromString(EntranceTidTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); entrance_list = Relation::Open(in_xValueRecord, inout_iOffset, xNumericType); if(!entrance_list) { node_rel->Delete(); edge_rel->Delete(); delete btree_node; return; } } IndoorGraph* IndoorGraph::Open(SmiRecord& valueRecord,size_t& offset, const ListExpr typeInfo) { return new IndoorGraph(valueRecord,offset,typeInfo); } bool IndoorGraph::OpenIndoorGraph(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenIndoorGraph()"<Save(valueRecord, offset, typeInfo); return result; } /* Save an indoor graph */ bool IndoorGraph::Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset, const ListExpr in_xTypeInfo) { // cout<<"Save()"<ReadFromString(NodeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!node_rel->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; /************************save edge****************************/ nl->ReadFromString(EdgeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!edge_rel->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; SecondoCatalog *ctlg = SecondoSystem::GetCatalog(); SmiRecordFile *rf = ctlg->GetFlobFile(); adj_list.saveToFile(rf, adj_list); SmiSize offset = 0; size_t bufsize = adj_list.headerSize(); char* buf = (char*) malloc(bufsize); adj_list.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf, bufsize, inout_iOffset); inout_iOffset += bufsize; free(buf); entry_adj_list.saveToFile(rf, entry_adj_list); offset = 0; buf = (char*) malloc(bufsize); entry_adj_list.serializeHeader(buf,offset); assert(offset==bufsize); in_xValueRecord.Write(buf,bufsize, inout_iOffset); free(buf); inout_iOffset += bufsize; /////////////////////////////save btree on node //////////////////// nl->ReadFromString(NodeBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_node->Save(in_xValueRecord, inout_iOffset, xNumericType)) return false; ///////////////////////////////////////////////////////////////////// /**************door tid for building entrance*************************/ nl->ReadFromString(EntranceTidTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!entrance_list->Save(in_xValueRecord,inout_iOffset,xNumericType)) return false; return true; } /* Load the Indoor graph */ void IndoorGraph::Load(int id, Relation* r1, Relation* r2, int type) { // cout<<"IndoorGraph::Load()"<ToString(ptrList1) + "))))"; Word xResult; int QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); node_rel = (Relation*)xResult.addr; /////////////////edge relation///////////////////// ListExpr ptrList2 = listutils::getPtrList(r2); strQuery = "(consume(sort(feed(" + EdgeTypeInfo + "(ptr " + nl->ToString(ptrList2) + ")))))"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); edge_rel = (Relation*)xResult.addr; ////////////adjacency list //////////////////////////////// ListExpr ptrList3 = listutils::getPtrList(edge_rel); strQuery = "(createbtree (" + EdgeTypeInfo + "(ptr " + nl->ToString(ptrList3) + "))" + "Door_tid1)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery,xResult); assert(QueryExecuted); BTree* btree_node_oid1 = (BTree*)xResult.addr; // cout<<"b-tree on edge is finished....."<GetNoTuples();i++){ CcInt* nodeid = new CcInt(true, i); BTreeIterator* btree_iter1 = btree_node_oid1->ExactMatch(nodeid); int start = adj_list.Size(); // cout<<"start "<Next()){ Tuple* edge_tuple = edge_rel->GetTuple(btree_iter1->GetId(), false); // int tid2 = ((CcInt*)edge_tuple->GetAttribute(I_DOOR_TID2))->GetIntval(); adj_list.Append(edge_tuple->GetTupleId());//get the edge tuple id edge_tuple->DeleteIfAllowed(); } delete btree_iter1; int end = adj_list.Size(); entry_adj_list.Append(ListEntry(start, end)); // cout<<"end "<ToString(ptrList4) + "))" + "Groom_oid1)"; // cout< groom_id_list; for(int i = 1;i <= r2->GetNoTuples();i++){ Tuple* groom_tuple = r2->GetTuple(i, false); int gid = ((CcInt*)groom_tuple->GetAttribute(IndoorGraph::I_GROOM_OID))->GetIntval(); groom_id_list.push_back(gid); groom_tuple->DeleteIfAllowed(); } sort(groom_id_list.begin(), groom_id_list.end()); vector::iterator last; last = unique(groom_id_list.begin(), groom_id_list.end()); num_of_grooms = 0; for(vector::iterator iter = groom_id_list.begin(); iter != last;iter++){ num_of_grooms++; }*/ ////////////////////////////////////////////////////////////////////// ////////////////the entrance of the building////////////////////////// ///////////////////////////////////////////////////////////////////// ListExpr xTypeInfo; nl->ReadFromString(EntranceTidTypeInfo, xTypeInfo); ListExpr xNumType = SecondoSystem::GetCatalog()->NumericType(xTypeInfo); Relation* s_rel = new Relation(xNumType, true); for(int i = 1;i <= r1->GetNoTuples();i++){ Tuple* door_tuple = r1->GetTuple(i, false); int groom_oid2 = ((CcInt*)door_tuple->GetAttribute(I_GROOM_OID2))->GetIntval(); // if(groom_oid2 == -1){ if(groom_oid2 == (int)UNDEFVAL){ Tuple* new_tuple = new Tuple(nl->Second(xNumType)); new_tuple->PutAttribute(0, new CcInt(true, door_tuple->GetTupleId())); s_rel->AppendTuple(new_tuple); new_tuple->DeleteIfAllowed(); } door_tuple->DeleteIfAllowed(); } ListExpr ptrList5 = listutils::getPtrList(s_rel); strQuery = "(consume(feed(" + EntranceTidTypeInfo + "(ptr " + nl->ToString(ptrList5) + "))))"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); entrance_list = (Relation*)xResult.addr; s_rel->Delete(); // cout<<"number of entrance "<GetNoTuples()<GetNoTuples() == 0){ cout<<"invalid building: no entrance"<& door_loc) { for(int i = 1;i <= entrance_list->GetNoTuples();i++){ Tuple* tuple1 = entrance_list->GetTuple(i, false); int tid = ((CcInt*)tuple1->GetAttribute(0))->GetIntval(); Tuple* tuple2 = node_rel->GetTuple(tid, false); Line* l = (Line*)tuple2->GetAttribute(I_DOOR_LOC); HalfSegment hs; l->Get(0, hs); Point lp = hs.GetLeftPoint(); Point rp = hs.GetRightPoint(); Point mp(true, (lp.GetX() + rp.GetX())/2, (lp.GetY() + rp.GetY())/2); door_loc.push_back(mp); tuple2->DeleteIfAllowed(); tuple1->DeleteIfAllowed(); } } /* get the position of the door by genloc */ void IndoorGraph::GetEntranceDoor2(vector& door_loc, vector& groom_list, vector& door_tid_list) { for(int i = 1;i <= entrance_list->GetNoTuples();i++){ Tuple* tuple1 = entrance_list->GetTuple(i, false); int tid = ((CcInt*)tuple1->GetAttribute(0))->GetIntval(); door_tid_list.push_back(tid); Tuple* tuple2 = node_rel->GetTuple(tid, false); int groom_oid = ((CcInt*)tuple2->GetAttribute(I_GROOM_OID1))->GetIntval(); /////////////////////////////////////////////////////////////////////////// /////////////////////////door position//////////////////////////////////// ///////////////////////////////////////////////////////////////////////// Line* l = (Line*)tuple2->GetAttribute(I_DOOR_LOC); HalfSegment hs; l->Get(0, hs); Point lp = hs.GetLeftPoint(); Point rp = hs.GetRightPoint(); Point mp(true, (lp.GetX() + rp.GetX())/2, (lp.GetY() + rp.GetY())/2); door_loc.push_back(mp); groom_list.push_back(groom_oid); tuple2->DeleteIfAllowed(); tuple1->DeleteIfAllowed(); } } /* collect all doors of a groom by oid */ void IndoorGraph::GetDoorsInGRoom(int groom_oid, vector& tid_list) { CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree_node->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter->GetId(), false); tid_list.push_back(tuple->GetTupleId()); tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; } /* get all adjacent nodes for a given node. indoor graph */ void IndoorNav::GetAdjNodeIG(int oid) { if(oid < 1 || oid > ig->GetNodeRel()->GetNoTuples()){ cout<<"invalid oid "<GetNodeRel()->GetNoTuples()<<" nodes "<GetEdgeRel()->GetNoTuples()<<" edges "< adj_list; ig->FindAdj(oid, adj_list); // cout<<"adj_list size "<GetEdgeRel()->GetTuple(adj_list[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_DOOR_TID2))->GetIntval(); Line3D* path = (Line3D*)edge_tuple->GetAttribute(IndoorGraph::I_PATH); door_tid_list1.push_back(oid); door_tid_list2.push_back(neighbor_id); path_list.push_back(*path); edge_tuple->DeleteIfAllowed(); } } /* generate interesting indoor points do not include the position on the staircase and elevator it contains OR, CO, BR */ void IndoorNav::GenerateIP1(int num) { int no_rooms = rel1->GetNoTuples(); // struct timeval tval; // struct timezone tzone; // gettimeofday(&tval, &tzone); // srand48(tval.tv_sec);//second // srand48(tval.tv_usec);//Microseconds const double TM_EPSILON = 0.001; for(int i = 1;i <= num;){ unsigned int room_oid; room_oid = GetRandom() % no_rooms + 1; Tuple* room_tuple = rel1->GetTuple(room_oid, false); string type = ((CcString*)room_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == ST || GetRoomEnum(type) == EL){ room_tuple->DeleteIfAllowed(); continue; } GRoom* groom = (GRoom*)room_tuple->GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); int xx = (int)(bbox.MaxD(0) - bbox.MinD(0)) + 1; int yy = (int)(bbox.MaxD(1) - bbox.MinD(1)) + 1; Point p1; Point p2; bool inside = false; int count = 1; while(inside == false && count <= 100){ int x = (GetRandom() + 1)% (xx*100); int y = (GetRandom() + 1)% (yy*100); double coord_x = x/100.0; double coord_y = y/100.0; if(coord_x < TM_EPSILON) coord_x = 0.0; if(coord_y < TM_EPSILON) coord_y = 0.0; p1.Set(coord_x, coord_y); //set back to relative position //lower the precision Modify_Point_3(p1); Coord x_cord = p1.GetX() + bbox.MinD(0); Coord y_cord = p1.GetY() + bbox.MinD(1); p2.Set(x_cord, y_cord); //absolute position inside = p2.Inside(*reg); count++; } if(inside){ float h = groom->GetLowHeight();////////////always on the lowest level Loc loc(p1.GetX(), p1.GetY()); GenLoc genl(room_oid, loc); Point3D q(true, p2.GetX(), p2.GetY(), h); genloc_list.push_back(genl); p3d_list.push_back(q); i++; } reg->DeleteIfAllowed(); room_tuple->DeleteIfAllowed(); } } /* generate interesting indoor points only include the position on the staircase */ void IndoorNav::GenerateIP2(int num) { int no_rooms = rel1->GetNoTuples(); const double TM_EPSILON = 0.001; for(int i = 1;i <= num;){ unsigned int room_oid; room_oid = GetRandom() % no_rooms + 1; Tuple* room_tuple = rel1->GetTuple(room_oid, false); string type = ((CcString*)room_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) != ST ){ room_tuple->DeleteIfAllowed(); continue; } GRoom* groom = (GRoom*)room_tuple->GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); int xx = (int)(bbox.MaxD(0) - bbox.MinD(0)) + 1; int yy = (int)(bbox.MaxD(1) - bbox.MinD(1)) + 1; Point p1; Point p2; bool inside = false; int count = 1; while(inside == false && count <= 100){ int x = (GetRandom() + 1)% (xx*100); int y = (GetRandom() + 1)% (yy*100); double coord_x = x/100.0; double coord_y = y/100.0; if(coord_x < TM_EPSILON) coord_x = 0.0; if(coord_y < TM_EPSILON) coord_y = 0.0; p1.Set(coord_x, coord_y); //set back to relative position //lower the precision Modify_Point_3(p1); Coord x_cord = p1.GetX() + bbox.MinD(0); Coord y_cord = p1.GetY() + bbox.MinD(1); p2.Set(x_cord, y_cord); //absolute position inside = p2.Inside(*reg); count++; } if(inside){ bool flag = false; float h = GetHeightInST2(groom, p2, flag); if(flag){ Loc loc(p1.GetX(), p1.GetY()); GenLoc genl(room_oid, loc); Point3D q(true, p2.GetX(), p2.GetY(), h); genloc_list.push_back(genl); p3d_list.push_back(q); i++; } } reg->DeleteIfAllowed(); room_tuple->DeleteIfAllowed(); } } /* generate an indoor location only in Office Room */ void IndoorNav::GenerateIP3(int num) { int no_rooms = rel1->GetNoTuples(); // struct timeval tval; // struct timezone tzone; // gettimeofday(&tval, &tzone); // srand48(tval.tv_sec);//second // srand48(tval.tv_usec);//Microseconds const double TM_EPSILON = 0.001; for(int i = 1;i <= num;){ unsigned int room_oid; room_oid = GetRandom() % no_rooms + 1; Tuple* room_tuple = rel1->GetTuple(room_oid, false); string type = ((CcString*)room_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) != OR){ room_tuple->DeleteIfAllowed(); continue; } GRoom* groom = (GRoom*)room_tuple->GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); ////////////////check complexity////////////////////// /////////we ignore the complex region here////////////////////// /////because it needs to build rtree and btree////////////////// ////////a lot of somethin sdb files, bdb SMI open too many files///////// CompTriangle* ct = new CompTriangle(reg); int complex_reg = ct->ComplexRegion(); delete ct; if(complex_reg == 1){ reg->DeleteIfAllowed(); room_tuple->DeleteIfAllowed(); continue; } ////////////////////////////////////// BBox<2> bbox = reg->BoundingBox(); int xx = (int)(bbox.MaxD(0) - bbox.MinD(0)) + 1; int yy = (int)(bbox.MaxD(1) - bbox.MinD(1)) + 1; Point p1; Point p2; bool inside = false; int count = 1; while(inside == false && count <= 100){ int x = (GetRandom() + 1)% (xx*100); int y = (GetRandom() + 1)% (yy*100); double coord_x = x/100.0; double coord_y = y/100.0; if(coord_x < TM_EPSILON) coord_x = 0.0; if(coord_y < TM_EPSILON) coord_y = 0.0; p1.Set(coord_x, coord_y); //set back to relative position //lower the precision Modify_Point_3(p1); Coord x_cord = p1.GetX() + bbox.MinD(0); Coord y_cord = p1.GetY() + bbox.MinD(1); p2.Set(x_cord, y_cord); //absolute position inside = p2.Inside(*reg); count++; } if(inside){ float h = groom->GetLowHeight();////////////always on the lowest level Loc loc(p1.GetX(), p1.GetY()); GenLoc genl(room_oid, loc); Point3D q(true, p2.GetX(), p2.GetY(), h); genloc_list.push_back(genl); p3d_list.push_back(q); i++; } reg->DeleteIfAllowed(); room_tuple->DeleteIfAllowed(); } } /* find the height of the point in a staircase. at which footstep */ float IndoorNav::GetHeightInST(GRoom* groom, Point p) { for(int i = 0; i < groom->Size(); i++){ Region temp_reg(0); float h; groom->Get( i, h, temp_reg); if(temp_reg.Contains(p)) return h; } cout<<"do not find the point in the 2D area"<Size(); i++){ Region temp_reg(0); float h; groom->Get( i, h, temp_reg); if(temp_reg.Contains(p)){ flag = true; return h; } } cout<<"do not find the point in the 2D area"<& periods, vector& elev_list, double speed) { for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); float h = groom->GetLowHeight(); Elevator elevator(h, 0.0, 0.0, 0.0, 0.0); elev_list.push_back(elevator); } groom_tuple->DeleteIfAllowed(); } if(elev_list.size() < 2){ // cout<<"only one floor, should not have elevator"<= 0;i --){ elev_list[i].t1 = elev_list[i + 1].t1 + stay + time_move; elev_list[i].t2 = elev_list[i + 1].t2 - stay - time_move; elev_list[i].m_t = time_move; elev_list[i].w_t = stay; } for(unsigned int i = 0;i < elev_list.size();i++){ // elev_list[i].Print(); Instant t1 = periods.start; t1.ReadFrom(elev_list[i].t1); Instant t2 = periods.start; t2.ReadFrom(elev_list[i].t2); // cout<<"first arrive "<* rtree, int num, Periods* peri, bool convert) { // cout<<"one elevator "< periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ GenLoc loc1 = genloc_list[i]; GenLoc loc2 = genloc_list[i + 1]; /* Loc loc_1(0.3, 0.4); Loc loc_2(0.2, 0.5); loc1.SetValue(71, loc_1); loc2.SetValue(153, loc_2);*/ //using elevator, for testing if(loc1.GetOid() == loc2.GetOid()) continue; cout<<"loc1 "<ShortestPath_Length(&loc1, &loc2, rel1, btree); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } /* get the building entrance location */ void IndoorNav::GetDoorLoc(IndoorGraph* ig, BTree* btree, vector& doorloc_list, vector& door_tid_list) { vector loc_list; vector groom_list; ig->GetEntranceDoor2(loc_list, groom_list, door_tid_list); for(unsigned int i = 0;i < loc_list.size();i++){ int groom_oid = groom_list[i]; CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel1->GetNoTuples()); Tuple* groom_tuple = rel1->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<2> bbox = groom->BoundingBox(); // Loc loc(loc_list[i].GetX() - bbox.MinD(0), // loc_list[i].GetY() - bbox.MinD(1)); double x = loc_list[i].GetX() - bbox.MinD(0); double y = loc_list[i].GetY() - bbox.MinD(1); const double tm_epsilon = 0.001; if( x < tm_epsilon) x = 0.0; if( y < tm_epsilon) y = 0.0; Loc loc(x,y); GenLoc gloc(groom_oid, loc); // cout<<"gloc "<DeleteIfAllowed(); } } /* generate interesting indoor moving objects. from the building entrance to a location in the building */ void IndoorNav::GenerateMO2_Start(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, int num, Periods* peri, bool convert) { // cout<<"GenerateMO2"< doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// IndoorNav* indoor_nav = new IndoorNav(ig); Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ GenLoc loc2 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc1 = doorloc_list[door_index]; if(loc1.GetOid() == loc2.GetOid()) continue; cout<<"loc1 "<ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); entrance_index.push_back(door_index + 1);//maps to tuple id /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } /* generate interesting indoor moving objects. from a location in the building to one of the entrances */ void IndoorNav::GenerateMO2_End(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, int num, Periods* peri, bool convert) { // cout<<"GenerateMO2"< doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// IndoorNav* indoor_nav = new IndoorNav(ig); Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ GenLoc loc1 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc2 = doorloc_list[door_index]; if(loc1.GetOid() == loc2.GetOid()) continue; cout<<"loc1 "<ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); entrance_index.push_back(door_index + 1);//maps to tuple id /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } /* create one indoor movement from the building entrance to an indoor location. this function is used to create indoor and outdoor trips */ void IndoorNav::GenerateMO3_Start(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri) { // GenerateIP1(1); GenerateIP3(1); //////////////////get the building entrance position///////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ///////////////////////////////////////////////////////////////////// // cout<<"indoor paths size "<GetNoComponents() == 0){ cout<<"not correct time periods"< periods; peri->Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); ////////////////////////////////////////////////////////////////////// int num = 1; int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ GenLoc loc2 = genloc_list[i]; int door_index = entrance_index - 1; GenLoc loc1 = doorloc_list[door_index]; // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_Start2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator2(mp3d, p3d_list, start_time, periods.start, elev_list, start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; /////////////////////////////////////////////////////////////////// //the following function takes time #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /* create one indoor movement from a location to the building entrance this function is used to create indoor and outdoor trips */ void IndoorNav::GenerateMO3_End(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri) { // GenerateIP1(1); GenerateIP3(1); //////////////////get the building entrance position///////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); //////////////////////initialize elevator////////////////////////////// if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"< periods; peri->Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); ////////////////////////////////////////////////////////////////////// int num = 1; int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ GenLoc loc1 = genloc_list[i]; int door_index = entrance_index - 1; GenLoc loc2 = doorloc_list[door_index]; /////////////////debuging////////////////////// /* Loc temp_loc(4.36,11.13); GenLoc temp_gloc(195, temp_loc); loc1 = temp_gloc;*/ ////////////////////////////////////////////// // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_End2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator2(mp3d, p3d_list, start_time, periods.start, elev_list, start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; ///////////////////////////////////////////////////////////// #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /* almost the same as GenerateMO3End by but giving the start location */ void IndoorNav::GenerateMO3_EndExt(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri, GenLoc loc_input) { //////////////////get the building entrance position///////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); //////////////////////initialize elevator////////////////////////////// if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"< periods; peri->Get(0, periods); double speed = GetMinimumDoorWidth(); vector elev_list; InitializeElevator(periods, elev_list, speed); ////////////////////////////////////////////////////////////////////// int num = 1; int count = 0; genloc_list.push_back(loc_input); for(unsigned int i = 0;i < genloc_list.size();i++){ GenLoc loc1 = genloc_list[i]; int door_index = entrance_index - 1; GenLoc loc2 = doorloc_list[door_index]; /////////////////debuging////////////////////// /* Loc temp_loc(4.36,11.13); GenLoc temp_gloc(195, temp_loc); loc1 = temp_gloc;*/ ////////////////////////////////////////////// // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_End2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && elev_list.size() > 1){ float delta_h = fabs(elev_list[1].h - elev_list[0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator2(mp3d, p3d_list, start_time, periods.start, elev_list, start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; ///////////////////////////////////////////////////////////// #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /* add temporal units (for movement in an elevator) */ void IndoorNav::AddUnitToMO_Elevator(MPoint3D* mp3d, vector& p3d_list, Instant& start_time, Instant& st, vector& elev_list) { assert(p3d_list.size() >= 2 && elev_list.size() >= 2); ////////////get the time for waiting/////////////////////////////////// double relative_start = start_time.ToDouble() - st.ToDouble(); double cycle_time = elev_list[elev_list.size() - 1].t2 - elev_list[elev_list.size() - 1].t1; while(relative_start > cycle_time){ relative_start -= cycle_time; } // printf("relative time %.12f\n", relative_start*86400000); Instant t = start_time; t.ReadFrom(relative_start + st.ToDouble()); // cout<<"relative time "< relative_start){ wait_time = elev_list[i].t2 - relative_start; }else{ wait_time = elev_list[i].t2 + cycle_time - relative_start; } }else{//check t1 if(elev_list[i].t1 > relative_start){ wait_time = elev_list[i].t1 - relative_start; }else{ wait_time = elev_list[i].t1 + cycle_time - relative_start; } } break; } } // printf("wait time %.12f, %.12f\n", wait_time, wait_time*86400000); ////////////////////unit for waiting///////////////////////// if(wait_time > 0.0){ Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + wait_time); up_interval.end = end; int64_t st = start_time.ToDouble()*86400000.0; int64_t et = end.ToDouble()*86400000.0; if(st != et){ up_interval.lc = true; up_interval.rc = false; Point3D p = p3d_list[0]; UPoint3D* unit = new UPoint3D(up_interval, p, p); mp3d->Add(*unit); delete unit; } start_time = end; } //////////////////////////////////////////////////////////////////////////// for(int i = 0;i < (int) p3d_list.size();i++){ if(i < (int)(p3d_list.size() - 1)){ Point3D p1 = p3d_list[i]; Point3D p2 = p3d_list[i + 1]; Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + elev_list[0].m_t); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; if(i < (int)(p3d_list.size() - 2)){ Interval up_interval2; up_interval2.start = start_time; Instant end2 = start_time; end2.ReadFrom(start_time.ToDouble() + elev_list[0].w_t); up_interval2.end = end2; up_interval2.lc = true; up_interval2.rc = false; UPoint3D* unit = new UPoint3D(up_interval2, p2, p2); mp3d->Add(*unit); delete unit; start_time = end2; } } } } /* add temporal units (for movement in an elevator) in implementation by loading stored groom oid */ void IndoorNav::AddUnitToMO_Elevator2(MPoint3D* mp3d, vector& p3d_list, Instant& start_time, Instant& st, vector& elev_list, int index, Line3D* l_room, int build_id, GenMO* genmo) { assert(p3d_list.size() >= 2 && elev_list.size() >= 2); ////////////get the time for waiting/////////////////////////////////// double relative_start = start_time.ToDouble() - st.ToDouble(); double cycle_time = elev_list[elev_list.size() - 1].t2 - elev_list[elev_list.size() - 1].t1; while(relative_start > cycle_time){ relative_start -= cycle_time; } // printf("relative time %.12f\n", relative_start*86400000); Instant t = start_time; t.ReadFrom(relative_start + st.ToDouble()); // cout<<"relative time "< relative_start){ wait_time = elev_list[i].t2 - relative_start; }else{ wait_time = elev_list[i].t2 + cycle_time - relative_start; } }else{//check t1 if(elev_list[i].t1 > relative_start){ wait_time = elev_list[i].t1 - relative_start; }else{ wait_time = elev_list[i].t1 + cycle_time - relative_start; } } break; } } // printf("wait time %.12f %.12f\n", wait_time, wait_time*86400000); ////////////////////unit for waiting///////////////////////// if(wait_time > 0.0){ Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + wait_time); up_interval.end = end; int64_t st = start_time.ToDouble()*86400000.0; int64_t et = end.ToDouble()*86400000.0; if(st != et){ up_interval.lc = true; up_interval.rc = false; Point3D p = p3d_list[0]; UPoint3D* unit = new UPoint3D(up_interval, p, p); mp3d->Add(*unit); delete unit; ///////////////////////////////////////////// /////////genric units/////////////////////// ///////////////////////////////////////////// Point3D q; l_room->Get(index, q); int groom_tid = 0; if(q.GetX() > 0 ) groom_tid = q.GetX(); else if(q.GetY() > 0) groom_tid = q.GetY(); else if(q.GetZ() > 0) groom_tid = q.GetZ(); else assert(false); Tuple* groom_tuple = rel1->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); char buffer1[64]; sprintf(buffer1, "%d", groom_oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); int new_groom_oid; sscanf(buffer2, "%d", &new_groom_oid);//////building id + room id/// // cout<<"ref oid "<Add(*ugenloc); delete ugenloc; } start_time = end; } //////////////////////////////////////////////////////////////////////////// for(int i = 0;i < (int) p3d_list.size();i++){ if(i < (int)(p3d_list.size() - 1)){ Point3D p1 = p3d_list[i]; Point3D p2 = p3d_list[i + 1]; Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + elev_list[0].m_t); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; ///////////////////////////////////////////// /////////genric units//////////////////////// ///////////////////////////////////////////// // int groom_tid = GetRef_RoomTid(index + i, l_room); int groom_tid = GetRef_RoomTid(index + i, l_room, true); Tuple* groom_tuple = rel1->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); char buffer1[64]; sprintf(buffer1, "%d", groom_oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); int new_groom_oid; sscanf(buffer2, "%d", &new_groom_oid);//////building id + room id/// // cout<<"ref oid "<Add(*ugenloc); delete ugenloc; if(i < (int)(p3d_list.size() - 2)){ Interval up_interval2; up_interval2.start = start_time; Instant end2 = start_time; end2.ReadFrom(start_time.ToDouble() + elev_list[0].w_t); up_interval2.end = end2; up_interval2.lc = true; up_interval2.rc = false; UPoint3D* unit = new UPoint3D(up_interval2, p2, p2); mp3d->Add(*unit); delete unit; start_time = end2; ///////////////////////////////////////////// /////////genric units////////////////////// ///////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){ //move in an elevator,we record the height // Loc loc_1(p2.GetZ(), -1.0); // Loc loc_2(p2.GetZ(), -1.0); Loc loc_1(p2.GetZ(), UNDEFVAL); Loc loc_2(p2.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; } } } } /* calculate the number of elevators in a building */ unsigned int IndoorNav::NumerOfElevators() { const double delta_dist = 0.001; vector center_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<2> bbox = groom->BoundingBox(); Point p(true, (bbox.MinD(0) + bbox.MaxD(0))/2, (bbox.MinD(1) + bbox.MaxD(1))/2); if(center_list.size() == 0)center_list.push_back(p); else{ unsigned int j = 0; for(;j < center_list.size();j++) if(center_list[j].Distance(p) < delta_dist)break; if(j == center_list.size()) center_list.push_back(p); } } groom_tuple->DeleteIfAllowed(); } return center_list.size(); } /* several elevators. for each elevator, an array is maintained */ void IndoorNav::InitializeElevator_New(Interval& periods, vector< vector >& elev_list, double speed) { const double delta_dist = 0.001; vector center_list; for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<2> bbox = groom->BoundingBox(); Point p(true, (bbox.MinD(0) + bbox.MaxD(0))/2, (bbox.MinD(1) + bbox.MaxD(1))/2); if(center_list.size() == 0)center_list.push_back(p); else{ unsigned int j = 0; for(;j < center_list.size();j++) if(center_list[j].Distance(p) < delta_dist)break; if(j == center_list.size()) center_list.push_back(p); } } groom_tuple->DeleteIfAllowed(); } vector empty_list; for(unsigned int i = 0 ; i < center_list.size();i++) elev_list.push_back(empty_list); for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<2> bbox = groom->BoundingBox(); float h = groom->GetLowHeight(); Point p(true, (bbox.MinD(0) + bbox.MaxD(0))/2, (bbox.MinD(1) + bbox.MaxD(1))/2); Elevator elevator(h, 0.0, 0.0, 0.0, 0.0); elevator.el_rect = bbox; for(unsigned int j = 0;j < center_list.size();j++){ if(center_list[j].Distance(p) < delta_dist){ elev_list[j].push_back(elevator); } } } groom_tuple->DeleteIfAllowed(); } // for(unsigned int i = 0;i < elev_list.size();i++) // cout<<"elevator "<= 0;j --){ elev_list[i][j].t1 = elev_list[i][j + 1].t1 + stay + time_move; elev_list[i][j].t2 = elev_list[i][j + 1].t2 - stay - time_move; elev_list[i][j].m_t = time_move; elev_list[i][j].w_t = stay; } } // for(unsigned int i = 0;i < elev_list.size();i++){ // for(unsigned int j = 0;j < elev_list[i].size();j++){ // Instant t1 = periods.start; // t1.ReadFrom(periods.start.ToDouble() + elev_list[i][j].t1); // // Instant t2 = periods.start; // t2.ReadFrom(periods.start.ToDouble() + elev_list[i][j].t2); // // cout<<"first arrive "<* rtree, int num, Periods* peri, bool convert, unsigned int num_elev) { // cout<<"several elevators "< periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ GenLoc loc1 = genloc_list[i]; GenLoc loc2 = genloc_list[i + 1]; if(loc1.GetOid() == loc2.GetOid()) continue; // cout<<"loc1 "<ShortestPath_Length(&loc1, &loc2, rel1, btree); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } void IndoorNav::AddUnitToMO_Elevator_New(MPoint3D* mp3d, vector& p3d_list, Instant& start_time, Instant& st, vector< vector >& elev_list) { assert(p3d_list.size() >= 2 && elev_list[0].size() >= 2); ////////////get the time for waiting/////////////////////////////////// double relative_start = start_time.ToDouble() - st.ToDouble(); ///////////////////////////////////////////////////////////////////////// ///////////////////find which elevator/////////////////////////////////// ///////////// different elevators (different heights)2 or 3 levels/////// ///////////////// have different cycle time///////////////////////////// ///////////////////////////////////////////////////////////////////////// float h1 = p3d_list[0].GetZ(); float h2 = p3d_list[ p3d_list.size() - 1].GetZ(); Point test_p(true, p3d_list[0].GetX(), p3d_list[0].GetY()); int elev_index = -1; for(unsigned int i = 0;i < elev_list.size();i++){ if(test_p.Inside(elev_list[i][0].el_rect)){ elev_index = i; break; } } assert(elev_index >= 0); ////////////////////////////////////////////////////////////////////// double cycle_time = elev_list[elev_index][elev_list[elev_index].size() - 1].t2 - elev_list[elev_index][elev_list[elev_index].size() - 1].t1; while(relative_start > cycle_time){ relative_start -= cycle_time; } // printf("relative time %.12f\n", relative_start*86400000); Instant t = start_time; t.ReadFrom(relative_start + st.ToDouble()); // cout<<"relative time "< relative_start){ // if(elev_list[i][j].t2 > relative_start || // (int)(elev_list[i][j].t2*86400.0) == relative_start_int){ wait_time = elev_list[i][j].t2 - relative_start; }else{ wait_time = elev_list[i][j].t2 + cycle_time - relative_start; } }else{//check t1 // cout<<"h1 > h2 "< relative_start){ wait_time = elev_list[i][j].t1 - relative_start; }else{ wait_time = elev_list[i][j].t1 + cycle_time - relative_start; } } found = true; Instant temp = start_time; temp.ReadFrom(start_time.ToDouble() + wait_time); // cout<<"elevator "< 0.0){ Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + wait_time); up_interval.end = end; int64_t st = start_time.ToDouble()*86400000.0; int64_t et = end.ToDouble()*86400000.0; if(st != et){ up_interval.lc = true; up_interval.rc = false; Point3D p = p3d_list[0]; UPoint3D* unit = new UPoint3D(up_interval, p, p); mp3d->Add(*unit); delete unit; } start_time = end; } //////////////////////////////////////////////////////////////////////////// for(int i = 0;i < (int) p3d_list.size();i++){ if(i < (int)(p3d_list.size() - 1)){ Point3D p1 = p3d_list[i]; Point3D p2 = p3d_list[i + 1]; Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + elev_list[0][0].m_t); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; if(i < (int)(p3d_list.size() - 2)){ Interval up_interval2; up_interval2.start = start_time; Instant end2 = start_time; end2.ReadFrom(start_time.ToDouble() + elev_list[0][0].w_t); up_interval2.end = end2; up_interval2.lc = true; up_interval2.rc = false; UPoint3D* unit = new UPoint3D(up_interval2, p2, p2); mp3d->Add(*unit); delete unit; start_time = end2; } } } } /* generate indoor moving objects with restored paths, loading from files */ void IndoorNav::AddUnitToMO_Elevator_New2(MPoint3D* mp3d, vector& p3d_list, Instant& start_time, Instant& st, vector< vector >& elev_list, int index, Line3D* l_room, int build_id, GenMO* genmo) { assert(p3d_list.size() >= 2 && elev_list[0].size() >= 2); ////////////get the time for waiting/////////////////////////////////// double relative_start = start_time.ToDouble() - st.ToDouble(); ///////////////////////////////////////////////////////////////////////// ///////////////////find which elevator/////////////////////////////////// ///////////// different elevators (different heights)2 or 3 levels/////// ///////////////// have different cycle time///////////////////////////// ///////////////////////////////////////////////////////////////////////// float h1 = p3d_list[0].GetZ(); float h2 = p3d_list[ p3d_list.size() - 1].GetZ(); Point test_p(true, p3d_list[0].GetX(), p3d_list[0].GetY()); int elev_index = -1; for(unsigned int i = 0;i < elev_list.size();i++){ if(test_p.Inside(elev_list[i][0].el_rect)){ elev_index = i; break; } } assert(elev_index >= 0); ////////////////////////////////////////////////////////////////////// double cycle_time = elev_list[elev_index][elev_list[elev_index].size() - 1].t2 - elev_list[elev_index][elev_list[elev_index].size() - 1].t1; while(relative_start > cycle_time){ relative_start -= cycle_time; } Instant t = start_time; t.ReadFrom(relative_start + st.ToDouble()); double wait_time = 0.0; bool found = false; for(unsigned int i = 0;i < elev_list.size();i++){ for(unsigned int j = 0;j < elev_list[i].size();j++){ if(AlmostEqual(h1, elev_list[i][j].h) && test_p.Inside(elev_list[i][j].el_rect)){ //point inside rectangle if(h1 < h2){ //check t2 if(elev_list[i][j].t2 > relative_start){ wait_time = elev_list[i][j].t2 - relative_start; }else{ wait_time = elev_list[i][j].t2 + cycle_time - relative_start; } }else{//check t1 if(elev_list[i][j].t1 > relative_start){ wait_time = elev_list[i][j].t1 - relative_start; }else{ wait_time = elev_list[i][j].t1 + cycle_time - relative_start; } } found = true; Instant temp = start_time; temp.ReadFrom(start_time.ToDouble() + wait_time); break; } } if(found)break; } ////////////////////unit for waiting///////////////////////// if(wait_time > 0.0){ Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + wait_time); up_interval.end = end; int64_t st = start_time.ToDouble()*86400000.0; int64_t et = end.ToDouble()*86400000.0; if(st != et){ up_interval.lc = true; up_interval.rc = false; Point3D p = p3d_list[0]; UPoint3D* unit = new UPoint3D(up_interval, p, p); mp3d->Add(*unit); delete unit; ///////////////////////////////////////////// /////////genric units/////////////////////// ///////////////////////////////////////////// Point3D q; l_room->Get(index, q); int groom_tid = 0; if(q.GetX() > 0 ) groom_tid = q.GetX(); else if(q.GetY() > 0) groom_tid = q.GetY(); else if(q.GetZ() > 0) groom_tid = q.GetZ(); else assert(false); Tuple* groom_tuple = rel1->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); char buffer1[64]; sprintf(buffer1, "%d", groom_oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); int new_groom_oid; sscanf(buffer2, "%d", &new_groom_oid);//////building id + room id/// // cout<<"ref oid "<Add(*ugenloc); delete ugenloc; } start_time = end; } //////////////////////////////////////////////////////////////////////////// for(int i = 0;i < (int) p3d_list.size();i++){ if(i < (int)(p3d_list.size() - 1)){ Point3D p1 = p3d_list[i]; Point3D p2 = p3d_list[i + 1]; Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + elev_list[0][0].m_t); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; ///////////////////////////////////////////// /////////generic units/////////////////////// ///////////////////////////////////////////// ////a point3d can be contained by maximum 3 grooms, so we use point3d// ////////to record tuple id ///////////////// // int groom_tid = GetRef_RoomTid(index + i, l_room); // cout<<"AddUnitToMO_Elevator_New2"<GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); char buffer1[64]; sprintf(buffer1, "%d", groom_oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); int new_groom_oid; sscanf(buffer2, "%d", &new_groom_oid);//////building id + room id/// // cout<<"ref oid "<Add(*ugenloc); delete ugenloc; if(i < (int)(p3d_list.size() - 2)){ Interval up_interval2; up_interval2.start = start_time; Instant end2 = start_time; end2.ReadFrom(start_time.ToDouble() + elev_list[0][0].w_t); up_interval2.end = end2; up_interval2.lc = true; up_interval2.rc = false; UPoint3D* unit = new UPoint3D(up_interval2, p2, p2); mp3d->Add(*unit); delete unit; start_time = end2; ///////////////////////////////////////////// /////////genric units/////////////////////// ///////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){ //move in an elevator,we record the height // Loc loc_1(p2.GetZ(), -1.0); // Loc loc_2(p2.GetZ(), -1.0); Loc loc_1(p2.GetZ(), UNDEFVAL); Loc loc_2(p2.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; } } } } /* a special trip from the building entrance to an office room the building has more than one elevators */ void IndoorNav::GenerateMO2_New_Start(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, int num, Periods* peri, bool convert, unsigned int num_elev) { // cout<<"several elevators "< doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// IndoorNav* indoor_nav = new IndoorNav(ig); Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ ///////////////////to building entrance/////////////////// // GenLoc loc1 = genloc_list[i]; // int door_index = i % doorloc_list.size(); // GenLoc loc2 = doorloc_list[door_index]; //////////////////from building entrance/////////////////////// GenLoc loc2 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc1 = doorloc_list[door_index]; if(loc1.GetOid() == loc2.GetOid()) continue; cout<<"loc1 "<ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); // indoor_nav->ShortestPath_Length_End(&loc1, &loc2, rel1, btree, // door_tid_list[door_index]); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); entrance_index.push_back(door_index + 1);//maps to tuple id /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } /* a special trip to the building entrance the building has more than one elevators */ void IndoorNav::GenerateMO2_New_End(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, int num, Periods* peri, bool convert, unsigned int num_elev) { GenerateIP1(num*2); //////////////////get the building entrance position/////////////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// IndoorNav* indoor_nav = new IndoorNav(ig); Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ if(i < genloc_list.size() - 1){ ///////////////////to building entrance/////////////////// GenLoc loc1 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc2 = doorloc_list[door_index]; if(loc1.GetOid() == loc2.GetOid()) continue; cout<<"loc1 "<ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); // cout<path_list[count].Length()<path_list[count]; // l3d->Print(); if(l3d->Length() > 0.0){ MPoint3D* mp3d = new MPoint3D(0); mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } }else AddUnitToMO(mp3d, p1, p2, start_time, speed); } } mp3d->EndBulkLoad(); mo_list.push_back(*mp3d); entrance_index.push_back(door_index + 1);//maps to tuple id /////////////////////////////////////////////////////////////////// if(convert) ToGenLoc(mp3d, rtree); mp3d->DeleteIfAllowed(); count++; } if(count == num)break; } } delete indoor_nav; } /* a special trip from the building entrance. the building has more than one elevators the reference room id is set by building id + room id */ void IndoorNav::GenerateMO3_New_Start(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri, unsigned int num_elev) { // GenerateIP1(1); GenerateIP3(1); //////////////////get the building entrance position/////////////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int num = 1; int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ //////////////////from building entrance/////////////////////// GenLoc loc2 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc1 = doorloc_list[door_index]; // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_Start2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_Start(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator_New2(mp3d, p3d_list, start_time, periods.start, elev_list,start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; /////////////////////////////////////////////////////////////////// #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /* a special trip to the building entrance the building has more than one elevators the reference room id is set by building id + room id */ void IndoorNav::GenerateMO3_New_End(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri, unsigned int num_elev) { // GenerateIP1(1); GenerateIP3(1); //////////////////get the building entrance position/////////////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int num = 1; int count = 0; for(unsigned int i = 0;i < genloc_list.size();i++){ ///////////////////to building entrance/////////////////// GenLoc loc1 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc2 = doorloc_list[door_index]; // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_End2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator_New2(mp3d, p3d_list, start_time, periods.start, elev_list, start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; ///////////////////////////////////////////////////////////////// #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /* almost the same as GenerateMO3 New End but giving the start location */ void IndoorNav::GenerateMO3_New_EndExt(IndoorGraph* ig, BTree* btree, R_Tree<3,TupleId>* rtree, Instant& start_time, int build_id, int entrance_index, MPoint3D* mp3d, GenMO* genmo, Periods* peri, unsigned int num_elev, GenLoc gloc_input) { //////////////////get the building entrance position/////////////////////// vector doorloc_list; vector door_tid_list; GetDoorLoc(ig, btree, doorloc_list, door_tid_list); ////////////////////////////////////////////////////////////////////////// Interval periods; if(peri->GetNoComponents() == 0){ cout<<"not correct time periods"<Get(0, periods); double speed = GetMinimumDoorWidth(); vector< vector > elev_list; InitializeElevator_New(periods, elev_list, speed); int num = 1; int count = 0; genloc_list.push_back(gloc_input); for(unsigned int i = 0;i < genloc_list.size();i++){ ///////////////////to building entrance/////////////////// GenLoc loc1 = genloc_list[i]; int door_index = i % doorloc_list.size(); GenLoc loc2 = doorloc_list[door_index]; // cout<<"loc1 "<::iterator iter = indoor_paths_list.find(path_oid); if(iter != indoor_paths_list.end()){ ShortestPath_Length_End2(&loc1, &loc2, rel1, btree, door_tid_list[door_index], entrance_index); find_path = true; }else{ ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); } #else ShortestPath_Length_End(&loc1, &loc2, rel1, btree, door_tid_list[door_index]); #endif Line3D* l3d = &path_list[count]; if(l3d->Length() > 0.0){ Line3D* l_room = NULL; #ifdef INDOOR_PATH if(find_path){ l_room = &rooms_id_list[count]; assert(l3d->Size() == l_room->Size()); } #endif mp3d->StartBulkLoad(); for(int j = 0;j < l3d->Size();j++){ if(j < l3d->Size() - 1){ Point3D p1, p2; l3d->Get(j, p1); l3d->Get(j + 1, p2); ///////////////process the movement in an elevator if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY()) && (elev_list.size() > 0 && elev_list[0].size() > 1)){ float delta_h = fabs(elev_list[0][1].h - elev_list[0][0].h); if(AlmostEqual(delta_h, p1.Distance(p2))){ int start_pos = j; vector p3d_list; p3d_list.push_back(p1); p3d_list.push_back(p2); int k = j + 1; for(;k < l3d->Size();k++){ if(k < l3d->Size() - 1){ Point3D q1, q2; l3d->Get(k, q1); l3d->Get(k + 1, q2); if(AlmostEqual(q1.GetX(), q2.GetX()) && AlmostEqual(q1.GetY(), q2.GetY())){//elevator p3d_list.push_back(q2); }else break; } } k--; j = k; #ifdef INDOOR_PATH if(find_path){ AddUnitToMO_Elevator_New2(mp3d, p3d_list, start_time, periods.start, elev_list, start_pos, l_room, build_id, genmo); }else{ AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); } #else AddUnitToMO_Elevator_New(mp3d, p3d_list, start_time, periods.start, elev_list); #endif } }else #ifdef INDOOR_PATH if(find_path){ AddUnitToMO2(mp3d, p1, p2, start_time, speed, j, l_room, build_id, genmo); }else{ AddUnitToMO(mp3d, p1, p2, start_time, speed); } #else AddUnitToMO(mp3d, p1, p2, start_time, speed); #endif } } mp3d->EndBulkLoad(); count++; ///////////////////////////////////////////////////////////////// #ifdef INDOOR_PATH if(find_path){ }else{ ToGenLoc2(mp3d, rtree, build_id, genmo); } #else ToGenLoc2(mp3d, rtree, build_id, genmo); #endif } if(count == num)break; } } /////////////////////////////////////////////////////////////////////////////// /* get the minimum width of door */ float IndoorNav::GetMinimumDoorWidth() { float door_width = numeric_limits::max(); //the speed for person for(int i = 1;i <= rel1->GetNoTuples();i++){ Tuple* groom_tuple = rel1->GetTuple(i, false); Line* door = (Line*)groom_tuple->GetAttribute(I_Door); for(int j = 0;j < door->Size();j++){ HalfSegment hs; door->Get(j, hs); if(!hs.IsLeftDomPoint())continue; if(hs.Length() < door_width)door_width = hs.Length(); } groom_tuple->DeleteIfAllowed(); } return door_width; } /* add units to the result moving objects */ void IndoorNav::AddUnitToMO(MPoint3D* mp3d, Point3D& p1, Point3D& p2, Instant& start_time, double speed) { const double dist_delta = 0.01; double d = p1.Distance(p2); if(d < speed || AlmostEqual(d, speed)){//staircase movement Interval up_interval; up_interval.start = start_time; Instant end = start_time; // end.ReadFrom(start_time.ToDouble() + d/(24.0*60.0*60.0*speed)); //////////set 0.75---1, a little slow ///////////////////////// end.ReadFrom(start_time.ToDouble() + 0.75/(24.0*60.0*60.0)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; }else if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY())){ //for the movement inside an elevator // if split, it can not find a groom Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + d/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; }else{ int no = (int)floor(d/speed); // double x = (p2.GetX() - p1.GetX())/no; // double y = (p2.GetY() - p1.GetY())/no; // double z = (p2.GetZ() - p1.GetZ())/no; double x = (p2.GetX() - p1.GetX())/(no + 1); double y = (p2.GetY() - p1.GetY())/(no + 1); double z = (p2.GetZ() - p1.GetZ())/(no + 1); for(int i = 0;i < no ;i++){ Point3D q1(true, p1.GetX() + i*x, p1.GetY() + i*y, p1.GetZ() + i*z); Point3D q2(true, p1.GetX() + (i+1)*x, p1.GetY() + (i+1)*y, p1.GetZ() + (i+1)*z); double dist = q1.Distance(q2); Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + dist/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, q1,q2); mp3d->Add(*unit); delete unit; start_time = end; // cout<<"q1 "<Add(*unit); delete unit; start_time = end; } } } } /* get the groom tid from the storing data */ int IndoorNav::GetRef_RoomTid(int index, Line3D* l, bool E) { Point3D q1, q2; l->Get(index, q1); l->Get(index + 1, q2); // cout<<"E "< tid_list1; if(q1.GetX() > 0) tid_list1.push_back(q1.GetX()); if(q1.GetY() > 0) tid_list1.push_back(q1.GetY()); if(q1.GetZ() > 0) tid_list1.push_back(q1.GetZ()); vector tid_list2; if(q2.GetX() > 0) tid_list2.push_back(q2.GetX()); if(q2.GetY() > 0) tid_list2.push_back(q2.GetY()); if(q2.GetZ() > 0) tid_list2.push_back(q2.GetZ()); // int tid = -1; // bool found = false; // for(unsigned int i = 0;i < tid_list1.size();i++){ // for(unsigned int j = 0;j < tid_list2.size();j++){ // if(tid_list1[i] == tid_list2[j]){ // tid = tid_list1[i]; // found = true; // } // } // } // // ///////////vertical movement in elevator//////////// // if(found == false) tid = tid_list1[0]; // // assert(tid > 0); // // return tid; vector tid_list; int tid = -1; bool found = false; for(unsigned int i = 0;i < tid_list1.size();i++){ for(unsigned int j = 0;j < tid_list2.size();j++){ if(tid_list1[i] == tid_list2[j]){ tid_list.push_back(tid_list1[i]); found = true; } } } ///////////vertical movement in elevator//////////// if(found == false){ // tid = tid_list1[0]; for(unsigned int i = 0;i < tid_list1.size();i++){ Tuple* groom_tuple = rel1->GetTuple(tid_list1[i], false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); groom_tuple->DeleteIfAllowed(); // if(type.compare("EL") == 0){ // tid = tid_list1[i]; // break; // } if(E){ if(type.compare("EL") == 0){ tid = tid_list1[i]; break; } }else{ if(type.compare("EL") != 0){ tid = tid_list1[i]; break; } } } }else{ if(tid_list.size() == 1) tid = tid_list[0]; else{ for(unsigned int i = 0;i < tid_list.size();i++){ Tuple* groom_tuple = rel1->GetTuple(tid_list[i], false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); groom_tuple->DeleteIfAllowed(); // cout<<" type "< 0); return tid; } /* add units to the result moving objects where the generic moving objects is created at the same time */ void IndoorNav::AddUnitToMO2(MPoint3D* mp3d, Point3D& p1, Point3D& p2, Instant& start_time, double speed, int index, Line3D* l_room, int build_id, GenMO* genmo) { // cout<<"p1 "<GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); char buffer1[64]; sprintf(buffer1, "%d", groom_oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); int new_groom_oid; sscanf(buffer2, "%d", &new_groom_oid);//building id + room id// // cout<<"ref oid "< up_interval; up_interval.start = start_time; Instant end = start_time; // end.ReadFrom(start_time.ToDouble() + d/(24.0*60.0*60.0*speed)); //////////set 0.75---1, a little slow ///////////////////////// end.ReadFrom(start_time.ToDouble() + 0.75/(24.0*60.0*60.0)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; //////////////////////////////////////////// ////////////generic units ////////////////// /////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p1.GetX() - bbox.MinD(0), p1.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){ //move in an elevator,we record the height // Loc loc_1(p1.GetZ(), -1.0); // Loc loc_2(p2.GetZ(), -1.0); Loc loc_1(p1.GetZ(), UNDEFVAL); Loc loc_2(p2.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; }else if(AlmostEqual(p1.GetX(), p2.GetX()) && AlmostEqual(p1.GetY(), p2.GetY())){ //for the movement inside an elevator // if split, it can not find a groom Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + d/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, p1, p2); mp3d->Add(*unit); delete unit; start_time = end; //////////////////////////////////////////// ////////////generic units ////////////////// /////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p1.GetX() - bbox.MinD(0), p1.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){//move in an elevator,we record the height // Loc loc_1(p1.GetZ(), -1.0); // Loc loc_2(p2.GetZ(), -1.0); Loc loc_1(p1.GetZ(), UNDEFVAL); Loc loc_2(p2.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; }else{ if(GetRoomEnum(type) == BR || GetRoomEnum(type) == ST || GetRoomEnum(type) == EL) CreateIUnits1(p1, p2, type, bbox, speed, start_time, mp3d, genmo, new_groom_oid); else CreateIUnits2(p1, p2, type, bbox, speed, start_time, mp3d, genmo, new_groom_oid);//merge movements // CreateIUnits1(p1, p2, type, bbox, speed, start_time, mp3d, genmo, // new_groom_oid);//no merging for general units }//end for else } /* no merge units */ void IndoorNav::CreateIUnits1(Point3D& p1, Point3D& p2, string type, Rectangle<2> bbox, double speed, Instant& start_time, MPoint3D* mp3d, GenMO* genmo, int new_groom_oid) { double d = p1.Distance(p2); const double dist_delta = 0.01; int no = (int)floor(d/speed); /* double x = (p2.GetX() - p1.GetX())/no; double y = (p2.GetY() - p1.GetY())/no; double z = (p2.GetZ() - p1.GetZ())/no; */ double x = (p2.GetX() - p1.GetX())/(no + 1); double y = (p2.GetY() - p1.GetY())/(no + 1); double z = (p2.GetZ() - p1.GetZ())/(no + 1); for(int i = 0;i < no ;i++){ Point3D q1(true, p1.GetX() + i*x, p1.GetY() + i*y, p1.GetZ() + i*z); Point3D q2(true, p1.GetX() + (i+1)*x, p1.GetY() + (i+1)*y, p1.GetZ() + (i+1)*z); double dist = q1.Distance(q2); Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + dist/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, q1,q2); mp3d->Add(*unit); delete unit; start_time = end; //////////////////////////////////////////// ////////////generic units ////////////////// /////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == BR || GetRoomEnum(type) == ST || GetRoomEnum(type) == OR || GetRoomEnum(type) == CO){//for debug,keep Loc loc_1(q1.GetX() - bbox.MinD(0), q1.GetY() - bbox.MinD(1)); Loc loc_2(q2.GetX() - bbox.MinD(0), q2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){ //move in an elevator,we record the height // Loc loc_1(q1.GetZ(), -1.0); // Loc loc_2(q2.GetZ(), -1.0); Loc loc_1(q1.GetZ(), UNDEFVAL); Loc loc_2(q2.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// if(i == no - 1){ Point3D q3 = q2; Point3D q4 = p2; double dist = q3.Distance(q4); if(dist < dist_delta) continue; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + dist/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; start_time = up_interval.end; // cout<<"start "<Add(*unit); delete unit; start_time = end; //////////////////////////////////////////// ////////////generic units ////////////////// /////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; if(GetRoomEnum(type) == BR ||GetRoomEnum(type) == ST || GetRoomEnum(type) == OR || GetRoomEnum(type) == CO){//keep for debug Loc loc_1(q3.GetX() - bbox.MinD(0), q3.GetY() - bbox.MinD(1)); Loc loc_2(q4.GetX() - bbox.MinD(0), q4.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else if(GetRoomEnum(type) == EL){ //move in an elevator,we record the height // Loc loc_1(q3.GetZ(), -1.0); // Loc loc_2(q4.GetZ(), -1.0); Loc loc_1(q3.GetZ(), UNDEFVAL); Loc loc_2(q4.GetZ(), UNDEFVAL); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); }else{ cout<<"should not be here"<Add(*ugenloc); delete ugenloc; } } } /* merge general units for OR and CO */ void IndoorNav::CreateIUnits2(Point3D& p1, Point3D& p2, string type, Rectangle<2> bbox, double speed, Instant& start_time, MPoint3D* mp3d, GenMO* genmo, int new_groom_oid) { const double dist_delta = 0.01; double d = p1.Distance(p2); int no = (int)floor(d/speed); double x = (p2.GetX() - p1.GetX())/(no + 1); double y = (p2.GetY() - p1.GetY())/(no + 1); double z = (p2.GetZ() - p1.GetZ())/(no + 1); Instant old_time = start_time; assert(GetRoomEnum(type) == OR || GetRoomEnum(type) == CO); for(int i = 0;i < no ;i++){ Point3D q1(true, p1.GetX() + i*x, p1.GetY() + i*y, p1.GetZ() + i*z); Point3D q2(true, p1.GetX() + (i+1)*x, p1.GetY() + (i+1)*y, p1.GetZ() + (i+1)*z); double dist = q1.Distance(q2); Interval up_interval; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + dist/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; UPoint3D* unit = new UPoint3D(up_interval, q1,q2); mp3d->Add(*unit); delete unit; start_time = end; /////////////////////////////////////////////////////////////////// if(i == no - 1){ Point3D q3 = q2; Point3D q4 = p2; double dist = q3.Distance(q4); if(dist < dist_delta) continue; up_interval.start = start_time; Instant end = start_time; end.ReadFrom(start_time.ToDouble() + dist/(24.0*60.0*60.0*speed)); up_interval.end = end; up_interval.lc = true; up_interval.rc = false; start_time = up_interval.end; // cout<<"start "<Add(*unit); delete unit; start_time = end; } } //////////////////////////////////////////// ////////////generic units ////////////////// /////////////////////////////////////////// GenLoc gloc1; GenLoc gloc2; Loc loc_1(p1.GetX() - bbox.MinD(0), p1.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); gloc1.SetValue(new_groom_oid, loc_1); gloc2.SetValue(new_groom_oid, loc_2); Interval up_interval; up_interval.start = old_time; up_interval.end = start_time; up_interval.lc = true; up_interval.rc = false; UGenLoc* ugenloc = new UGenLoc(up_interval, gloc1, gloc2, GetTM("Indoor")); genmo->Add(*ugenloc); delete ugenloc; } /* convert a 3d point to genloc */ void IndoorNav::ToGenLoc(MPoint3D* mp3d, R_Tree<3,TupleId>* rtree) { GenMO* genmo = new GenMO(0); genmo->StartBulkLoad(); for(int i = 0;i < mp3d->GetNoComponents();i++){ UPoint3D unit; mp3d->Get(i, unit); GenLoc loc1, loc2; Get_GenLoc(unit.p0, unit.p1, loc1, loc2, rtree); UGenLoc* ugenloc = new UGenLoc(unit.timeInterval, loc1, loc2, GetTM("Indoor")); genmo->Add(*ugenloc); delete ugenloc; } genmo->EndBulkLoad(); genmo_list.push_back(*genmo); genmo->DeleteIfAllowed(); } /* convert a 3d point to genloc. the reference room id is changed or added the building id.finally the reference id is: buildingid + roomid */ void IndoorNav::ToGenLoc2(MPoint3D* mp3d, R_Tree<3,TupleId>* rtree, int build_id, GenMO* genmo) { // cout<<"ToGenLoc2 "<GetNoComponents();i++){ UPoint3D unit; mp3d->Get(i, unit); GenLoc loc1, loc2; // Get_GenLoc(unit.p0, unit.p1, loc1, loc2, rtree); ///reset reference oid: building id + room id/// Get_GenLoc2(unit.p0, unit.p1, loc1, loc2, rtree, build_id); UGenLoc* ugenloc = new UGenLoc(unit.timeInterval, loc1, loc2, GetTM("Indoor")); genmo->Add(*ugenloc); delete ugenloc; } } /* the two genloc should have the same oid */ void IndoorNav::Get_GenLoc(Point3D p1, Point3D p2, GenLoc& loc1, GenLoc& loc2, R_Tree<3,TupleId>* rtree) { SmiRecordId adr = rtree->RootRecordId(); vector tid_list1; vector tid_list2; DFTraverse(rtree, adr, p1, tid_list1); DFTraverse(rtree, adr, p1, tid_list2); // cout<<"p3d_1 "< 0); assert(tid_list2.size() > 0); int tid1, tid2; bool found = false; for(unsigned int i = 0;i < tid_list1.size();i++){ tid1 = tid_list1[i]; for(unsigned int j = 0;j < tid_list2.size();j++){ tid2 = tid_list2[j]; if(tid1 == tid2){ found = true; break; } } if(found) break; } /* if(tid1 != tid2){ cout<<"do not find the same groom for two locations"<GetTuple(tid1, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); int oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p1.GetX() - bbox.MinD(0), p1.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); loc1.SetValue(oid, loc_1); loc2.SetValue(oid, loc_2); }else if(GetRoomEnum(type) == EL){//move in an elevator,we record the height // Loc loc_1(p1.GetZ(), -1); // Loc loc_2(p2.GetZ(), -1); Loc loc_1(p1.GetZ(), UNDEFVAL); Loc loc_2(p2.GetZ(), UNDEFVAL); loc1.SetValue(oid, loc_1); loc2.SetValue(oid, loc_2); }else{ cout<<"should not be here"<GetTuple(tid1, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL)break; groom_tuple->DeleteIfAllowed(); } assert(i < tid_list1.size()); Tuple* groom_tuple = rel1->GetTuple(tid1, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); int oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); /////////////////////////////////////////////////////////////////////// Rectangle<2> bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == EL){ // cout<<"elevator2 "<* rtree, int build_id) { SmiRecordId adr = rtree->RootRecordId(); vector tid_list1; vector tid_list2; DFTraverse(rtree, adr, p1, tid_list1); DFTraverse(rtree, adr, p2, tid_list2); // cout<<"p3d_1 "< 0); assert(tid_list2.size() > 0); //////////maximum 3 for the case of staircase entrance /////////////// // cout<GetTuple(tid1, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); int oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); ////////////////////////////////////////////////////////////////////// //////////reset the oid by plus building id for the first six numbers/ ///////////////////////////////////////////////////////////////////// char buffer1[64]; sprintf(buffer1, "%d", oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); // cout<<"building id "< bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == OR || GetRoomEnum(type) == BR || GetRoomEnum(type) == CO || GetRoomEnum(type) == ST){ Loc loc_1(p1.GetX() - bbox.MinD(0), p1.GetY() - bbox.MinD(1)); Loc loc_2(p2.GetX() - bbox.MinD(0), p2.GetY() - bbox.MinD(1)); loc1.SetValue(oid, loc_1); loc2.SetValue(oid, loc_2); }else if(GetRoomEnum(type) == EL){//move in an elevator,we record the height // cout<<"elevator1 "<GetTuple(tid1, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL) { groom_tuple->DeleteIfAllowed(); break; } groom_tuple->DeleteIfAllowed(); } assert(i < tid_list1.size()); Tuple* groom_tuple = rel1->GetTuple(tid1, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); int oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); ////////////////////////////////////////////////////////////////////// //////////reset the oid by plus building id for the first six numbers/ ///////////////////////////////////////////////////////////////////// char buffer1[64]; sprintf(buffer1, "%d", oid); char buffer2[64]; sprintf(buffer2, "%d", build_id); strcat(buffer2, buffer1); // cout<<"building id "< bbox = groom->BoundingBox(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == EL){ // cout<<"elevator2 "< bbox, Point3D& p) { assert(bbox.IsDefined()); assert(p.IsDefined()); if( (bbox.MinD(0) < p.GetX() || AlmostEqual(bbox.MinD(0), p.GetX())) && (bbox.MaxD(0) > p.GetX() || AlmostEqual(bbox.MaxD(0), p.GetX())) && (bbox.MinD(1) < p.GetY() || AlmostEqual(bbox.MinD(1), p.GetY())) && (bbox.MaxD(1) > p.GetY() || AlmostEqual(bbox.MaxD(1), p.GetY())) && (bbox.MinD(2) < p.GetZ() || AlmostEqual(bbox.MinD(2), p.GetZ())) && (bbox.MaxD(2) > p.GetZ() || AlmostEqual(bbox.MaxD(2), p.GetZ())) ) return true; else return false; } /* traverse the 3D rtree to find whether a groom contains the 3d point */ void IndoorNav::DFTraverse(R_Tree<3,TupleId>* rtree, SmiRecordId adr, Point3D p, vector& tid_list) { R_TreeNode<3,TupleId>* node = rtree->GetMyNode(adr,false, rtree->MinEntries(0), rtree->MaxEntries(0)); for(int j = 0;j < node->EntryCount();j++){ if(node->IsLeaf()){ R_TreeLeafEntry<3,TupleId> e = (R_TreeLeafEntry<3,TupleId>&)(*node)[j]; Tuple* groom_tuple = rel1->GetTuple(e.info,false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Rectangle<3> groom_box = groom->BoundingBox3D(); if(BBoxContainPoint3D(groom_box, p)){ // tid_list.push_back(e.info); Region r(0); groom->GetRegion(r); Point q(true, p.GetX(), p.GetY()); if(q.Inside(r))tid_list.push_back(e.info); } groom_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<3> e = (R_TreeInternalEntry<3>&)(*node)[j]; if(BBoxContainPoint3D(e.box, p)){ DFTraverse(rtree, e.pointer, p, tid_list); } } } delete node; } ostream& operator<<(ostream& o, const IPath_elem& elem) { o<<"tri_index "<< elem.tri_index<<" " <<"realweight "<DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); // cout<<"groom oid1 "<GetNodeRel(); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// //////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); vector tid_list1; tid_list1.push_back(start_tid); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// //////////////////////////////////////////////////////////////////// CcInt* search_id2 = new CcInt(true, groom_oid2); BTreeIterator* btree_iter2 = btree->ExactMatch(search_id2); vector tid_list2; vector door_end; while(btree_iter2->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter2->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid2, groom_oid1, door_end) == false) tid_list2.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; // cout<<"tid_list1 size "< start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectEndLoc2(gloc1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); float min_h1 = MIN(start_h1, start_h2); float max_h1 = MAX(start_h1, start_h2); // for(unsigned int i = 0;i < start_door_path.size();i++) // path_list.push_back(start_door_path[i]); // // return; //////////calculate once for the connection between end loc and its door//// vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; if(!ConnectEndLoc(gloc2, tid_list2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); float min_h2 = MIN(end_h1, end_h2); float max_h2 = MAX(end_h1, end_h2); float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); // cout<<"min h "< candidate_path; double prune_dist = -1.0; for(unsigned int i = 0;i < tid_list1.size();i++){ // cout<<"source door tid "<GetTuple(tid_list1[i], false); unsigned int gri1 = ((CcInt*)door_tuple1->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri1 == groom_oid1); for(unsigned int j = 0;j < tid_list2.size();j++){ // cout<<"dest door tid "<GetTuple(tid_list2[j], false); unsigned int gri2 = ((CcInt*)door_tuple2->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid2); IndoorShortestPath(tid_list1[i], tid_list2[j], candidate_path, &start_door_path[i], &end_door_path[j], prune_dist, min_h, max_h, -1); door_tuple2->DeleteIfAllowed(); // cout<DeleteIfAllowed(); } ///////////////////select the path with minimum length//////////////////// if(candidate_path.size() > 0){ double l = numeric_limits::max(); int index = 0; for(unsigned int i = 0; i < candidate_path.size();i++){ if(candidate_path[i].Size() > 0 && candidate_path[i].Length() < l){ l = candidate_path[i].Length(); index = i; } } path_list.push_back(candidate_path[index]); }else{ // cout<<"no path available"<DeleteIfAllowed(); } } /* find a path from the building entrance to one office room where the path from building entrance to office room is already found */ void IndoorNav::ShortestPath_Length_Start2(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* groom_btree, int start_tid, int entrance_id) { if(IsLocEqual(gloc1, gloc2, rel)){ cout<<"the two locations are equal to each other"<DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); if(groom_oid1 == groom_oid2){ PathInOneRoom(gloc1, gloc2, rel, groom_btree); return; } Relation* node_rel = ig->GetNodeRel(); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// //////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); vector tid_list1; tid_list1.push_back(start_tid); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// //////////////////////////////////////////////////////////////////// CcInt* search_id2 = new CcInt(true, groom_oid2); BTreeIterator* btree_iter2 = btree->ExactMatch(search_id2); vector tid_list2; vector door_end; vector door_tid_list; while(btree_iter2->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter2->GetId(), false); int door_tid = tuple->GetTupleId(); door_tid_list.push_back(door_tid);/////////all doors include dead doors if(DeadDoor(door_tid, groom_oid2, groom_oid1, door_end) == false){ tid_list2.push_back(door_tid); }else{ //////////do not consier such a connection/////////////// door_tid_list[door_tid_list.size() - 1] = 0; } tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; ////////calculate once for the connection between start loc and its door//// vector start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectEndLoc2(gloc1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); //////////calculate once for the connection between end loc and its door//// vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; if(!ConnectEndLoc(gloc2, tid_list2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } /* for(unsigned int i = 0;i < end_door_path.size();i++){ Point3D q; end_door_path[i].Get(0, q); cout<<"i "< candidate_path; vector rooms_oid; //store groom oid for point3d int count = 0; for(unsigned int i = 0;i < door_tid_list.size();i++){ if(door_tid_list[i] > 0){ int path_oid = GetIndooPathID2(entrance_id, groom_oid2,i, true); map::iterator iter = indoor_paths_list.find(path_oid); map::iterator iter_room = rooms_list.find(path_oid); if(iter != indoor_paths_list.end() && iter_room != rooms_list.end()){ // cout<second.Length()<StartBulkLoad(); Line3D* l_room = new Line3D(0); l_room->StartBulkLoad(); assert(iter->second.Size() == iter_room->second.Size()); for(int j = 0;j < iter->second.Size();j++){ Point3D q; iter->second.Get(j, q); *l3d += q; Point3D p; iter_room->second.Get(j, p); *l_room += p; } Point3D q1; iter->second.Get(iter->second.Size() - 1, q1); Point3D q2; end_door_path[count].Get(0, q2); const double delta_d = 0.001; assert(q1.Distance(q2) < delta_d); for(int j = 1;j < end_door_path[count].Size();j++){ Point3D q; end_door_path[count].Get(j, q); *l3d += q; Point3D p(true, groom_oid2, groom_oid2, groom_oid2); *l_room += p; } l_room->EndBulkLoad(); l3d->EndBulkLoad(); candidate_path.push_back(*l3d); rooms_oid.push_back(*l_room); l3d->DeleteIfAllowed(); l_room->DeleteIfAllowed(); }else{ cout<<"path_id "< 0){ double l = numeric_limits::max(); int index = 0; for(unsigned int i = 0; i < candidate_path.size();i++){ if(candidate_path[i].Size() > 0 && candidate_path[i].Length() < l){ l = candidate_path[i].Length(); index = i; } } path_list.push_back(candidate_path[index]); rooms_id_list.push_back(rooms_oid[index]); }else{ // cout<<"no path available"<DeleteIfAllowed(); } } /* return the shortest path with minimum length for indoor navigation the start location is in a room and the end location is the building entrance */ void IndoorNav::ShortestPath_Length_End(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* groom_btree, int end_tid) { if(IsLocEqual(gloc1, gloc2, rel)){ cout<<"the two locations are equal to each other"<DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); // cout<<"groom oid1 "<GetNodeRel(); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// //////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); CcInt* search_id1 = new CcInt(true, groom_oid1); BTreeIterator* btree_iter1 = btree->ExactMatch(search_id1); vector tid_list1; vector door_start; while(btree_iter1->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter1->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid1, groom_oid2, door_start) == false) tid_list1.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; //////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// //////////////////////////////////////////////////////////////////// vector tid_list2; tid_list2.push_back(end_tid); ///////////////////////////////////////////////////////////////////// // cout<<"tid_list1 size "< start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectStartLoc(gloc1, tid_list1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); float min_h1 = MIN(start_h1, start_h2); float max_h1 = MAX(start_h1, start_h2); // for(unsigned int i = 0;i < start_door_path.size();i++) // path_list.push_back(start_door_path[i]); // // return; //////////calculate once for the connection between end loc and its door//// vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; if(!ConnectEndLoc2(gloc2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); float min_h2 = MIN(end_h1, end_h2); float max_h2 = MAX(end_h1, end_h2); float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); //////////////////////////////////////////////////////////////////////// ////////////////////for each possible door, search the path///////////// //////////////////////////////////////////////////////////////////////// vector candidate_path; double prune_dist = -1.0; for(unsigned int i = 0;i < tid_list1.size();i++){ // cout<<"source door tid "<GetTuple(tid_list1[i], false); unsigned int gri1 = ((CcInt*)door_tuple1->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri1 == groom_oid1); for(unsigned int j = 0;j < tid_list2.size();j++){ // cout<<"dest door tid "<GetTuple(tid_list2[j], false); unsigned int gri2 = ((CcInt*)door_tuple2->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid2); IndoorShortestPath(tid_list1[i], tid_list2[j], candidate_path, &start_door_path[i], &end_door_path[j], prune_dist, min_h, max_h, groom_oid1); door_tuple2->DeleteIfAllowed(); // cout<DeleteIfAllowed(); } ///////////////////select the path with minimum length//////////////////// if(candidate_path.size() > 0){ double l = numeric_limits::max(); int index = 0; for(unsigned int i = 0; i < candidate_path.size();i++){ if(candidate_path[i].Size() > 0 && candidate_path[i].Length() < l){ l = candidate_path[i].Length(); index = i; } } path_list.push_back(candidate_path[index]); }else{ // cout<<"no path available"<DeleteIfAllowed(); } } /* find the paths by loading from disk files from a room to the entrance of a building */ void IndoorNav::ShortestPath_Length_End2(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* groom_btree, int end_tid, int entrance_id) { if(IsLocEqual(gloc1, gloc2, rel)){ cout<<"the two locations are equal to each other"<DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); // cout<<"groom oid1 "<GetNodeRel(); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// //////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); CcInt* search_id1 = new CcInt(true, groom_oid1); BTreeIterator* btree_iter1 = btree->ExactMatch(search_id1); vector tid_list1; vector door_start; vector door_tid_list; while(btree_iter1->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter1->GetId(), false); int door_tid = tuple->GetTupleId(); ///all doors should be included (dead doors)//////////////// door_tid_list.push_back(door_tid); if(DeadDoor(door_tid, groom_oid1, groom_oid2, door_start) == false) tid_list1.push_back(door_tid); else{ //////such connection are not considered////////// door_tid_list[door_tid_list.size() - 1] = 0; } tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; //////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// //////////////////////////////////////////////////////////////////// vector tid_list2; tid_list2.push_back(end_tid); ///////////////////////////////////////////////////////////////////// // cout<<"tid_list1 size "< start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectStartLoc(gloc1, tid_list1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); //////////calculate once for the connection between end loc and its door//// vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; if(!ConnectEndLoc2(gloc2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } assert(end_h1 > INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); //////////////////////////////////////////////////////////////////////// ////////////////////for each possible door, search the path///////////// //////////////////////////////////////////////////////////////////////// vector candidate_path; vector rooms_oid; int count = 0; for(unsigned int i = 0;i < door_tid_list.size();i++){ if(door_tid_list[i] > 0){ int path_oid = GetIndooPathID2(entrance_id, groom_oid1, i, false); // cout<<"path_oid "<::iterator iter = indoor_paths_list.find(path_oid); map::iterator iter_room = rooms_list.find(path_oid); if(iter != indoor_paths_list.end() && iter_room != rooms_list.end()){ Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); Line3D* l_room = new Line3D(0); l_room->StartBulkLoad(); assert(iter->second.Size() == iter_room->second.Size()); for(int j = 0; j < start_door_path[count].Size();j++){ Point3D q; start_door_path[count].Get(j, q); *l3d += q; ////////groom oid of the current point3d---old method//////////// // Point3D p(true, groom_oid1, groom_oid1, groom_oid1); // *l_room += p; //////////////more groom oids---new method /////////////////// if(j < start_door_path[count].Size() - 1){//use the data from file Point3D p(true, groom_oid1, groom_oid1, groom_oid1); *l_room += p; } } /////////end point of path in the room should be equal to door loc//// Point3D q1; iter->second.Get(0, q1); Point3D q2; start_door_path[count].Get(start_door_path[count].Size() - 1, q2); const double delta_d = 0.001; assert(q1.Distance(q2) < delta_d); for(int j = 1;j < iter->second.Size();j++){ Point3D q; iter->second.Get(j, q); *l3d += q; //////////////////add the data is missing in the above//////////// if(j == 1){/////use the data from disk file, has more groom oids Point3D tmp_p; iter_room->second.Get(0, tmp_p); *l_room += tmp_p; } Point3D p; iter_room->second.Get(j, p); *l_room += p; } l3d->EndBulkLoad(); l_room->EndBulkLoad(); candidate_path.push_back(*l3d); rooms_oid.push_back(*l_room); l3d->DeleteIfAllowed(); l_room->DeleteIfAllowed(); }else{ cout<<"path_id "< 0){ double l = numeric_limits::max(); int index = 0; for(unsigned int i = 0; i < candidate_path.size();i++){ if(candidate_path[i].Size() > 0 && candidate_path[i].Length() < l){ l = candidate_path[i].Length(); index = i; } } path_list.push_back(candidate_path[index]); rooms_id_list.push_back(rooms_oid[index]); }else{ // cout<<"no path available"<DeleteIfAllowed(); } } /* return the shortest path with minimum length for indoor navigation */ void IndoorNav::ShortestPath_Length(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* groom_btree) { ////////////////////////////////////////// /////////////for debuging//////////////// ///////////////////////////////////////// /* Loc temp_loc1(4.36, 11.13); Loc temp_loc2(0, 31); GenLoc temp_gloc1(195, temp_loc1); GenLoc temp_gloc2(52, temp_loc2); gloc1 = &temp_gloc1; gloc2 = &temp_gloc2;*/ if(IsLocEqual(gloc1, gloc2, rel)){ cout<<"the two locations are equal to each other"<DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); // cout<<"groom oid1 "<GetNodeRel(); //////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// //////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); CcInt* search_id1 = new CcInt(true, groom_oid1); BTreeIterator* btree_iter1 = btree->ExactMatch(search_id1); vector tid_list1; vector door_start; while(btree_iter1->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter1->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid1, groom_oid2, door_start) == false) tid_list1.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; //////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// //////////////////////////////////////////////////////////////////// CcInt* search_id2 = new CcInt(true, groom_oid2); BTreeIterator* btree_iter2 = btree->ExactMatch(search_id2); vector tid_list2; vector door_end; while(btree_iter2->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter2->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid2, groom_oid1, door_end) == false) tid_list2.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; // cout<<"tid_list1 size "< start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectStartLoc(gloc1, tid_list1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); float min_h1 = MIN(start_h1, start_h2); float max_h1 = MAX(start_h1, start_h2); // for(unsigned int i = 0;i < start_door_path.size();i++) // path_list.push_back(start_door_path[i]); // // return; //////////calculate once for the connection between end loc and its door//// vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; if(!ConnectEndLoc(gloc2, tid_list2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } // cout< INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); float min_h2 = MIN(end_h1, end_h2); float max_h2 = MAX(end_h1, end_h2); float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); //////////////////////////////////////////////////////////////////////// ////////////////////for each possible door, search the path///////////// //////////////////////////////////////////////////////////////////////// vector candidate_path; double prune_dist = -1.0; for(unsigned int i = 0;i < tid_list1.size();i++){ // cout<<"source door tid "<GetTuple(tid_list1[i], false); unsigned int gri1 = ((CcInt*)door_tuple1->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri1 == groom_oid1); for(unsigned int j = 0;j < tid_list2.size();j++){ // cout<<"dest door tid "<GetTuple(tid_list2[j], false); unsigned int gri2 = ((CcInt*)door_tuple2->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid2); IndoorShortestPath(tid_list1[i], tid_list2[j], candidate_path, &start_door_path[i], &end_door_path[j], prune_dist, min_h, max_h, groom_oid1); door_tuple2->DeleteIfAllowed(); // cout<DeleteIfAllowed(); } ///////////////////select the path with minimum length//////////////////// if(candidate_path.size() > 0){ double l = numeric_limits::max(); int index = 0; for(unsigned int i = 0; i < candidate_path.size();i++){ if(candidate_path[i].Size() > 0 && candidate_path[i].Length() < l){ l = candidate_path[i].Length(); index = i; } } path_list.push_back(candidate_path[index]); }else{ // cout<<"no path available"<DeleteIfAllowed(); } } /* new method to compute the connection between a location and all its doors use dual graph and visual graph if the region is complex */ bool IndoorNav::ConnectEndLoc(GenLoc* gloc, vector tid_list, Relation* rel, BTree* btree, vector& candidate_path, float& low_h, float& high_h) { unsigned int groom_oid = gloc->GetOid(); ///////////////find the room//////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; ////////////////////////////////////////////////////////////////////////// // cout<<"groom tid "<GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); low_h = groom->GetLowHeight(); high_h = groom->GetHighHeight(); ///////////////////////////////////////////////////////////////////////// if(GetRoomEnum(type) == ST){/////////in the staircase ConnectEndLocST(groom_tuple, gloc, tid_list, candidate_path); groom_tuple->DeleteIfAllowed(); return true; } if(GetRoomEnum(type) == EL){ groom_tuple->DeleteIfAllowed(); cout<<"inside the elevator. not interesting places"<GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); float h = groom->GetLowHeight(); double x1 = gloc->GetLoc().loc1 + bbox.MinD(0); double y1 = gloc->GetLoc().loc2 + bbox.MinD(1); Point p1(true, x1, y1); Modify_Point2(p1);// numeric problem, not so many digit after dot reg->DeleteIfAllowed(); ///////////////////////////////////////////////////////////////////////// /////////////////////////get the 2D area///////////////////////////////// ///////////////////////////////////////////////////////////////////////// const double dist_delta = 0.001; Region* r = new Region(0); int i = 0; for(;i < groom->Size();i++){ float temp_h; groom->Get(i, temp_h, *r); if(fabs(h - temp_h) < dist_delta){ break; } r->Clear(); } if(i == groom->Size()){ cout<<" such height " <ComplexRegion(); delete ct; assert(complex_reg >= 0); vector obj_name; DualGraph* dg = NULL; VisualGraph* vg = NULL; Relation* tri_rel = NULL; int oid1 = 0; if(complex_reg == 1){ ///complex region, we build dual graph and visual graph // cout<<"complex region"<GetObject(obj_name[0], dg_addr, dg_def); ctlg->GetObject(obj_name[1], vg_addr, vg_def); ctlg->GetObject(obj_name[2], rel_addr, rel_def); if(dg_def && vg_def && rel_def){ dg = (DualGraph*)dg_addr.addr; vg = (VisualGraph*)vg_addr.addr; tri_rel = (Relation*)rel_addr.addr; assert(dg != NULL); assert(vg != NULL); assert(tri_rel != NULL); FindPointInDG1(dg, &p1, oid1); assert(1 <= oid1 && oid1 <= dg->node_rel->GetNoTuples()); }else{ cout<<"open dual graph or visual graph error"<DeleteIfAllowed(); groom_tuple->DeleteIfAllowed(); DeleteSecondoObj(obj_name); return false; } } ////////////build the connection between loc and all doors in that room////// Relation* node_rel = ig->GetNodeRel(); for(unsigned int j = 0;j < tid_list.size();j++){ int door_tid = tid_list[j]; // cout<<"door tid "<GetTuple(door_tid, false); unsigned int gri2 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid); /////////////////////////////////////////////////////////////////// /////////////////get the position of the door////////////////////// /////////////////////////////////////////////////////////////////// Line* l = (Line*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC); assert(l->Size() == 2); HalfSegment hs; l->Get(0, hs); double x2 = (hs.GetLeftPoint().GetX() + hs.GetRightPoint().GetX())/2; double y2 = (hs.GetLeftPoint().GetY() + hs.GetRightPoint().GetY())/2; door_tuple->DeleteIfAllowed(); Point p2(true, x2, y2); Modify_Point2(p2); // numeric problem, not so many digit after dot ////////////////computes the shortest path//////////////////////////// Line* sp_path = new Line(0); if(complex_reg == 1){ ////////////////////////////////////////////////////////////////// //////////////////////////!!!! careful!!!!!/////////////////////// ////////////////////////////////////////////////////////////////// if(EuclideanConnection(r, &p2, &p1, sp_path)){ } else{ Walk_SP* wsp = new Walk_SP(dg, vg, NULL, NULL); wsp->rel3 = tri_rel; int oid2 = 0; FindPointInDG1(dg, &p2, oid2); assert(1 <= oid2 && oid2 <= dg->node_rel->GetNoTuples()); wsp->WalkShortestPath2(oid2, oid1, p2, p1, sp_path); delete wsp; } }else{ /////////////////////////////////////////////////////////////////// //////////////////////////!!!! careful!!!!!/////////////////////// ////////////////////////////////////////////////////////////////// ShortestPath_InRegion(r, &p2, &p1, sp_path); } if(sp_path->Size() == 0){ if(p1.Distance(p2) < EPSDIST){//the position happens to be the door Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); Point3D q(true, p1.GetX(), p1.GetY(), h); *l3d += q; l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); } sp_path->DeleteIfAllowed(); continue; } ///////////////////////////////////////////////////////////////////// SimpleLine* sl = new SimpleLine(0); sl->fromLine(*sp_path); SpacePartition* sp = new SpacePartition(); vector mhs; sp->ReorderLine(sl, mhs); delete sp; sl->DeleteIfAllowed(); sp_path->DeleteIfAllowed(); if(mhs[0].from.Distance(p2) < dist_delta && mhs[mhs.size() - 1].to.Distance(p1) < dist_delta){ }else{ assert(mhs[mhs.size() - 1].to.Distance(p2) < dist_delta && mhs[0].from.Distance(p1) < dist_delta); vector temp_mhs; for(int i = mhs.size() - 1;i >= 0;i--){ MyHalfSegment seg = mhs[i]; Point p = seg.from; seg.from = seg.to; seg.to = p; temp_mhs.push_back(seg); } mhs.clear(); for(unsigned int i = 0;i < temp_mhs.size();i++) mhs.push_back(temp_mhs[i]); assert(mhs[0].from.Distance(p2) < dist_delta && mhs[mhs.size() - 1].to.Distance(p1) < dist_delta); } /////////////////////////////////////////////////////////////////// ///////////////////construct 3D line////////////////////////////// /////////////////////////////////////////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point temp_p = mhs[i].to; Point3D q1(true, temp_p.GetX(), temp_p.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); } r->DeleteIfAllowed(); groom_tuple->DeleteIfAllowed(); if(complex_reg == 1)DeleteSecondoObj(obj_name); return true; } /* the location is a door (building entrance) */ bool IndoorNav::ConnectEndLoc2(GenLoc* gloc, Relation* rel, BTree* btree, vector& candidate_path, float& low_h, float& high_h) { unsigned int groom_oid = gloc->GetOid(); ///////////////find the room//////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; ////////////////////////////////////////////////////////////////////////// assert(1<= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); low_h = groom->GetLowHeight(); high_h = groom->GetHighHeight(); groom_tuple->DeleteIfAllowed(); Line3D* l3d = new Line3D(0); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); return true; } /* shortest path of two locations in the same staircase */ void IndoorNav::ComputePath3DST(GRoom* groom, Point loc1, Point loc2, float h1, float h2, vector& candidate_path) { const double delta_dist = 0.001; if(fabs(h1-h2) < delta_dist){ float h = h1; vector mhs; FindPathInRegion(groom, h, mhs, &loc1, &loc2); ///////////////// convert to 3D line ////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point p1 = mhs[i].to; Point3D q1(true, p1.GetX(), p1.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); }else if(h1 < h2){ vector middle_path; //from low to high ConstructMiddlePath2(groom, middle_path, h1, h2); Point q1(true, middle_path[0].GetX(), middle_path[0].GetY()); Point q2(true, middle_path[middle_path.size() - 1].GetX(), middle_path[middle_path.size() - 1].GetY()); vector mhs1; FindPathInRegion(groom, h1, mhs1, &loc1, &q1); vector mhs2; FindPathInRegion(groom, h2, mhs2, &q2, &loc2); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0 ;i < mhs1.size();i++){ Point p = mhs1[i].from; Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } for(unsigned int i = 0 ;i < middle_path.size() - 1;i++){ *l3d += middle_path[i]; } // cout<<"mhs2 size "<EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); }else if(h1 > h2){ vector middle_path; //from low to high ConstructMiddlePath2(groom, middle_path, h2, h1); Point q1(true, middle_path[middle_path.size() - 1].GetX(), middle_path[middle_path.size() - 1].GetY()); Point q2(true, middle_path[0].GetX(), middle_path[0].GetY()); vector mhs1; FindPathInRegion(groom, h1, mhs1, &loc1, &q1); vector mhs2; FindPathInRegion(groom, h2, mhs2, &q2, &loc2); Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0 ;i < mhs1.size();i++){ Point p = mhs1[i].from; Point3D q(true, p.GetX(), p.GetY(), h1); *l3d += q; } for(int i = middle_path.size() - 1;i > 0; i--){ *l3d += middle_path[i]; } for(unsigned int i = 0 ;i < mhs2.size();i++){ Point p = mhs2[i].from; Point3D q(true, p.GetX(), p.GetY(), h2); *l3d += q; if(i == mhs2.size() - 1){ Point p = mhs2[i].to; Point3D q(true, p.GetX(), p.GetY(), h2); *l3d += q; } } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); }else assert(false); } /* build the connection from the end location to all doors in a staircase */ void IndoorNav::ConnectEndLocST(Tuple* groom_tuple, GenLoc* gloc, vector tid_list, vector& candidate_path) { unsigned int groom_oid = gloc->GetOid(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); reg->DeleteIfAllowed(); Point loc2; Coord x_cord1 = gloc->GetLoc().loc1 + bbox.MinD(0); Coord y_cord1 = gloc->GetLoc().loc2 + bbox.MinD(1); loc2.Set(x_cord1, y_cord1); //absolute position float h2 = GetHeightInST(groom, loc2); Relation* node_rel = ig->GetNodeRel(); for(unsigned int j = 0;j < tid_list.size();j++){ int door_tid = tid_list[j]; // cout<<"door tid "<GetTuple(door_tid, false); unsigned int gri2 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid); /////////////////////////////////////////////////////////////////// /////////////////get the position of the door////////////////////// /////////////////////////////////////////////////////////////////// Line* l = (Line*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC); assert(l->Size() == 2); HalfSegment hs; l->Get(0, hs); double x2 = (hs.GetLeftPoint().GetX() + hs.GetRightPoint().GetX())/2; double y2 = (hs.GetLeftPoint().GetY() + hs.GetRightPoint().GetY())/2; Line3D* l3 = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D temp3d_p; l3->Get(0, temp3d_p); float h1 = temp3d_p.GetZ(); door_tuple->DeleteIfAllowed(); Point loc1(true, x2, y2); ComputePath3DST(groom, loc1, loc2, h1, h2, candidate_path); /////////////////////////////////////////////////////////////////////// } } /* connect the start location to all doors in that room. if the region is complex, it calls the dual graph, visual graph */ bool IndoorNav::ConnectStartLoc(GenLoc* gloc, vector tid_list, Relation* rel, BTree* btree, vector& candidate_path, float& low_h, float& high_h) { unsigned int groom_oid = gloc->GetOid(); ///////////////find the room//////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; ////////////////////////////////////////////////////////////////////////// // cout<<"groom tid "<GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); low_h = groom->GetLowHeight(); high_h = groom->GetHighHeight(); ///////////////////////////////////////////////////////////////////////// if(GetRoomEnum(type) == ST){/////////in the staircase ConnectStartLocST(groom_tuple, gloc, tid_list, candidate_path); groom_tuple->DeleteIfAllowed(); return true; } if(GetRoomEnum(type) == EL){ groom_tuple->DeleteIfAllowed(); cout<<"inside the elevator. not interesting places"<GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); float h = groom->GetLowHeight(); double x1 = gloc->GetLoc().loc1 + bbox.MinD(0); double y1 = gloc->GetLoc().loc2 + bbox.MinD(1); Point p1(true, x1, y1); Modify_Point2(p1);//numeric problem, we do not need so many number after dot reg->DeleteIfAllowed(); ///////////////////////////////////////////////////////////////////////// /////////////////////////get the 2D area///////////////////////////////// ///////////////////////////////////////////////////////////////////////// const double dist_delta = 0.001; Region* r = new Region(0); int i = 0; for(;i < groom->Size();i++){ float temp_h; groom->Get(i, temp_h, *r); if(fabs(h - temp_h) < dist_delta){ break; } r->Clear(); } if(i == groom->Size()){ cout<<" such height " <ComplexRegion(); delete ct; assert(complex_reg >= 0); vector obj_name; DualGraph* dg = NULL; VisualGraph* vg = NULL; Relation* tri_rel = NULL; int oid1 = 0; if(complex_reg == 1){ ///complex region, we build dual graph and visual graph GetSecondoObj(r, obj_name); assert(obj_name.size() == 3); SecondoCatalog* ctlg = SecondoSystem::GetCatalog(); bool dg_def, vg_def, rel_def; Word dg_addr, vg_addr, rel_addr; ctlg->GetObject(obj_name[0], dg_addr, dg_def); ctlg->GetObject(obj_name[1], vg_addr, vg_def); ctlg->GetObject(obj_name[2], rel_addr, rel_def); if(dg_def && vg_def && rel_def){ dg = (DualGraph*)dg_addr.addr; vg = (VisualGraph*)vg_addr.addr; tri_rel = (Relation*)rel_addr.addr; assert(dg != NULL); assert(vg != NULL); assert(tri_rel != NULL); FindPointInDG1(dg, &p1, oid1); assert(1 <= oid1 && oid1 <= dg->node_rel->GetNoTuples()); }else{ cout<<"open dual graph or visual graph error"<DeleteIfAllowed(); groom_tuple->DeleteIfAllowed(); DeleteSecondoObj(obj_name); return false; } } ////////////build the connection between loc and all doors in that room////// Relation* node_rel = ig->GetNodeRel(); for(unsigned int j = 0;j < tid_list.size();j++){ int door_tid = tid_list[j]; // cout<<"door tid "<GetTuple(door_tid, false); unsigned int gri2 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid); /////////////////////////////////////////////////////////////////// /////////////////get the position of the door////////////////////// /////////////////////////////////////////////////////////////////// Line* l = (Line*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC); assert(l->Size() == 2); HalfSegment hs; l->Get(0, hs); double x2 = (hs.GetLeftPoint().GetX() + hs.GetRightPoint().GetX())/2; double y2 = (hs.GetLeftPoint().GetY() + hs.GetRightPoint().GetY())/2; door_tuple->DeleteIfAllowed(); Point p2(true, x2, y2); Modify_Point2(p2);//numeric problem, do not need so many number after dot ////////////////computes the shortest path//////////////////////////// Line* sp_path = new Line(0); if(complex_reg == 1){ ////////////////////////////////////////////////////////////////// //////////////////////////!!!! careful!!!!!/////////////////////// ////////////////////////////////////////////////////////////////// if(EuclideanConnection(r, &p1, &p2, sp_path)){ }else{ Walk_SP* wsp = new Walk_SP(dg, vg, NULL, NULL); wsp->rel3 = tri_rel; int oid2 = 0; FindPointInDG1(dg, &p2, oid2); assert(1 <= oid2 && oid2 <= dg->node_rel->GetNoTuples()); wsp->WalkShortestPath2(oid1, oid2, p1, p2, sp_path); delete wsp; } }else{ /////////////////////////////////////////////////////////////////// //////////////////////////!!!! careful!!!!!/////////////////////// ////////////////////////////////////////////////////////////////// ShortestPath_InRegion(r, &p1, &p2, sp_path); } if(sp_path->Size() == 0){ if(p1.Distance(p2) < EPSDIST){//the position happens to be the door Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); Point3D q(true, p1.GetX(), p1.GetY(), h); *l3d += q; l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); } sp_path->DeleteIfAllowed(); continue; } ///////////////////////////////////////////////////////////////////// SimpleLine* sl = new SimpleLine(0); sl->fromLine(*sp_path); SpacePartition* sp = new SpacePartition(); vector mhs; sp->ReorderLine(sl, mhs); delete sp; sl->DeleteIfAllowed(); sp_path->DeleteIfAllowed(); // cout< temp_mhs; for(int i = mhs.size() - 1;i >= 0;i--){ MyHalfSegment seg = mhs[i]; Point p = seg.from; seg.from = seg.to; seg.to = p; temp_mhs.push_back(seg); } mhs.clear(); for(unsigned int i = 0;i < temp_mhs.size();i++) mhs.push_back(temp_mhs[i]); assert(mhs[0].from.Distance(p1) < dist_delta && mhs[mhs.size() - 1].to.Distance(p2) < dist_delta); } /////////////////////////////////////////////////////////////////// ///////////////////construct 3D line////////////////////////////// /////////////////////////////////////////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point temp_p = mhs[i].to; Point3D q1(true, temp_p.GetX(), temp_p.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); } r->DeleteIfAllowed(); groom_tuple->DeleteIfAllowed(); if(complex_reg == 1)DeleteSecondoObj(obj_name); return true; } /* build the connection from the start location to all doors in a staircase */ void IndoorNav::ConnectStartLocST(Tuple* groom_tuple, GenLoc* gloc, vector tid_list, vector& candidate_path) { unsigned int groom_oid = gloc->GetOid(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); reg->DeleteIfAllowed(); Point loc1; Coord x_cord1 = gloc->GetLoc().loc1 + bbox.MinD(0); Coord y_cord1 = gloc->GetLoc().loc2 + bbox.MinD(1); loc1.Set(x_cord1, y_cord1); //absolute position float h1 = GetHeightInST(groom, loc1); Relation* node_rel = ig->GetNodeRel(); for(unsigned int j = 0;j < tid_list.size();j++){ int door_tid = tid_list[j]; // cout<<"door tid "<GetTuple(door_tid, false); unsigned int gri2 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid); /////////////////////////////////////////////////////////////////// /////////////////get the position of the door////////////////////// /////////////////////////////////////////////////////////////////// Line* l = (Line*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC); assert(l->Size() == 2); HalfSegment hs; l->Get(0, hs); double x2 = (hs.GetLeftPoint().GetX() + hs.GetRightPoint().GetX())/2; double y2 = (hs.GetLeftPoint().GetY() + hs.GetRightPoint().GetY())/2; Line3D* l3 = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D temp3d_p; l3->Get(0, temp3d_p); float h2 = temp3d_p.GetZ(); door_tuple->DeleteIfAllowed(); Point loc2(true, x2, y2); ComputePath3DST(groom, loc1, loc2, h1, h2, candidate_path); /////////////////////////////////////////////////////////////////////// } } /* the door is connected to a room which has only one entrance, and the entrance equals to the door an example query: loc1 oid 342 (2.65 0.96 ) loc2 oid 74 (1.99 9.21 ) shortest path in minimum length include dead door for connecton: Total runtime ... Times (elapsed / cpu): 39.8204sec / 39.03sec = 1.02025 Total runtime ... Times (elapsed / cpu): 3.78682sec / 3.73sec = 1.01523 do not include dead door: Total runtime ... Times (elapsed / cpu): 2.73761sec / 2.74sec = 0.999128 Total runtime ... Times (elapsed / cpu): 0.828596sec / 0.83sec = 0.998308 big improvement shortest path in time Times (elapsed / cpu): 7.82145sec / 7.81sec = 1.00147 Times (elapsed / cpu): 1:03min (62.6424sec) /61.33sec = 1.0214 Times (elapsed / cpu): 2.22701sec / 2.22sec = 1.00316 Times (elapsed / cpu): 6.33788sec / 6.33sec = 1.00124 shortest path in room Times (elapsed / cpu): 1:34min (94.291sec) /92.23sec = 1.02235 Times (elapsed / cpu): 3.27043sec / 3.26sec = 1.0032 */ bool IndoorNav::DeadDoor(int door_tid, int groomoid, int groom_oid_end, vector& door_list) { // cout<<"check Dead Door"<GetNodeRel()->GetTuple(door_tid, false); int gri1 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); int gri2 = ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID2))->GetIntval(); Line3D* l3d1 = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D p3d_1, p3d_2; l3d1->Get(0, p3d_1); l3d1->Get(1, p3d_2); Point3D p3d1(true, (p3d_1.GetX() + p3d_2.GetX())/2, (p3d_1.GetY() + p3d_2.GetY())/2, p3d_1.GetZ()); door_tuple->DeleteIfAllowed(); int groom_oid; if(gri1 == groomoid) groom_oid = gri2; else if(gri2 == groomoid) groom_oid = gri1; else assert(false); // cout<Size()<<" p3d1 "<GetBTree(); CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); vector tid_list; const double delta_dist = 0.001; while(btree_iter->Next()){ Tuple* tuple = ig->GetNodeRel()->GetTuple(btree_iter->GetId(), false); int tid = tuple->GetTupleId(); if(groom_oid == groom_oid_end){////////////the end room tid_list.push_back(tid); tuple->DeleteIfAllowed(); continue; } // int gr1 = // ((CcInt*)tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); // int gr2 = // ((CcInt*)tuple->GetAttribute(IndoorGraph::I_GROOM_OID2))->GetIntval(); // // if(!((gri1 == gr1 && gri2 == gr2) ||(gri1 == gr2 && gri2 == gr1))){ // tid_list.push_back(tid); // } Line3D* l3d2 = (Line3D*)tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D q3d_1, q3d_2; l3d2->Get(0, q3d_1); l3d2->Get(1, q3d_2); Point3D p3d2(true, (q3d_1.GetX() + q3d_2.GetX())/2, (q3d_1.GetY() + q3d_2.GetY())/2, q3d_1.GetZ()); // cout<Size()<<" p3d2 "<DeleteIfAllowed(); continue; } tid_list.push_back(tid); tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; // cout<<"door tid "< 0){ ////////////////////////////////////////////////////////////// /////////the door with the same location is included already// ///////////////////////////////////////////////////////////// // cout<<"check door pos "<GetOid(); int groom_oid2 = gloc2->GetOid(); assert(1 <= groom_oid1 && groom_oid1 <= rel->GetNoTuples()); assert(1 <= groom_oid2 && groom_oid2 <= rel->GetNoTuples()); Tuple* groom_tuple1 = rel->GetTuple(groom_oid1, false); Tuple* groom_tuple2 = rel->GetTuple(groom_oid2, false); GRoom* groom1 = (GRoom*)groom_tuple1->GetAttribute(I_Room); GRoom* groom2 = (GRoom*)groom_tuple2->GetAttribute(I_Room); Region* reg1 = new Region(0); Region* reg2 = new Region(0); groom1->GetRegion(*reg1); groom2->GetRegion(*reg2); BBox<2> bbox1 = reg1->BoundingBox(); BBox<2> bbox2 = reg2->BoundingBox(); float h1 = groom1->GetLowHeight(); float h2 = groom2->GetLowHeight(); reg1->DeleteIfAllowed(); reg2->DeleteIfAllowed(); groom_tuple1->DeleteIfAllowed(); groom_tuple2->DeleteIfAllowed(); double x1 = gloc1->GetLoc().loc1 + bbox1.MinD(0); double y1 = gloc1->GetLoc().loc2 + bbox1.MinD(1); double x2 = gloc2->GetLoc().loc1 + bbox2.MinD(0); double y2 = gloc2->GetLoc().loc2 + bbox2.MinD(1); Point3D p1(true, x1, y1, h1); Point3D p2(true, x2, y2, h2); const double dist_delta = 0.001; if(p1.Distance(p2) < dist_delta) return true; return false; } /* two locations are in the same room */ void IndoorNav::PathInOneRoom(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* btree) { int groom_oid = gloc1->GetOid(); ///////////////find the room//////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; ////////////////////////////////////////////////////////////////////////// // Tuple* groom_tuple = rel->GetTuple(groom_oid, false); assert(1<= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); ////////////////////////////////////////////////////////////////////////// if(GetRoomEnum(type) == ST){//////////location is in the staircase Line3D* l3d = new Line3D(0); PathInOneST(groom_tuple, gloc1, gloc2, l3d); groom_tuple->DeleteIfAllowed(); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); return; } if(GetRoomEnum(type) == EL){ groom_tuple->DeleteIfAllowed(); Line3D* l3d = new Line3D(0); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); cout<<"inside the elevator. not interesting places"<GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); float h = groom->GetLowHeight(); double x1 = gloc1->GetLoc().loc1 + bbox.MinD(0); double y1 = gloc1->GetLoc().loc2 + bbox.MinD(1); double x2 = gloc2->GetLoc().loc1 + bbox.MinD(0); double y2 = gloc2->GetLoc().loc2 + bbox.MinD(1); Point p1(true, x1, y1); Point p2(true, x2, y2); // cout<<"p1 "< mhs; FindPathInRegion(groom, h, mhs, &p1, &p2); reg->DeleteIfAllowed(); groom_tuple->DeleteIfAllowed(); ///////////////// conver to 3D line ////////////////////////////// Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); for(unsigned int i = 0;i < mhs.size();i++){ Point p = mhs[i].from; Point3D q(true, p.GetX(), p.GetY(), h); *l3d += q; if(i == mhs.size() - 1){ Point p1 = mhs[i].to; Point3D q1(true, p1.GetX(), p1.GetY(), h); *l3d += q1; } } l3d->EndBulkLoad(); path_list.push_back(*l3d); l3d->DeleteIfAllowed(); } /* find the path from one door (id1) to another (id2) */ inline bool IndoorNav::MiddlePoint(Line3D* l, Point3D& p) { if(l->Size() != 2) return false; Point3D q1, q2; l->Get(0, q1); l->Get(1, q2); double x = (q1.GetX() + q2.GetX())/2; double y = (q1.GetY() + q2.GetY())/2; double z = (q1.GetZ() + q2.GetZ())/2; Point3D result(true, x, y, z); p = result; return true; } /* compute the shortest in a staircase. two locations are in the same staircase */ void IndoorNav::PathInOneST(Tuple* groom_tuple, GenLoc* gloc1, GenLoc* gloc2, Line3D* l3d) { // cout<<"PathInOneST "<GetAttribute(I_Room); Region* reg = new Region(0); groom->GetRegion(*reg); BBox<2> bbox = reg->BoundingBox(); reg->DeleteIfAllowed(); Point loc1, loc2; Coord x_cord1 = gloc1->GetLoc().loc1 + bbox.MinD(0); Coord y_cord1 = gloc1->GetLoc().loc2 + bbox.MinD(1); loc1.Set(x_cord1, y_cord1); //absolute position Coord x_cord2 = gloc2->GetLoc().loc1 + bbox.MinD(0); Coord y_cord2 = gloc2->GetLoc().loc2 + bbox.MinD(1); loc2.Set(x_cord2, y_cord2); //absolute position float h1 = GetHeightInST(groom, loc1); float h2 = GetHeightInST(groom, loc2); vector path_line3d; ComputePath3DST(groom, loc1, loc2, h1, h2, path_line3d); if(path_line3d.size() == 1) l3d = &path_line3d[0]; else assert(false); } /* compute the shortest path from one door to another door */ void IndoorNav::IndoorShortestPath(int id1, int id2, vector& candidate_path, Line3D* l3d_s, Line3D* l3d_d, double& prune_dist, float min_h, float max_h, int start_groom_oid) { // cout<<"start_groom_oid "<GetNodeRel(); Tuple* door_tuple1 = node_rel->GetTuple(id1, false); Tuple* door_tuple2 = node_rel->GetTuple(id2, false); Line3D* l3d1 = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Line3D* l3d2 = (Line3D*)door_tuple2->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D start_p, end_p; if(MiddlePoint(l3d1, start_p) == false || MiddlePoint(l3d2, end_p) == false){ cout<<"incorrect door "<DeleteIfAllowed(); door_tuple2->DeleteIfAllowed(); if(start_p.Distance(end_p) < dist_delta){////the same location Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// *l3d += start_p; ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); return; } priority_queue path_queue; vector expand_queue; vector visit_flag1;////////////door visit for(int i = 1; i <= node_rel->GetNoTuples();i++) visit_flag1.push_back(false); // ofstream output("debug.txt"); /////////// initialize the queue ////////////////////////////// InitializeQueue(id1, &start_p, &end_p, path_queue, expand_queue); //////////////////////////////////////////////////////////////// bool find = false; IPath_elem dest;//////////destination while(path_queue.empty() == false){ IPath_elem top = path_queue.top(); path_queue.pop(); if(visit_flag1[top.tri_index - 1]) continue; ////////////larger than an existing value/////////////// if(prune_dist > 0.0 && top.real_w > prune_dist){ return; } ///////////////////////////////////////////////////////////// // top.Print(); if(top.tri_index == id2){ // cout<<"find the shortest path"<GetTuple(top.tri_index, false); /////////////////get the position of the door//////////////////////////// Point3D q; Line3D* door_loc = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); assert(MiddlePoint(door_loc, q)); // int groom_oid1 = // ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); // int groom_oid2 = // ((CcInt*)door_tuple->GetAttribute(IndoorGraph::I_GROOM_OID2))->GetIntval(); door_tuple->DeleteIfAllowed(); ////////////////////////////////////////////////////////////////// ////////////////out of the height range/////////////////////////// /////////////////////////////////////////////////////////////////// // for the train station, the same height on different platform // can not be pruned if(fabs(min_h - max_h) > EPSDIST){ //not equal to each other if(q.GetZ() - max_h > dist_delta || min_h - q.GetZ() > dist_delta){ continue; } } /////////////////////////////////////////////////////////////////// // output<<"top door goid1 "< adj_list; ig->FindAdj(top.tri_index, adj_list); ///////////////////////////////////////////////////////////// int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ Tuple* edge_tuple = ig->GetEdgeRel()->GetTuple(adj_list[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_DOOR_TID2))->GetIntval(); Line3D* path = (Line3D*)edge_tuple->GetAttribute(IndoorGraph::I_PATH); int groom_oid = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_GROOM_OID))->GetIntval(); if(visit_flag1[neighbor_id - 1]){ // output<<"door visit already"<DeleteIfAllowed(); continue; } if(groom_oid == start_groom_oid){ edge_tuple->DeleteIfAllowed(); continue; } Tuple* door_tuple1 = node_rel->GetTuple(neighbor_id, false); Line3D* l = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D p; assert(MiddlePoint(l, p));//get the point of next door door_tuple1->DeleteIfAllowed(); if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(p.GetZ() - max_h > dist_delta || min_h - p.GetZ() > dist_delta){ edge_tuple->DeleteIfAllowed(); continue; } } int cur_size = expand_queue.size(); double w = top.real_w + path->Length(); double hw = p.Distance(end_p); IPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w, *path); path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////construct the result////////////////////////////// if(find){ vector ps_list; while(dest.prev_index != -1){ // cout<<"sub path "< 0){ if(ps_list.size() == 0){ for(int i = dest.path.Size() - 1;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } }else{ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } } dest = expand_queue[dest.prev_index]; } // cout<<"sub path"< 0){ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// for(int i = ps_list.size() - 1;i >= 0; i--){ *l3d += ps_list[i]; } ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); if(prune_dist < 0.0){ prune_dist = l3d->Length(); }else if(l3d->Length() < prune_dist){ prune_dist = l3d->Length(); } // cout<<"length: "<Length()<DeleteIfAllowed(); }else{ // cout<<"no path available "<StartBulkLoad(); l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); } } /* Initialize the queue, put the start door into the queue */ void IndoorNav::InitializeQueue(int id, Point3D* start_p, Point3D* end_p, priority_queue& path_queue, vector& expand_queue) { // cout<<"InitializeQueue "<Distance(*end_p); Line3D* l3d = new Line3D(0); IPath_elem elem(-1, cur_size, id, w + hw, w, *l3d); path_queue.push(elem); expand_queue.push_back(elem); l3d->DeleteIfAllowed(); } ///////////////////////////////////////////////////////////////////////////// //////////////////////////minimum number of rooms//////////////////////////// ///////////////////////////////////////////////////////////////////////////// void IndoorNav::ShortestPath_Room(GenLoc* gloc1, GenLoc* gloc2, Relation* rel, BTree* groom_btree) { if(IsLocEqual(gloc1, gloc2, rel)){ cout<<"the two locations are equal to each other"<GetOid()); BTreeIterator* btree_iter = groom_btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); groom_oid_list.push_back(gloc1->GetOid()); room_list.push_back(*groom); groom_tuple->DeleteIfAllowed(); return; } unsigned int groom_oid1 = gloc1->GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); // cout<<"groom oid1 "<ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); groom_oid_list.push_back(groom_oid1); room_list.push_back(*groom); groom_tuple->DeleteIfAllowed(); return; } Relation* node_rel = ig->GetNodeRel(); /////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// /////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); CcInt* search_id1 = new CcInt(true, groom_oid1); BTreeIterator* btree_iter1 = btree->ExactMatch(search_id1); vector tid_list1; vector door_start; while(btree_iter1->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter1->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid1, groom_oid2, door_start) == false) tid_list1.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; GetHeightOfGRoom(groom_oid1, groom_btree, rel, start_h1, start_h2); assert(start_h1 > INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); float min_h1 = MIN(start_h1, start_h2); float max_h1 = MAX(start_h1, start_h2); /////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// /////////////////////////////////////////////////////////////////// CcInt* search_id2 = new CcInt(true, groom_oid2); BTreeIterator* btree_iter2 = btree->ExactMatch(search_id2); vector tid_list2; vector door_end; while(btree_iter2->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter2->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid2, groom_oid1, door_end) == false) tid_list2.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; // cout<<"tid1 size "< INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); float min_h2 = MIN(end_h1, end_h2); float max_h2 = MAX(end_h1, end_h2); float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); ////////////////////for each possible door, search the path///////////// vector< vector > candidate_path; int start_groom_oid = gloc1->GetOid(); int end_groom_oid = gloc2->GetOid(); for(unsigned int i = 0;i < tid_list1.size();i++){ // cout<<"source door tid "<GetTuple(tid_list1[i], false); unsigned int gri1 = ((CcInt*)door_tuple1->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri1 == groom_oid1); for(unsigned int j = 0;j < tid_list2.size();j++){ Tuple* door_tuple2 = node_rel->GetTuple(tid_list2[j], false); unsigned int gri2 = ((CcInt*)door_tuple2->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri2 == groom_oid2); IndoorShortestPath_Room(tid_list1[i], tid_list2[j], candidate_path, start_groom_oid, end_groom_oid, min_h, max_h); door_tuple2->DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } ///////////////////select the path with minimum length//////////////////// if(candidate_path.size() > 0){ unsigned int l = candidate_path[0].size(); int index = 0; for(unsigned int i = 1; i < candidate_path.size();i++){ // cout<<"i "<GetTuple(candidate_path[index][i],false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); if(GetRoomEnum(type) == EL){//process special part vector el_id; el_id.push_back(candidate_path[index][i]); unsigned int j = i + 1; for(; j < candidate_path[index].size();j++){ Tuple* tuple = rel->GetTuple(candidate_path[index][j],false); string groom_type = ((CcString*)tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(groom_type) == EL) el_id.push_back(candidate_path[index][j]); else{ tuple->DeleteIfAllowed(); break; } tuple->DeleteIfAllowed(); } assert(i != 0); /////////start and end locations are in OR or CO///////////// assert(j < candidate_path[index].size() - 1);//impossible to end in EL Tuple* gr_tuple1 = rel->GetTuple(candidate_path[index][i - 1],false); GRoom* groom1 = (GRoom*)gr_tuple1->GetAttribute(I_Room); float h1 = groom1->GetLowHeight(); gr_tuple1->DeleteIfAllowed(); Tuple* gr_tuple2 = rel->GetTuple(candidate_path[index][j],false); GRoom* groom2 = (GRoom*)gr_tuple2->GetAttribute(I_Room); float h2 = groom2->GetLowHeight(); gr_tuple2->DeleteIfAllowed(); const double delta_d = 0.01; Point center_p; if(h1 < h2){////// add after // cout<<"h1 < h2"<<" h1:"<GetTuple(el_id[k], false); GRoom* gr = (GRoom*)t->GetAttribute(I_Room); int groom_oid = ((CcInt*)t->GetAttribute(I_OID))->GetIntval(); groom_oid_list.push_back(groom_oid); room_list.push_back(*gr); // cout<<"oid "< gr_box = gr->BoundingBox(); double center_x = (gr_box.MinD(0) + gr_box.MaxD(0))/2; double center_y = (gr_box.MinD(1) + gr_box.MaxD(1))/2; center_p.Set(center_x, center_y); } t->DeleteIfAllowed(); } for(int k = 1; k <= rel->GetNoTuples();k++){ Tuple* t = rel->GetTuple(k, false); GRoom* gr = (GRoom*)t->GetAttribute(I_Room); string groom_type = ((CcString*)t->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(groom_type) == EL && AlmostEqual(gr->GetLowHeight(), h2)){ Rectangle<2> box = gr->BoundingBox(); double x = (box.MinD(0) + box.MaxD(0))/2; double y = (box.MinD(1) + box.MaxD(1))/2; Point p(true, x, y); /////several elevators, compare the center point ///// if(center_p.Distance(p) < delta_d){ int groom_oid = ((CcInt*)t->GetAttribute(I_OID))->GetIntval(); groom_oid_list.push_back(groom_oid); // cout<<"groom oid "<DeleteIfAllowed(); break; } } t->DeleteIfAllowed(); } }else{//add before // cout<<"h1 > h2 "<<"h1 :"<GetTuple(el_id[0], false); GRoom* gr = (GRoom*)t->GetAttribute(I_Room); Rectangle<2> gr_box = gr->BoundingBox(); double center_x = (gr_box.MinD(0) + gr_box.MaxD(0))/2; double center_y = (gr_box.MinD(1) + gr_box.MaxD(1))/2; center_p.Set(center_x, center_y); t->DeleteIfAllowed(); for(int k = 1; k <= rel->GetNoTuples();k++){ Tuple* t = rel->GetTuple(k, false); GRoom* gr = (GRoom*)t->GetAttribute(I_Room); string groom_type = ((CcString*)t->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(groom_type) == EL && AlmostEqual(gr->GetLowHeight(), h1)){ Rectangle<2> box = gr->BoundingBox(); double x = (box.MinD(0) + box.MaxD(0))/2; double y = (box.MinD(1) + box.MaxD(1))/2; Point p(true, x, y); if(center_p.Distance(p) < delta_d){ int groom_oid = ((CcInt*)t->GetAttribute(I_OID))->GetIntval(); groom_oid_list.push_back(groom_oid); room_list.push_back(*gr); t->DeleteIfAllowed(); // cout<<"find "<DeleteIfAllowed(); } for(unsigned int k = 0;k < el_id.size();k++){ Tuple* t = rel->GetTuple(el_id[k], false); GRoom* gr = (GRoom*)t->GetAttribute(I_Room); int groom_oid = ((CcInt*)t->GetAttribute(I_OID))->GetIntval(); groom_oid_list.push_back(groom_oid); room_list.push_back(*gr); t->DeleteIfAllowed(); } } i = j - 1; }else{ // groom_oid_list.push_back(candidate_path[index][i]); int groom_oid = ((CcInt*)groom_tuple->GetAttribute(I_OID))->GetIntval(); groom_oid_list.push_back(groom_oid); room_list.push_back(*groom); } groom_tuple->DeleteIfAllowed(); } }else{ cout<<"no path available"<ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); start_h1 = groom->GetLowHeight(); start_h2 = groom->GetHighHeight(); groom_tuple->DeleteIfAllowed(); } /* shortest path from one door to another door, decided by the number of rooms */ void IndoorNav::IndoorShortestPath_Room(int id1, int id2, vector >& candidate_path, int s_room_oid, int e_room_oid, float min_h, float max_h) { // cout<<"s_room_oid "<GetNodeRel(); Tuple* door_tuple1 = node_rel->GetTuple(id1, false); Tuple* door_tuple2 = node_rel->GetTuple(id2, false); Line3D* l3d1 = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Line3D* l3d2 = (Line3D*)door_tuple2->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D start_p, end_p; if(MiddlePoint(l3d1, start_p) == false || MiddlePoint(l3d2, end_p) == false){ cout<<"incorrect door "<DeleteIfAllowed(); door_tuple2->DeleteIfAllowed(); if(start_p.Distance(end_p) < dist_delta){//two doors at the same location vector temp_list; temp_list.push_back(s_room_oid); temp_list.push_back(e_room_oid); candidate_path.push_back(temp_list); return; } priority_queue path_queue; vector expand_queue; vector visit_flag1;////////////door visit for(int i = 1; i <= node_rel->GetNoTuples();i++) visit_flag1.push_back(false); // ofstream output("debug.txt"); /////////// initialize the queue ////////////////////////////// int cur_size = expand_queue.size(); double w = 0.0; // double hw = start_p.Distance(end_p); double hw = 0.0; Line3D* l3d = new Line3D(0); IPath_elem elem(-1, cur_size, id1, w + hw, w, *l3d, s_room_oid); path_queue.push(elem); expand_queue.push_back(elem); l3d->DeleteIfAllowed(); //////////////////////////////////////////////////////////////// bool find = false; IPath_elem dest;//////////destination while(path_queue.empty() == false){ IPath_elem top = path_queue.top(); path_queue.pop(); if(visit_flag1[top.tri_index - 1])continue; if(top.tri_index == id2){ // cout<<"find the shortest path"<GetTuple(top.tri_index, false); /////////////////get the position of the door//////////////////////////// Point3D q; Line3D* door_loc = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); assert(MiddlePoint(door_loc, q)); door_tuple->DeleteIfAllowed(); if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(q.GetZ() - max_h > dist_delta || min_h - q.GetZ() > dist_delta){ continue; } } ////////find its adjacecy element, and push them into queue and path////// vector adj_list; ig->FindAdj(top.tri_index, adj_list); ///////////////////////////////////////////////////////////// int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ Tuple* edge_tuple = ig->GetEdgeRel()->GetTuple(adj_list[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_DOOR_TID2))->GetIntval(); Line3D* path = (Line3D*)edge_tuple->GetAttribute(IndoorGraph::I_PATH); int groom_oid = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_GROOM_OID))->GetIntval(); if(visit_flag1[neighbor_id - 1]){ edge_tuple->DeleteIfAllowed(); continue; } if(groom_oid == s_room_oid){ edge_tuple->DeleteIfAllowed(); continue; } Tuple* door_tuple1 = node_rel->GetTuple(neighbor_id, false); Line3D* l = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D p; assert(MiddlePoint(l, p));//get the point of next door door_tuple1->DeleteIfAllowed(); if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(p.GetZ() - max_h > dist_delta || min_h - p.GetZ() > dist_delta){ continue; } } int cur_size = expand_queue.size(); // double w = top.real_w + path->Length(); // double hw = p.Distance(end_p); double w = top.real_w; if(path->Length() > 0.0) w++; //one more room double hw = 0.0; IPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w, *path, groom_oid); path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////construct the result////////////////////////////// if(find){ vector groom_oid_list; groom_oid_list.push_back(e_room_oid); while(dest.prev_index != -1){ // cout<<"sub path "< 0){ int oid = groom_oid_list[groom_oid_list.size() - 1]; if(oid != dest.groom_oid) groom_oid_list.push_back(dest.groom_oid); } dest = expand_queue[dest.prev_index]; } // cout<<"sub path"< temp_list; for(int i = groom_oid_list.size() - 1;i >= 0;i--){ // cout<<"groom_oid "<DeleteIfAllowed(); return; } ////////////get some parameters/////////////////////////////////////// ///// 1. the height of the elevator, 2. the number of floors //////// ///// 3. the average speed of people 4.the speed of the elevator ///// //////////// 1 = 4 ///////////////////////////////// ////////////////////////////////////////////////////////////////////// vector height_list; float door_width = numeric_limits::max(); //the speed for person bool haselevator = false; for(int i = 1;i <= rel->GetNoTuples();i++){ Tuple* groom_tuple = rel->GetTuple(i, false); Line* door = (Line*)groom_tuple->GetAttribute(I_Door); for(int j = 0;j < door->Size();j++){ HalfSegment hs; door->Get(j, hs); if(!hs.IsLeftDomPoint())continue; if(hs.Length() < door_width)door_width = hs.Length(); } string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); if(GetRoomEnum(type) == EL){ GRoom* groom = (GRoom*)groom_tuple->GetAttribute(I_Room); height_list.push_back(groom->GetLowHeight()); haselevator = true; } groom_tuple->DeleteIfAllowed(); } sort(height_list.begin(), height_list.end()); float floor_height = 0; if(height_list.size() >= 2){ floor_height = height_list[1] - height_list[0]; } int num_floors = height_list.size(); // cout<<"floor height "<GetOid(); unsigned int groom_oid2 = gloc2->GetOid(); if(groom_oid1 == groom_oid2){ PathInOneRoom(gloc1, gloc2, rel, groom_btree); cost_list.push_back(path_list[0].Length() / speed_person); return; } ///////////////////////////////////////////////////////////////////////// Relation* node_rel = ig->GetNodeRel(); /////////////////////////////////////////////////////////////////// ///////////////collect all doors in start room////////////////////// /////////////////////////////////////////////////////////////////// BTree* btree = ig->GetBTree(); CcInt* search_id1 = new CcInt(true, groom_oid1); BTreeIterator* btree_iter1 = btree->ExactMatch(search_id1); vector tid_list1; vector door_start; while(btree_iter1->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter1->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid1, groom_oid2, door_start) == false) tid_list1.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter1; delete search_id1; /////////////////////////////////////////////////////////////////// ///////////////collect all doors in end room////////////////////// /////////////////////////////////////////////////////////////////// CcInt* search_id2 = new CcInt(true, groom_oid2); BTreeIterator* btree_iter2 = btree->ExactMatch(search_id2); vector tid_list2; vector door_end; while(btree_iter2->Next()){ Tuple* tuple = node_rel->GetTuple(btree_iter2->GetId(), false); int door_tid = tuple->GetTupleId(); if(DeadDoor(door_tid, groom_oid2, groom_oid1, door_end) == false) tid_list2.push_back(door_tid); tuple->DeleteIfAllowed(); } delete btree_iter2; delete search_id2; // cout< start_door_path; float start_h1 = INVALID_HEIGHT; float start_h2 = INVALID_HEIGHT; if(!ConnectStartLoc(gloc1, tid_list1, rel, groom_btree, start_door_path, start_h1, start_h2)){ cout<<"connect start location to doors error"<DeleteIfAllowed(); return; } assert(start_h1 > INVALID_HEIGHT && start_h2 > INVALID_HEIGHT); float min_h1 = MIN(start_h1, start_h2); float max_h1 = MAX(start_h1, start_h2); vector end_door_path; float end_h1 = INVALID_HEIGHT; float end_h2 = INVALID_HEIGHT; //////calculate once for the connection between end loc and all its door/// if(!ConnectEndLoc(gloc2, tid_list2, rel, groom_btree, end_door_path, end_h1, end_h2)){ cout<<"connect end location to doors error"<DeleteIfAllowed(); return; } assert(end_h1 > INVALID_HEIGHT && end_h2 > INVALID_HEIGHT); float min_h2 = MIN(end_h1, end_h2); float max_h2 = MAX(end_h1, end_h2); float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); /////////////////////////////////////////////////////////////////////// ////////////////////for each possible door, search the path///////////// /////////////////////////////////////////////////////////////////////// vector candidate_path; vector timecost; double prune_time = -1.0; for(unsigned int i = 0;i < tid_list1.size();i++){ Tuple* door_tuple1 = node_rel->GetTuple(tid_list1[i], false); unsigned int gri1 = ((CcInt*)door_tuple1->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); assert(gri1 == groom_oid1); for(unsigned int j = 0;j < tid_list2.size();j++){ Tuple* door_tuple2 = node_rel->GetTuple(tid_list2[j], false); unsigned int gri1 = ((CcInt*)door_tuple2->GetAttribute(IndoorGraph::I_GROOM_OID1))->GetIntval(); /*path with minimum travelling time. it calculate two shortest paths: one is without elevator and the other might include elevator. if it includes the elevator, then the cost on the elevator is rest (uncertain value). Finally, compare the two costs. */ assert(gri1 == groom_oid2); IndoorShortestPath_Time1(tid_list1[i], tid_list2[j], candidate_path, &start_door_path[i], &end_door_path[j], timecost, param, rel, groom_btree, prune_time, min_h, max_h, groom_oid1); if(haselevator){ IndoorShortestPath_Time2(tid_list1[i], tid_list2[j], candidate_path, &start_door_path[i], &end_door_path[j], timecost, param, rel, groom_btree, prune_time, min_h, max_h, groom_oid1); } door_tuple2->DeleteIfAllowed(); } door_tuple1->DeleteIfAllowed(); } assert(candidate_path.size() == timecost.size()); ///////////////////select the path with minimum length//////////////////// if(candidate_path.size() > 0 && timecost.size() > 0){ double l = timecost[0]; int index = 0; for(unsigned int i = 1; i < timecost.size();i++){ if(timecost[i] < l){ l = timecost[i]; index = i; } } path_list.push_back(candidate_path[index]); cost_list.push_back(timecost[index]); }else cout<<"no path available"<& candidate_path, Line3D* l3d_s, Line3D* l3d_d, vector& timecost, I_Parameter& param, Relation* rel, BTree* btree, double& prune_time, float min_h, float max_h, int start_groom_oid) { // cout<<"IndoorShortestPath_Time1()"<GetNodeRel(); Tuple* door_tuple1 = node_rel->GetTuple(id1, false); Tuple* door_tuple2 = node_rel->GetTuple(id2, false); Line3D* l3d1 = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Line3D* l3d2 = (Line3D*)door_tuple2->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D start_p, end_p; if(MiddlePoint(l3d1, start_p) == false || MiddlePoint(l3d2, end_p) == false){ cout<<"incorrect door "<DeleteIfAllowed(); door_tuple2->DeleteIfAllowed(); if(start_p.Distance(end_p) < dist_delta){////the same location Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// *l3d += start_p; ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); double cost_t = l3d->Length()/param.speed_person; timecost.push_back(cost_t); l3d->DeleteIfAllowed(); return; } priority_queue path_queue; vector expand_queue; vector visit_flag1;////////////door visit for(int i = 1; i <= node_rel->GetNoTuples();i++) visit_flag1.push_back(false); float max_speed = MAX(param.speed_person, param.speed_elevator); /////////// initialize the queue ////////////////////////////// int cur_size = expand_queue.size(); double w = 0; double hw = start_p.Distance(end_p) / max_speed; Line3D* l3d = new Line3D(0); IPath_elem elem(-1, cur_size, id1, w + hw, w, *l3d); path_queue.push(elem); expand_queue.push_back(elem); l3d->DeleteIfAllowed(); //////////////////////////////////////////////////////////////// ///////////////////the path belongs to an elevator////////////////////// vector h_list; //all possible values for(int i = 0;i <= 2*param.num_floors;i++){ h_list.push_back(param.floor_height + i*param.floor_height); } ////////////////////////////////////////////////////////////////// bool find = false; IPath_elem dest;//////////destination while(path_queue.empty() == false){ IPath_elem top = path_queue.top(); path_queue.pop(); if(visit_flag1[top.tri_index - 1])continue; if(prune_time > 0.0 && top.real_w > prune_time){ return; } if(top.tri_index == id2){ // cout<<"find the shortest path"<GetTuple(top.tri_index, false); /////////////////get the position of the door//////////////////////////// Point3D q; Line3D* door_loc = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); assert(MiddlePoint(door_loc, q)); door_tuple->DeleteIfAllowed(); if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(q.GetZ() - max_h > dist_delta || min_h - q.GetZ() > dist_delta){ continue; } } ////////find its adjacecy element, and push them into queue and path////// vector adj_list; ig->FindAdj(top.tri_index, adj_list); ///////////////////////////////////////////////////////////// int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ Tuple* edge_tuple = ig->GetEdgeRel()->GetTuple(adj_list[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_DOOR_TID2))->GetIntval(); Line3D* path = (Line3D*)edge_tuple->GetAttribute(IndoorGraph::I_PATH); int groom_oid = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_GROOM_OID))->GetIntval(); if(groom_oid > 0 && IsElevator(groom_oid, rel, btree)){ edge_tuple->DeleteIfAllowed(); continue; } if(visit_flag1[neighbor_id - 1]){ edge_tuple->DeleteIfAllowed(); continue; } if(groom_oid == start_groom_oid){ edge_tuple->DeleteIfAllowed(); continue; } Tuple* door_tuple1 = node_rel->GetTuple(neighbor_id, false); Line3D* l = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D p; assert(MiddlePoint(l, p));//get the point of next door door_tuple1->DeleteIfAllowed(); /////////////////////////////////////////// /////////////height limitation///////////// /////////////////////////////////////////// if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(p.GetZ() - max_h > dist_delta || min_h - p.GetZ() > dist_delta){ continue; } } int cur_size = expand_queue.size(); ////////////// set the weight ////////////////////////////////////// double w = top.real_w + SetTimeWeight(path->Length(), groom_oid, rel, btree, param); double hw = p.Distance(end_p) / max_speed; ////////////////////////////////////////////////////////////////////// IPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w, *path); path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////construct the result////////////////////////////// if(find){ double cost_t = dest.real_w; // cout<<"cost_t "< ps_list; while(dest.prev_index != -1){ if(dest.path.Size() > 0){ if(ps_list.size() == 0){ for(int i = dest.path.Size() - 1;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } }else{ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } } dest = expand_queue[dest.prev_index]; } if(dest.path.Size() > 0){ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// for(int i = ps_list.size() - 1;i >= 0; i--){ *l3d += ps_list[i]; } ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); l3d->DeleteIfAllowed(); if(l3d_s->Size() > 0) cost_t += l3d_s->Length() / param.speed_person; if(l3d_d->Size() > 0) cost_t += l3d_d->Length() / param.speed_person; timecost.push_back(cost_t); if(prune_time < 0.0) prune_time = cost_t; else if(cost_t < prune_time) prune_time = cost_t; } } /* check whether the room is an elevator */ bool IndoorNav::IsElevator(int groom_oid, Relation* rel, BTree* btree) { CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) == EL){//////////// an elevator return true; }else return false; } /* calculate the time cost of an edge: use the length of path and speed value */ float IndoorNav::SetTimeWeight(double l, int groom_oid, Relation* rel, BTree* btree, I_Parameter& param) { if(groom_oid == 0){/////////no real connection.two doors at the same lcoation return 0; } ///////////////find the room//////////////////////////////////////////// CcInt* search_id = new CcInt(true, groom_oid); BTreeIterator* btree_iter = btree->ExactMatch(search_id); int groom_tid = 0; while(btree_iter->Next()){ groom_tid = btree_iter->GetId(); break; } delete btree_iter; delete search_id; assert(1 <= groom_tid && groom_tid <= rel->GetNoTuples()); Tuple* groom_tuple = rel->GetTuple(groom_tid, false); string type = ((CcString*)groom_tuple->GetAttribute(I_Type))->GetValue(); groom_tuple->DeleteIfAllowed(); if(GetRoomEnum(type) != EL){////////////not an elevator return l/param.speed_person; }else if(GetRoomEnum(type) == EL){ return l/param.speed_elevator; } cout<<"should not visit here"<& candidate_path, Line3D* l3d_s, Line3D* l3d_d, vector& timecost, I_Parameter& param, Relation* rel, BTree* btree, double& prune_time, float min_h, float max_h, int start_groom_oid) { // cout<<"IndoorShortestPath_Time2 "<GetNodeRel(); Tuple* door_tuple1 = node_rel->GetTuple(id1, false); Tuple* door_tuple2 = node_rel->GetTuple(id2, false); Line3D* l3d1 = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Line3D* l3d2 = (Line3D*)door_tuple2->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D start_p, end_p; if(MiddlePoint(l3d1, start_p) == false || MiddlePoint(l3d2, end_p) == false){ cout<<"incorrect door "<DeleteIfAllowed(); door_tuple2->DeleteIfAllowed(); if(start_p.Distance(end_p) < dist_delta){////the same location Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// *l3d += start_p; ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); double cost_t = l3d->Length()/param.speed_person; timecost.push_back(cost_t); l3d->DeleteIfAllowed(); return; } priority_queue path_queue; vector expand_queue; vector visit_flag1;////////////door visit for(int i = 1; i <= node_rel->GetNoTuples();i++) visit_flag1.push_back(false); /////////// initialize the queue ////////////////////////////// int cur_size = expand_queue.size(); double w = 0; double hw = start_p.Distance(end_p); Line3D* l3d = new Line3D(0); IPath_elem elem(-1, cur_size, id1, w + hw, w, *l3d); path_queue.push(elem); expand_queue.push_back(elem); l3d->DeleteIfAllowed(); ////////////////////////////////////////////////////////////////// bool find = false; IPath_elem dest;//////////destination while(path_queue.empty() == false){ IPath_elem top = path_queue.top(); path_queue.pop(); if(visit_flag1[top.tri_index - 1])continue; if(prune_time > 0.0 && top.real_w > prune_time){ return; } if(top.tri_index == id2){ // cout<<"find the shortest path"<GetTuple(top.tri_index, false); /////////////////get the position of the door//////////////////////////// Point3D q; Line3D* door_loc = (Line3D*)door_tuple->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); assert(MiddlePoint(door_loc, q)); door_tuple->DeleteIfAllowed(); /////////////////////////////////////////// /////////////height limitation///////////// /////////////////////////////////////////// if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(q.GetZ() - max_h > dist_delta || min_h - q.GetZ() > dist_delta){ continue; } } ////////find its adjacecy element, and push them into queue and path////// vector adj_list; ig->FindAdj(top.tri_index, adj_list); ///////////////////////////////////////////////////////////// int pos_expand_path = top.cur_index; for(unsigned int i = 0;i < adj_list.size();i++){ Tuple* edge_tuple = ig->GetEdgeRel()->GetTuple(adj_list[i], false); int neighbor_id = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_DOOR_TID2))->GetIntval(); Line3D* path = (Line3D*)edge_tuple->GetAttribute(IndoorGraph::I_PATH); int groom_oid = ((CcInt*)edge_tuple->GetAttribute(IndoorGraph::I_GROOM_OID))->GetIntval(); if(visit_flag1[neighbor_id - 1]){ edge_tuple->DeleteIfAllowed(); continue; } if(groom_oid == start_groom_oid){ edge_tuple->DeleteIfAllowed(); continue; } Tuple* door_tuple1 = node_rel->GetTuple(neighbor_id, false); Line3D* l = (Line3D*)door_tuple1->GetAttribute(IndoorGraph::I_DOOR_LOC_3D); Point3D p; assert(MiddlePoint(l, p));//get the point of next door door_tuple1->DeleteIfAllowed(); /////////////////////////////////////////// /////////////height limitation///////////// /////////////////////////////////////////// if(fabs(min_h - max_h) > EPSDIST){//train station, different platforms if(p.GetZ() - max_h > dist_delta || min_h - p.GetZ() > dist_delta){ continue; } } int cur_size = expand_queue.size(); ////////////// set the weight ////////////////////////////////////// double w = top.real_w + SetTimeWeight(path->Length(), groom_oid, rel, btree, param); double hw = p.Distance(end_p); ////////////////////////////////////////////////////////////////////// IPath_elem elem(pos_expand_path, cur_size, neighbor_id, w + hw, w, *path, groom_oid); path_queue.push(elem); expand_queue.push_back(elem); edge_tuple->DeleteIfAllowed(); } visit_flag1[top.tri_index - 1] = true; } ////////////////construct the result////////////////////////////// if(find){ double cost_t = 0; // cout<<"cost_t "< ps_list; double elevator_length = 0; while(dest.prev_index != -1){ if(dest.path.Size() > 0){ int groom_oid = dest.groom_oid; ///////////////////if the path belongs to lift////////////////// if(groom_oid > 0 && IsElevator(groom_oid, rel, btree)) elevator_length += dest.path.Length(); if(ps_list.size() == 0){ for(int i = dest.path.Size() - 1;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } }else{ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } } dest = expand_queue[dest.prev_index]; } if(dest.path.Size() > 0){ for(int i = dest.path.Size() - 2;i >= 0;i--){ Point3D q; dest.path.Get(i, q); ps_list.push_back(q); } } Line3D* l3d = new Line3D(0); l3d->StartBulkLoad(); //////////////////connect to the start point//////////////////// for(int i = 0;i < l3d_s->Size() - 1;i++){ Point3D q; l3d_s->Get(i, q); *l3d += q; } /////////////////////////////////////////////////////////////// for(int i = ps_list.size() - 1;i >= 0; i--){ *l3d += ps_list[i]; } ////////////////////connect to the end point///////////////////// for(int i = 1;i < l3d_d->Size();i++){ Point3D q; l3d_d->Get(i, q); *l3d += q; } l3d->EndBulkLoad(); candidate_path.push_back(*l3d); if(elevator_length > 0.0){ cost_t = (l3d->Length() - elevator_length) / param.speed_person; cost_t += CostInElevator( elevator_length, param); }else cost_t = l3d->Length() / param.speed_person; l3d->DeleteIfAllowed(); timecost.push_back(cost_t); if(prune_time < 0.0) prune_time = cost_t; else if(cost_t < prune_time) prune_time = cost_t; } } /* the uncertain cost value on an elevator: let l be absolute length of two floors and h be the distance between two consecutive floors, there are n floors. the distribution is: l, l+h, l+2h, l+3h, ...l+2nh */ float IndoorNav::CostInElevator(double l, I_Parameter& param) { vector h_list; //all possible values for(int i = 0;i <= 2*param.num_floors;i++){ h_list.push_back(l + i*param.floor_height); } const int size = h_list.size(); int index = GetRandom() % size; return h_list[index]/param.speed_elevator; } //////////////////////////////////////////////////////////////////////// /////////////temporal unit: UPoint3D /////////////////////////////////// /////////////////////////////////////////////////////////////////////// /* interporlation function for the location */ void UPoint3D::TemporalFunction( const Instant& t, Point3D& result, bool ignoreLimits ) const { if( !IsDefined() || !t.IsDefined() || (!timeInterval.Contains( t ) && !ignoreLimits) ) { result.SetDefined(false); } else if( t == timeInterval.start ) { result = p0; result.SetDefined(true); } else if( t == timeInterval.end ) { result = p1; result.SetDefined(true); } else { Instant t0 = timeInterval.start; Instant t1 = timeInterval.end; double x = (p1.GetX() - p0.GetX()) * ((t - t0) / (t1 - t0)) + p0.GetX(); double y = (p1.GetY() - p0.GetY()) * ((t - t0) / (t1 - t0)) + p0.GetY(); double z = (p1.GetZ() - p0.GetZ()) * ((t - t0) / (t1 - t0)) + p0.GetZ(); Point3D p(true, x, y, z); result = p; } } /* check whether a location is visited */ bool UPoint3D::Passes( const Point3D& gloc ) const { return false; } /* restrict the movement at a location */ bool UPoint3D::At( const Point3D& loc, TemporalUnit& res ) const { return false; } UPoint3D* UPoint3D::Clone() const { UPoint3D* res; if(this->IsDefined()){ res = new UPoint3D(timeInterval, p0, p1); res->del.isDefined = del.isDefined; }else{ res = new UPoint3D(false); } return res; } void UPoint3D::CopyFrom(const Attribute* right) { const UPoint3D* loc = static_cast(right); if(loc->del.isDefined){ timeInterval.CopyFrom(loc->timeInterval); p0 = loc->p0; p1 = loc->p1; } del.isDefined = loc->del.isDefined; } const Rectangle<4> UPoint3D::BoundingBox(const Geoid* geoid) const { if(this->IsDefined()){ double minMax[] = {MIN(p0.GetX(), p1.GetX()), MAX(p0.GetX(), p1.GetX()), MIN(p0.GetY(), p1.GetY()), MAX(p0.GetY(), p1.GetY()), MIN(p0.GetZ(), p1.GetZ()), MAX(p0.GetZ(), p1.GetZ()), timeInterval.start.ToDouble(), timeInterval.end.ToDouble()}; return Rectangle<4>(true,minMax ); }else return Rectangle<4>(false); } ListExpr UPoint3DProperty() { 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("-> DATA"), nl->StringAtom("upoint3d"), nl->StringAtom("()"), nl->StringAtom("((interval (1.0 12.0 3.0)))")))); } /* Output (interval, p0, p1) */ ListExpr OutUPoint3D( ListExpr typeInfo, Word value ) { // cout<<"OutUPoint3D"<IsDefined()){ return nl->SymbolAtom("undef"); } if( loc->IsEmpty() ){ return nl->TheEmptyList(); } ListExpr timeintervalList = nl->FourElemList( OutDateTime( nl->TheEmptyList(), SetWord(&loc->timeInterval.start) ), OutDateTime( nl->TheEmptyList(), SetWord(&loc->timeInterval.end) ), nl->BoolAtom( loc->timeInterval.lc ), nl->BoolAtom( loc->timeInterval.rc)); ListExpr loc1 = OutPoint3D(nl->TheEmptyList(), &(loc->p0)); ListExpr loc2 = OutPoint3D(nl->TheEmptyList(), &(loc->p1)); return nl->ThreeElemList(timeintervalList,loc1,loc2); } /* In function */ Word InUPoint3D( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { string errmsg; if ( nl->ListLength( instance ) == 3 ){ 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 ){ correct = true; Instant *start = (Instant *)InInstant( nl->TheEmptyList(), nl->First( first ), errorPos, errorInfo, correct ).addr; if( !correct || !start->IsDefined() ){ errmsg = "InUPoint3D(): first instant must be defined!."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; return SetWord( Address(0) ); } Instant *end = (Instant *)InInstant( nl->TheEmptyList(), nl->Second( first ), errorPos, errorInfo, correct ).addr; if( !correct || !end->IsDefined() ) { errmsg = "InUPoint3D(): second instant must be defined!."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete start; delete end; return SetWord( Address(0) ); } Interval tinterval( *start, *end, nl->BoolValue( nl->Third( first ) ), nl->BoolValue( nl->Fourth( first ) ) ); delete start; delete end; correct = tinterval.IsValid(); if (!correct) { errmsg = "InUPoint3D(): Non valid time interval."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } ////////////////////////////////////////////////////////////////// ListExpr second = nl->Second( instance ); if(nl->ListLength(second) != 3){ errmsg = "InUPoint3D(): three parameters for Point3D."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } bool loc1_correct; Point3D* loc1 = (Point3D*)InPoint3D(typeInfo, second, errorPos,errorInfo, loc1_correct).addr; if(loc1_correct == false){ errmsg = "InUPoint3D(): Non correct first location."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } ///////////////////////////////////////////////////////////////////// ListExpr third = nl->Third(instance); if(nl->ListLength(third) != 3){ errmsg = "InUPoint3D(): three parameters for Point3D."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } bool loc2_correct; Point3D* loc2 = (Point3D*)InPoint3D(typeInfo, third, errorPos,errorInfo, loc2_correct).addr; if(loc2_correct == false){ errmsg = "InUPoint3D(): Non correct second location."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); return SetWord( Address(0) ); } ///////////////////////////////////////////////////////////////////// // cout<IsValid(); if( correct ) return SetWord( up ); errmsg = "InUPoint3D(): Error in start/end point."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); delete up; } }else if ( nl->IsAtom( instance ) && nl->AtomType( instance ) == SymbolType && nl->SymbolValue( instance ) == "undef" ){ UPoint3D *loc = new UPoint3D(false); loc->timeInterval= Interval(DateTime(instanttype), DateTime(instanttype),true,true); correct = loc->timeInterval.IsValid(); if ( correct ) return (SetWord( loc )); } errmsg = "InUPoint3D(): Error in representation."; errorInfo = nl->Append(errorInfo, nl->StringAtom(errmsg)); correct = false; return SetWord( Address(0) ); } /* Open a UPoint3D object */ bool OpenUPoint3D(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { // cout<<"OpenUPoint3D()"<DeleteIfAllowed(); w.addr = 0; } Word CloneUPoint3D( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneUPoint3D"<IsEqual( type, "upoint3d" )); } ////////////////////////////////////////////////////////////////// ////////// MPoinr3D ///////////////////////////////////////////// ////////////////////////////////////////////////////////////////// ListExpr MPoint3DProperty() { 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("-> MAPPING"), nl->StringAtom("mpoint3d"), nl->StringAtom("(u1,...,un)"), nl->StringAtom("((interval (1 10.0 1.0)(1 12.0 3.0)))")))); } bool CheckMPoint3D( ListExpr type, ListExpr& errorInfo ) { // cout<<"CheckMPoint3D"<IsEqual( type, "mpoint3d" )); } void MPoint3D::Clear() { Mapping::Clear(); } /* copy it from another data */ void MPoint3D::CopyFrom(const Attribute* right) { const MPoint3D *mo = (const MPoint3D*)right; assert( mo->IsOrdered() ); Clear(); this->SetDefined(mo->IsDefined()); if( !this->IsDefined() ) { return; } StartBulkLoad(); UPoint3D unit; for( int i = 0; i < mo->GetNoComponents(); i++ ){ mo->Get( i, unit ); Add( unit ); } EndBulkLoad( false ); } Attribute* MPoint3D::Clone() const { assert( IsOrdered() ); MPoint3D* result; if( !this->IsDefined() ){ result = new MPoint3D( 0 ); } else { result = new MPoint3D( GetNoComponents() ); if(GetNoComponents()>0){ result->units.resize(GetNoComponents()); } result->StartBulkLoad(); UPoint3D unit; for( int i = 0; i < GetNoComponents(); i++ ){ Get( i, unit ); result->Add( unit ); } result->EndBulkLoad( false ); } result->SetDefined(this->IsDefined()); return (Attribute*) result; } /* put new unit. it only inserts the new unit and does not calculate the bounding box. */ void MPoint3D::Add(const UPoint3D& unit) { assert(unit.IsDefined()); assert(unit.IsValid()); if(!IsDefined()){ SetDefined(false); return; } units.Append(unit); } bool MPoint3D::EndBulkLoad(const bool sort, const bool checkvalid) { return Mapping::EndBulkLoad(sort, checkvalid); } /* 3d line representing the trajectory of indoor moving objects */ void MPoint3D::Trajectory(Line3D& l) { l.Clear(); l.StartBulkLoad(); for(int i = 0;i < GetNoComponents();i++){ UPoint3D unit; Get(i, unit); l += unit.p0; if(i == GetNoComponents() - 1) l+= unit.p1; } l.EndBulkLoad(); } /////////////////////////////////////////////////////////////////////////// //////////////////////Building//////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// string Building::RoomBTreeTypeInfo = "(rel (tuple ((oid int) (Name string) \ (Type string) (Room groom) (Door line))) int)"; string Building::Indoor_GRoom_Door_Extend = "(rel (tuple ((Oid int) \ (Name string) (Type string) (Room groom) (Door line) (TID tid) (BBox rect3))))"; string Building::RoomRTreeTypeInfo = "(rel (tuple ((oid int) (Name string)\ (Type string) (Room groom) (Door line) (TID tid) (BBox rect3))) rect3 FALSE)"; ListExpr BuildingProperty() { 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("-> DATA"), nl->StringAtom("building"), nl->StringAtom("((def, id))"), nl->StringAtom("((TRUE 1))")))); } void* Building::Cast(void* addr) { return NULL; } int SizeOfBuilding() { // cout<<"SizeOfBuilding"<IsEqual( type, "building" )); } void CloseBuilding( const ListExpr typeInfo, Word& w ) { // cout<<"CloseBuilding"<(w.addr); w.addr = 0; } Word CloneBuilding( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneBuilding"<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 3){ cout<<"length should be 3"<First(instance); ListExpr second = nl->Second(instance); ListExpr third = nl->Third(instance); if(!nl->IsAtom(first) || nl->AtomType(first) != BoolType){ cout<< "building(): definition must be bool type"<BoolValue(first); if(!nl->IsAtom(second) || nl->AtomType(second) != IntType){ cout<< "building(): building id must be int type"<IntValue(second); if(!nl->IsAtom(third) || nl->AtomType(third) != StringType){ cout<< "building(): building type must be string type"<StringValue(third); Building* building = new Building(d, id, GetBuildingType(type)); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// return SetWord(building); } correct = false; return SetWord(Address(0)); } /* output the building */ ListExpr OutBuilding( ListExpr typeInfo, Word value ) { // cout<<"OutBuilding"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList( nl->StringAtom("Building Id:"), nl->IntAtom(build->GetId())); ListExpr list2 = nl->TheEmptyList(); list2 = nl->TwoElemList( nl->StringAtom("Building Type :"), nl->StringAtom(GetBuildingStr(build->GetType()))); ListExpr list3 = nl->TheEmptyList(); if(build->IsIGInit()){ list3 = nl->TwoElemList( nl->StringAtom("Indoor Graph Id:"), nl->IntAtom(build->GetIGId())); }else list3 = nl->OneElemList( nl->StringAtom("Indoor Graph undef")); ListExpr list4 = nl->TheEmptyList(); return nl->FourElemList(list1, list2, list3, list4); } bool SaveBuilding(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { Building* build = (Building*)value.addr; return build->Save(valueRecord, offset, typeInfo); } bool OpenBuilding(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { value.addr = Building::Open(valueRecord, offset, typeInfo); return value.addr != NULL; } Building::Building():def(false), building_id(0), building_type(-1), indoorgraph_init(false), indoorgraph_id(0), rel_rooms(NULL), btree_room(NULL), rtree_rel_box(NULL) { // cout<<"default constructor"<ReadFromString(IndoorNav::Indoor_GRoom_Door,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); rel_rooms = Relation::Open(valueRecord, offset, xNumericType); if(!rel_rooms) { return; } nl->ReadFromString(RoomBTreeTypeInfo,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_room = BTree::Open(valueRecord, offset, xNumericType); if(!btree_room) { rel_rooms->Delete(); return; } ///////////////////rtree on bus stops ////////////////////////////// Word xValue; if(!(rtree_rel_box->Open(valueRecord,offset, RoomRTreeTypeInfo,xValue))){ rel_rooms->Delete(); delete btree_room; return; } rtree_rel_box = ( R_Tree<3,TupleId>* ) xValue.addr; // cout<<"rtree root node id "<RootRecordId()<Close(); if(btree_room != NULL) delete btree_room; if(rtree_rel_box != NULL) delete rtree_rel_box; } bool Building::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { valueRecord.Write(&def, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Write(&building_id, sizeof(int), offset); offset += sizeof(int); valueRecord.Write(&building_type, sizeof(unsigned int), offset); offset += sizeof(unsigned int); valueRecord.Write(&indoorgraph_init, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Write(&indoorgraph_id, sizeof(unsigned int), offset); offset += sizeof(unsigned int); ListExpr xType; ListExpr xNumericType; ////////////////////rooms relation///////////////////////////// nl->ReadFromString(IndoorNav::Indoor_GRoom_Door, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!rel_rooms->Save(valueRecord,offset,xNumericType)) return false; ////////////////////btree on rooms relation///////////////////////////// nl->ReadFromString(RoomBTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_room->Save(valueRecord, offset, xNumericType)) return false; ////////////////////rtree on rooms relation//////////////////////////// if(!rtree_rel_box->Save(valueRecord, offset)){ return false; } return true; } void Building::SetIndoorGraphId(int gid) { if(gid > 0){ indoorgraph_id = gid; indoorgraph_init = true; StorePaths(); }else{ cout<<"invalid indoor graph id "< 0){ cout<<"paths file already exists"< doorloc_list; vector door_tid_list; IndoorNav* indoornav = new IndoorNav(rel_rooms, NULL); indoornav->ig = ig; indoornav->GetDoorLoc(ig, btree_room, doorloc_list, door_tid_list); // cout<<"number of entrances "<= MAX_ENTRANCE){ cout<<"error: assume the number is less than "<GetNoTuples() >= MAX_ROOM_NO){ cout<<"error:assume the number is less than "<GetTuple(door_gloc.GetOid(), false); GRoom* door_groom = (GRoom*)door_room_tuple->GetAttribute(IndoorNav::I_Room); float low_h1 = door_groom->GetLowHeight(); float high_h1 = door_groom->GetHighHeight(); float min_h1 = MIN(low_h1, high_h1); float max_h1 = MAX(low_h1, high_h1); for(int j = 1; j <= rel_rooms->GetNoTuples();j++){ Tuple* room_tuple = rel_rooms->GetTuple(j, false); int groom_oid = ((CcInt*)room_tuple->GetAttribute(IndoorNav::I_OID))->GetIntval(); string groom_type = ((CcString*)room_tuple->GetAttribute(IndoorNav::I_Type))->GetValue(); if(groom_oid == (int)door_gloc.GetOid()){ room_tuple->DeleteIfAllowed(); continue; } if((GetRoomEnum(groom_type) == ST || GetRoomEnum(groom_type) == EL)){ room_tuple->DeleteIfAllowed(); continue; } GRoom* groom = (GRoom*)room_tuple->GetAttribute(IndoorNav::I_Room); float low_h2 = groom->GetLowHeight(); float high_h2 = groom->GetHighHeight(); float min_h2 = MIN(low_h2, high_h2); float max_h2 = MAX(low_h2, high_h2); //////////////////////////////////////////////////////////////// ////////////////find all doors of this room//////////////////// /////////////////////////////////////////////////////////////// float min_h = MIN(min_h1, min_h2); float max_h = MAX(max_h1, max_h2); vector doors_list; ig->GetDoorsInGRoom(groom_oid, doors_list); if(doors_list.size() >= MAX_DOOR_INROOM){ room_tuple->DeleteIfAllowed(); continue; } Line3D* l3d_s = new Line3D(0); Line3D* l3d_e = new Line3D(0); double prune_dist = -1.0; for(unsigned int k = 0;k < doors_list.size();k++){ //!!! use -1, 0 is used already for entrance door///////// /////////////from entrance to rooms/////////////////////////// vector from_path_list; indoornav->IndoorShortestPath(door_tid_list[i], doors_list[k], from_path_list, l3d_s, l3d_e, prune_dist, min_h, max_h, -1); prune_dist = -1.0; WritePathToFile(fp, &from_path_list[0], i + 1, groom_oid, k, true); /////////from rooms to entrance////////////////////// vector to_path_list; indoornav->IndoorShortestPath(doors_list[k], door_tid_list[i], to_path_list, l3d_s, l3d_e, prune_dist, min_h, max_h, -1); prune_dist = -1.0; WritePathToFile(fp, &to_path_list[0], i + 1, groom_oid, k, false); } l3d_s->DeleteIfAllowed(); l3d_e->DeleteIfAllowed(); room_tuple->DeleteIfAllowed(); sum_paths += doors_list.size()*2; // break; } door_room_tuple->DeleteIfAllowed(); } delete indoornav; CloseIndoorGraph(ig); // cout<<"total paths "< oid_num(8,0); oid_num[0] = entrance; if(from) oid_num[7] = 1; else oid_num[7] = 0; unsigned int index = 4; int num1 = groom_oid; while(index > 0){ oid_num[index] = num1%10; index--; num1 = num1/10; if(num1 == 0) break; } num1 = door_num; index = 6; while(index > 4){ oid_num[index] = num1%10; index--; num1 = num1/10; if(num1 == 0) break; } /* cout<<"entrance id "< 0) // path_oid += oid_num[l]*pow(10, expo); path_oid += oid_num[l]*pow((double)10, expo); else path_oid += oid_num[l]; } // cout<<" path_oid "<Size()); for(int i = 0;i < path->Size();i++){ Point3D q; path->Get(i, q); // fprintf(fp, "%f %f %f\n", q.GetX(), q.GetY(), q.GetZ()); fprintf(fp, "%f %f %f ", q.GetX(), q.GetY(), q.GetZ()); /////////////////////////////////////////////////////////////////////// //use rtree rel box in Building to find all groom containing the point// //////////////////////////////////////////////////////////////////////// vector groom_tid_list; DFTraverse(rtree_rel_box->RootRecordId(), q, groom_tid_list); const unsigned int max_groom = 3; const unsigned int min_groom = 1; if(groom_tid_list.size() > max_groom ||groom_tid_list.size() < min_groom){ cout<<"this should not occur"<& tid_list) { R_TreeNode<3,TupleId>* node = rtree_rel_box->GetMyNode(adr,false, rtree_rel_box->MinEntries(0), rtree_rel_box->MaxEntries(0)); for(int j = 0;j < node->EntryCount();j++){ if(node->IsLeaf()){ R_TreeLeafEntry<3,TupleId> e = (R_TreeLeafEntry<3,TupleId>&)(*node)[j]; Tuple* groom_tuple = rel_rooms->GetTuple(e.info,false); GRoom* groom = (GRoom*)groom_tuple->GetAttribute(IndoorNav::I_Room); Rectangle<3> groom_box = groom->BoundingBox3D(); if(BBoxContainPoint3D(groom_box, p)){ Region r(0); groom->GetRegion(r); Point q(true, p.GetX(), p.GetY()); if(q.Inside(r)){ tid_list.push_back(e.info); /* int oid = ((CcInt*)groom_tuple->GetAttribute(IndoorNav::I_OID))->GetIntval(); oid_list.push_back(oid);*/ } } groom_tuple->DeleteIfAllowed(); }else{ R_TreeInternalEntry<3> e = (R_TreeInternalEntry<3>&)(*node)[j]; if(BBoxContainPoint3D(e.box, p)){ DFTraverse(e.pointer, p, tid_list); } } } delete node; } /* read the path from disk file */ void ReadIndoorPath(string name, int path_oid, Line3D* l3d_res) { // cout<<"building "< path_list;//////implemented by a binary tree while (!feof(fp)){ int path_id, no; if(fscanf(fp, "%d %d", &path_id, &no) < 0){ // cout<<"read path error1"<StartBulkLoad(); float x, y, z; float temp_x, temp_y, temp_z; for(int i = 0;i < no;i++){ int res = fscanf(fp, "%f %f %f %f %f %f", &x, &y, &z, &temp_x, &temp_y, &temp_z); if(res > 0){ Point3D q(true, x, y, z); *l3d += q; } } l3d->EndBulkLoad(); assert(l3d->Length() > 0.0); // IndoorPath i_path(path_id, *l3d); // path_list.push_back(i_path); path_list.insert(pair(path_id, *l3d)); l3d->DeleteIfAllowed(); } fclose(fp); // sort(path_list.begin(), path_list.end()); map::iterator iter = path_list.find(path_oid); if(iter != path_list.end()){ *l3d_res = iter->second; }else{ cout<<" path "< oid_num(8,0); oid_num[0] = entrance; if(b) oid_num[7] = 1; else oid_num[7] = 0; unsigned int index = 4; int num1 = groom_oid; while(index > 0){ oid_num[index] = num1%10; index--; num1 = num1/10; if(num1 == 0) break; } int path_oid = 0; for(unsigned int l = 0;l < oid_num.size();l++){ int expo = oid_num.size() - 1 - l; if(expo > 0) // path_oid += oid_num[l]*pow(10, expo); path_oid += oid_num[l]*pow((double)10, expo); else path_oid += oid_num[l]; } return path_oid; } int GetIndooPathID2(int entrance, int groom_oid, int door_num, bool b) { vector oid_num(8,0); oid_num[0] = entrance; if(b) oid_num[7] = 1; else oid_num[7] = 0; unsigned int index = 4; int num1 = groom_oid; while(index > 0){ oid_num[index] = num1%10; index--; num1 = num1/10; if(num1 == 0) break; } num1 = door_num; index = 6; while(index > 4){ oid_num[index] = num1%10; index--; num1 = num1/10; if(num1 == 0) break; } int path_oid = 0; for(unsigned int l = 0;l < oid_num.size();l++){ int expo = oid_num.size() - 1 - l; if(expo > 0) // path_oid += oid_num[l]*pow(10, expo); path_oid += oid_num[l]*pow((double)10, expo); else path_oid += oid_num[l]; } return path_oid; } /* load paths from disk file */ void Building::LoadPaths(map& path_list, map& room_id_list) { string name = GetBuildingStr(building_type); string path_str = IndoorPathPrefix + name + IndoorPathSuffix; FILE *fp = fopen(path_str.c_str(), "r"); if(fp == NULL){ cout<StartBulkLoad(); room_id->StartBulkLoad(); float x, y, z; float temp_x, temp_y, temp_z; for(int i = 0;i < no;i++){ int res = fscanf(fp, "%f %f %f %f %f %f", &x, &y, &z, &temp_x, &temp_y, &temp_z); if(res > 0){ Point3D q(true, x, y, z); *l3d += q; Point3D p(true, temp_x, temp_y, temp_z); *room_id += p; } } l3d->EndBulkLoad(); room_id->EndBulkLoad(); assert(l3d->Length() > 0.0); assert(l3d->Size() == room_id->Size()); // IndoorPath i_path(path_id, *l3d); // path_list.push_back(i_path); path_list.insert(pair(path_id, *l3d)); room_id_list.insert(pair(path_id, *room_id)); l3d->DeleteIfAllowed(); delete room_id; } fclose(fp); // cout<= 0){ building_type = type; def = true; }else{ def = true; } // cout<GetNoTuples()<<" rooms "<ToString(ptrList1) + "))))"; // cout<ToString(ptrList2) + "))" + "Oid)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); btree_room = (BTree*)xResult.addr; ListExpr ptrList3 = listutils::getPtrList(rel2); strQuery = "(bulkloadrtree(feed (" + Indoor_GRoom_Door_Extend + " (ptr " + nl->ToString(ptrList3) + "))) BBox)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); rtree_rel_box = ( R_Tree<3,TupleId>* ) xResult.addr; } IndoorGraph* Building::OpenIndoorGraph() { if(indoorgraph_init == false) return NULL; ListExpr xObjectList = SecondoSystem::GetCatalog()->ListObjects(); xObjectList = nl->Rest(xObjectList); while(!nl->IsEmpty(xObjectList)){ // Next element in list ListExpr xCurrent = nl->First(xObjectList); xObjectList = nl->Rest(xObjectList); // Type of object is at fourth position in list ListExpr xObjectType = nl->First(nl->Fourth(xCurrent)); if(nl->IsAtom(xObjectType) && nl->SymbolValue(xObjectType) == "indoorgraph"){ // Get name of the bus graph ListExpr xObjectName = nl->Second(xCurrent); string strObjectName = nl->SymbolValue(xObjectName); // Load object to find out the id of the pavement Word xValue; bool bDefined; bool bOk = SecondoSystem::GetCatalog()->GetObject(strObjectName, xValue, bDefined); if(!bDefined || !bOk){ // Undefined continue; } IndoorGraph* ig = (IndoorGraph*)xValue.addr; if(ig->g_id == indoorgraph_id && ig->GetGraphType() == (int)building_type){ // This is the indoor graph we have been looking for return ig; }else{ SecondoSystem::GetCatalog()->CloseObject(nl->SymbolAtom("indoorgraph"), xValue); } } } return NULL; } void Building::CloseIndoorGraph(IndoorGraph* ig) { if(ig == NULL) return; Word xValue; xValue.addr = ig; SecondoSystem::GetCatalog()->CloseObject(nl->SymbolAtom( "indoorgraph" ), xValue); } /////////////////////////////////////////////////////////////////////// /////////// Indoor Building Infrastructure///////////////////////////// /////////////////////////////////////////////////////////////////////// string IndoorInfra::BuildingPath_Info = "(rel (tuple ((Reg_id int) (Sp point)\ (Sp_index int) (Ep point) (Ep2 point) (Ep2_gloc genloc) (Path line))))"; string IndoorInfra::RegId1BTreeTypeInfo = "(rel (tuple ((Reg_id int)(Sp point)\ (Sp_index int) (Ep point) (Ep2 point) (Ep2_gloc genloc) (Path line))) int)"; string IndoorInfra::BuildingType_Info = "(rel (tuple ((Reg_id int)\ (GeoData rect) (Poly_id int) (Reg_type int) (Building_type int)\ (Building_type2 string) (Building_id int))))"; string IndoorInfra::RegId2BTreeTypeInfo = "(rel (tuple ((Reg_id int) \ (GeoData rect) (Poly_id int) (Reg_type int) (Building_type int) \ (Building_type2 string) (Building_id int))) int)"; string IndoorInfra::BuildingTypeRtreeInfo = "(rtree (tuple ((Reg_id int)\ (GeoData rect) (Poly_id int) (Reg_type int) (Building_type int)\ (Building_type2 string) (Building_id int))) rect FALSE)"; ListExpr IndoorInfraProperty() { 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("-> DATA"), nl->StringAtom("indoorinfra"), nl->StringAtom("((def, id))"), nl->StringAtom("((TRUE 1))")))); } /* In function. there is not nested list expression here. */ Word InIndoorInfra( const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct ) { // cout<<"length "<ListLength(instance)<IsAtom( instance ) ){ if(nl->ListLength(instance) != 2){ cout<<"length should be 2"<First(instance); ListExpr second = nl->Second(instance); if(!nl->IsAtom(first) || nl->AtomType(first) != BoolType){ cout<< "indoorinfra(): definition must be bool type"<BoolValue(first); if(!nl->IsAtom(second) || nl->AtomType(second) != IntType){ cout<< "indoorinfra(): building id must be int type"<IntValue(second); IndoorInfra* indoor = new IndoorInfra(d, id); ////////////////very important ///////////////////////////// correct = true; /////////////////////////////////////////////////////////// return SetWord(indoor); } correct = false; return SetWord(Address(0)); } /* output the indoorinfra */ ListExpr OutIndoorInfra( ListExpr typeInfo, Word value ) { // cout<<"OutIndoorInfra"<IsDefined()){ return nl->SymbolAtom("undef"); } ListExpr list1 = nl->TwoElemList( nl->StringAtom("IndoorInfra Id:"), nl->IntAtom(indoor->GetId())); ListExpr list2 = nl->TheEmptyList(); return nl->TwoElemList(list1, list2); } bool OpenIndoorInfra(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { value.addr = IndoorInfra::Open(valueRecord, offset, typeInfo); return value.addr != NULL; } bool SaveIndoorInfra(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo, Word& value) { IndoorInfra* indoor = (IndoorInfra*)value.addr; return indoor->Save(valueRecord, offset, typeInfo); } Word CreateIndoorInfra(const ListExpr typeInfo) { // cout<<"CreateIndoorInfra()"<(w.addr); w.addr = 0; } Word CloneIndoorInfra( const ListExpr typeInfo, const Word& w ) { // cout<<"CloneIndoorInfra"<IsEqual( type, "indoorinfra" )); } IndoorInfra::IndoorInfra():def(false),indoor_id(0), digit_build_id(0), building_path(NULL), btree_reg_id1(NULL), building_type(NULL), btree_reg_id2(NULL), rtree_building(NULL) { } IndoorInfra::IndoorInfra(bool b, int id):def(b),indoor_id(id),digit_build_id(0), building_path(NULL), btree_reg_id1(NULL), building_type(NULL), btree_reg_id2(NULL), rtree_building(NULL) { } IndoorInfra::IndoorInfra(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo):def(false), indoor_id(0), digit_build_id(0), building_path(NULL), btree_reg_id1(NULL), building_type(NULL), btree_reg_id2(NULL), rtree_building(NULL) { valueRecord.Read(&def, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Read(&indoor_id, sizeof(int), offset); offset += sizeof(int); valueRecord.Read(&digit_build_id, sizeof(int), offset); offset += sizeof(int); ListExpr xType; ListExpr xNumericType; /**************Open relation for buildings with paths*******************/ nl->ReadFromString(BuildingPath_Info, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); building_path = Relation::Open(valueRecord, offset, xNumericType); if(!building_path) { return; } // cout<<"open "<GetNoTuples()<ReadFromString(RegId1BTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_reg_id1 = BTree::Open(valueRecord, offset, xNumericType); if(!btree_reg_id1) { building_path->Delete(); return; } nl->ReadFromString(BuildingType_Info,xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); building_type = Relation::Open(valueRecord, offset, xNumericType); if(!building_type) { building_path->Delete(); delete btree_reg_id1; return; } ///////////////////btree on relation for buildings with paths////////////// nl->ReadFromString(RegId2BTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); btree_reg_id2 = BTree::Open(valueRecord, offset, xNumericType); if(!btree_reg_id2) { building_path->Delete(); delete btree_reg_id1; building_type->Delete(); return; } ///////////////////rtree on building rectangles////////////////////////////// Word xValue; if(!(rtree_building->Open(valueRecord,offset, BuildingTypeRtreeInfo,xValue))){ building_path->Delete(); delete btree_reg_id1; building_type->Delete(); delete btree_reg_id2; return; } rtree_building = ( R_Tree<2,TupleId>* ) xValue.addr; // cout<<"open "<GetNoTuples()<Close(); if(btree_reg_id1 != NULL) delete btree_reg_id1; if(building_type != NULL) building_type->Close(); if(btree_reg_id2 != NULL) delete btree_reg_id2; if(rtree_building != NULL) delete rtree_building; } IndoorInfra* IndoorInfra::Open(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { return new IndoorInfra(valueRecord, offset, typeInfo); } bool IndoorInfra::Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo) { valueRecord.Write(&def, sizeof(bool), offset); offset += sizeof(bool); valueRecord.Write(&indoor_id, sizeof(int), offset); offset += sizeof(int); valueRecord.Write(&digit_build_id, sizeof(int), offset); offset += sizeof(int); ListExpr xType; ListExpr xNumericType; ////////////////////building with paths relation/////////////////////////// nl->ReadFromString(BuildingPath_Info, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!building_path->Save(valueRecord,offset,xNumericType)) return false; ///////////////btree on relation for buildings with paths//////////////// nl->ReadFromString(RegId1BTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_reg_id1->Save(valueRecord, offset, xNumericType)) return false; ////////////////////building with types relation/////////////////////////// nl->ReadFromString(BuildingType_Info, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!building_type->Save(valueRecord,offset,xNumericType)) return false; ///////////////btree on relation for buildings with types//////////////// nl->ReadFromString(RegId2BTreeTypeInfo, xType); xNumericType = SecondoSystem::GetCatalog()->NumericType(xType); if(!btree_reg_id2->Save(valueRecord, offset, xNumericType)) return false; ///////////////////////rtree on building rectangles /////////////////////// if(!rtree_building->Save(valueRecord, offset)){ return false; } return true; } /* load relations for indoor infrastructure */ void IndoorInfra::Load(int id, Relation* rel1, Relation* rel2) { // cout<GetNoTuples()<GetNoTuples()<ToString(ptrList1) + "))))"; // cout<ToString(ptrList2) + "))" + "Reg_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); btree_reg_id1 = (BTree*)xResult.addr; ////////////////building relation with types/////////////////////////////// ListExpr ptrList3 = listutils::getPtrList(rel2); strQuery = "(consume(feed(" + BuildingType_Info + "(ptr " + nl->ToString(ptrList3) + "))))"; // cout<ToString(ptrList4) + "))" + "Reg_id)"; QueryExecuted = QueryProcessor::ExecuteQuery(strQuery, xResult); assert(QueryExecuted); btree_reg_id2 = (BTree*)xResult.addr; int min_id = numeric_limits::max(); int max_id = numeric_limits::min(); for(int i = 1;i <= rel2->GetNoTuples();i++){ Tuple* tuple = rel2->GetTuple(i, false); int build_id = ((CcInt*)tuple->GetAttribute(INDOORIF_BUILD_ID))->GetIntval(); if(build_id < min_id) min_id = build_id; if(build_id > max_id) max_id = build_id; tuple->DeleteIfAllowed(); } char buf1[64], buf2[64]; sprintf(buf1, "%d", min_id); sprintf(buf2, "%d", max_id); assert(strlen(buf1) == strlen(buf2)); //////////record how many numbers are used to recored building id////////// digit_build_id = strlen(buf1); ////////////////////////////////////////////////// /////////////////building rtree ///////////////// ///////////////////////////////////////////////// ListExpr ptrList5 = listutils::getPtrList(building_type); strQuery = "(bulkloadrtree(addid(feed (" + BuildingType_Info + " (ptr " + nl->ToString(ptrList5) + ")))) GeoData)"; QueryExecuted = QueryProcessor::ExecuteQuery ( strQuery, xResult ); assert ( QueryExecuted ); rtree_building = ( R_Tree<2,TupleId>* ) xResult.addr; } /* given a reg id, it finds the corresponding tuples in path relation and returns the tuple id for the path relation the path relation stores the path from building entrance to the pavement area */ void IndoorInfra::GetPathIDFromTypeID(int reg_id, vector& path_id_list) { CcInt* search_id = new CcInt(true, reg_id); BTreeIterator* btree_iter = btree_reg_id1->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = building_path->GetTuple(btree_iter->GetId(), false); int regid = ((CcInt*)tuple->GetAttribute(INDOORIF_REG_ID))->GetIntval(); assert(reg_id == regid); path_id_list.push_back(btree_iter->GetId()); tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; } /* given a rectangle id, it returns the building type */ void IndoorInfra::GetTypeFromRegId(int reg_id, int& type, int& build_id, Rectangle<2>& build_rect) { CcInt* search_id = new CcInt(true, reg_id); BTreeIterator* btree_iter = btree_reg_id2->ExactMatch(search_id); while(btree_iter->Next()){ Tuple* tuple = building_type->GetTuple(btree_iter->GetId(), false); int regid = ((CcInt*)tuple->GetAttribute(INDOORIF_REG_ID_2))->GetIntval(); type = ((CcInt*)tuple->GetAttribute(INDOORIF_BUILD_TYPE))->GetIntval(); build_id = ((CcInt*)tuple->GetAttribute(INDOORIF_BUILD_ID))->GetIntval(); build_rect = *((Rectangle<2>*)tuple->GetAttribute(INDOORIF_GEODATA)); assert(reg_id == regid); tuple->DeleteIfAllowed(); } delete btree_iter; delete search_id; }