.
*/
/** ***********************************************************
*
*
* PURPOSE:
* The spatial domain of an MDD is represented by an object
* of class RasMInterval. It specifies lower and upper bound
* of the point set for each dimension of an MDD. Internally,
* the class is realized through an array of intervals of type
* RasSInterval.
*
* For the operations union, difference, and intersection the
* dimensionalties of the operands must be equal, otherwise an
* exception is raised. The semantics of the operations are
* defined as follows for each dimension:
*
* | ... fixed bound
* -* ... open bound
*
*
* class orientation union difference intersection
* -----------------------------------------------------------
* 1 |-a-| |-b-| error a error
*
* 2 |-a-| [a1,b2] [a1,b1] [b1,a2]
* 2 |-b-|
*
* 3 |--a--| a error b
* 3 |-b-|
*
* 4 |-b-| [b1,a2] [b2,a2] [a1,b2]
* 4 |-a-|
*
* 5 |--b--| b error a
* 5 |-a-|
*
* 6 |-b-| |-a-| error a error
*
* 7 |-a-|-b-| [a1,b2] a [a2,a2]
*
* 8 |-b-|-a-| [b1,a2] a [b2,b2]
*
* 9 |--a--| a [a1,b1] b
* 9 |-b-|
*
* 10 |--a--| a [b2,a2] b
* 10 |-b-|
*
* 11 |-a-| a error a
* 11 |-b-|
*
* 12 |--b--| b error a
* 12 |-a-|
*
* 13 |--b--| b error a
* 13 |-a-|
*
* -----------------------------------------------------
*
* 14 |--a--* a error b
* 14 |-b-|
*
* 15 |--a--* a [b2,a2] b
* 15 |-b-|
*
* 16 |-b-| |-a-* error a error
*
* 17 |-b-|-a-* [b1,a2] a [b2,b2]
*
* 18 |--a--* [b1,a2] [b2,a2] [a1,b2]
* 18 |-b-|
*
* -----------------------------------------------------
*
* 19 *--a--| a error b
* 19 |-b-|
*
* 20 *--a--| a [a1,b1] b
* 20 |-b-|
*
* 21 *-a-| |-b-| error a error
*
* 22 *-a-|-b-| [a1,b2] a [a2,a2]
*
* 23 *--a--| [a1,b2] [a1,b1] [b1,a2]
* 23 |-b-|
*
* -----------------------------------------------------
*
* 24 |--b--* b error a
* 24 |-a-|
*
* 25 |--b--* b error a
* 25 |-a-|
*
* 26 |-a-| |-b-* error a error
*
* 27 |-a-|-b-* [a1,b2] a [a2,a2]
*
* 28 |--b--* [a1,b2] [a1,b1] [b1,a2]
* 28 |-a-|
*
* -----------------------------------------------------
*
* 29 *--b--| b error a
* 29 |-a-|
*
* 30 *--b--| b error a
* 30 |-a-|
*
* 31 *-b-| |-a-| error a error
*
* 32 *-b-|-a-| [b1,a2] a [b2,b2]
*
* 33 *--b--| [b1,a2] [b2,a2] [a1,b2]
* 33 |-a-|
*
* -----------------------------------------------------
*
* 34 *-a-| |-b-* error a error
*
* 35 *-a-|-b-* [a1,b2] a [a2,a2]
*
* 36 *-a-| [a1,b2] [a1,b1] [b1,a2]
* 36 |-b-*
*
* -----------------------------------------------------
*
* 37 *-b-| |-a-* error a error
*
* 38 *-b-|-a-* [b1,a2] a [b2,b2]
*
* 39 *-b-| [b1,a2] [a1,b1] [a1,b2]
* 39 |-a-*
*
* -----------------------------------------------------
*
* 40 *-a-| b error a
* 40 *-b-|
*
* 41 *-a-| a error a
* 41 *-b-|
*
* 42 *-b-| a [b2,a2] b
* 42 *-a-|
*
* -----------------------------------------------------
*
* 43 |-a-* a [a1,b1] b
* 43 |-b-*
*
* 44 |-a-* a error a
* 44 |-b-*
*
* 45 |-b-* b error a
* 45 |-a-*
*
* -----------------------------------------------------
* 46 *-a-* |-b-| a error b
*
* 47 *-b-* |-a-| b error b
*
* 48 *-a-* a [b2,a2] b
* 48 *-b-|
*
* 49 *-a-* a [a1,b1] b
* 49 |-b-*
*
* 50 *-b-* b error a
* 50 *-a-|
*
* 51 *-b-* b error a
* 51 |-a-*
*
* 52 *-a-* a error a
* 52 *-b-*
*
* Attention: The difference operation has to be reconsidered in future
* concerning a discrete interpretation of the intervals.
*
* The closure operation defines an interval which is the smallest
* interval containing the two operands.
* The method intersectsWith() returns false in the error cases of the
* intersection operation and true otherwise.
*
* * @version $Revision: 1.15 $
*
*
*
*
* COMMENTS:
*
*
*********************************************************** */
public class RasMInterval
{
static final String rcsid = "@(#)Package rasj, class RasMInterval: $Header: /home/rasdev/CVS-repository/rasdaman/java/rasj/RasMInterval.java,v 1.15 2003/12/10 21:04:23 rasdev Exp $";
/** array for storing the intervals */
protected RasSInterval[] intervals;
/** dimensionality of the domain */
protected int dimensionality;
/** number of components initialized already */
protected int streamInitCnt;
/**
* Constructor getting dimensionality for stream initializing.
* @param dim the dimensionality of this MInterval
**/
public RasMInterval(int dim)
{
dimensionality = dim;
streamInitCnt = 0;
intervals = new RasSInterval[dimensionality];
for(int i=0; i= dimensionality)
throw new RasStreamInputOverflowException();
intervals[streamInitCnt++] = newInterval;
}
/**
* Method for stream initialization with point intervals.
* @param p the point interval that has to be streamed
**/
public void stream(long p) throws RasStreamInputOverflowException, RasResultIsNoIntervalException
{
if(streamInitCnt >= dimensionality)
throw new RasStreamInputOverflowException();
intervals[streamInitCnt++] = new RasSInterval(p, p);
}
/**
* Default constructor.
**/
public RasMInterval()
{
dimensionality = 0;
streamInitCnt = 0;
intervals = null;
}
/**
* Copy constructor.
* @param mInterval the MInterval that is to be copied
**/
public RasMInterval(final RasMInterval mInterval)
throws RasStreamInputOverflowException, RasIndexOutOfBoundsException
{
dimensionality = mInterval.dimension();
streamInitCnt = mInterval.streamInitCnt;
intervals = new RasSInterval[ dimensionality ];
for(int i=0; i= dimensionality)
throw new RasIndexOutOfBoundsException(0, dimensionality-1, i);
return intervals[i];
}
/**
* Write access to the i-th interval.
* @param i the dimension that is to be accessed
* @param value the interval that is to be assigned to the specified dimension
**/
public void setItem(int i, RasSInterval value) throws RasIndexOutOfBoundsException
{
if(i < 0 || i >= dimensionality)
throw new RasIndexOutOfBoundsException(0, dimensionality-1, i);
intervals[i] = value;
}
/*
* set MInterval
public final RasMInterval setTo(final RasMInterval mInterval)
throws RasStreamInputOverflowException, RasIndexOutOfBoundsException
{
if(this != mInterval)
{
if((intervals != null) && dimensionality != mInterval.dimension())
{
intervals = null;
}
dimensionality = mInterval.dimension();
streamInitCnt = mInterval.streamInitCnt;
if(intervals == null)
intervals = new RasSInterval[ dimensionality ];
for(int i=0; i
* -1 | if the point has not the same dimensionality |
* 1 | if the point is covered by this MInterval |
* 0 | if the point is not covered |
*
**/
public final int covers(RasPoint pnt)
{
if (dimensionality != pnt.dimension())
return -1;
try {
for (int i = 0; i < pnt.dimension(); i++)
{
if ((intervals[i].isLowFixed() && pnt.item(i) < intervals[i].low()) ||
(intervals[i].isHighFixed() && pnt.item(i) > intervals[i].high()))
return 0;
}
return 1;
}
catch(RasIndexOutOfBoundsException e) {
// This cannot occur (theoretically)
throw new RasClientInternalException("RasMInterval","covers(RasPoint pnt)",e.getMessage());
}
}
/**
* Method for testing if this interval covers the given interval.
* @param inter2 the MInterval to be tested
* @return
*
* -1 | if the point has not the same dimensionality |
* 1 | if the point is covered by this MInterval |
* 0 | if the point is not covered |
**/
public int covers(RasMInterval inter2)
{
if(dimensionality != inter2.dimension())
return -1;
try {
for (int i = 0; i < dimensionality ; i++)
{
if (
( intervals[i].isLowFixed() &&
(!(inter2.item(i).isLowFixed()) ||
intervals[i].low() > inter2.item(i).low() // both lows fixed here
)
) || // end of lows check
( intervals[i].isHighFixed() &&
(!(inter2.item(i).isHighFixed()) ||
intervals[i].high() < inter2.item(i).high() // both highs fixed here
)
)
)
return 0;
}
return 1;
}
catch( RasIndexOutOfBoundsException e) {
// this can not occur (theoretically)
throw new RasClientInternalException("RasMInterval","covers(RasMInterval inter2)",e.getMessage());
}
}
/**
* Gets the dimensionality of this MInterval.
* @return the dimensionality of this MInterval
**/
public int dimension()
{
return dimensionality;
}
/**
* Gets the point with the lowest coordinates in every dimension.
* @return the origin of this MInterval (the point with the lowest coordinates)
**/
public RasPoint getOrigin()
{
try {
int i;
RasPoint pt = new RasPoint(dimensionality);
for(i=0; i
* +-------------+---------------------------------------+
* | A | B |
* +-------------|---------------------------------------|
*
* and the following two are not:
*
* +-------------+-------------------------+
* | | B |
* | A +-------------------------+
* +-------------+
*
*
* @param b the MInterval to be checked
* @return true if the two intervalls are mergeable
**/
public boolean isMergeable(final RasMInterval b)
{
final RasMInterval a = this; // An alias to this object
// The blocks must have the same dimensionality to be mergeable
if (a.dimensionality != b.dimensionality)
return false;
// Count the number of adjacent frontiers
int onesDifferences = 0;
// Is Mergeable variable
boolean isMerg = true;
// For all dimensions
try {
for (int i=0; i
* Note that this method modifies the current MInterval. If you want to
* get a new MInterval, use the {@link #createTranslation(RasPoint) createTranslation} method
* instead.
* @param t the point to be added
* @return the current MInterval
**/
public RasMInterval translate(RasPoint t)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
int i;
if(dimensionality != t.dimension())
throw new RasDimensionMismatchException(dimensionality, t.dimension());
try {
for(i=0; i
* This operation is only legal if all lower bounds are
* fixed and the point has the same dimension as the MInterval!
* @param t the point to be added
* @return the new MInterval
**/
public RasMInterval createTranslation(RasPoint t)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(dimensionality != t.dimension())
throw new RasDimensionMismatchException(dimensionality, t.dimension());
RasMInterval result = new RasMInterval(dimensionality);
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createUnion(RasMInterval) createUnion} instead.
* @param mint1 the first MInterval
* @param mint2 the second MInterval
* @return the current MInterval (representing the union of mint1 and mint2)
**/
public RasMInterval unionOf(final RasMInterval mint1, final RasMInterval mint2)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(mint1.dimension() != mint2.dimension())
throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension());
// cleanup + initializing of this
dimensionality = mint1.dimension();
streamInitCnt = dimensionality;
intervals = new RasSInterval[ dimensionality ];
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createUnion(RasMInterval) createUnion} instead.
* @param mint the MInterval to be used for the union
* @return the current MInterval (after the union with mint)
**/
public RasMInterval unionWith(final RasMInterval mint)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(dimensionality != mint.dimension())
throw new RasDimensionMismatchException( dimensionality, mint.dimension());
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createDifference(RasMInterval) createDifference} instead.
* @param mint1 the first MInterval
* @param mint2 the second MInterval
* @return the current MInterval (representing the difference of mint1 and mint2)
**/
public RasMInterval differenceOf(final RasMInterval mint1, final RasMInterval mint2)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(mint1.dimension() != mint2.dimension())
throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension());
// cleanup + initializing of this
dimensionality = mint1.dimension();
streamInitCnt = dimensionality;
intervals = new RasSInterval[ dimensionality ];
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createDifference(RasMInterval) createDifference} instead.
* @param mint the MInterval used for building the difference
* @return the current MInterval (representing the difference of this MInterval and mint)
**/
public RasMInterval differenceWith(final RasMInterval mint)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(dimensionality != mint.dimension())
throw new RasDimensionMismatchException(dimensionality, mint.dimension());
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createIntersection(RasMInterval) createIntersection} instead.
* @param mint1 the first MInterval
* @param mint2 the second MInterval
* @return the current MInterval (representing the intersection of mint1 and mint2)
**/
public RasMInterval intersectionOf(RasMInterval mint1, RasMInterval mint2)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(mint1.dimension() != mint2.dimension())
throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension());
// cleanup + initializing of this
dimensionality = mint1.dimension();
streamInitCnt = dimensionality;
intervals = new RasSInterval[ dimensionality ];
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createIntersection(RasMInterval) createIntersection} instead.
* @param mint the MInterval used for building the intersection
* @return the current MInterval (representing the intersection of this MInterval and mint)
**/
public RasMInterval intersectionWith(RasMInterval mint)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(dimensionality != mint.dimension())
throw new RasDimensionMismatchException(dimensionality, mint.dimension());
try {
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createClosure(RasMInterval) createClosure} instead.
* @param mint1 the first MInterval
* @param mint2 the second MInterval
* @return the current MInterval (representing the closure of mint1 and mint2)
**/
public RasMInterval closureOf(RasMInterval mint1, RasMInterval mint2)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(mint1.dimension() != mint2.dimension())
throw new RasDimensionMismatchException( mint1.dimension(), mint2.dimension());
// cleanup + initializing of this
dimensionality = mint1.dimension();
streamInitCnt = dimensionality;
intervals = new RasSInterval[ dimensionality ];
try
{
for(int i=0; iNote that this operation modifies the current object. If you want to get a new MInterval,
* use {@link #createClosure(RasMInterval) createClosure} instead.
* @param mint the MInterval used for building the closure
* @return the current MInterval (representing the closure of this MInterval and mint)
**/
public RasMInterval closureWith(final RasMInterval mint)
throws RasDimensionMismatchException, RasResultIsNoIntervalException
{
if(dimensionality != mint.dimension())
throw new RasDimensionMismatchException( dimensionality, mint.dimension());
try
{
for(int i=0; i intervals[i].high())
throw new RasIndexOutOfBoundsException(intervals[i].low(), intervals[i].high(), point.item(i) );
offset = (offset + point.item(i) - intervals[i].low()) * (intervals[i+1].high() - intervals[i+1].low() + 1);
}
// now i = dimensionality - 1
if(point.item(i) < intervals[i].low() || point.item(i) > intervals[i].high())
throw new RasIndexOutOfBoundsException(intervals[i].low(), intervals[i].high(), point.item(i) );
offset += point.item(i) - intervals[i].low();
return offset;
}
/**
* This method calculates the spatial domain
* coordinates as a point from the offset
* specified. Lower dimensions are higher
* valued which means that the highest dimension
* is stored in a sequence.
**/
RasPoint cellPoint(long offset) throws RasResultIsNoCellException
{
int i;
long factor=1;
RasPoint pt = new RasPoint(dimensionality);
try {
if(offset >= cellCount())
throw new RasResultIsNoCellException();
for(i=0; i= dimensionality)
throw new RasIndexOutOfBoundsException(0, dimensionality-1, dim);
dimensionality -= 1;
streamInitCnt = dimensionality;
RasSInterval[] newIntervals = new RasSInterval[ dimensionality ];
for(int i=0, j=0; i 0)
sz += dimensionality * 18;
return sz;
}
/** gives back the string representation */
public String toString()
{
String retString = "";
if(dimensionality > 0)
{
for(int i=0; i