All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.metamx.collections.spatial.Node Maven / Gradle / Ivy

package com.metamx.collections.spatial;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.primitives.Floats;
import com.google.common.primitives.Ints;
import it.uniroma3.mat.extendedset.intset.ConciseSet;
import it.uniroma3.mat.extendedset.intset.ImmutableConciseSet;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

/**
 */
public class Node
{
  private final float[] minCoordinates;
  private final float[] maxCoordinates;

  private final List children;
  private final boolean isLeaf;
  private final ConciseSet conciseSet;

  private Node parent;

  public Node(float[] minCoordinates, float[] maxCoordinates, boolean isLeaf)
  {
    this(
        minCoordinates,
        maxCoordinates,
        Lists.newArrayList(),
        isLeaf,
        null,
        new ConciseSet()
    );
  }

  public Node(
      float[] minCoordinates,
      float[] maxCoordinates,
      List children,
      boolean isLeaf,
      Node parent,
      ConciseSet conciseSet
  )
  {
    Preconditions.checkArgument(minCoordinates.length == maxCoordinates.length);

    this.minCoordinates = minCoordinates;
    this.maxCoordinates = maxCoordinates;
    this.children = children;
    for (Node child : children) {
      child.setParent(this);
    }
    this.isLeaf = isLeaf;
    this.conciseSet = conciseSet;
    this.parent = parent;
  }

  public int getNumDims()
  {
    return minCoordinates.length;
  }

  public float[] getMinCoordinates()
  {
    return minCoordinates;
  }

  public float[] getMaxCoordinates()
  {
    return maxCoordinates;
  }

  public Node getParent()
  {
    return parent;
  }

  public void addChild(Node node)
  {
    if (node == this) {
      System.out.println("WTF");
    }
    node.setParent(this);
    children.add(node);
  }

  public List getChildren()
  {
    return children;
  }

  public boolean isLeaf()
  {
    return isLeaf;
  }

  public double getArea()
  {
    return calculateArea();
  }

  public boolean contains(Node other)
  {
    Preconditions.checkArgument(getNumDims() == other.getNumDims());

    for (int i = 0; i < getNumDims(); i++) {
      if (other.getMinCoordinates()[i] < minCoordinates[i] || other.getMaxCoordinates()[i] > maxCoordinates[i]) {
        return false;
      }
    }
    return true;
  }

  public boolean contains(float[] coords)
  {
    Preconditions.checkArgument(getNumDims() == coords.length);

    for (int i = 0; i < getNumDims(); i++) {
      if (coords[i] < minCoordinates[i] || coords[i] > maxCoordinates[i]) {
        return false;
      }
    }
    return true;
  }

  public boolean enclose()
  {
    boolean retVal = false;
    float[] minCoords = new float[getNumDims()];
    Arrays.fill(minCoords, Float.MAX_VALUE);
    float[] maxCoords = new float[getNumDims()];
    Arrays.fill(maxCoords, -Float.MAX_VALUE);

    for (Node child : getChildren()) {
      for (int i = 0; i < getNumDims(); i++) {
        minCoords[i] = Math.min(child.getMinCoordinates()[i], minCoords[i]);
        maxCoords[i] = Math.max(child.getMaxCoordinates()[i], maxCoords[i]);
      }
    }

    if (!Arrays.equals(minCoords, minCoordinates)) {
      System.arraycopy(minCoords, 0, minCoordinates, 0, minCoordinates.length);
      retVal = true;
    }
    if (!Arrays.equals(maxCoords, maxCoordinates)) {
      System.arraycopy(maxCoords, 0, maxCoordinates, 0, maxCoordinates.length);
      retVal = true;
    }

    return retVal;
  }

  public ConciseSet getConciseSet()
  {
    return conciseSet;
  }

  public void addToConciseSet(Node node)
  {
    conciseSet.addAll(node.getConciseSet());
  }

  public void clear()
  {
    children.clear();
    conciseSet.clear();
  }

  public int getSizeInBytes()
  {
    return ImmutableNode.HEADER_NUM_BYTES
           + 2 * getNumDims() * Floats.BYTES
           + Ints.BYTES // size of Concise set
           + conciseSet.getWords().length * Ints.BYTES
           + getChildren().size() * Ints.BYTES;
  }

  public int storeInByteBuffer(ByteBuffer buffer, int position)
  {
    buffer.position(position);
    buffer.putShort((short) (((isLeaf ? 0x1 : 0x0) << 15) | getChildren().size()));
    for (float v : getMinCoordinates()) {
      buffer.putFloat(v);
    }
    for (float v : getMaxCoordinates()) {
      buffer.putFloat(v);
    }
    byte[] bytes = ImmutableConciseSet.newImmutableFromMutable(conciseSet).toBytes();
    buffer.putInt(bytes.length);
    buffer.put(bytes);

    position = buffer.position();
    int childStartOffset = position + getChildren().size() * Ints.BYTES;
    for (Node child : getChildren()) {
      buffer.putInt(position, childStartOffset);
      childStartOffset = child.storeInByteBuffer(buffer, childStartOffset);
      position += Ints.BYTES;
    }

    return childStartOffset;
  }

  private double calculateArea()
  {
    double area = 1.0;
    for (int i = 0; i < minCoordinates.length; i++) {
      area *= (maxCoordinates[i] - minCoordinates[i]);
    }
    return area;
  }

  private void setParent(Node p)
  {
    parent = p;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy