Files
secondo/Algebras/TransportationMode/PaveGraph.h
2026-01-23 17:03:45 +08:00

1084 lines
35 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
[1] Header File of the PaveGraph. Graph Model for Walk Planning
May, 2010 Jianqiu xu
[TOC]
1 Overview
2 Defines and includes
*/
#ifndef PaveGraph_H
#define PaveGraph_H
#include "Algebra.h"
#include "NestedList.h"
#include "QueryProcessor.h"
#include "Algebras/RTree/RTreeAlgebra.h"
#include "Algebras/BTree/BTreeAlgebra.h"
#include "Algebras/Temporal/TemporalAlgebra.h"
#include "StandardTypes.h"
#include "LogMsg.h"
#include "NList.h"
#include "Algebras/Relation-C++/RelationAlgebra.h"
#include "ListUtils.h"
#include "Algebras/Network/NetworkAlgebra.h"
#include "Algebras/Spatial/RegionTools.h"
#include <fstream>
#include <stack>
#include <vector>
#include <queue>
#include "Attribute.h"
#include "Tools/Flob/DbArray.h"
#include "Tools/Flob/Flob.h"
#include "WinUnix.h"
#include "AvlTree.h"
#include "Symbols.h"
#include "GeneralType.h"
#include <bitset>
///////////////////////graph model for walk planning///////////////////////
static const float EPSILON=0.0000000001f;
/*
structure for shortest path searching in a polygon
the graph is build the decomposed triangles.
it finds the path with minimum number of triangles connecting the start point
and the end point
*/
struct Path_elem{
int prev_index;//previous in expansion list
int cur_index; //current entry in expansion list
int tri_index; //object id
Path_elem(){}
Path_elem(int p, int c, int t):prev_index(p), cur_index(c),
tri_index(t){}
Path_elem(const Path_elem& pe):prev_index(pe.prev_index),
cur_index(pe.cur_index), tri_index(pe.tri_index){}
Path_elem& operator=(const Path_elem& pe)
{
// cout<<"Path_elem ="<<endl;
prev_index = pe.prev_index;
cur_index = pe.cur_index;
tri_index = pe.tri_index;
return *this;
}
};
struct SPath_elem:public Path_elem{
unsigned int weight;
SPath_elem(){}
SPath_elem(int p, int c, int t, int w):Path_elem(p, c, t), weight(w){}
SPath_elem(const SPath_elem& se):Path_elem(se),
weight(se.weight){}
SPath_elem& operator=(const SPath_elem& se)
{
// cout<<"SPath_elem ="<<endl;
Path_elem::operator=(se);
weight = se.weight;
return *this;
}
bool operator<(const SPath_elem& se) const
{
return weight > se.weight;
}
void Print()
{
cout<<"prev "<<prev_index<<" cur "<<cur_index
<<"tri_index" <<tri_index<<" weight "<<weight<<endl;
}
};
/*
structure for shortest path searching
*/
struct WPath_elem:public Path_elem{
double weight;
Point loc;
double real_w;
WPath_elem(){}
WPath_elem(int p, int c, int t, double w, Point& q,double w2):
Path_elem(p, c, t), weight(w), loc(q), real_w(w2){}
WPath_elem(const WPath_elem& wp):Path_elem(wp),
weight(wp.weight),loc(wp.loc), real_w(wp.real_w){}
WPath_elem& operator=(const WPath_elem& wp)
{
// cout<<"SPath_elem ="<<endl;
Path_elem::operator=(wp);
weight = wp.weight;
loc = wp.loc;
real_w = wp.real_w;
return *this;
}
bool operator<(const WPath_elem& wp) const
{
return weight > wp.weight;
}
void Print()
{
cout<<" tri_index" <<tri_index<<" loc "<<loc
<<" realweight "<<real_w<<" weight "<<weight<<endl;
}
};
struct RPoint;
struct MyPoint;
struct MySegDist;
struct MyHalfSegment;
struct SpacePartition;
struct CompTriangle{
Region* reg;
std::vector<Region> triangles;
std::vector<Region> sleeve;
std::vector<Point> plist1;
std::vector<Point> plist2;
std::vector<Point> plist3;
unsigned int count;
Line* path;
TupleType* resulttype;
CompTriangle();
CompTriangle(Region* r);
~CompTriangle();
void Triangulation();
unsigned int NoOfCycles();
void PolygonContourPoint(unsigned int no_cyc, int no_p_contour[],
std::vector<double>&, std::vector<double>&);
void PolygonContourPoint2(unsigned int no_cyc, int no_p_contour[],
std::vector<double>&, std::vector<double>&);
void NewTriangulation();
void NewTriangulation2();
inline bool InsideTriangle(float Ax, float Ay,
float Bx, float By,
float Cx, float Cy,
float Px, float Py);
bool Snip(const std::vector<Point>& contour,int u,int v,int w,int n,int *V);
bool GetClockwise(const std::vector<Point>& contour);
float Area(const std::vector<Point>& contour);
bool GetTriangles(const std::vector<Point>& contour,
std::vector<Point>& result);
//detect whether a polygon is a convex or concave
bool IsConvex(std::vector<Point>);
bool PolygonConvex();
bool PolygonConvex2(int& error);
int ComplexRegion();
//compute the shortest path between two points inside a polgyon
void GeoShortestPath(Point*, Point*);
//compute the channel/sleeve between two points
void GetChannel(Point*, Point*);
void PtoSegSPath(Point*, HalfSegment*, std::vector<Region>&, Line*);
//find adjacenct triangles
void FindAdj(unsigned int, std::vector<bool>&, std::vector<int>&);
void ConstructConvexChannel1(std::list<MyPoint>&, std::list<MyPoint>&, Point&,
std::vector<Point>&, bool);
void ConstructConvexChannel2(std::list<MyPoint>, std::list<MyPoint>, Point&,
std::vector<Point>&, bool);
void SelectPointOnSeg(std::list<MyPoint>, std::list<MyPoint>, HalfSegment*,
Point&, Point&);
//////////////////for rotational plane sweep ///////////////////////
static std::string AllPointsInfo;
enum AllPointsTypeInfo{V=0, NEIGHBOR1, NEIGHBOR2, REGID};
void GetAllPoints();
void GetVPoints(Relation* r1, Relation* r2, Rectangle<2>* bbox,
Relation* r3, int attr_pos);
/* void ProcessNeighbor(multiset<MySegDist>&, RPoint&, Point&,
Point&, Point&, SpacePartition*, ofstream& );*/
void ProcessNeighbor(std::multiset<MySegDist>&, RPoint&, Point&,
Point&, Point&, SpacePartition*);
void InitializeAVL( std::multiset<MySegDist>& sss,
Point& query_p, Point& hp,
Point& p, Point& neighbor,
SpacePartition* sp);
void InitializeQueue(std::priority_queue<RPoint>& allps,
Point& query_p, Point& hp, Point& p,
SpacePartition* sp, Point* q1,
Point* q2, int id);
void PrintAVLTree(std::multiset<MySegDist>& sss, std::ofstream&);
std::vector<Line> connection;
std::vector<int> reg_id;
// std::vector<float> angles;
};
struct ListEntry{
ListEntry(){} //do not initialize the members
ListEntry(int l, int h):low(l),high(h){}
ListEntry(const ListEntry& le):low(le.low), high(le.high){}
int low, high;
};
class BaseGraph{
public:
BaseGraph();
BaseGraph(ListExpr in_xValue,int in_iErrorPos,ListExpr& inout_xErrorInfo,
bool& inout_bCorrect);
BaseGraph(SmiRecord&, size_t&, const ListExpr);
~BaseGraph();
void Destroy();
static ListExpr BaseGraphProp();
static int SizeOfBaseGraph();
static void* CastBaseGraph(void* addr);
static Word CloneBaseGraph(const ListExpr typeInfo, const Word& w);
///////////////////////////////////////////////////////////////////
Relation* GetEdgeRel(){return edge_rel;}
Relation* GetNodeRel(){return node_rel;}
inline int No_Of_Node(){return node_rel->GetNoTuples();}
void FindAdj(int node_id, std::vector<bool>& flag,
std::vector<int>& adj_list);
void FindAdj(int node_id, std::vector<int>& adj_list);
unsigned int g_id;
Relation* node_rel;
Relation* edge_rel;
DbArray<int> adj_list;
DbArray<ListEntry> entry_adj_list;
};
class DualGraph:public BaseGraph{
public:
static std::string NodeTypeInfo;
static std::string BTreeNodeTypeInfo;
static std::string EdgeTypeInfo;
static std::string NodeRTreeTypeInfo;
/*schema for edge and node*/
enum DGNodeTypeInfo{OID = 0, RID, PAVEMENT};
enum DGEdgeTypeInfo{OIDFIRST = 0, OIDSECOND, COMMAREA};
/////////////for triangle ///////////////////////
static std::string TriangleTypeInfo1;
static std::string TriangleTypeInfo2;
static std::string TriangleTypeInfo3;
static std::string TriangleTypeInfo4;
enum Tri1TypeInfo{V1 = 0, V2,V3,CENTROID,TOID};
enum Tri2TypeInfo{CYCLENO = 0, VERTEX};
//(vid,triid)
//for each vertex, which triangle it belongs to
enum Tri4TypeInfo{VID = 0, TRIID};
////////////constructor and deconstructor///////////////////////
~DualGraph();
DualGraph();
DualGraph(ListExpr in_xValue,int in_iErrorPos,ListExpr& inout_xErrorInfo,
bool& inout_bCorrect);
DualGraph(SmiRecord&, size_t&, const ListExpr);
///////////////function for typeconstructor////////////////////////
void Load(int, Relation*,Relation*);
void LoadSortNode(Relation* r1);
static ListExpr OutDualGraph(ListExpr typeInfo, Word value);
ListExpr Out(ListExpr typeInfo);
static Word InDualGraph(ListExpr in_xTypeInfo, ListExpr in_xValue,
int in_iErrorPos, ListExpr& inout_xErrorInfo,
bool& inout_bCorrect);
static Word CreateDualGraph(const ListExpr typeInfo);
static void CloseDualGraph(const ListExpr typeInfo, Word& w);
static void DeleteDualGraph(const ListExpr typeInfo, Word& w);
static bool CheckDualGraph(ListExpr type, ListExpr& errorInfo);
static bool SaveDualGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
bool Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset,
const ListExpr in_xTypeInfo);
static bool OpenDualGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
static DualGraph* Open(SmiRecord& valueRecord,size_t& offset,
const ListExpr typeInfo);
void LineIntersectTri(Line*l, std::vector<Line>& line_list);
void DFTraverse(R_Tree<2,TupleId>* rtree, SmiRecordId adr,
Line* line, std::vector<Line>& line_list);
int GetTriId_OfPoint(Point& loc);
void DFTraverse2(R_Tree<2,TupleId>* rtree, SmiRecordId adr,
Point& loc, std::vector<int>& tri_oid_list);
void DFTraverse3(R_Tree<2,TupleId>* rtree, SmiRecordId adr,
Point& loc, std::vector<int>& tri_oid_list,
double dist);
//////////////////////////////////////////////////////////////////////
//////////calculate a path, for cells in metro route//////////////////
void Path_Weight(int start, int end, std::vector<int>& path);
//////////////////////////////////////////////////////////////////
int min_tri_oid_1; //smaller than the minimum tri oid (minoid - 1)
Relation* node_rel_sort; ///////sort by bbox, better performance for search
R_Tree<2,TupleId>* rtree_node;//build an rtree on triangles
};
class VisualGraph: public BaseGraph{
public:
static std::string NodeTypeInfo;
static std::string EdgeTypeInfo;
static std::string QueryTypeInfo;
enum VGNodeTypeInfo{OID = 0, LOC};
enum VGEdgeTypeInfo{OIDFIRST = 0,OIDSECOND, CONNECTION};
enum VGQueryTypeInfo{QOID = 0, QLOC1, QLOC2}; //relative, absolute position
//////////////////////////////////////////////////////////////
~VisualGraph();
VisualGraph();
VisualGraph(ListExpr in_xValue,int in_iErrorPos,
ListExpr& inout_xErrorInfo,
bool& inout_bCorrect);
VisualGraph(SmiRecord&, size_t&, const ListExpr);
//////////////////////////////////////////////////////////////
void Load(int, Relation*, Relation*);
static ListExpr OutVisualGraph(ListExpr typeInfo, Word value);
ListExpr Out(ListExpr typeInfo);
static bool CheckVisualGraph(ListExpr type, ListExpr& errorInfo);
static void CloseVisualGraph(const ListExpr typeInfo, Word& w);
static void DeleteVisualGraph(const ListExpr typeInfo, Word& w);
static Word CreateVisualGraph(const ListExpr typeInfo);
static Word InVisualGraph(ListExpr in_xTypeInfo,
ListExpr in_xValue,
int in_iErrorPos, ListExpr& inout_xErrorInfo,
bool& inout_bCorrect);
static bool OpenVisualGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
static VisualGraph* Open(SmiRecord& valueRecord,size_t& offset,
const ListExpr typeInfo);
static bool SaveVisualGraph(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
bool Save(SmiRecord& in_xValueRecord,size_t& inout_iOffset,
const ListExpr in_xTypeInfo);
};
struct Walk_SP{
DualGraph* dg;
VisualGraph* vg;
Relation* rel1; //query relation1
Relation* rel2; //query relation2
unsigned int count;
TupleType* resulttype;
std::vector<int> oids;
std::vector<int> oids1;
std::vector<int> oids2;
std::vector<Line> path;
std::vector<Point> q_loc1;
std::vector<Point> q_loc2;
std::vector<int> oid_list;
std::vector<int> rid_list;
std::vector<Region> reg_list;
std::vector<network::GPoint> gp_list;
std::vector<Point> p_list;
Relation* rel3; //triangle relation (v1 int)(v2 int)(v3 int)(centroid point)
Relation* rel4; //vertex relation (vid int)(triid int)
BTree* btree;
Walk_SP();
~Walk_SP();
Walk_SP(DualGraph* g1, VisualGraph* g2, Relation* r1, Relation* r2);
void WalkShortestPath(Line* res);
void WalkShortestPath2(int oid1, int oid2, Point loc1, Point loc2,
Line* res);
bool EuclideanConnect(Point loc1, Point loc2);
void DFTraverse2(R_Tree<2,TupleId>* rtree, SmiRecordId adr, Line* line,
double& l);
bool EuclideanConnect2(int oid1, Point loc1, int oid2, Point loc2);
void TestWalkShortestPath(int, int);
void GenerateData1(int no_p);
void GenerateData2(int no_p);
void GenerateData3(int no_p);
bool GenerateData4(int oid);
void DFTraverse(R_Tree<2,TupleId>* rtree, SmiRecordId adr, Region* reg,
std::vector<int>& r_id_list);
void SetPaveRid(R_Tree<2,TupleId>* rtree);
void PaveLocToGP(network::Network* n);
bool PaveLocToGPoint(Point* loc, network::Network* n,
std::vector<int> route_id_list);
};
/*
clamp structure for pruning triangles searching
*/
struct Clamp{
Point apex;
Point foot1;
Point foot2;
double angle;
Clamp(){}
Clamp(Point& p1, Point& p2, Point& p3):apex(p1),foot1(p2),foot2(p3)
{
double b = apex.Distance(foot1);
double c = apex.Distance(foot2);
double a = foot1.Distance(foot2);
assert(AlmostEqual(b*c,0.0) == false);
double value = (b*b+c*c-a*a)/(2*b*c);
if(AlmostEqual(value,-1.0)) value = -1;
if(AlmostEqual(value,1.0)) value = 1;
angle = acos(value);
// cout<<"angle "<<angle<<" degree "<<angle*180.0/pi<<endl;
assert(0.0 <= angle && angle <= 3.1416);
}
Clamp(const Clamp& clamp):apex(clamp.apex),
foot1(clamp.foot1),foot2(clamp.foot2),
angle(clamp.angle){}
Clamp& operator=(const Clamp& clamp)
{
apex = clamp.apex;
foot1 = clamp.foot1;
foot2 = clamp.foot2;
angle = clamp.angle;
return *this;
}
void Print()
{
cout<<"apex "<<apex<<" foot1 "<<foot1<<" foot2 "
<<foot2<<"angle "<<angle<<endl;
}
};
struct Triangle;
struct VGraph{
DualGraph* dg;
Relation* rel1;//query relation
Relation* rel2;//triangle relation (v1 int)(v2 int)(v3 int)(centroid point)
Relation* rel3;//visibility graph node relation
Relation* rel4;//vertex relation (vid int)(triid int)
BTree* btree;
unsigned int count;
TupleType* resulttype;
std::vector<int> oids1;
std::vector<int> oids2;
std::vector<int> oids3;
std::vector<Point> p_list;
std::vector<Line> line;
std::vector<Region> regs;
VisualGraph* vg;
VGraph();
~VGraph();
VGraph(DualGraph* g, Relation* r1, Relation* r2, Relation* r3);
VGraph(VisualGraph* g);
void GetVNode();
void GetAdjNodeDG(int oid);
void GetAdjNodeVG(int oid);
void GetVisibleNode1(int tri_id, Point* query_p);
void GetVisibleNode2(int tri_id, Point* query_p, int type);
bool CheckVisibility1(Clamp& clamp, Point& checkp, int vp);
bool CheckVisibility2(Clamp& clamp, Point& checkp1, Point& checkp2);
void DFTraverse(int id, Clamp& clamp, int pre_id, int type);
bool PathContainHS(std::vector<int> tri_list, HalfSegment hs);
bool GetIntersectionPoint(Point& p1,Point& p2,Clamp& clamp, Point& ip,bool);
bool GetVNode_QV(int tri_id, Point* query_p,int,int,int);
void DecomposeTriangle();
void FindTriContainVertex(int vid, int tri_id, Point* query_p);
bool Collineation(Point& p1, Point& p2, Point& p3);
void GetVNodeOnVertex(int vid, Point* query_p);
void GetVGEdge();
bool MyCross(const HalfSegment& hs1, const HalfSegment& hs2);
////////////////////for walk shortest algorithm/////////////////////////
void GetVisibilityNode(int tri_id, Point query_p);
};
/*
structure used for creating the triangles of a polygon in such a way that two
relations work together. we assign a unique number for each contour point
rel1. store the relation for the points of the contour
rel2. store the number of each point and the centroid
*/
struct RegVertex{
Region* reg;
unsigned int count;
TupleType* resulttype;
std::vector<int> cycleno;
std::vector<Point> regnodes;
std::vector<int> v1_list;
std::vector<int> v2_list;
std::vector<int> v3_list;
Relation* rel1;
Relation* rel2;
std::vector<Line> line;
std::vector<Region> tri_list;
RegVertex(){}
RegVertex(Region* r):reg(r), count(0), resulttype(NULL){}
RegVertex(Relation* r1, Relation* r2): count(0), resulttype(NULL),
rel1(r1), rel2(r2){}
~RegVertex(){
if(resulttype != NULL) resulttype->DeleteIfAllowed();
}
void CreateVertex();
void TriangulationNew();
void TriangulationExt();
void TriangulationNew2();
void TriangulationExt2();
void GetDGEdge();
void GetDGEdgeRTree(R_Tree<2,TupleId>*);
void ShareEdge(Region* reg1, Region* reg2, int, int,
std::vector<std::vector<int> >&);
void DFTraverse(R_Tree<2,TupleId>* rtree, SmiRecordId adr,
int oid, Region* reg,
std::vector<std::vector<int> >& adj_node);
};
struct Triangle{
int oid;
int v1, v2, v3;
int c1, c2, c3;
int neighbor_no;//maximum 3
Triangle(){}
Triangle(int n1, int n2, int n3):oid(0),v1(n1),v2(n2),v3(n3),
c1(0),c2(0),c3(0),neighbor_no(0){}
Triangle(int id, int n1, int n2, int n3, int cyc1, int cyc2, int cyc3):
oid(id),v1(n1),v2(n2),v3(n3),c1(cyc1),c2(cyc2),c3(cyc3),neighbor_no(0)
{
}
Triangle(const Triangle& tri):oid(tri.oid),v1(tri.v1),v2(tri.v2),v3(tri.v3),
c1(tri.c1),c2(tri.c2),c3(tri.c3),
neighbor_no(tri.neighbor_no){}
Triangle& operator=(const Triangle& tri)
{
oid = tri.oid;
v1 = tri.v1;
v2 = tri.v2;
v3 = tri.v3;
c1 = tri.c1;
c2 = tri.c2;
c3 = tri.c3;
neighbor_no = tri.neighbor_no;
return *this;
}
int ShareEdge(Triangle& tri)
{
bool flag1 = false;
bool flag2 = false;
bool flag3 = false;
if(v1 == tri.v1 || v1 == tri.v2 || v1 == tri.v3)
flag1 = true;
if(v2 == tri.v1 || v2 == tri.v2 || v2 == tri.v3)
flag2 = true;
if(v3 == tri.v1 || v3 == tri.v2 || v3 == tri.v3)
flag3 = true;
if(flag1 && flag2) return 1; //v1 v2
if(flag1 && flag3) return 2; //v1 v3
if(flag2 && flag3) return 3; //v2 v3
return 0;
}
void Print()
{
cout<<"oid "<<oid<<" "<<
v1<<" "<<v2<<" "<<v3<<" neighbor "<<neighbor_no<<endl;
cout<<"cycleno "<<c1<<" "<<c2<<" "<<c3<<endl;
}
};
struct TriNode{
Triangle tri;
TriNode* next;
TriNode(){next = NULL;}
TriNode(Triangle& t, TriNode* n):tri(t), next(n){}
};
/*
Calculate the Z-order value for the input point
*/
inline long ZValue(Point& p)
{
std::bitset<20> b;
double base = 2,exp = 20;
int x = (int)p.GetX();
int y = (int)p.GetY();
assert (x < pow(base,exp));
assert (y < pow(base,exp));
std::bitset<10> b1(x);
std::bitset<10> b2(y);
bool val;
b.reset();
for(int j = 0; j < 10;j++){
val = b1[j];
b.set(2*j,val);
val = b2[j];
b.set(2*j+1,val);
}
return b.to_ulong();
}
inline void Modify_Point_3(Point& p)
{
double x,y;
x = p.GetX();
y = p.GetY();
// printf("%.10f %.10f\n",x, y);
x = ((int)(x*1000.0 + 0.5))/1000.0;
y = ((int)(y*1000.0 + 0.5))/1000.0;
// printf("%.10f %.10f\n",x, y);
p.Set(x,y);
}
// struct MHSNode{
// MyHalfSegment mhs;
// MHSNode* next;
// MHSNode(MyHalfSegment hs, MHSNode* pointer):mhs(hs),next(pointer){}
// };
struct MHSNode;
struct Hole{
Hole(char* input):in(input){count = 0;resulttype=NULL;}
Hole(){count=0;resulttype = NULL;}
~Hole(){if(resulttype != NULL) resulttype->DeleteIfAllowed();}
std::ifstream in;
unsigned int count;
TupleType* resulttype;
std::vector<Region> regs1;
std::vector<Region> regs2;
std::vector<Region> regs;
void GetContour();
void GetContour(unsigned int no_reg);
void GetPolygon(int no_ps);//create a polygon
void SpacePartitioning(Points* gen_ps, std::vector<HalfSegment>& hs_segs);
void SpacePartitioning(std::vector<Point> ps,
std::vector<HalfSegment>& hs_segs,
Point sf, Point sl);
void DiscoverContour(MHSNode* head, Region* r);
void DiscoverContour(Points* ps, Region* r);
bool NoSelfIntersects(Region* r);
void GetHole(Region* r);
};
/////////////////////////////////////////////////////////////////////////////
///////////////////////////search maximum rectangle//////////////////////////
////////////////////////////////////////////////////////////////////////////
Rectangle<2> GetMaxRect(Region*);
Rectangle<2> GetMaxRect2(Region*);
Rectangle<2> RectInTriangle(std::vector<Point>& ps);
struct GeomPoint{
GeomPoint(){}
GeomPoint(int ptx, int pty){
x = ptx;
y = pty;
}
GeomPoint(const GeomPoint& gp):x(gp.x), y (gp.y){}
GeomPoint& operator=(const GeomPoint& gp)
{
x = gp.x;
y = gp.y;
return *this;
}
int min(int a, int b){
if(a<=b) return a; else return b;
}
int max(int a, int b){
if (a>=b) return a; else return b;
}
void Print()
{
cout<<"( "<<x<<" "<<y<<" )"<<endl;
}
int x;
int y;
};
struct GeomEdge{
GeomEdge(){}
GeomEdge(GeomPoint p, GeomPoint q){
xmin = p.min(p.x, q.x);
xmax = p.max(p.x, q.x);
ymin = p.min(p.y, q.y);
ymax = p.max(p.y, q.y);
m = ((double)(q.y-p.y))/((double)(q.x-p.x));
b = p.y - m*(p.x);
isTop = p.x > q.x; //edge from right to left (ccw)
isRight = p.y > q.y; //edge from bottom to top (ccw)
}
GeomEdge(const GeomEdge& ge):xmin(ge.xmin), xmax(ge.xmax), ymin(ge.ymin),
ymax(ge.ymax), m (ge.m), b(ge.b), isTop(ge.isTop), isRight(ge.isRight)
{}
GeomEdge& operator=(const GeomEdge& ge)
{
xmin = ge.xmin;
xmax = ge.xmax;
ymin = ge.ymin;
ymax = ge.ymax;
isTop = ge.isTop;
isRight = ge.isRight;
m = ge.m;
b = ge.b;
return *this;
}
void Print(){
cout<<"xmin "<<xmin<<" xmax "<<xmax<<" ymin "<<ymin<<" ymax "<<ymax<<endl;
}
int xmin, xmax; /* horiz, +x is right */
int ymin, ymax; /* vertical, +y is down */
double m,b; /* y = mx + b */
bool isTop, isRight; /* position of edge w.r.t. hull */
};
////////////// minimum area for a region and a rectangle ///////////////////
//////// the building should be complex so that it coveras a large area/////
const float mini_reg_area = 1000.0;
// const float mini_rect_area = 800.0;
// const float maxi_rect_area = 8000.0;
const float mini_rect_area = 100.0;
const float maxi_rect_area = 15000.0;
const float mini_tri_area = 200.0;
const float maxi_tri_area = 30000.0;
const float mini_dist_build = 15.0;
const float length_limit = 50.0;
struct Build_Rect{
int reg_id;
Rectangle<2> rect;
int poly_id;
int reg_type;
int build_type;
bool init;
int quadrant;
Build_Rect(){}
Build_Rect(int id1, Rectangle<2>& r, int id2, int t):
reg_id(id1), rect(r), poly_id(id2), reg_type(t){
build_type = 0, init = false; quadrant = 0;
}
Build_Rect(const Build_Rect& br):reg_id(br.reg_id), rect(br.rect),
poly_id(br.poly_id), reg_type(br.reg_type), build_type(br.build_type),
init(br.init), quadrant(br.quadrant){}
void Print()
{
cout<<"reg_id "<<reg_id<<" rect "<<rect<<" poly_id "<<poly_id
<<" reg_type "<<reg_type<<endl;
}
};
class Building;
class IndoorGraph;
struct MaxRect{
static std::string BuildingRectTypeInfo;
static std::string RegionElemTypeInfo;
static std::string BuildingRectExtTypeInfo;
static std::string BuildingParaInfo;
bool fixed;
int fixedX, fixedY;
std::vector<Rectangle<2> > RectList;
int status;
int start, stop; //tangents for iterative convex hull
int g_xmin, g_xmax, g_ymin, g_ymax; //position of hull
int yxmax; //y coord of xmax
GeomPoint rectp;
int recth, rectw;
bool changed;
int result;
std::vector<GeomPoint> geo_p_list;
std::vector<GeomEdge> geo_e_list;
/////////////////////////////////////////////////////////////////////////
std::vector<int> reg_id_list;
std::vector<Rectangle<2> > rect_list;
std::vector<Region> reg_list;
std::vector<SimpleLine> sl_list;
std::vector<int> reg_type_list;
std::vector<int> poly_id_list;
Relation* rel1;
Relation* rel2;
BTree* btree;
std::vector<Point> sp_list;
std::vector<unsigned int> sp_index_list;
std::vector<Point> ep_list;
std::vector<Point> ep_list2;
std::vector<Line> path_list;
std::vector<int> build_id_list;
std::vector<GenLoc> genloc_list;
std::vector<int> sp_type_list;
std::vector<int> build_type_list;
std::vector<std::string> build_type2_list;
std::vector<Building*> build_pointer;
std::vector<IndoorGraph*> igraph_pointer;
unsigned int count;
TupleType* resulttype;
enum BuildingRect{REG_ID = 0, GEODATA, POLY_ID, REG_TYPE};
enum RegionElem{REGID=0, COVAREA};
enum BuildingRect_Ext{REG_ID_EXT = 0, GEODATA_EXT, POLY_ID_EXT,
REG_TYPE_EXT, BUILDING_TYPE, BUILDING_TYPE_2};
MaxRect() {
count=0;resulttype = NULL;
}
MaxRect(Relation* r):rel1(r){
count=0;
resulttype = NULL;
}
MaxRect(Relation* r1, Relation* r2, BTree* bt):
rel1(r1), rel2(r2), btree(bt){
count=0;
resulttype = NULL;
}
~MaxRect(){
if(resulttype != NULL) resulttype->DeleteIfAllowed();
}
void Init(){
fixed = false;
fixedX = 1;
fixedY = 1;
}
void SetPoint(std::vector<GeomPoint>& list);
// position of point w.r.t. hull edgesign of twice the area of triangle abc
bool onLeft(GeomPoint a, GeomPoint b, GeomPoint c);
bool pointOutside(GeomPoint p);
bool computeEdgeList();
inline int yIntersect(int xi, GeomEdge e);
int xIntersect(int y);
GeomEdge findEdge(int x, bool isTop);
void computeLargestRectangle();
bool IsCycle(SimpleLine* sl);
void RemoveDirty(int attr1, int attr2);
void RemoveDirtyRegion(int regid, Region* reg);
void ConvexReg(int attr1, int attr2);
/////////////////merge several triangles to be convex polygon/////////////
void MergeTriangle(CompTriangle* ct, int reg_id);
/////////////whether two triangle have a commone edge////////////////
bool NeighborTriangle(Region* r1, Region* r2);
/////////get the maximum rectangle for each region/////////////////
void GetRectangle1(int attr1, int attr2, Relation*);
////////////////check whether all coordinates are positive///////////////
////////////because the function to get maximum rectangle needs all ////
/////////////positive coordinates///////////////////////////////////////
bool ValidRegion(Region* r);
////////build the path between the entrance of the building and pavement///
bool RegionWithHole(std::vector<Rectangle<2> >& hole_list, Region* reg);
void SetStartAndEndPoint(Region* r, std::vector<Point>& build_sp_list,
std::vector<Point>& build_ep_list);
void MapToPavement(DualGraph* , Point loc);
//////////set the building entrance according to the floor plan////////
void OpenBuilding();
void OpenIndoorGraph();
void LoadIndoorPaths(std::vector< std::map<int, Line3D> >& paths,
std::vector< std::map<int, Line3D> >& rooms);
void CloseIndoorGraph();
void CloseBuilding();
void PathToBuilding(Space* gl_sp);
void CreateEntranceforBuilding(Region* r, std::vector<int>& tid_list,
DualGraph* dg);
void BuildingEntrance(int graph_type, Rectangle<2>* rect,
std::vector<Point>& build_sp_list);
void BuildingEntranceHouse(Rectangle<2>* rect,
std::vector<Point>& build_sp_list,
std::vector<Point>& build_ep_list, Region* r);
void Get2DAreadAndDoor(int build_type, Rectangle<2>& build_area,
std::vector<Point>& door_list);
void Path_BuildingPave(Point sp, Point ep, Rectangle<2>* rect,
Region* r, DualGraph* dg);
void PathOnBorder(Line* boundary_temp, Point sp, Point cp_border,
Line* path2, int& edgeno);
////////////set the type for each rectange(building)///////////////////
void SetBuildingType(R_Tree<2,TupleId>* rtree, Space* gl_sp);
void SetAirPort(std::vector<Build_Rect>& list, R_Tree<2,TupleId>* rtree);
bool NoNeighbor(Build_Rect& br, R_Tree<2,TupleId>* rtree);
void DFTraverse1(R_Tree<2,TupleId>* rtree, SmiRecordId adr,
Rectangle<2>& rect, std::vector<int>& tri_oid_list);
void SetTrainStation(std::vector<Build_Rect>& list);
void SetCinema(std::vector<Build_Rect>& build_rect_list,
unsigned int no, Rectangle<2> bbox);
bool NoNeighborCinema(std::vector<Build_Rect>& list1, Build_Rect br,
Rectangle<2> bbox);
void SetHotel(std::vector<Build_Rect>& build_rect_list, unsigned int no,
Rectangle<2> bbox);
bool NoNeighborHotel(std::vector<Build_Rect>& list1, Build_Rect br,
Rectangle<2> bbox);
void SetShopMall(std::vector<Build_Rect>& build_rect_list, unsigned int no,
Rectangle<2> bbox);
bool NoNeighborShopMall(std::vector<Build_Rect>& list1, Build_Rect br,
Rectangle<2> bbox);
void SetOffice24(std::vector<Build_Rect>& build_rect_list, unsigned int no);
void SetOffice38(std::vector<Build_Rect>& build_rect_list, unsigned int no);
void SetHospital(std::vector<Build_Rect>& build_rect_list, unsigned int no);
bool NoNeighborHospital(std::vector<Build_Rect>& list1, Build_Rect br);
bool NoNearbyShopMallAndCinema(std::vector<Build_Rect>& list,
Build_Rect br);
void SetLibrary(std::vector<Build_Rect>& build_rect_list, unsigned int no);
bool NoNeighborLibrary(std::vector<Build_Rect>& list, Build_Rect br);
bool NoNearbyCommercialBuilding(std::vector<Build_Rect>& list,
Build_Rect br);
void SetSchool(std::vector<Build_Rect>& build_rect_list, unsigned int no);
bool NoNeighborSchool(std::vector<Build_Rect>& list, Build_Rect br);
void SetUniversity(std::vector<Build_Rect>& list, unsigned int no);
bool NoNeighborUniversity(std::vector<Build_Rect>& list, Build_Rect br);
void SetHouse(std::vector<Build_Rect>& build_rect_list, unsigned int no);
bool NoNearbyNeighbors1(std::vector<Build_Rect>& list, Build_Rect br);
};
bool RegContainRect(Region* reg, Rectangle<2>& rect);
/*
for the infrastructure Region Based Outdoor
*/
class Pavement{
public:
Pavement();
Pavement(bool d, unsigned int i);
Pavement(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo);
enum PavementTypeInfo{P_OID = 0, P_RID, P_PAVEMENT};
~Pavement();
bool IsDefined() const { return def;}
unsigned int GetId() const {return pave_id;}
void Load(unsigned int i, Relation* r);
bool IsDGInit(){return dg_init;}
bool IsVGInit(){return vg_init;}
unsigned int GetDGId(){return dg_id;}
unsigned int GetVGId(){return vg_id;}
Relation* GetPaveRel();
void SetDualGraphId(int id);
void SetVisualGraphId(int id);
DualGraph* GetDualGraph();
void CloseDualGraph(DualGraph* dg);
VisualGraph* GetVisualGraph();
void CloseVisualGraph(VisualGraph* dg);
bool Save(SmiRecord& valueRecord, size_t& offset, const ListExpr typeInfo);
static Pavement* Open(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo);
static void* Cast(void* addr);
private:
bool def;
unsigned int pave_id;
bool dg_init;
unsigned int dg_id;
bool vg_init;
unsigned int vg_id;
Relation* pave_rel;
};
ListExpr PavementProperty();
ListExpr OutPavement( ListExpr typeInfo, Word value );
Word InPavement( const ListExpr typeInfo, const ListExpr instance,
const int errorPos, ListExpr& errorInfo, bool& correct );
bool OpenPavement(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
bool SavePavement(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
Word CreatePavement(const ListExpr typeInfo);
void DeletePavement(const ListExpr typeInfo, Word& w);
void ClosePavement( const ListExpr typeInfo, Word& w );
Word ClonePavement( const ListExpr typeInfo, const Word& w );
int SizeOfPavement();
bool CheckPavement( ListExpr type, ListExpr& errorInfo );
/*
check whether the maximum distance between two lines is smaller than d
if it is smaller than d, return true; otherwise false
*/
bool SmallerD(Line* l1, Line* l2, float d);
#endif