edu.uci.ics.jung.visualization.spatial.Spatial Maven / Gradle / Ivy
package edu.uci.ics.jung.visualization.spatial;
import com.google.common.collect.Sets;
import edu.uci.ics.jung.layout.model.LayoutModel;
import edu.uci.ics.jung.layout.model.Point;
import edu.uci.ics.jung.layout.util.RadiusNetworkNodeAccessor;
import edu.uci.ics.jung.visualization.VisualizationModel;
import edu.uci.ics.jung.visualization.layout.RadiusNetworkElementAccessor;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* Basic interface for Spatial data
*
* @author Tom Nelson
*/
public interface Spatial extends LayoutModel.LayoutStateChangeListener {
/**
* a flag to suggest whether or not the spatial structure should be used
*
* @param active
*/
void setActive(boolean active);
/** @return a hint about whether the spatial structure should be used */
boolean isActive();
/** @return a geometic representation of the spatial structure */
List getGrid();
/**
* a short-lived collection of recent pick target areas
*
* @return
*/
Collection getPickShapes();
/** destroy the current spatial structure */
void clear();
/** rebuild the data structure */
void recalculate();
/** @return the 2 dimensional area of interest for this class */
Rectangle2D getLayoutArea();
/** @param bounds the new bounds for the data struture */
void setBounds(Rectangle2D bounds);
/**
* expands the passed rectangle so that it includes the passed point
*
* @param rect the area to consider
* @param p the point that may be outside of the area
* @return a new rectangle
*/
default Rectangle2D getUnion(Rectangle2D rect, Point2D p) {
rect.add(p);
return rect;
}
default Rectangle2D getUnion(Rectangle2D rect, double x, double y) {
rect.add(x, y);
return rect;
}
/**
* update the spatial structure with the (possibly new) location of the passed element
*
* @param element the element to consider
* @param location the location of the element
*/
void update(T element, Point location);
/**
* @param p a point to search in the spatial structure
* @return all leaf nodes that contain the passed point
*/
Set extends TreeNode> getContainingLeafs(Point2D p);
/**
* @param x the x location to search for
* @param y the y location to search for
* @return all leaf nodes that contain the passed coordinates
*/
Set extends TreeNode> getContainingLeafs(double x, double y);
/**
* @param element element to search for
* @return the leaf node that currently contains the element (not a spatial search)
*/
TreeNode getContainingLeaf(Object element);
/**
* @param shape a shape to filter the spatial structure's elements
* @return all elements that are contained in the passed shape
*/
Set getVisibleElements(Shape shape);
/**
* @param p a point to search in the spatial structure
* @return the closest element to the passed point
*/
T getClosestElement(Point2D p);
/**
* @param x coordinate of a point to search in the spatial structure
* @param y coordinate of a point to search in the spatial structure
* @return the closest element to the passed coordinates
*/
T getClosestElement(double x, double y);
/**
* a special case Spatial that does no filtering
*
* @param the type for elements in the spatial
* @param the type for the Nodes in a LayoutModel
*/
abstract class NoOp extends AbstractSpatial {
private TreeNode treeNode;
public NoOp(LayoutModel layoutModel) {
super(layoutModel);
this.treeNode = new DegenerateTreeNode(layoutModel);
}
/**
* return the entire area
*
* @return
*/
@Override
public List getGrid() {
return Collections.singletonList(getLayoutArea());
}
/** nothing to clear */
@Override
public void clear() {
// no op
}
/** nothing to recalculate */
@Override
public void recalculate() {
// no op
}
/**
* return the entire area
*
* @return
*/
@Override
public Rectangle2D getLayoutArea() {
return new Rectangle2D.Double(0, 0, layoutModel.getWidth(), layoutModel.getHeight());
}
/**
* nothing to change
*
* @param bounds the new bounds for the data struture
*/
@Override
public void setBounds(Rectangle2D bounds) {
// no op
}
/**
* nothing to update
*
* @param element the element to consider
* @param location the location of the element
*/
@Override
public void update(T element, Point location) {
// no op
}
/**
* @param p a point to search in the spatial structure
* @return the single element that contains everything
*/
@Override
public Set extends TreeNode> getContainingLeafs(Point2D p) {
return Collections.singleton(this.treeNode);
}
/**
* @param x the x location to search for
* @param y the y location to search for
* @return the single element that contains everything
*/
@Override
public Set extends TreeNode> getContainingLeafs(double x, double y) {
return Collections.singleton(this.treeNode);
}
/**
* @param element element to search for
* @return the single leaf that contains everything
*/
@Override
public TreeNode getContainingLeaf(Object element) {
return this.treeNode;
}
/**
* a TreeNode that is immutable and covers the entire layout area
*
* @param
*/
public static class DegenerateTreeNode implements TreeNode {
LayoutModel layoutModel;
public DegenerateTreeNode(LayoutModel layoutModel) {
this.layoutModel = layoutModel;
}
@Override
public Rectangle2D getBounds() {
return new Rectangle2D.Double(0, 0, layoutModel.getWidth(), layoutModel.getHeight());
}
/**
* contains no children
*
* @return
*/
@Override
public List extends TreeNode> getChildren() {
return Collections.emptyList();
}
}
public static class Node extends NoOp {
RadiusNetworkNodeAccessor accessor;
public Node(LayoutModel layoutModel) {
super(layoutModel);
this.accessor = new RadiusNetworkNodeAccessor<>();
}
@Override
public Set getVisibleElements(Shape shape) {
return Sets.newHashSet(layoutModel.getGraph().nodes());
}
@Override
public void setActive(boolean active) {
// noop
}
@Override
public N getClosestElement(Point2D p) {
return getClosestElement(p.getX(), p.getY());
}
@Override
public N getClosestElement(double x, double y) {
return null; // use radius node accessor
}
}
public static class Edge extends NoOp {
private VisualizationModel visualizationModel;
RadiusNetworkElementAccessor accessor;
public Edge(VisualizationModel visualizationModel) {
super(visualizationModel.getLayoutModel());
this.visualizationModel = visualizationModel;
this.accessor = new RadiusNetworkElementAccessor<>(visualizationModel.getNetwork());
}
@Override
public Set getVisibleElements(Shape shape) {
return Sets.newHashSet(visualizationModel.getNetwork().edges());
}
@Override
public void setActive(boolean active) {
// noop
}
@Override
public E getClosestElement(Point2D p) {
return getClosestElement(p.getX(), p.getY());
}
@Override
public E getClosestElement(double x, double y) {
return accessor.getEdge(layoutModel, x, y);
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy