1406 lines
37 KiB
C++
1406 lines
37 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2019,
|
|
University in Hagen,
|
|
Faculty of Mathematics and 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
|
|
----
|
|
|
|
*/
|
|
|
|
|
|
#include "IrregularGrid2D.h"
|
|
#include "Algebras/Relation-C++/RelationAlgebra.h"
|
|
#include "Algebras/Collection/IntSet.h"
|
|
#include <map>
|
|
#include <iterator>
|
|
|
|
Cell::Cell() {
|
|
cellId = -1;
|
|
valFrom = -1;
|
|
valTo = -1;
|
|
nbrPoints = -1;
|
|
}
|
|
|
|
void
|
|
Cell::setCellId(int cell_id) {
|
|
this->cellId = cell_id;
|
|
}
|
|
|
|
int
|
|
Cell::getCellId() {
|
|
return cellId;
|
|
}
|
|
|
|
void
|
|
Cell::setValFrom(double val_from) {
|
|
valFrom = val_from;
|
|
}
|
|
|
|
double
|
|
Cell::getValFrom() {
|
|
return valFrom;
|
|
}
|
|
|
|
void
|
|
Cell::setValTo(double val_to) {
|
|
valTo = val_to;
|
|
}
|
|
|
|
double
|
|
Cell::getValTo() {
|
|
return valTo;
|
|
}
|
|
|
|
int
|
|
Cell::getNbrOfPoints() {
|
|
return nbrPoints;
|
|
}
|
|
|
|
void
|
|
Cell::setNbrOfPoints(int nbr_points) {
|
|
nbrPoints = nbr_points;
|
|
}
|
|
|
|
Cell::~Cell() { }
|
|
|
|
VCell::VCell() {
|
|
}
|
|
|
|
std::vector<HCell>&
|
|
VCell::getRow() {
|
|
return row;
|
|
}
|
|
|
|
VCell::~VCell() { }
|
|
|
|
HCell::HCell() {
|
|
upper = nullptr;
|
|
}
|
|
|
|
void
|
|
HCell::setUpper(HCell* upper_) {
|
|
upper = upper_;
|
|
}
|
|
|
|
HCell*
|
|
HCell::getUpper() {
|
|
return upper;
|
|
}
|
|
|
|
HCell::~HCell() { }
|
|
|
|
IrregularGrid2D::IrregularGrid2D() {
|
|
boundingBox = nullptr;
|
|
rowCount = 0;
|
|
cellCount = 0;
|
|
}
|
|
|
|
IrregularGrid2D::IrregularGrid2D(const IrregularGrid2D& g) {
|
|
boundingBox = g.boundingBox;
|
|
rowCount = g.rowCount;
|
|
cellCount = g.cellCount;
|
|
}
|
|
|
|
IrregularGrid2D::IrregularGrid2D(Rectangle<2> &bounding_box,
|
|
int row_count, int cell_count) {
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::Set(Stream<Rectangle<2>> rStream,
|
|
Rectangle<2> &bounding_box,
|
|
int row_count, int cell_count) {
|
|
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
|
|
createIrgrid2D(rStream);
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::SetVector(std::vector<Rectangle<2>>* rVector,
|
|
Rectangle<2> &bounding_box,
|
|
int row_count, int cell_count) {
|
|
boundingBox = &bounding_box;
|
|
rowCount = row_count;
|
|
cellCount = cell_count;
|
|
|
|
createIrgrid2DVector(rVector);
|
|
}
|
|
|
|
std::vector<CellInfo*>
|
|
IrregularGrid2D::getCellInfoVector(IrregularGrid2D *in_irgrid2d) {
|
|
std::vector<CellInfo*> cell_info_vect {};
|
|
|
|
std::vector<VCell>* col = &in_irgrid2d->getColumnVector();
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell* vcell = &col->at(colIdx);
|
|
double vf = vcell->getValFrom();
|
|
double vt = vcell->getValTo();
|
|
|
|
std::vector<HCell>* row_vect = &vcell->getRow();
|
|
|
|
for(size_t cellIdx = 0; cellIdx < row_vect->size(); cellIdx++) {
|
|
HCell* cell = &row_vect->at(cellIdx);
|
|
int cid = cell->getCellId();
|
|
int np = cell->getNbrOfPoints();
|
|
double hf = cell->getValFrom();
|
|
double ht = cell->getValTo();
|
|
|
|
CellInfo* ci = new CellInfo(cid, np, hf, ht, vf, vt);
|
|
cell_info_vect.push_back(ci);
|
|
}
|
|
}
|
|
|
|
return cell_info_vect;
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::createIrgrid2D(Stream<Rectangle<2>> rStream) {
|
|
// sort input points by y-coordinates
|
|
processInput(rStream);
|
|
// create irregular grid 2d by point density
|
|
buildGrid();
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::createIrgrid2DVector(std::vector<Rectangle<2>>* rVector) {
|
|
// sort input points by y-coordinates
|
|
processInputVector(rVector);
|
|
// create irregular grid 2d by point density
|
|
buildGrid();
|
|
}
|
|
|
|
bool
|
|
pointComparisonX(RPoint p1, RPoint p2) {
|
|
return p1.x < p2.x;
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::buildGrid() {
|
|
|
|
// create grid structure
|
|
double bb_top = boundingBox->getMaxY();
|
|
double bb_bot = boundingBox->getMinY();
|
|
double colOffset = (bb_top - bb_bot) / rowCount;
|
|
|
|
double bb_right = boundingBox->getMaxX();
|
|
double bb_left = boundingBox->getMinX();
|
|
double hOffset = (bb_right - bb_left) / cellCount;
|
|
|
|
double col_boundary_val = bb_bot;
|
|
int hcell_id = 1;
|
|
|
|
for(int c = 0; c < rowCount; c++) {
|
|
VCell vcell = VCell();
|
|
vcell.setValFrom(col_boundary_val);
|
|
|
|
col_boundary_val += colOffset;
|
|
vcell.setValTo(col_boundary_val);
|
|
|
|
double cell_boundary_val = bb_left;
|
|
for(int r = 0; r < cellCount; r++) {
|
|
HCell hcell = HCell();
|
|
|
|
hcell.setValFrom(cell_boundary_val);
|
|
|
|
cell_boundary_val += hOffset;
|
|
hcell.setValTo(cell_boundary_val);
|
|
|
|
hcell.cellId = hcell_id;
|
|
hcell_id++;
|
|
|
|
// will be determined later
|
|
hcell.upper = nullptr;
|
|
|
|
vcell.getRow().push_back(hcell);
|
|
|
|
}
|
|
columnVector.push_back(vcell);
|
|
}
|
|
|
|
// adjust boundaries by point distribution
|
|
int nbrOfPoints = points.size();
|
|
int pointsPerRow = nbrOfPoints / rowCount;
|
|
std::vector<RPoint> tmp_row_points {};
|
|
|
|
int pointIdx = 0;
|
|
int point_counter = 0;
|
|
for(int colIdx = 0; colIdx < rowCount; colIdx++) {
|
|
for(size_t dp_idx = pointIdx; dp_idx < points.size(); dp_idx++) {
|
|
RPoint rp = points[dp_idx];
|
|
tmp_row_points.push_back(rp);
|
|
point_counter ++;
|
|
|
|
if ((point_counter == pointsPerRow) || (dp_idx == points.size()-1)) {
|
|
// adjust y-boundaries
|
|
|
|
if (colIdx > 0) {
|
|
getColumnVector()[colIdx].setValFrom(
|
|
getColumnVector()[colIdx-1].getValTo());
|
|
}
|
|
|
|
double new_val_to_y;
|
|
if (dp_idx == points.size()-1) {
|
|
new_val_to_y = bb_top;
|
|
} else {
|
|
new_val_to_y = rp.y;
|
|
}
|
|
getColumnVector()[colIdx].setValTo(new_val_to_y);
|
|
getColumnVector()[colIdx].setNbrOfPoints(point_counter);
|
|
|
|
point_counter = 0;
|
|
|
|
// adjust x-boundaries
|
|
std::sort(tmp_row_points.begin(), tmp_row_points.end(),
|
|
pointComparisonX);
|
|
|
|
std::vector<HCell> c_row = columnVector[colIdx].getRow();
|
|
int pointsPerCell = tmp_row_points.size() / cellCount;
|
|
|
|
int tmpPointIdx = 0;
|
|
for(int h = 0; h < cellCount; h++) {
|
|
std::vector<HCell>* hcel_vec_ptr = &columnVector[colIdx].getRow();
|
|
|
|
for(size_t tmp_rp_idx = tmpPointIdx;
|
|
tmp_rp_idx < tmp_row_points.size(); tmp_rp_idx++) {
|
|
|
|
RPoint rp_t = tmp_row_points[tmp_rp_idx];
|
|
point_counter ++;
|
|
|
|
if((point_counter == pointsPerCell)
|
|
|| (tmp_rp_idx == tmp_row_points.size()-1)
|
|
/* || (h == cellCount-1 ) */) {
|
|
|
|
if (h > 0) {
|
|
hcel_vec_ptr->at(h).setValFrom(
|
|
hcel_vec_ptr->at(h-1).getValTo());
|
|
}
|
|
|
|
double new_val_to_x;
|
|
if ((tmp_rp_idx == tmp_row_points.size()-1)
|
|
|| (h == cellCount-1)) {
|
|
new_val_to_x = bb_right;
|
|
} else {
|
|
new_val_to_x = rp_t.x;
|
|
}
|
|
hcel_vec_ptr->at(h).setValTo(new_val_to_x);
|
|
|
|
tmpPointIdx = tmp_rp_idx + 1;
|
|
hcel_vec_ptr->at(h).setNbrOfPoints(point_counter);
|
|
|
|
// Smoothing in case of odd number of points per cell
|
|
if (h+1 < cellCount) {
|
|
pointsPerCell = (tmp_row_points.size()-tmpPointIdx)
|
|
/ (cellCount-1-h);
|
|
}
|
|
|
|
point_counter = 0;
|
|
|
|
// next cell
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
tmp_row_points.clear();
|
|
pointIdx = dp_idx + 1;
|
|
|
|
// Smoothing in case of odd number of points per row
|
|
if (colIdx+1 < rowCount) {
|
|
pointsPerRow = (points.size()-pointIdx)
|
|
/ (rowCount-1-colIdx);
|
|
}
|
|
|
|
point_counter = 0;
|
|
|
|
// one row up
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// clear aux. vectors
|
|
if (points.size() > 0) {
|
|
points.clear();
|
|
}
|
|
if (tmp_row_points.size() > 0) {
|
|
tmp_row_points.clear();
|
|
}
|
|
|
|
// update cell pointer
|
|
if (rowCount > 1 && cellCount > 0) {
|
|
for(int c = 0; c < rowCount-1; c++) {
|
|
std::vector<HCell>* row_lower = &getColumnVector().at(c).getRow();
|
|
std::vector<HCell>* row_upper = &getColumnVector().at(c+1).getRow();
|
|
|
|
int pointToCellIdx = 0;
|
|
for(int h = 0; h < cellCount; h++) {
|
|
HCell* lower_cell_ptr = &row_lower->at(h);
|
|
HCell* upper_cell_ptr = &row_upper->at(pointToCellIdx);
|
|
|
|
if (lower_cell_ptr->getValFrom() <= upper_cell_ptr->getValTo()) {
|
|
lower_cell_ptr->setUpper(upper_cell_ptr);
|
|
} else {
|
|
HCell* next_upper_cell_ptr;
|
|
do {
|
|
pointToCellIdx ++;
|
|
next_upper_cell_ptr = &row_upper->at(pointToCellIdx);
|
|
lower_cell_ptr->setUpper(next_upper_cell_ptr);
|
|
} while (lower_cell_ptr->getValFrom()
|
|
>= next_upper_cell_ptr->getValTo());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const double min[] { boundingBox->getMinX(), boundingBox->getMinY() };
|
|
const double max[] { boundingBox->getMaxX(), boundingBox->getMaxY() };
|
|
box.Set(true, min, max);
|
|
}
|
|
|
|
bool
|
|
pointComparisonY(RPoint p1, RPoint p2) {
|
|
return p1.y < p2.y;
|
|
}
|
|
|
|
RPoint
|
|
getRectangleCentre(Rectangle<2>* r) {
|
|
double a = (r->getMaxY() - r->getMinY()) / (double)2;
|
|
double b = (r->getMaxX() - r->getMinX()) / (double)2;
|
|
|
|
RPoint r_c { (r->getMinX())+b, (r->getMinY())+a };
|
|
|
|
return r_c;
|
|
}
|
|
|
|
// check if a rectangle is inside the irgrid2d bounding box
|
|
bool
|
|
insideBoundingBox(Rectangle<2>* bbox, Rectangle<2>* r) {
|
|
double le = bbox->getMinX();
|
|
double ri = bbox->getMaxX();
|
|
double bo = bbox->getMinY();
|
|
double to = bbox->getMaxY();
|
|
|
|
if (r->getMinX() >= le && r->getMaxX() <= ri
|
|
&& r->getMinY() >= bo && r->getMaxY() <=to) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::processInput(Stream<Rectangle<2>> rStream) {
|
|
rStream.open();
|
|
Rectangle<2>* next = rStream.request();
|
|
|
|
while(next != 0){
|
|
if (!insideBoundingBox(boundingBox, next)) {
|
|
// rectangle (partially) outside the bounding box is discarded
|
|
next = rStream.request();
|
|
continue;
|
|
}
|
|
|
|
points.push_back(getRectangleCentre(next));
|
|
next = rStream.request();
|
|
}
|
|
rStream.close();
|
|
|
|
// sort point vector by y-coordinates
|
|
std::sort(points.begin(), points.end(), pointComparisonY);
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::processInputVector(std::vector<Rectangle<2>>* rVector) {
|
|
for (Rectangle<2> bbox : *rVector) {
|
|
if (!insideBoundingBox(boundingBox, &bbox)) {
|
|
// rectangle (partially) outside the bounding box is discarded
|
|
continue;
|
|
}
|
|
points.push_back(getRectangleCentre(&bbox));
|
|
}
|
|
|
|
// sort point vector by y-coordinates
|
|
std::sort(points.begin(), points.end(), pointComparisonY);
|
|
}
|
|
|
|
Rectangle<2> *
|
|
IrregularGrid2D::getBoundingBox() {
|
|
return boundingBox;
|
|
}
|
|
|
|
int
|
|
IrregularGrid2D::getRowCount() {
|
|
return rowCount;
|
|
}
|
|
|
|
int
|
|
IrregularGrid2D::getCellCount() {
|
|
return cellCount;
|
|
}
|
|
|
|
void
|
|
IrregularGrid2D::setColumnVector(std::vector<VCell> column_vect) {
|
|
this->columnVector = column_vect;
|
|
}
|
|
|
|
std::vector<VCell>&
|
|
IrregularGrid2D::getColumnVector() {
|
|
return this->columnVector;
|
|
}
|
|
|
|
IrregularGrid2D::~IrregularGrid2D() {}
|
|
|
|
// Type Constructor irgrid2d
|
|
ListExpr
|
|
IrregularGrid2D::PropertyIrGrid2D()
|
|
{
|
|
ListExpr desclst = nl->TextAtom();
|
|
nl->AppendText(desclst,
|
|
"A <rectangle> bounding box followed by list of rows.\n"
|
|
"A row consists of two-element list (<from> <to>) "
|
|
"followed by list of cells.\n"
|
|
"A cell consists of four-element list\n(<from> <to> <id> <ref_id>).");
|
|
|
|
ListExpr formatlst = nl->TextAtom();
|
|
nl->AppendText(formatlst,
|
|
"((0.0 2.0 0.0 2.0)(\n(0.0 0.45)((0.0 0.4 1 3)(0.4 2.0 2 4))\n"
|
|
"(0.45 2.0)((0.0 0.3 3 -1)(0.3 2.0 4 -1))))");
|
|
|
|
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(IrregularGrid2D::BasicType()),
|
|
desclst,
|
|
formatlst)));
|
|
}
|
|
|
|
|
|
// Out function
|
|
ListExpr
|
|
IrregularGrid2D::OutIrGrid2D( ListExpr typeInfo, Word value ) {
|
|
IrregularGrid2D* irgrid2d = static_cast<IrregularGrid2D*>( value.addr );
|
|
|
|
if (irgrid2d != nullptr) {
|
|
Rectangle<2> * b_box = irgrid2d->getBoundingBox();
|
|
ListExpr bboxLstExpr = nl->FourElemList(
|
|
nl->RealAtom(b_box->getMinX()),
|
|
nl->RealAtom(b_box->getMaxX()),
|
|
nl->RealAtom(b_box->getMinY()),
|
|
nl->RealAtom(b_box->getMaxY()));
|
|
|
|
std::vector<VCell>* col = &irgrid2d->getColumnVector();
|
|
|
|
ListExpr rowLstExpr = nl->Empty();
|
|
ListExpr lastRowLstExpr;
|
|
if (col->size() > 0) {
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell* vcell = &col->at(colIdx);
|
|
if (colIdx > 0) {
|
|
lastRowLstExpr = nl->Append(lastRowLstExpr,
|
|
nl->TwoElemList(nl->RealAtom(vcell->getValFrom()),
|
|
nl->RealAtom(vcell->getValTo())));
|
|
} else {
|
|
rowLstExpr = nl->OneElemList(
|
|
nl->TwoElemList(nl->RealAtom(vcell->getValFrom()),
|
|
nl->RealAtom(vcell->getValTo())));
|
|
lastRowLstExpr = rowLstExpr;
|
|
}
|
|
|
|
std::vector<HCell>* row_vect = &col->at(colIdx).getRow();
|
|
if (row_vect->size() > 0) {
|
|
ListExpr cellLstExpr;
|
|
ListExpr lastCellLstExpr;
|
|
for(size_t rowIdx = 0; rowIdx < row_vect->size(); rowIdx++) {
|
|
HCell* row_cell = &row_vect->at(rowIdx);
|
|
|
|
if (rowIdx > 0) {
|
|
lastCellLstExpr = nl->Append(lastCellLstExpr,
|
|
nl->FourElemList(nl->RealAtom(row_cell->getValFrom()),
|
|
nl->RealAtom(row_cell->getValTo()),
|
|
nl->IntAtom(row_cell->getCellId()),
|
|
nl->IntAtom((row_cell->getUpper() != nullptr
|
|
? row_cell->getUpper()->getCellId() : -1))));
|
|
} else {
|
|
cellLstExpr = nl->OneElemList(nl->FourElemList
|
|
(nl->RealAtom(row_cell->getValFrom()),
|
|
nl->RealAtom(row_cell->getValTo()),
|
|
nl->IntAtom(row_cell->getCellId()),
|
|
nl->IntAtom((row_cell->getUpper() != nullptr
|
|
? row_cell->getUpper()->getCellId() : -1))));
|
|
lastCellLstExpr = cellLstExpr;
|
|
}
|
|
}
|
|
lastRowLstExpr = nl->Append(lastRowLstExpr, cellLstExpr);
|
|
}
|
|
}
|
|
}
|
|
ListExpr irgrid2dLstExpr = nl->TwoElemList(bboxLstExpr, rowLstExpr);
|
|
return irgrid2dLstExpr;
|
|
} else {
|
|
return (nl->SymbolAtom(Symbol::UNDEFINED()));
|
|
}
|
|
}
|
|
|
|
|
|
// In function
|
|
Word
|
|
IrregularGrid2D::InIrGrid2D( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct ) {
|
|
|
|
Word w = SetWord(Address(0));
|
|
|
|
try {
|
|
Rectangle<2>* bbox;
|
|
|
|
ListExpr bboxLstExpr;
|
|
ListExpr rowLstExpr;
|
|
|
|
if ( nl->ListLength( instance ) == 2 ) {
|
|
bboxLstExpr = nl->First(instance);
|
|
rowLstExpr = nl->Second(instance);
|
|
} else {
|
|
throw 1;
|
|
}
|
|
|
|
// fetch bounding box information from input
|
|
if (nl->ListLength( bboxLstExpr ) == 4 ) {
|
|
ListExpr left = nl->First(bboxLstExpr);
|
|
ListExpr right = nl->Second(bboxLstExpr);
|
|
ListExpr bottom = nl->Third(bboxLstExpr);
|
|
ListExpr top = nl->Fourth(bboxLstExpr);
|
|
|
|
if ( nl->IsAtom(left) && nl->AtomType(left) == RealType
|
|
&& nl->IsAtom(right) && nl->AtomType(right) == RealType
|
|
&& nl->IsAtom(bottom) && nl->AtomType(bottom) == RealType
|
|
&& nl->IsAtom(top) && nl->AtomType(top) == RealType) {
|
|
|
|
double min[2], max[2];
|
|
min[0] = nl->RealValue(left);
|
|
min[1] = nl->RealValue(bottom);
|
|
max[0] = nl->RealValue(right);
|
|
max[1] = nl->RealValue(top);
|
|
|
|
bbox = new Rectangle<2>(true, min, max);
|
|
} else {
|
|
throw 3;
|
|
}
|
|
|
|
} else {
|
|
throw 2;
|
|
}
|
|
|
|
// fetch row information from input
|
|
|
|
// temporary support structures
|
|
std::map<int, int> cellRef;
|
|
std::map<int, HCell*> cellIds;
|
|
|
|
std::vector<VCell> column_vec {};
|
|
int row_cnt = 0;
|
|
int cell_cnt = 0;
|
|
if (nl->ListLength( rowLstExpr ) > 1 ) {
|
|
VCell vc;
|
|
VCell* vc_ptr;
|
|
|
|
while(!nl->IsEmpty(rowLstExpr)) {
|
|
ListExpr lstElem = nl->First(rowLstExpr);
|
|
|
|
if ((nl->ListLength(lstElem)) == 2
|
|
&& (nl->IsAtom(nl->First(lstElem))
|
|
&& nl->IsAtom(nl->Second(lstElem))) ) {
|
|
// a two-element double list initiates a new row
|
|
row_cnt ++;
|
|
|
|
ListExpr fLst = nl->First(lstElem);
|
|
ListExpr tLst = nl->Second(lstElem);
|
|
|
|
if ( nl->AtomType(fLst) == RealType
|
|
&& nl->AtomType(tLst) == RealType) {
|
|
vc = VCell();
|
|
|
|
vc.setValFrom(nl->RealValue(fLst));
|
|
vc.setValTo(nl->RealValue(tLst));
|
|
column_vec.push_back(vc);
|
|
vc_ptr = &(column_vec.back());
|
|
}
|
|
} else {
|
|
ListExpr rowLstExpr = lstElem; // row
|
|
|
|
while(!nl->IsEmpty(rowLstExpr)) {
|
|
// cell information
|
|
ListExpr cellLstExpr = nl->First(rowLstExpr);
|
|
if (nl->ListLength( cellLstExpr ) == 4) {
|
|
// a four-element list initiates a new cell
|
|
ListExpr cv1Lst = nl->First(cellLstExpr);
|
|
ListExpr cv2Lst = nl->Second(cellLstExpr);
|
|
ListExpr cv3Lst = nl->Third(cellLstExpr);
|
|
ListExpr cv4Lst = nl->Fourth(cellLstExpr);
|
|
|
|
if ( nl->IsAtom(cv1Lst) && nl->AtomType(cv1Lst) == RealType
|
|
&& nl->IsAtom(cv2Lst) && nl->AtomType(cv2Lst) == RealType
|
|
&& nl->IsAtom(cv3Lst) && nl->AtomType(cv3Lst) == IntType
|
|
&& nl->IsAtom(cv4Lst) && nl->AtomType(cv4Lst) == IntType) {
|
|
HCell* hc = new HCell();
|
|
hc->setValFrom(nl->RealValue(cv1Lst));
|
|
hc->setValTo(nl->RealValue(cv2Lst));
|
|
hc->setCellId(nl->IntValue(cv3Lst));
|
|
// will be determined later
|
|
hc->setUpper(nullptr);
|
|
|
|
vc_ptr->getRow().push_back(*hc);
|
|
int cellRefId = nl->IntValue(cv4Lst);
|
|
if (cellRefId != -1) {
|
|
cellRef.insert(std::make_pair(
|
|
((int)nl->IntValue(cv3Lst)), cellRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
((int)nl->IntValue(cv3Lst)), hc));
|
|
} else {
|
|
throw 5;
|
|
}
|
|
}
|
|
rowLstExpr = nl->Rest(rowLstExpr);
|
|
}
|
|
}
|
|
// determine number of cells (one-time)
|
|
if (row_cnt > 0 && cell_cnt == 0) {
|
|
cell_cnt = vc_ptr->getRow().size();
|
|
}
|
|
rowLstExpr = nl->Rest(rowLstExpr);
|
|
}
|
|
} else {
|
|
throw 4;
|
|
}
|
|
|
|
// update pointer
|
|
if (row_cnt > 0 && cell_cnt > 0) {
|
|
for(int colIdx = 0; colIdx < row_cnt-1; colIdx++) {
|
|
VCell* vcell = &column_vec.at(colIdx);
|
|
std::vector<HCell>* row_vect = &vcell->getRow();
|
|
for(int cIdx = 0; cIdx < cell_cnt; cIdx++) {
|
|
HCell* hcell = &(*row_vect).at(cIdx);
|
|
if(cellRef.find(hcell->getCellId()) != cellRef.end()) {
|
|
int cell_ref = cellRef.at(hcell->getCellId());
|
|
if(cellIds.find(cell_ref) != cellIds.end()) {
|
|
hcell->setUpper(cellIds.at(cell_ref));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
correct = true;
|
|
IrregularGrid2D* irgrid = new IrregularGrid2D(*bbox, row_cnt, cell_cnt);
|
|
irgrid->setColumnVector(column_vec);
|
|
irgrid->box = *bbox;
|
|
w.addr = irgrid;
|
|
return w;
|
|
} catch (int e) {
|
|
correct = false;
|
|
cmsg.inFunError("Expecting a irgrid2d list representation. Exit code "
|
|
+ std::to_string(e));
|
|
|
|
return w;
|
|
}
|
|
}
|
|
|
|
bool
|
|
IrregularGrid2D::OpenIrGrid2D(SmiRecord& valueRecord,
|
|
size_t& offset, const ListExpr typeInfo, Word& value)
|
|
{
|
|
size_t size = sizeof(int);
|
|
size_t sizeD = sizeof(double);
|
|
int xr = 0, yb = 0;
|
|
size_t cols = 0, rows = 0;
|
|
double vf = 0.0, vt = 0.0; //column values
|
|
double rvf = 0.0, rvt = 0.0; // row values
|
|
int rid = 0, cellu = 0;
|
|
double xmin=0.0, xmax=0.0, ymin=0.0, ymax=0.0;
|
|
std::map<int, int> cellRef;
|
|
std::map<int, HCell*> cellIds;
|
|
|
|
std::vector<VCell> column_vec {};
|
|
VCell vc;
|
|
VCell* vc_ptr;
|
|
bool ok = true;
|
|
|
|
ok = ok && valueRecord.Read( &xmin, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &xmax, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &ymin, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &ymax, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
ok = ok && valueRecord.Read( &xr, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &yb, size, offset );
|
|
offset += size;
|
|
|
|
// colsize
|
|
ok = ok && valueRecord.Read( &cols, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t i = 0; i < cols; i++)
|
|
{
|
|
vc = VCell();
|
|
ok = ok && valueRecord.Read( &vf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &vt, sizeD, offset );
|
|
offset += sizeD;
|
|
vc.setValFrom(vf);
|
|
vc.setValTo(vt);
|
|
column_vec.push_back(vc);
|
|
vc_ptr = &(column_vec.back());
|
|
|
|
//rowsize
|
|
ok = ok && valueRecord.Read( &rows, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t j = 0; j < rows; j++)
|
|
{
|
|
HCell* hc = new HCell();
|
|
ok = ok && valueRecord.Read( &rvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &rvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Read( &rid, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Read( &cellu, size, offset );
|
|
offset += size;
|
|
hc->setValFrom(rvf);
|
|
hc->setValTo(rvt);
|
|
hc->setCellId(rid);
|
|
hc->setUpper(nullptr);
|
|
vc_ptr->getRow().push_back(*hc);
|
|
int cellRefId = cellu;
|
|
if (cellRefId != -1) {
|
|
cellRef.insert(std::make_pair(
|
|
rid, cellRefId));
|
|
}
|
|
cellIds.insert(std::make_pair(
|
|
rid, hc));
|
|
}
|
|
}
|
|
// update pointer
|
|
if (xr > 0 && yb > 0) {
|
|
for(int colIdx = 0; colIdx < xr; colIdx++) {
|
|
VCell* vcell = &column_vec.at(colIdx);
|
|
std::vector<HCell>* row_vect = &vcell->getRow();
|
|
for(int cIdx = 0; cIdx < yb; cIdx++) {
|
|
HCell* hcell = &(*row_vect).at(cIdx);
|
|
if(cellRef.find(hcell->getCellId()) != cellRef.end()) {
|
|
int cell_ref = cellRef.at(hcell->getCellId());
|
|
if(cellIds.find(cell_ref) != cellIds.end()) {
|
|
hcell->setUpper(cellIds.at(cell_ref));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
const double min[] { xmin, ymin };
|
|
const double max[] { xmax, ymax };
|
|
Rectangle<2> *bbox = new Rectangle<2>(true, min, max);
|
|
IrregularGrid2D* irgrid = new IrregularGrid2D(*bbox, xr, yb);
|
|
irgrid->setColumnVector(column_vec);
|
|
irgrid->box = *bbox;
|
|
value.addr = irgrid;
|
|
|
|
return ok;
|
|
}
|
|
|
|
bool
|
|
IrregularGrid2D::SaveIrGrid2D(SmiRecord& valueRecord,
|
|
size_t& offset, const ListExpr typeInfo, Word& value)
|
|
{
|
|
IrregularGrid2D* r = static_cast<IrregularGrid2D*>( value.addr );
|
|
|
|
size_t size = sizeof(int);
|
|
size_t sizeD = sizeof(double);
|
|
bool ok = true;
|
|
|
|
double minx = r->box.getMinX();//->getMaxX();
|
|
double maxx = r->box.getMaxX();//->getMaxX();
|
|
double miny = r->box.getMinY();// b_box->getMinY();
|
|
double maxy = r->box.getMaxY(); // b_box->getMaxY();
|
|
|
|
ok = ok && valueRecord.Write(&minx, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&maxx, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&miny, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&maxy, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
ok = ok && valueRecord.Write(&r->rowCount, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&r->cellCount, size, offset );
|
|
offset += size;
|
|
|
|
std::vector<VCell>* col = &r->getColumnVector();
|
|
size_t cols = col->size();
|
|
if (col->size() > 0) {
|
|
ok = ok && valueRecord.Write(&cols, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t colIdx = 0; colIdx < col->size(); colIdx++) {
|
|
VCell* vcell = &col->at(colIdx);
|
|
double vf = vcell->getValFrom();
|
|
double vt = vcell->getValTo();
|
|
ok = ok && valueRecord.Write(&vf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&vt, sizeD, offset );
|
|
offset += sizeD;
|
|
|
|
|
|
std::vector<HCell>* row_vect = &col->at(colIdx).getRow();
|
|
size_t rows = row_vect->size();
|
|
if (row_vect->size() > 0) {
|
|
ok = ok && valueRecord.Write(&rows, sizeof(size_t), offset );
|
|
offset += sizeof(size_t);
|
|
for(size_t rowIdx = 0; rowIdx < row_vect->size(); rowIdx++) {
|
|
HCell* row_cell = &row_vect->at(rowIdx);
|
|
double rvf = row_cell->getValFrom();
|
|
double rvt = row_cell->getValTo();
|
|
int ri = row_cell->getCellId();
|
|
int ru = row_cell->getUpper() != nullptr
|
|
? row_cell->getUpper()->getCellId() : -1;
|
|
ok = ok && valueRecord.Write(&rvf, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&rvt, sizeD, offset );
|
|
offset += sizeD;
|
|
ok = ok && valueRecord.Write(&ri, size, offset );
|
|
offset += size;
|
|
ok = ok && valueRecord.Write(&ru, size, offset );
|
|
offset += size;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
// This function checks whether the type constructor is applied correctly.
|
|
bool
|
|
IrregularGrid2D::KindCheckIrGrid2D( ListExpr type, ListExpr& errorInfo )
|
|
{
|
|
return (nl->IsEqual( type, IrregularGrid2D::BasicType() ));
|
|
}
|
|
|
|
// Close -function
|
|
void
|
|
IrregularGrid2D::CloseIrGrid2D( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete (IrregularGrid2D *)w.addr;
|
|
w.addr = 0;
|
|
}
|
|
|
|
// Clone function
|
|
Word
|
|
IrregularGrid2D::CloneIrGrid2D( const ListExpr typeInfo, const Word& w )
|
|
{
|
|
IrregularGrid2D *g = new IrregularGrid2D( *((IrregularGrid2D *)w.addr) );
|
|
return SetWord( g );
|
|
}
|
|
|
|
// Create function
|
|
Word
|
|
IrregularGrid2D::CreateIrGrid2D( const ListExpr typeInfo )
|
|
{
|
|
return SetWord( new IrregularGrid2D() );
|
|
}
|
|
|
|
// Delete function
|
|
void
|
|
IrregularGrid2D::DeleteIrGrid2D( const ListExpr typeInfo, Word& w )
|
|
{
|
|
delete (IrregularGrid2D *)w.addr;
|
|
w.addr = 0;
|
|
}
|
|
|
|
// SizeOf function
|
|
int
|
|
IrregularGrid2D::SizeOfIrGrid2D()
|
|
{
|
|
return sizeof(IrregularGrid2D);
|
|
}
|
|
|
|
/*
|
|
Type mapping function ~IrGrid2dFeedTypeMap~
|
|
|
|
It is used for the ~feed~ operator.
|
|
|
|
*/
|
|
ListExpr
|
|
IrregularGrid2D::IrGrid2dFeedTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 1)) {
|
|
|
|
ListExpr first = nl->First(args);
|
|
if (IrregularGrid2D::checkType(first)) {
|
|
ListExpr resAttrList = nl->ThreeElemList(
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Id"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Count"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Cell"),
|
|
nl->SymbolAtom(Rectangle<2>::BasicType())));
|
|
|
|
return nl->TwoElemList(listutils::basicSymbol<Stream<Tuple>>(),
|
|
nl->TwoElemList(
|
|
listutils::basicSymbol<Tuple>(),
|
|
resAttrList));
|
|
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following argument is expected:"
|
|
" irgrid2d";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
// for value mapping function of ~feed~ operator
|
|
struct IrGridTupleInfo
|
|
{
|
|
std::vector<CellInfo*> cell_info_vect;
|
|
unsigned int currentTupleIdx;
|
|
ListExpr numTupleTypeList;
|
|
|
|
void init(IrregularGrid2D *irgrid2d_in) {
|
|
currentTupleIdx = 0;
|
|
cell_info_vect = IrregularGrid2D::getCellInfoVector(irgrid2d_in);
|
|
|
|
ListExpr tupleTypeLst = nl->TwoElemList(
|
|
nl->SymbolAtom(Tuple::BasicType()),
|
|
nl->ThreeElemList(
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Id"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Count"),
|
|
nl->SymbolAtom(CcInt::BasicType())),
|
|
nl->TwoElemList(
|
|
nl->SymbolAtom("Cell"),
|
|
nl->SymbolAtom(Rectangle<2>::BasicType()))));
|
|
|
|
SecondoCatalog* sc = SecondoSystem::GetCatalog();
|
|
numTupleTypeList = sc->NumericType(tupleTypeLst);
|
|
}
|
|
|
|
TupleType* getTupleType() {
|
|
TupleType *tupleType = new TupleType(numTupleTypeList);
|
|
|
|
return tupleType;
|
|
}
|
|
|
|
Tuple* getNext(TupleType *ttype) {
|
|
if (currentTupleIdx < cell_info_vect.size()) {
|
|
CellInfo * cell_info = cell_info_vect.at(currentTupleIdx);
|
|
int tp_p1 = cell_info->cellId;
|
|
int tp_p2 = cell_info->statNbrOfPoints;
|
|
Rectangle<2> tp_p3 = *cell_info->cell;
|
|
|
|
Tuple *tuple = new Tuple(ttype);
|
|
tuple->PutAttribute(0, new CcInt(true, tp_p1));
|
|
tuple->PutAttribute(1, new CcInt(true, tp_p2));
|
|
tuple->PutAttribute(2, new Rectangle<2> (tp_p3));
|
|
|
|
currentTupleIdx++;
|
|
return tuple;
|
|
} else {
|
|
return nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
/*
|
|
Value mapping function of operator ~feed~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid2D::IrGrid2dValueMapFeed( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
IrregularGrid2D *input_irgrid2d_ptr =
|
|
static_cast<IrregularGrid2D*>( args[0].addr );
|
|
|
|
IrGridTupleInfo* tp_info = static_cast<IrGridTupleInfo*>(local.addr);
|
|
TupleType* tupleType = nullptr;
|
|
Tuple* tuple = nullptr;
|
|
|
|
switch (message) {
|
|
case OPEN: {
|
|
tp_info = new IrGridTupleInfo();
|
|
tp_info->init(input_irgrid2d_ptr);
|
|
local.addr = tp_info;
|
|
|
|
return 0;
|
|
}
|
|
case REQUEST: {
|
|
if (local.addr) {
|
|
tp_info = ((IrGridTupleInfo*)local.addr);
|
|
tupleType = tp_info->getTupleType();
|
|
} else {
|
|
return CANCEL;
|
|
}
|
|
// get next tuple
|
|
tuple = tp_info->getNext(tupleType);
|
|
if (tuple != nullptr) {
|
|
result.addr = tuple;
|
|
return YIELD;
|
|
} else {
|
|
result.addr = 0;
|
|
return CANCEL;
|
|
}
|
|
}
|
|
case CLOSE: {
|
|
if (local.addr) {
|
|
tp_info = ((IrGridTupleInfo*)local.addr);
|
|
delete tp_info;
|
|
local.addr = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
Type mapping function ~IrGrid2dCellnosTypeMap~
|
|
|
|
It is used for the ~cellnos\_ir~ operator.
|
|
|
|
*/
|
|
ListExpr
|
|
IrregularGrid2D::IrGrid2dCellnosTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 2)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
|
|
if (IrregularGrid2D::checkType(first) && Rectangle<2>::checkType(second)) {
|
|
return nl->SymbolAtom(collection::IntSet::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following two arguments are expected:"
|
|
" irgrid2d x rect";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid2D::IrGrid2dSCCTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 4)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
ListExpr third = nl->Third(args);
|
|
ListExpr fourth = nl->Fourth(args);
|
|
|
|
if (IrregularGrid2D::checkType(first) && Rectangle<2>::checkType(second)
|
|
&& Rectangle<2>::checkType(third) && CcInt::checkType(fourth)) {
|
|
return nl->SymbolAtom(CcBool::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following four arguments are expected:"
|
|
" irgrid2d x rect x rect x int";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
ListExpr
|
|
IrregularGrid2D::IrGrid2dGetCellTypeMap( ListExpr args )
|
|
{
|
|
if(nl->HasLength(args, 2)) {
|
|
ListExpr first = nl->First(args);
|
|
ListExpr second = nl->Second(args);
|
|
|
|
if (IrregularGrid2D::checkType(first) && CcInt::checkType(second)) {
|
|
return nl->SymbolAtom(Rectangle<2>::BasicType());
|
|
}
|
|
}
|
|
|
|
const std::string errMsg = "The following two arguments are expected:"
|
|
" irgrid2d x int";
|
|
|
|
return listutils::typeError(errMsg);
|
|
}
|
|
|
|
|
|
|
|
template <class C>
|
|
bool
|
|
InCell(C cell, double val) {
|
|
return (val >= cell.getValFrom()
|
|
&& val < cell.getValTo());
|
|
}
|
|
|
|
template <class C>
|
|
bool
|
|
GtCell(C cell, double val) {
|
|
return (cell.getValFrom() >= val);
|
|
}
|
|
|
|
template <class C>
|
|
int
|
|
CellBS(const std::vector<C>* c_vec, int start, int end, const double val) {
|
|
if (start > end) {
|
|
return -1;
|
|
}
|
|
|
|
const int mid = start + ((end - start) / 2);
|
|
|
|
if (InCell(c_vec->at(mid), val)) {
|
|
return mid;
|
|
} else if (GtCell(c_vec->at(mid), val)) {
|
|
return CellBS(c_vec, start, mid-1, val);
|
|
}
|
|
|
|
return CellBS(c_vec, mid+1, end, val);
|
|
}
|
|
|
|
void cellNum( IrregularGrid2D *input_irgrid2d_ptr,
|
|
Rectangle<2> *search_window_ptr, std::set<int> *cell_ids)
|
|
{
|
|
std::vector<VCell>* col = &input_irgrid2d_ptr->getColumnVector();
|
|
|
|
double le = search_window_ptr->getMinX();
|
|
double ri = search_window_ptr->getMaxX();
|
|
double bo = search_window_ptr->getMinY();
|
|
double to = search_window_ptr->getMaxY();
|
|
|
|
int pos_bo = CellBS(col, 0, col->size(), bo);
|
|
if (pos_bo != -1) {
|
|
VCell vCell = col->at(pos_bo);
|
|
std::vector<HCell>* row = &vCell.getRow();
|
|
|
|
int pos_le = CellBS(row, 0, row->size(), le);
|
|
if (pos_le != -1) {
|
|
|
|
// collect ids
|
|
unsigned int cellIdx = pos_le;
|
|
while (cellIdx < row->size()) {
|
|
HCell i = row->at(cellIdx);
|
|
cell_ids->insert(i.getCellId());
|
|
|
|
if ((ri >= i.getValFrom() && ri < i.getValTo())
|
|
|| (cellIdx == row->size()-1 && ri >= i.getValFrom())) {
|
|
HCell fi = row->at(pos_le);
|
|
if (to >= vCell.getValTo() && fi.getUpper() != nullptr) {
|
|
vCell = col->at(++pos_bo);
|
|
row = &vCell.getRow();
|
|
|
|
HCell * u = fi.getUpper();
|
|
int nbr_cpr = input_irgrid2d_ptr->getCellCount();
|
|
int cid_pos = (u->getCellId()) % nbr_cpr;
|
|
pos_le = cid_pos == 0 ? nbr_cpr-1 : cid_pos-1;
|
|
|
|
cellIdx = pos_le-1;
|
|
} else if (to < vCell.getValTo() || fi.getUpper() == nullptr) {
|
|
break;
|
|
}
|
|
}
|
|
cellIdx++;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Value mapping function of operator ~cellnos\_ir~
|
|
|
|
*/
|
|
int
|
|
IrregularGrid2D::IrGrid2dValueMapCellnos( Word* args, Word& result, int message,
|
|
Word& local, Supplier s ) {
|
|
IrregularGrid2D *input_irgrid2d_ptr
|
|
= static_cast<IrregularGrid2D*>( args[0].addr );
|
|
|
|
Rectangle<2> *search_window_ptr
|
|
= static_cast<Rectangle<2>*>( args[1].addr );
|
|
|
|
if (input_irgrid2d_ptr != nullptr && search_window_ptr != nullptr) {
|
|
std::set<int> cell_ids;
|
|
|
|
result = qp->ResultStorage(s);
|
|
collection::IntSet* res = (collection::IntSet*) result.addr;
|
|
|
|
Rectangle<2> * b_box = input_irgrid2d_ptr->getBoundingBox();
|
|
if (!search_window_ptr->Intersects(*b_box)) {
|
|
cell_ids.insert(0);
|
|
res->setTo(cell_ids);
|
|
return 0;
|
|
}
|
|
|
|
// 'truncate' search window in case of partial cutting
|
|
if (!b_box->Contains(*search_window_ptr)) {
|
|
search_window_ptr = new Rectangle<2>(
|
|
search_window_ptr->Intersection(*b_box));
|
|
|
|
cell_ids.insert(0);
|
|
}
|
|
|
|
cellNum(input_irgrid2d_ptr, search_window_ptr, &cell_ids);
|
|
|
|
res->setTo(cell_ids);
|
|
|
|
return 0;
|
|
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int
|
|
IrregularGrid2D::IrGrid2dValueMapSCC( Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
IrregularGrid2D *input_irgrid2d_ptr
|
|
= static_cast<IrregularGrid2D*>( args[0].addr );
|
|
|
|
Rectangle<2> *search_window_ptr
|
|
= static_cast<Rectangle<2>*>( args[1].addr );
|
|
Rectangle<2> *search_window_ptr2
|
|
= static_cast<Rectangle<2>*>( args[2].addr );
|
|
|
|
CcInt* cellno_ptr = static_cast<CcInt*>(args[3].addr);
|
|
int cellno = cellno_ptr->GetIntval();
|
|
|
|
std::set<int> cell_ids;
|
|
std::set<int> cell_ids2;
|
|
|
|
|
|
if (input_irgrid2d_ptr != nullptr && search_window_ptr != nullptr
|
|
&& search_window_ptr2 != nullptr)
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
CcBool *res = (CcBool*) result.addr;
|
|
bool boolval = false;
|
|
|
|
Rectangle<2> * b_box = input_irgrid2d_ptr->getBoundingBox();
|
|
if (!search_window_ptr->Intersects(*b_box)
|
|
|| !search_window_ptr2->Intersects(*b_box)) {
|
|
return 0;
|
|
}
|
|
|
|
// 'truncate' search window in case of partial cutting
|
|
if (!b_box->Contains(*search_window_ptr)) {
|
|
search_window_ptr = new Rectangle<2>(
|
|
search_window_ptr->Intersection(*b_box));
|
|
|
|
cell_ids.insert(0);
|
|
}
|
|
|
|
if (!b_box->Contains(*search_window_ptr2)) {
|
|
search_window_ptr2 = new Rectangle<2>(
|
|
search_window_ptr2->Intersection(*b_box));
|
|
|
|
cell_ids2.insert(0);
|
|
}
|
|
|
|
cellNum(input_irgrid2d_ptr, search_window_ptr, &cell_ids);
|
|
cellNum(input_irgrid2d_ptr, search_window_ptr2, &cell_ids2);
|
|
|
|
std::vector<int> v(sizeof(cell_ids)+ sizeof(cell_ids2));
|
|
std::vector<int>::iterator it;
|
|
|
|
it=std::set_intersection (cell_ids.begin(), cell_ids.end(),
|
|
cell_ids2.begin(), cell_ids2.end(), v.begin());
|
|
v.resize(it-v.begin());
|
|
|
|
if(v.empty()) {
|
|
//no intersection between rectangles
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
|
|
if(v[0] == cellno)
|
|
{
|
|
boolval = true;
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
|
|
res->Set( true, boolval);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
IrregularGrid2D::IrGrid2dValueMapGetCell(Word* args, Word& result, int message,
|
|
Word& local, Supplier s)
|
|
{
|
|
IrregularGrid2D *input_irgrid2d_ptr
|
|
= static_cast<IrregularGrid2D*>( args[0].addr );
|
|
|
|
CcInt* cellno_ptr = static_cast<CcInt*>(args[1].addr);
|
|
int cellno = cellno_ptr->GetIntval();
|
|
|
|
if (input_irgrid2d_ptr != nullptr)
|
|
{
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<2> *res = (Rectangle<2>*) result.addr;
|
|
|
|
std::vector<VCell>* column = &input_irgrid2d_ptr->getColumnVector();
|
|
for(size_t i = 0; i < column->size(); i++)
|
|
{
|
|
VCell vCell = column->at(i);
|
|
std::vector<HCell>* row = &vCell.getRow();
|
|
for(size_t ii=0; ii < row->size(); ii++)
|
|
{
|
|
HCell hCell = row->at(ii);
|
|
if(cellno == hCell.getCellId())
|
|
{
|
|
double min[2], max[2];
|
|
min[0] = hCell.getValFrom();
|
|
min[1] = vCell.getValFrom();
|
|
max[0] = hCell.getValTo();
|
|
max[1] = vCell.getValTo();
|
|
res->Set(true, min, max);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
|
}
|