/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2009-2012, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library 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
* Lesser General Public License for more details.
*/
package org.geotoolkit.internal.tree;
import java.io.IOException;
import java.util.List;
import org.apache.sis.util.ArgumentChecks;
import static org.geotoolkit.internal.tree.TreeUtilities.*;
import org.geotoolkit.index.tree.Node;
/**
* Define a generic Calculator to define computing rules of tree.
*
* @author Rémi Maréchal (Geomatys).
* @author Martin Desruisseaux (Geomatys).
*/
public abstract class Calculator {
/**
* @param envelop
* @return envelop bulk or area.
*/
public abstract double getSpace(final double[] envelope);
/**
* @param envelop
* @return evelop edge.
*/
public abstract double getEdge(final double[] envelope);
/**
* @param envelopA
* @param envelopB
* @return distance between envelopA, envelopB.
*/
public abstract double getDistanceEnvelope(final double[] envelopeA, final double[] envelopeB);
/**
* @param positionA
* @param positionB
* @return distance between positionA, positionB.
*/
public abstract double getDistancePoint(final double[] positionA, final double[] positionB);
/**
* @param envelopA
* @param envelopB
* @return overlaps between envelopA, envelopB.
*/
public abstract double getOverlaps(final double[] envelopeA, final double[] envelopeB);
/**
* <blockquote><font size=-1> <strong>NOTE : In case of narrowing, value between 0 and 1
* is returned.</strong> </font></blockquote>
*
* @param envMin
* @param envMax
* @return enlargement from envMin to envMax.
*/
public abstract double getEnlargement(final double[] envelopeMin, final double[] envelopeMax);
/**
* Sort elements list.
*
* @param index : ordinate choosen to compare.
* @param lowerOrUpper : true to sort from "lower boundary", false from "upper boundary"
* @param list : elements which will be sorted.
* @return sorted list.
*/
public void sortList(int index, boolean lowerOrUpper, List<Node> list) throws IOException {
ArgumentChecks.ensureNonNull("list", list);
if (list.isEmpty()) return ;
final int siz = list.size();
double[] env1, env2;
double val1, val2;
boolean alreadySort;
for (int bornMin = 0; bornMin < siz-1; bornMin++) {
alreadySort = true;
for (int id2 = siz-1; id2 > bornMin; id2--) {
env1 = list.get(id2).getBoundary();
env2 = list.get(id2-1).getBoundary();
if (lowerOrUpper) {
val1 = getMinimum(env1, index);
val2 = getMinimum(env2, index);
} else {
val1 = getMaximum(env1, index);
val2 = getMaximum(env2, index);
}
if (val2 > val1) {
alreadySort = false;
list.add(id2-1, list.remove(id2));
}
}
if (alreadySort) break;
}
}
/**
* Sort elements list.
*
* @param index : ordinate choosen to compare.
* @param lowerOrUpper : true to sort from "lower boundary", false from "upper boundary"
* @param list : elements which will be sorted.
* @return sorted list.
*/
public void sort(int index, boolean lowerOrUpper, double[][] tabBoundary) throws IOException {
ArgumentChecks.ensureNonNull("list", tabBoundary);
if (tabBoundary.length == 0) return ;
final int siz = tabBoundary.length;
double[] envExchange;
double val1, val2;
boolean alreadySort;
for (int bornMin = 0; bornMin < siz-1; bornMin++) {
alreadySort = true;
for (int id2 = siz-1; id2 > bornMin; id2--) {
if (lowerOrUpper) {
val1 = getMinimum(tabBoundary[id2], index);
val2 = getMinimum(tabBoundary[id2 - 1], index);
} else {
val1 = getMaximum(tabBoundary[id2], index);
val2 = getMaximum(tabBoundary[id2 - 1], index);
}
if (val2 > val1) {
alreadySort = false;
envExchange = tabBoundary[id2-1];
tabBoundary[id2-1] = tabBoundary[id2];
tabBoundary[id2] = envExchange;
}
}
if (alreadySort) break;
}
}
/**
* Sort elements list.
*
* @param index : ordinate choosen to compare.
* @param lowerOrUpper : true to sort from "lower boundary", false from "upper boundary"
* @param list : elements which will be sorted.
* @return sorted list.
*/
public void sort(int index, boolean lowerOrUpper, Node[] children) throws IOException {
ArgumentChecks.ensureNonNull("children", children);
if (children.length == 0) return ;
final int siz = children.length;
Node nodeExchange;
double val1, val2;
boolean alreadySort;
for (int bornMin = 0; bornMin < siz-1; bornMin++) {
alreadySort = true;
for (int id2 = siz-1; id2 > bornMin; id2--) {
if (lowerOrUpper) {
val1 = getMinimum(children[id2].getBoundary(), index);
val2 = getMinimum(children[id2 - 1].getBoundary(), index);
} else {
val1 = getMaximum(children[id2].getBoundary(), index);
val2 = getMaximum(children[id2 - 1].getBoundary(), index);
}
if (val2 > val1) {
alreadySort = false;
nodeExchange = children[id2-1];
children[id2-1] = children[id2];
children[id2] = nodeExchange;
}
}
if (alreadySort) break;
}
}
}