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

470 lines
13 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]
Started March 2012, Fabio Vald\'{e}s
[TOC]
\section{Overview}
This is the implementation of the Symbolic Trajectory Algebra.
\section{Defines and Includes}
*/
#include "Algorithms.h"
#include "Algebras/Raster2/sbool.h"
#include "Algebras/Raster2/sint.h"
#include "Algebras/Raster2/Operators/fromLine.h"
#include "Algebras/Hash/HashAlgebra.h"
#include "Algebras/NestedRelation/NestedRelationAlgebra.h"
#include "SecondoSMI.h"
namespace stj {
enum DirectionNum {DIR_ERROR = -1, EAST, NORTHEAST, NORTH, NORTHWEST, WEST,
SOUTHWEST, SOUTH, SOUTHEAST};
/*
\section{class ~MaxspeedRaster~}
*/
class MaxspeedRaster {
public:
MaxspeedRaster(raster2::sint *_hgt, NestedRelation *_nrel, RTree2TID *_rtree)
: hgt(_hgt), nrel(_nrel), rtree(_rtree) {
grid = hgt->getGrid();
primary = nrel->getPrimary();
subrel = nrel->getSubRel("WayInfo");
sc = SecondoSystem::GetCatalog();
}
const int getMaxspeedFromRoadInfo(std::string roadInfo1,
std::string roadInfo2);
const int getMaxspeedFromLeaf(TupleId leafinfo);
const int getMaxspeed(const raster2::RasterIndex<2> pos);
private:
raster2::sint *hgt;
NestedRelation *nrel;
RTree2TID *rtree;
raster2::grid2 grid;
Relation *primary;
SubRelation *subrel;
SecondoCatalog *sc;
};
template<class T>
class NegIndexVector2D {
public:
NegIndexVector2D() {}
void initialize(const int _minX, const int _maxX, const int _minY,
const int _maxY, const T _value) {
minX = _minX;
maxX = _maxX;
minY = _minY;
maxY = _maxY;
content.resize(maxX - minX + 1, std::vector<T>(maxY - minY + 1, _value));
}
void set(const int x, const int y, const T value) {
assert(minX <= x && x <= maxX && minY <= y && y <= maxY);
content[x - minX][y - minY] = value;
}
T get(const int x, const int y) const {
assert(minX <= x && x <= maxX && minY <= y && y <= maxY);
return content[x - minX][y - minY];
}
unsigned int getXsize() const {
return content.size();
}
unsigned int getYsize(const int x) const {
assert(x >= 0 && x < (int)content.size());
return content[x].size();
}
private:
std::vector<std::vector<T> > content;
int minX, maxX, minY, maxY;
};
struct RoadCourse {
RoadCourse() : dirSeq(true), heightSeq(true) {}
~RoadCourse() {}
void setStartPoint(const Point& startPt) {
dirCourse.push_back(NewPair<int, Point>(-1, startPt));
}
void addDir(const Point& pt, const std::string dirStr, const bool isNewValue){
int pos = 0;
if (!dirCourse.empty()) {
pos = dirCourse[dirCourse.size() - 1].first;
}
if (isNewValue) {
Label lb(dirStr);
Instant start(pos, 0, datetime::instanttype),
end(pos + 1, 0, datetime::instanttype);
temporalalgebra::SecInterval iv(start, end, true, false);
ULabel ul(iv, lb);
dirSeq.Add(ul);
pos++;
}
dirCourse.push_back(NewPair<int, Point>(pos, pt));
}
void addHeight(const raster2::RasterIndex<2> ri, const int height,
const bool isNewValue) {
int pos = 0;
if (!heightCourse.empty()) {
pos = heightCourse[heightCourse.size() - 1].first;
}
if (isNewValue) {
std::ostringstream heightStr;
heightStr << height << "-" << (height + 10);
Label lb(heightStr.str());
Instant start(pos, 0, datetime::instanttype),
end(pos + 1, 0, datetime::instanttype);
temporalalgebra::SecInterval iv(start, end, true, false);
ULabel ul(iv, lb);
heightSeq.Add(ul);
pos++;
}
heightCourse.push_back(NewPair<int, raster2::RasterIndex<2> >(pos, ri));
}
bool restorePoints(const int first, const int last, Point& resultStart,
Point& resultEnd) {
int left = binarySearchDirCourse(first, true);
int right = binarySearchDirCourse(last, false);
if (left == -1 || right == -1) {
return false;
}
resultStart = dirCourse[left].second;
resultEnd = dirCourse[right].second;
return true;
}
int binarySearchDirCourse(const int value, const bool isMin) {
if (dirCourse.empty()) {
return -1;
}
int start = 0;
int end = dirCourse.size() - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (dirCourse[mid].first == value) {
int limit = mid;
if (isMin) {
while (dirCourse[limit].first == value) {
limit--;
}
}
else {
while (dirCourse[limit].first == value) {
limit++;
}
}
return limit;
}
else if (value < dirCourse[mid].first){
end = mid - 1;
}
else{
start = mid + 1;
}
}
return -1;
}
void clear() {
dirCourse.clear();
heightCourse.clear();
dirSeq.Clear();
heightSeq.Clear();
}
std::vector<NewPair<int, Point> > dirCourse; // -1 for start
std::vector<NewPair<int, raster2::RasterIndex<2> > > heightCourse;
MLabel dirSeq, heightSeq;
};
/*
\section{class ~Tileareas~}
*/
class Tileareas {
friend class RestoreTrajLI;
public:
Tileareas() : raster(0), noTransitions(0), areaFile(true), ttaFile(false),
transFile(false) {}
Tileareas(const bool dummy) : raster(0), noTransitions(0), areaFile(false),
ttaFile(false), transFile(false) {}
Tileareas(const Tileareas& _src);
~Tileareas();
bool belongsToRaster(const int x, const int y) {
return (minX <= x && x <= maxX && minY <= y && y <= maxY);
}
void processTile(const int x, const int y, int& prevValue);
void trimAreaVector();
void recordAreaTransitions(const int x, const int y);
void retrieveAreas(raster2::sint *_raster);
void print(const bool printRange, const bool printAreas,
const bool printTileToArea, const bool printTransitions);
void getNodeSeqFromNodesBTree(BTree* btree, const int startNode,
NewPair<std::vector<int>, std::vector<int> >& seqs);
void getSegmentsFromNodesBTree(BTree *btree, Relation *nodesRel,
std::vector<int>& nodeSeq, std::vector<HalfSegment>& segments);
void recordRoadCourses(raster2::sint *_raster);
TupleType* getTupleType();
ListExpr getTupleTypeInfo();
bool createRoadCourseRelation(const std::string& name);
void processRoadCourse(const std::vector<HalfSegment>& segments,
RoadCourse& rc);
void deleteFiles();
static const std::string BasicType() {return "tileareas";}
static bool checkType(ListExpr t) {return listutils::isSymbol(t,BasicType());}
static ListExpr Property();
static ListExpr Out(ListExpr typeInfo, Word value);
static Word In(const ListExpr typeInfo, const ListExpr instance,
const int errorPos, ListExpr& errorInfo, bool& correct);
static Word Create(const ListExpr typeInfo);
static void Delete(const ListExpr typeInfo, Word& w);
static bool Open(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
static bool Save(SmiRecord& valueRecord, size_t& offset,
const ListExpr typeInfo, Word& value);
static void Close(const ListExpr typeInfo, Word& w);
static Word Clone(const ListExpr typeInfo, const Word& w);
static int SizeOfObj();
static bool TypeCheck(ListExpr typeList, ListExpr& errorInfo);
private:
raster2::sint *raster; // not stored persistently
int minX, maxX, minY, maxY;
unsigned int noTransitions;
std::vector<std::set<NewPair<int, int> > > areas;
NegIndexVector2D<int> tileToArea;
std::vector<std::vector<std::set<int> > > transitions; // area x dir -> areas
SmiRecordFile areaFile, ttaFile, transFile;
std::vector<RoadCourse> roadCourses;
};
extern TypeConstructor tileareasTC;
/*
\section{struct ~Tile~}
Applied for the operator ~restoreTraj~.
*/
struct Tile {
Tile(const int newX, const int newY) : x(newX), y(newY) {path.clear();}
Tile(const int newX, const int newY,
const std::vector<NewPair<int, int> > newPath)
: x(newX), y(newY), path(newPath) {
path.push_back(NewPair<int, int>(x, y));
}
bool operator<(const Tile& tile) const {
if (x == tile.x) {
if (y == tile.y) {
if (path.size() == tile.path.size()) {
for (unsigned int i = 0; i < path.size(); i++) {
if (!(path[i] == tile.path[i])) {
return path[i] < tile.path[i];
}
}
return false;
}
return path.size() < tile.path.size();
}
return (y < tile.y);
}
return (x < tile.x);
}
bool operator==(const Tile& tile) const {
if (x == tile.x && y == tile.y) {
for (unsigned int i = 0; i < path.size(); i++) {
if (!(path[i] == tile.path[i])) {
return false;
}
}
return true;
}
return false;
}
void set(const int newX, const int newY) {
path.push_back(NewPair<int, int>(this->x, this->y));
x = newX;
y = newY;
}
Tile moveTo(const DirectionNum dir) {
Tile result(this->x, this->y, path);
switch (dir) {
case EAST: {
result.x++;
break;
}
case NORTHEAST: {
result.x++;
result.y++;
break;
}
case NORTH: {
result.y++;
break;
}
case NORTHWEST: {
result.x--;
result.y++;
break;
}
case WEST: {
result.x--;
break;
}
case SOUTHWEST: {
result.x--;
result.y--;
break;
}
case SOUTH: {
result.y--;
break;
}
case SOUTHEAST: {
result.x++;
result.y--;
break;
}
default: {
break;
}
}
return result;
}
int x, y;
std::vector<NewPair<int, int> > path;
};
/*
\section{struct ~AreaHistory~}
Applied for the operator ~restoreTraj~.
*/
struct AreaHistory {
AreaHistory() {}
AreaHistory(const int area) {history.push_back(area);}
bool operator<(const AreaHistory& ah) const {
if (history.size() != ah.history.size()) {
return history.size() < ah.history.size();
}
for (unsigned int i = 0; i < history.size(); i++) {
if (history[i] != ah.history[i]) {
return history[i] < ah.history[i];
}
}
return 0;
}
friend std::ostream& operator<<(std::ostream& os, const AreaHistory& ah) {
os << "<";
for (unsigned int i = 0; i < ah.history.size(); i++) {
os << ah.history[i] << ", ";
}
os << ">" << endl;
return os;
}
std::vector<int> history;
};
/*
\section{class ~RestoreTrajLI~}
Applied for the operator ~restoreTraj~.
*/
class RestoreTrajLI {
public:
RestoreTrajLI(Relation *e, BTree *ht, RTree2TID *st, raster2::sint *r,
Hash *rh, raster2::sint *mr, Tileareas *ta, MLabel *h, MLabel *d, MLabel *s);
RestoreTrajLI() {}
bool retrieveSequel(const int startPos, std::set<int>& result);
void processNeighbors(const int origin, const Instant& inst,
const int height, std::set<int>& result);
void getNeighborAreas(const int origin, const DirectionNum dirNum,
std::set<int>& result);
void retrieveAreasFromHeight(const int pos, std::set<int>& result);
void updateCoords(const DirectionNum dir, int& x, int& y);
int getHeightFromArea(const int areaNo);
int getMaxspeedFromArea(const int areaNo);
void getBboxFromArea(const int areaNo, Rectangle<2>& result);
static const DirectionNum dirLabelToNum(const Label& dirLabel);
static const std::string dirNumToString(const DirectionNum dirNum);
static const DirectionNum dirDoubleToNum(const double dirDouble);
const int getDirectionDistance(const DirectionNum dir,
const DirectionNum dir2);
const int getSpeedFromLabel(const Label& speedLabel, const bool getMax);
Rectangle<2>* nextCandidate();
private:
Relation *edgesRel;
BTree *heightBtree;
RTree2TID *segmentsRtree;
raster2::sint *raster;
Hash *rhash;
raster2::sint *maxspeedRaster;
Tileareas *tileareas;
MLabel *height;
MLabel *direction;
MLabel *speed;
std::set<int> resultAreas;
std::set<int>::iterator it;
// std::vector<std::vector<NewPair<int> > > tileSequences;
};
}