package rasj; import java.lang.*; import java.util.*; /* * This file is part of rasdaman community. * * Rasdaman community 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 3 of the License, or * (at your option) any later version. * * Rasdaman community 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 rasdaman community. If not, see . * * Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann / rasdaman GmbH. * * For more information please see * or contact Peter Baumann via . */ /** *********************************************************** *
 *
 * 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 * * * * **/ 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
-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