/* ---- 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 ---- Declarations for the RasterSpatialAlgebra May, 2007 Leonardo Azevedo, Rafael Brand */ #ifndef __RASTERSPATIAL_ALGEBRA_H__ #define __RASTERSPATIAL_ALGEBRA_H__ /* 1 Preliminaries 1.1 Includes and global declarations */ #include "Algebras/Raster/RasterAlgebra.h" #include "Algebras/Spatial/SpatialAlgebra.h" #include #include "Tools/Flob/DbArray.h" #include "Algebras/Raster/Signature/GenerateRaster.h" class Raster4CRS; namespace rasterspatial{ extern long compareSignatures4CRS( Signature4CRS *assinat4crs1, Signature4CRS *assinat4crs2, MBR &mbrIntersection); /* 2 Data structures 2.1 RasterRegion */ class CRasterRegion: public Region { private: public: static const std::string BasicType() { return "rasterRegion"; } Raster4CRS *rasterSignature; //potency dx dy signature... DbArray rasterFLOB; bool rasterDefined; /* Do not use this constructor. */ CRasterRegion(){}; CRasterRegion(const Region& rr); CRasterRegion(const CRasterRegion& rr); CRasterRegion(int i); Raster4CRS *getRaster() ; Raster4CRS *readRaster() const; void setRaster(Raster4CRS *raster); Raster4CRS *calculateRaster(int signatureType) const; void Raster4CRSToFLOB(); void FLOBToRaster4CRS(); bool Intersects(CRasterRegion &rr2); int preIntersects( const Region& r) const; bool MBRIntersects( const Region& r) const; bool ExactIntersects( const Region& r) const; CRasterRegion* Clone() const { return new CRasterRegion(*(const CRasterRegion *)this); } int NumOfFLOBs(void) const; Flob *GetFLOB(const int i); CRasterRegion& operator=( CRasterRegion& r ); }; CRasterRegion& CRasterRegion::operator=( CRasterRegion& r ) { Region::operator=((Region) r); rasterFLOB.clean(); if( r.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( r.rasterFLOB.Size() ); for( int i = 0; i < r.rasterFLOB.Size(); i++ ) { unsigned long hs; r.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } } setRaster(r.getRaster()->Clone()); return *this; } /* 2.1.1 Constructors. */ CRasterRegion::CRasterRegion(const Region& rr) : Region(rr), rasterFLOB(0){ rasterDefined = false; rasterFLOB.clean(); //rasterSignature = calculateRaster(); rasterFLOB.clean(); rasterSignature = NULL; }; CRasterRegion::CRasterRegion(const CRasterRegion& rr) : Region(rr), rasterFLOB(0){ rasterDefined = false; rasterFLOB.clean(); if( rr.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( rr.rasterFLOB.Size() ); for( int i = 0; i < rr.rasterFLOB.Size(); i++ ) { unsigned long hs; rr.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } FLOBToRaster4CRS(); } else { setRaster(rr.readRaster()->Clone()); } }; CRasterRegion::CRasterRegion(int i) : Region(i), rasterFLOB(0){ //rasterFLOB.Clear(); rasterDefined = false; rasterSignature = NULL; }; /* 2.1.2 getRaster. */ Raster4CRS *CRasterRegion::getRaster() { if (IsEmpty()) return NULL; if (rasterDefined) return rasterSignature; else { rasterDefined = true; rasterSignature = calculateRaster(3); return rasterSignature; } }; Raster4CRS *CRasterRegion::readRaster() const{ if (!IsEmpty() && rasterDefined) { return rasterSignature; } else { return NULL; } }; void CRasterRegion::setRaster(Raster4CRS *raster){ rasterDefined = true; rasterSignature = raster; Raster4CRSToFLOB(); }; Raster4CRS *CRasterRegion::calculateRaster(int signatureType) const{ Raster4CRS* raster = NULL; Signature4CRS* signature = NULL; const Region *r1 = this; int potency =0; do { SignatureType type; if (signatureType == 3) type = SIGNAT_3CRS; else if (signatureType == 4) type = SIGNAT_4CRS; else cout << "Invalid signatureType" << std::endl; signature = GeraRasterSecondo::generateRaster( 1, r1, NULL, NULL, potency, type); potency++; } while (signature==NULL); raster = new Raster4CRS(signature->fullMap(), signatureType); raster->signatureType = signatureType; return raster; }; /* 2.1.3 Intersect functions. */ bool CRasterRegion::Intersects(CRasterRegion &rr2) { int result; result = preIntersects((Region)rr2); if(result == 0 || result == 1) return result == 1; //MBR test if(!MBRIntersects((Region)rr2)) return false; //Raster signature test MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rr2.getRaster(), mbrIntersection); if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects; //exact test return ExactIntersects((Region) rr2); } int CRasterRegion::preIntersects( const Region& r) const { assert( IsOrdered() && r.IsOrdered() ); if( IsEmpty() && r.IsEmpty() ) return 1; if( IsEmpty() || r.IsEmpty() ) return 0; return 2; } bool CRasterRegion::MBRIntersects( const Region& r) const { if( !BoundingBox().Intersects( r.BoundingBox() ) ) return false; return true; } // Function RegionIntersects used for distinguish the first and second steps //of the Intersects funcion bool CRasterRegion::ExactIntersects(const Region &r) const { if( Inside( r ) || r.Inside( *this ) ) return true; HalfSegment hs1, hs2; for( int i = 0; i < Size(); i++ ) { Get( i, hs1 ); if( hs1.IsLeftDomPoint() ) { for( int j = 0; j < r.Size(); j++ ) { r.Get( j, hs2 ); if( hs2.IsLeftDomPoint() && hs1.Intersects( hs2 ) ) return true; } } } return false; } /* 2.1.4. Function that converts a Raster4CRS to a FLOB */ void CRasterRegion::Raster4CRSToFLOB(){ if (rasterDefined) { Signature4CRS::Weight filling; rasterFLOB.clean(); rasterFLOB.Append(rasterSignature->signatureType); rasterFLOB.Append(rasterSignature->map->potency); rasterFLOB.Append(rasterSignature->map->dx); rasterFLOB.Append(rasterSignature->map->dy); long cellSize = 1l << rasterSignature->map->potency; long computedCells = 0; unsigned long FLOBelement = 0; long minXcell = rasterSignature->map->mbr.min.x - (rasterSignature->map->mbr.min.x % cellSize) - (cellSize * (rasterSignature->map->mbr.min.x < 0 && (rasterSignature->map->mbr.min.x % cellSize != 0) ? 1 : 0)); long minYcell = rasterSignature->map->mbr.min.y - (rasterSignature->map->mbr.min.y % cellSize) - (cellSize * (rasterSignature->map->mbr.min.y < 0 && (rasterSignature->map->mbr.min.y % cellSize != 0) ? 1 : 0)); for( long i=minXcell; i <= rasterSignature->map->mbr.max.x; i+=cellSize) { for(long j=minYcell; j <= rasterSignature->map->mbr.max.y; j+=cellSize) { filling = rasterSignature->block(i,j,cellSize); FLOBelement = (FLOBelement << 2) | filling; computedCells++; if (computedCells == (sizeof (unsigned long) * 4) ) { rasterFLOB.Append(FLOBelement); FLOBelement = 0; computedCells = 0; } } } if (computedCells > 0) { rasterFLOB.Append(FLOBelement); } } else { if (rasterFLOB.Size() > 0) { rasterFLOB.clean(); } } } /* 2.1.5. Function that converts a FLOB to Raster4CRS */ void CRasterRegion::FLOBToRaster4CRS(){ unsigned long potency, dx, dy, signatureType; unsigned long l; rasterFLOB.Get(0, l); signatureType = l; rasterFLOB.Get(1, l); potency = l; rasterFLOB.Get(2, l); dx = l; rasterFLOB.Get(3, l); dy = l; long cellSize = 1l << potency; long numElements = dx * dy; Signature4CRS::Weight *filling = new Signature4CRS::Weight[numElements]; for (int i = 0; i < numElements; i++) filling[i] = Signature4CRS::Empty; unsigned long pFLOBelement; unsigned long FLOBelement; int positionInElement = -1; unsigned int currentCell = 0; Signature4CRS::Weight ocup; int positionInFLOB = 0; long int minXcell = (long int)(this->BoundingBox().MinD(0) - ((long int)this->BoundingBox().MinD(0) % cellSize) - (cellSize * (this->BoundingBox().MinD(0) < 0 && ((long int)this->BoundingBox().MinD(0) % cellSize != 0) ? 1 : 0))); long int minYcell = (long int)(this->BoundingBox().MinD(1) - ((long int)this->BoundingBox().MinD(1) % cellSize) - (cellSize * (this->BoundingBox().MinD(1) < 0 && ((long int)this->BoundingBox().MinD(1) % cellSize != 0) ? 1 : 0))); Coordinate cmin ((long int)this->BoundingBox().MinD(0), (long int)this->BoundingBox().MinD(1)); Coordinate cmax ((long int)this->BoundingBox().MaxD(0), (long int)this->BoundingBox().MaxD(1)); rasterSignature = new Raster4CRS(1, cmin, cmax, cellSize, dx, dy, filling, signatureType); long totalCells = (long)((this->BoundingBox().MaxD(0) - minXcell + 1) * (this->BoundingBox().MaxD(1) - minYcell + 1)); for( long i=minXcell; i <= this->BoundingBox().MaxD(0); i+=cellSize) for(long j=minYcell; j <= this->BoundingBox().MaxD(1); j+=cellSize) { if (positionInElement < 0){ // the 4 itens at the beggining are signatureType, potency, dx and dy rasterFLOB.Get(positionInFLOB + 4, pFLOBelement); FLOBelement = pFLOBelement; positionInElement = 0; //if (dx * dy - currentCell < sizeof(unsigned long) * 4) if ((totalCells - currentCell) < (int)sizeof(unsigned long) * 4) //positionInElement = (dx * dy - currentCell) - 1; positionInElement = (totalCells - currentCell) - 1; else positionInElement = sizeof(unsigned long) * 4 - 1; positionInFLOB++; } switch ( (FLOBelement >> (positionInElement * 2)) & 3 ) { case 0: ocup = Signature4CRS::Empty; break; case 1: ocup = Signature4CRS::Weak; break; case 2: ocup = Signature4CRS::Strong; break; default: ocup = Signature4CRS::Full; } rasterSignature->mapBlock((unsigned)((i - minXcell) / cellSize), (unsigned)((j - minYcell) / cellSize), ocup); positionInElement--; currentCell++; } rasterDefined = true; } int CRasterRegion::NumOfFLOBs(void) const { return 2; } Flob *CRasterRegion::GetFLOB(const int i){ assert(i == 0 || i == 1); return i == 0 ? Region::GetFLOB(0) : &rasterFLOB; } /* 2.2. RasterLine */ class CRasterLine: public Line { private: //Raster4CRS *rasterSignature; //potency dx dy signature... DbArray rasterFLOB; public: static const std::string BasicType() { return "rasterLine"; } Raster4CRS *rasterSignature; bool rasterDefined; CRasterLine() {}; CRasterLine(Line l); CRasterLine(const CRasterLine& rl); CRasterLine(int i); Raster4CRS *getRaster(); Raster4CRS *readRaster() const; void setRaster(Raster4CRS *raster); Raster4CRS *calculateRaster(int signatureType) const; bool Intersects(CRasterLine &rl2); int preIntersects( const Line& l) const; bool MBRIntersects( const Line& l) const; bool ExactIntersects( const Line& l) const; bool Intersects(CRasterRegion &rr2); int preIntersects( const Region& r) const; bool MBRIntersects( const Region& r) const; bool ExactIntersects( const Region& r) const; void Raster4CRSToFLOB(); void FLOBToRaster4CRS(); virtual CRasterLine* Clone() const { return new CRasterLine(*(const CRasterLine *)this); } int NumOfFLOBs(void) const; Flob *GetFLOB(const int i); CRasterLine& operator=( CRasterLine& rl ); }; CRasterLine& CRasterLine::operator=( CRasterLine& rl ) { Line::operator=((Line) rl); rasterFLOB.clean(); if( rl.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( rl.rasterFLOB.Size() ); for( int i = 0; i < rl.rasterFLOB.Size(); i++ ) { unsigned long hs; rl.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } } setRaster(rl.getRaster()->Clone()); return *this; } CRasterLine::CRasterLine(Line l) : Line(l), rasterFLOB(0){ //rasterSignature = calculateRaster(); rasterDefined = false; rasterSignature = NULL; }; CRasterLine::CRasterLine(const CRasterLine& rl) : Line(rl), rasterFLOB(0){ rasterDefined = false; rasterFLOB.clean(); rasterFLOB.clean(); if( rl.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( rl.rasterFLOB.Size() ); for( int i = 0; i < rl.rasterFLOB.Size(); i++ ) { unsigned long hs; rl.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } } setRaster(rl.readRaster()->Clone()); }; CRasterLine::CRasterLine(int i) : Line(i), rasterFLOB(0){ //if(i > 0) //rasterSignature = calculateRaster(); rasterDefined = false; rasterSignature = NULL; }; Raster4CRS *CRasterLine::getRaster(){ if (IsEmpty()) return NULL; if (rasterDefined) return rasterSignature; else { rasterDefined = true; rasterSignature = calculateRaster(3); return rasterSignature; } }; Raster4CRS *CRasterLine::readRaster() const{ if (!IsEmpty() && rasterDefined) return rasterSignature; else return NULL; }; void CRasterLine::setRaster(Raster4CRS *raster){ rasterDefined = true; rasterSignature = raster; Raster4CRSToFLOB(); }; Raster4CRS *CRasterLine::calculateRaster(int signatureType) const{ Raster4CRS* raster; Signature4CRS* signature = NULL; const Line *l1 = this; int potency =0; do { SignatureType type; if (signatureType == 3) type = SIGNAT_3CRS; else if (signatureType == 4) type = SIGNAT_4CRS; else cout << "Invalid signatureType" << std::endl; signature = GeraRasterSecondo::generateRaster( 1, NULL, l1, NULL, potency, type); potency++; } while (signature==NULL); raster = new Raster4CRS(signature->fullMap(), signatureType); raster->signatureType = signatureType; return raster; }; bool CRasterLine::Intersects(CRasterLine &rl2) { int result; result = preIntersects((Line)rl2); if(result == 0 || result == 1) return result == 1; if(!MBRIntersects((Line)rl2)) { return false; } MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rl2.getRaster(), mbrIntersection); //FALSE_HIT 0 //HIT 1 //INCONCLUSIVE 2 if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects == 1; //exact test return ExactIntersects((Line)rl2); } int CRasterLine::preIntersects( const Line& l) const { assert( IsOrdered() && l.IsOrdered() ); if( IsEmpty() && l.IsEmpty() ) return 1; if( IsEmpty() || l.IsEmpty() ) return 0; return 2; } bool CRasterLine::MBRIntersects( const Line& l) const { if( !BoundingBox().Intersects( l.BoundingBox() ) ) return false; return true; } bool CRasterLine::ExactIntersects( const Line& l) const { HalfSegment hs1, hs2; for( int i = 0; i < Size(); i++ ) { Get( i, hs1 ); if( hs1.IsLeftDomPoint() ) { for( int j = 0; j < l.Size(); j++ ) { l.Get( j, hs2 ); if (hs2.IsLeftDomPoint()) { if( hs1.Intersects( hs2 ) ) return true; } } } } return false; } bool CRasterLine::Intersects(CRasterRegion &rr2) { int result; result = preIntersects((Region)rr2); if(result == 0 || result == 1) return result == 1; if(!MBRIntersects((Region)rr2)) return false; MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rr2.getRaster(), mbrIntersection); if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects == 1; //exact test return ExactIntersects((Region)rr2); } int CRasterLine::preIntersects( const Region& r) const { assert( IsOrdered() && r.IsOrdered() ); if( IsEmpty() && r.IsEmpty() ) return 1; if( IsEmpty() || r.IsEmpty() ) return 0; return 2; } bool CRasterLine::MBRIntersects( const Region& r) const { if( !BoundingBox().Intersects( r.BoundingBox() ) ) return false; return true; } bool CRasterLine::ExactIntersects( const Region& r) const { HalfSegment hsl, hsr; for( int i = 0; i < Size(); i++ ) { Get( i, hsl ); if( hsl.IsLeftDomPoint() ) { for( int j = 0; j < r.Size(); j++ ) { r.Get( j, hsr ); if( hsr.IsLeftDomPoint() ) { if( hsl.Intersects( hsr ) ) return true; } } if( r.Contains( hsl.GetLeftPoint() ) || r.Contains( hsl.GetRightPoint() ) ) return true; } } return false; } void CRasterLine::Raster4CRSToFLOB(){ if (rasterDefined) { Signature4CRS::Weight filling; rasterFLOB.clean(); rasterFLOB.Append(rasterSignature->signatureType); rasterFLOB.Append(rasterSignature->map->potency); rasterFLOB.Append(rasterSignature->map->dx); rasterFLOB.Append(rasterSignature->map->dy); long cellSize = 1l << rasterSignature->map->potency; long computedCells = 0; unsigned long FLOBelement = 0; int numCelulas = 0; long minXcell = rasterSignature->map->mbr.min.x - (rasterSignature->map->mbr.min.x % cellSize) - (cellSize * (rasterSignature->map->mbr.min.x < 0 && (rasterSignature->map->mbr.min.x % cellSize != 0) ? 1 : 0)); long minYcell = rasterSignature->map->mbr.min.y - (rasterSignature->map->mbr.min.y % cellSize) - (cellSize * (rasterSignature->map->mbr.min.y < 0 && (rasterSignature->map->mbr.min.y % cellSize != 0) ? 1 : 0)); for( long i=minXcell; i <= rasterSignature->map->mbr.max.x; i+=cellSize) for(long j=minYcell; j <= rasterSignature->map->mbr.max.y; j+=cellSize) { filling = rasterSignature->block(i,j,cellSize); FLOBelement = (FLOBelement << 2) | filling; computedCells++; if (computedCells == (sizeof (unsigned long) * 4) ) { rasterFLOB.Append(FLOBelement); FLOBelement = 0; computedCells = 0; } numCelulas++; } if (computedCells > 0) { rasterFLOB.Append(FLOBelement); } } else { if (rasterFLOB.Size() > 0) { rasterFLOB.clean(); } } } void CRasterLine::FLOBToRaster4CRS(){ unsigned long potency, dx, dy, signatureType; //const Signature4CRS::Weight *filling; unsigned long l; rasterFLOB.Get(0, l); signatureType = l; rasterFLOB.Get(1, l); potency = l; rasterFLOB.Get(2, l); dx = l; rasterFLOB.Get(3, l); dy = l; long cellSize = 1l << potency; long numElements = dx * dy; Signature4CRS::Weight *filling = new Signature4CRS::Weight[numElements]; unsigned long pFLOBelement; unsigned long FLOBelement; int positionInElement = -1; unsigned int currentCell = 0; Signature4CRS::Weight ocup; int positionInFLOB = 0; long minXcell = (long)((this->BoundingBox().MinD(0) - ((long int)this->BoundingBox().MinD(0) % cellSize)) - (cellSize * (this->BoundingBox().MinD(0) < 0 && ((long int)this->BoundingBox().MinD(0) % cellSize != 0) ? 1 : 0))); long minYcell = (long)((this->BoundingBox().MinD(1) - ((long int)this->BoundingBox().MinD(1) % cellSize)) - (cellSize * (this->BoundingBox().MinD(1) < 0 && ((long int)this->BoundingBox().MinD(1) % cellSize != 0) ? 1 : 0))); for( long i= minXcell; i <= this->BoundingBox().MaxD(0); i+=cellSize) for(long j= minYcell; j <= this->BoundingBox().MaxD(1); j+=cellSize) { if (positionInElement < 0){ // +4 to consider potency, dx e dy rasterFLOB.Get(positionInFLOB + 4, pFLOBelement); FLOBelement = pFLOBelement; positionInElement = 0; if (dx * dy - currentCell < sizeof(unsigned long) * 4) positionInElement = (dx * dy - currentCell) - 1; else positionInElement = sizeof(unsigned long) * 4 - 1; positionInFLOB++; } switch ( (FLOBelement >> (positionInElement * 2)) & 3 ) { case 0: ocup = Signature4CRS::Empty; break; case 1: ocup = Signature4CRS::Weak; break; case 2: ocup = Signature4CRS::Strong; break; default: ocup = Signature4CRS::Full; } filling[currentCell] = ocup; positionInElement--; currentCell++; } Coordinate x ((long int)this->BoundingBox().MinD(0), (long int)this->BoundingBox().MinD(1)); Coordinate y ((long int)this->BoundingBox().MaxD(0), (long int)this->BoundingBox().MaxD(1)); rasterSignature = new Raster4CRS(1, x, y, cellSize, dx, dy, filling, signatureType); rasterDefined = true; } int CRasterLine::NumOfFLOBs(void) const { return 3; } Flob *CRasterLine::GetFLOB(const int i){ assert(i == 0 || i == 1 || i == 2); return i < 2 ? Line::GetFLOB(i) : &rasterFLOB; } /* 2.3. RasterPoints */ enum object {none, first, second, both}; enum status {endnone, endfirst, endsecond, endboth}; class CRasterPoints: public Points { private: Raster4CRS *rasterSignature; //potency dx dy signature... DbArray rasterFLOB; void SelectFirst_pp( const Points& P1, const Points& P2, object& obj, status& stat ); void SelectNext_pp( const Points& P1, const Points& P2, object& obj, status& stat ); public: static const std::string BasicType() { return "rasterPoints"; } bool rasterDefined; CRasterPoints(){}; CRasterPoints(Points p); CRasterPoints(const CRasterPoints& rp); CRasterPoints(const int initsize); Raster4CRS *getRaster(); Raster4CRS *readRaster() const; void setRaster(Raster4CRS *raster); Raster4CRS *calculateRaster(int signatureType) const; bool Intersects(CRasterRegion &rr2); int preIntersects( const Region& r) const; bool MBRIntersects( const Region& r) const; bool ExactIntersects( const Region& r) const; bool Intersects(CRasterLine &rl2); int preIntersects( const Line& l) const; bool MBRIntersects( const Line& l) const; bool ExactIntersects( const Line& l) const; bool Intersects(CRasterPoints &rp2); int preIntersects( const Points& ps) const; bool MBRIntersects( const Points& ps) const; bool ExactIntersects( const Points& ps) ; void Raster4CRSToFLOB(); void FLOBToRaster4CRS(); virtual CRasterPoints* Clone() const { return new CRasterPoints(*(const CRasterPoints *)this); } int NumOfFLOBs(void) const; Flob *GetFLOB(const int i); CRasterPoints& operator=( CRasterPoints& rp ); }; CRasterPoints& CRasterPoints::operator=( CRasterPoints& rp ) { Points::operator=((Points) rp); rasterFLOB.clean(); if( rp.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( rp.rasterFLOB.Size() ); for( int i = 0; i < rp.rasterFLOB.Size(); i++ ) { unsigned long hs; rp.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } } setRaster(rp.getRaster()->Clone()); return *this; } CRasterPoints::CRasterPoints(Points p) : Points(p), rasterFLOB(0){ rasterDefined = false; rasterFLOB.clean(); //rasterSignature = calculateRaster(); rasterSignature = NULL; }; CRasterPoints::CRasterPoints(const CRasterPoints& rp) : Points(rp), rasterFLOB(0){ rasterDefined = false; rasterFLOB.clean(); rasterFLOB.clean(); if( rp.rasterFLOB.Size() > 0 ) { rasterFLOB.resize( rp.rasterFLOB.Size() ); for( int i = 0; i < rp.rasterFLOB.Size(); i++ ) { unsigned long hs; rp.rasterFLOB.Get( i, hs ); rasterFLOB.Put( i, hs ); } } setRaster(rp.readRaster()->Clone()); }; CRasterPoints::CRasterPoints(const int initsize) : Points(initsize), rasterFLOB(0){ rasterDefined = false; rasterSignature = NULL; }; Raster4CRS *CRasterPoints::getRaster(){ if (IsEmpty()) return NULL; if (rasterDefined) return rasterSignature; else { rasterDefined = true; rasterSignature = calculateRaster(3); return rasterSignature; } }; Raster4CRS *CRasterPoints::readRaster() const{ if (!IsEmpty() && rasterDefined) return rasterSignature; else return NULL; }; void CRasterPoints::setRaster(Raster4CRS *raster){ rasterDefined = true; rasterSignature = raster; Raster4CRSToFLOB(); }; Raster4CRS *CRasterPoints::calculateRaster(int signatureType) const{ Raster4CRS* raster; Signature4CRS* signature; const CRasterPoints *rp = this; int potency =0; do { SignatureType type; if (signatureType == 3) type = SIGNAT_3CRS; else if (signatureType == 4) type = SIGNAT_4CRS; else cout << "Invalid signatureType" << std::endl; signature = GeraRasterSecondo::generateRaster( 1, NULL, NULL, rp, potency, type); potency++; } while (signature==NULL); raster = new Raster4CRS(signature->fullMap(), signatureType); raster->signatureType = signatureType; return raster; }; bool CRasterPoints::Intersects(CRasterRegion &rr2) { int result; result = preIntersects(rr2); if(result == 0 || result == 1) return result == 1; //MBR test if(!MBRIntersects(rr2)) return false; //Raster Signature test MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rr2.getRaster(), mbrIntersection); if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects == 1; //exact test return ExactIntersects(rr2); } int CRasterPoints::preIntersects( const Region& r) const { assert( IsOrdered() && r.IsOrdered() ); if( IsEmpty() && r.IsEmpty() ) return 1; if( IsEmpty() || r.IsEmpty() ) return 0; return 2; } bool CRasterPoints::MBRIntersects( const Region& r) const { if( !BoundingBox().Intersects( r.BoundingBox() ) ) return false; return true; } bool CRasterPoints::ExactIntersects( const Region& r) const { Point p; for( int i = 0; i < Size(); i++ ) { Get( i, p ); if( r.Contains( p ) ) return true; } return false; } bool CRasterPoints::Intersects(CRasterLine &rl2) { int result; result = preIntersects(rl2); if(result == 0 || result == 1) return result == 1; //MBR test if(!MBRIntersects(rl2)) return false; //Raster Signature test MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rl2.getRaster(), mbrIntersection); if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects == 1; //exact test return ExactIntersects(rl2); } int CRasterPoints::preIntersects( const Line& l) const { assert( IsOrdered() && l.IsOrdered() ); if( IsEmpty() && l.IsEmpty() ) return 1; if( IsEmpty() || l.IsEmpty() ) return 0; return 2; } bool CRasterPoints::MBRIntersects( const Line& l) const { if( !BoundingBox().Intersects( l.BoundingBox() ) ) return false; return true; } bool CRasterPoints::ExactIntersects( const Line& l) const { Point p; for( int i = 0; i < Size(); i++ ) { Get( i, p ); if( l.Contains( p ) ) return true; } return false; } bool CRasterPoints::Intersects(CRasterPoints &rp2) { int result; result = preIntersects(rp2); if(result == 0 || result == 1) return result == 1; //MBR test if(!MBRIntersects(rp2)) return false; //Raster Signature test MBR mbrIntersection; int rasterIntersects = compareSignatures4CRS( this->getRaster(), rp2.getRaster(), mbrIntersection); if (rasterIntersects == 0 || rasterIntersects == 1) return rasterIntersects == 1; //exact test return ExactIntersects(rp2); } int CRasterPoints::preIntersects( const Points& ps) const { assert( IsOrdered() && ps.IsOrdered() ); if( IsEmpty() && ps.IsEmpty() ) return 1; if( IsEmpty() || ps.IsEmpty() ) return 0; return 2; } bool CRasterPoints::MBRIntersects( const Points& ps) const { if( !BoundingBox().Intersects( ps.BoundingBox() ) ) return false; return true; } bool CRasterPoints::ExactIntersects( const Points& ps) { object obj; status stat; SelectFirst_pp( *this, ps, obj, stat ); while( stat != endboth ) { if( obj == both ) return true; SelectNext_pp( *this, ps, obj, stat ); } return false; } void CRasterPoints::Raster4CRSToFLOB(){ if (rasterDefined) { Signature4CRS::Weight filling; rasterFLOB.clean(); rasterFLOB.Append(rasterSignature->signatureType); rasterFLOB.Append(rasterSignature->map->potency); rasterFLOB.Append(rasterSignature->map->dx); rasterFLOB.Append(rasterSignature->map->dy); long cellSize = 1l << rasterSignature->map->potency; long computedCells = 0; unsigned long FLOBelement = 0; long minXcell = rasterSignature->map->mbr.min.x - (rasterSignature->map->mbr.min.x % cellSize) - (cellSize * (rasterSignature->map->mbr.min.x < 0 && (rasterSignature->map->mbr.min.x % cellSize != 0) ? 1 : 0)); long minYcell = rasterSignature->map->mbr.min.y - (rasterSignature->map->mbr.min.y % cellSize) - (cellSize * (rasterSignature->map->mbr.min.y < 0 && (rasterSignature->map->mbr.min.y % cellSize != 0) ? 1 : 0)); for( long i=minXcell; i <= rasterSignature->map->mbr.max.x; i+=cellSize) for(long j=minYcell; j <= rasterSignature->map->mbr.max.y; j+=cellSize) { filling = rasterSignature->block(i,j,cellSize); FLOBelement = (FLOBelement << 2) | filling; computedCells++; if (computedCells == (sizeof (unsigned long) * 4) ) { rasterFLOB.Append(FLOBelement); FLOBelement = 0; computedCells = 0; } } if (computedCells > 0) rasterFLOB.Append(FLOBelement); } else { if (rasterFLOB.Size() > 0) { rasterFLOB.clean(); } } } void CRasterPoints::FLOBToRaster4CRS(){ unsigned long potency, dx, dy, signatureType; unsigned long l; rasterFLOB.Get(0, l); signatureType = l; rasterFLOB.Get(1, l); potency = l; rasterFLOB.Get(2, l); dx = l; rasterFLOB.Get(3, l); dy = l; long cellSize = 1l << potency; long numElements = dx * dy; Signature4CRS::Weight *filling = new Signature4CRS::Weight[numElements]; unsigned long pFLOBelement; unsigned long FLOBelement; int positionInElement = -1; unsigned int currentCell = 0; Signature4CRS::Weight ocup; int positionInFLOB = 0; long int minXcell = (long int)((this->BoundingBox().MinD(0) - ((long int)this->BoundingBox().MinD(0) % cellSize)) - (cellSize * (this->BoundingBox().MinD(0) < 0 && ((long int)this->BoundingBox().MinD(0) % cellSize != 0) ? 1 : 0))); long int minYcell = (long int)((this->BoundingBox().MinD(1) - ((long int)this->BoundingBox().MinD(1) % cellSize)) - (cellSize * (this->BoundingBox().MinD(1) < 0 && ((long int)this->BoundingBox().MinD(1) % cellSize != 0) ? 1 : 0))); for( long i=minXcell; i <= this->BoundingBox().MaxD(0); i+=cellSize) for(long j=minYcell; j <= this->BoundingBox().MaxD(1); j+=cellSize) { if (positionInElement < 0){ // add 4 to consider potency, dx e dy rasterFLOB.Get(positionInFLOB + 4, pFLOBelement); FLOBelement = pFLOBelement; positionInElement = 0; if (dx * dy - currentCell < sizeof(unsigned long) * 4) positionInElement = (dx * dy - currentCell) - 1; else positionInElement = sizeof(unsigned long) * 4 - 1; positionInFLOB++; } switch ( (FLOBelement >> (positionInElement * 2)) & 3 ) { case 0: ocup = Signature4CRS::Empty; break; case 1: ocup = Signature4CRS::Weak; break; case 2: ocup = Signature4CRS::Strong; break; default: ocup = Signature4CRS::Full; } filling[currentCell] = ocup; positionInElement--; currentCell++; } Coordinate x ((long int)this->BoundingBox().MinD(0), (long int)this->BoundingBox().MinD(1)); Coordinate y ((long int)this->BoundingBox().MaxD(0), (long int)this->BoundingBox().MaxD(1)); rasterSignature = new Raster4CRS(1, x, y, cellSize, dx, dy, filling, signatureType); rasterDefined = true; } int CRasterPoints::NumOfFLOBs(void) const { return 2; } Flob *CRasterPoints::GetFLOB(const int i){ assert(i == 0 || i == 1); return i == 0 ? Points::GetFLOB(0) : &rasterFLOB; } //auxiliary functions for Intersection test of two Points void CRasterPoints::SelectFirst_pp( const Points& P1, const Points& P2, object& obj, status& stat ) { P1.SelectFirst(); P2.SelectFirst(); Point p1, p2; bool gotP1 = P1.GetPt( p1 ), gotP2 = P2.GetPt( p2 ); if( !gotP1 && !gotP2 ) { obj = none; stat = endboth; } else if( !gotP1 ) { obj = second; stat = endfirst; } else if( !gotP2 ) { obj = first; stat = endsecond; } else //both defined { stat = endnone; if( p1 < p2 ) obj = first; else if( p1 > p2 ) obj = second; else obj = both; } } void CRasterPoints::SelectNext_pp( const Points& P1, const Points& P2, object& obj, status& stat ) { // 1. get the current elements Point p1, p2; bool gotP1 = P1.GetPt( p1 ), gotP2 = P2.GetPt( p2 ); //2. move the pointers if( !gotP1 && !gotP2 ) { //do nothing } else if( !gotP1 ) { P2.SelectNext(); gotP2 = P2.GetPt( p2 ); } else if( !gotP2 ) { P1.SelectNext(); gotP1 = P1.GetPt( p1 ); } else //both currently defined { if( p1 < p2 ) //then hs1 is the last output { P1.SelectNext(); gotP1 = P1.GetPt( p1 ); } else if( p1 > p2 ) { P2.SelectNext(); gotP2 = P2.GetPt( p2 ); } else { P1.SelectNext(); gotP1 = P1.GetPt( p1 ); P2.SelectNext(); gotP2 = P2.GetPt( p2 ); } } //3. generate the outputs if( !gotP1 && !gotP2 ) { obj = none; stat = endboth; } else if( !gotP1 ) { obj = second; stat = endfirst; } else if( !gotP2 ) { obj = first; stat = endsecond; } else //both defined { stat = endnone; if( p1 < p2 ) obj = first; else if( p1 > p2 ) obj = second; else obj = both; } } } #endif