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

org.jungrapht.samples.spatial.SpatialRTreeTest Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008, The JUNG Authors
 * All rights reserved.
 *
 * This software is open-source under the BSD license; see either "license.txt"
 * or https://github.com/tomnelson/jungrapht-visualization/blob/master/LICENSE for a description.
 */
package org.jungrapht.samples.spatial;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.util.function.Supplier;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.WindowConstants;
import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultGraphType;
import org.jgrapht.graph.builder.GraphTypeBuilder;
import org.jgrapht.util.SupplierUtil;
import org.jungrapht.visualization.VisualizationModel;
import org.jungrapht.visualization.VisualizationViewer;
import org.jungrapht.visualization.control.*;
import org.jungrapht.visualization.control.modal.ModeControls;
import org.jungrapht.visualization.layout.algorithms.LayoutAlgorithm;
import org.jungrapht.visualization.layout.algorithms.StaticLayoutAlgorithm;
import org.jungrapht.visualization.layout.model.LayoutModel;
import org.jungrapht.visualization.layout.util.RadiusVertexAccessor;
import org.jungrapht.visualization.layout.util.VertexAccessor;
import org.jungrapht.visualization.renderers.Renderer;
import org.jungrapht.visualization.spatial.Spatial;
import org.jungrapht.visualization.spatial.SpatialQuadTree;
import org.jungrapht.visualization.spatial.SpatialRTree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A test that puts a lot of vertices on the screen with a visible quadtree. When the button is
 * pushed, 1000 random points are generated in order to find the closest vertex for each point. The
 * search is done both with the SpatialQuadTree and with the RadiusGraphElementAccessor. If they
 * don't find the same vertex, the testing halts after highlighting the problem vertices along with
 * the search point.
 *
 * 

A mouse click at a location will highlight the closest vertex to the pick point. * *

A toggle button will turn on/off the display of the spatialquadtree features, including the * expansion of the search target (red circle) in order to find the closest vertex. * * @author Tom Nelson */ public class SpatialRTreeTest extends JPanel { private static final Logger log = LoggerFactory.getLogger(SpatialRTreeTest.class); public SpatialRTreeTest() { setLayout(new BorderLayout()); Graph g = GraphTypeBuilder.forGraphType(DefaultGraphType.directedMultigraph()) .buildGraph(); Dimension viewPreferredSize = new Dimension(600, 600); Dimension layoutPreferredSize = new Dimension(600, 600); LayoutAlgorithm layoutAlgorithm = new StaticLayoutAlgorithm(); VisualizationModel model = VisualizationModel.builder(g) .layoutAlgorithm(layoutAlgorithm) .layoutSize(layoutPreferredSize) .build(); VisualizationViewer vv = VisualizationViewer.builder(model).viewSize(viewPreferredSize).build(); vv.getRenderContext().setVertexLabelFunction(Object::toString); vv.getRenderContext().setVertexLabelPosition(Renderer.VertexLabel.Position.CNTR); Supplier vertexFactory = new VertexFactory(); Supplier edgeFactory = SupplierUtil.createIntegerSupplier(); final EditingModalGraphMouse graphMouse = EditingModalGraphMouse.builder() .renderContextSupplier(vv::getRenderContext) .multiLayerTransformerSupplier(vv.getRenderContext()::getMultiLayerTransformer) .vertexFactory(vertexFactory) .edgeFactory(edgeFactory) .build(); // the EditingGraphMouse will pass mouse event coordinates to the // vertexLocations function to set the locations of the vertices as // they are created vv.setGraphMouse(graphMouse); // vv.addKeyListener(graphMouse.getModeKeyListener()); JRadioButton showSpatialEffects = new JRadioButton("Show Spatial Structure"); showSpatialEffects.addItemListener( e -> { if (e.getStateChange() == ItemEvent.SELECTED) { System.err.println("TURNED ON LOGGING"); // turn on the logging // programmatically set the log level so that the spatial grid is drawn for this demo and the SpatialGrid logging is output ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) log; LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory(); ctx.getLogger("org.jungrapht.visualization.layout.spatial").setLevel(Level.DEBUG); ctx.getLogger("org.jungrapht.visualization.layout.spatial.rtree").setLevel(Level.DEBUG); ctx.getLogger("org.jungrapht.visualization.DefaultVisualizationServer") .setLevel(Level.TRACE); ctx.getLogger("org.jungrapht.visualization.picking").setLevel(Level.TRACE); repaint(); } else if (e.getStateChange() == ItemEvent.DESELECTED) { System.err.println("TURNED OFF LOGGING"); // turn off the logging // programmatically set the log level so that the spatial grid is drawn for this demo and the SpatialGrid logging is output ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) log; LoggerContext ctx = (LoggerContext) LoggerFactory.getILoggerFactory(); ctx.getLogger("org.jungrapht.visualization.layout.spatial").setLevel(Level.INFO); ctx.getLogger("org.jungrapht.visualization.layout.spatial.rtree").setLevel(Level.INFO); ctx.getLogger("org.jungrapht.visualization.DefaultVisualizationServer") .setLevel(Level.INFO); ctx.getLogger("org.jungrapht.visualization.picking").setLevel(Level.INFO); repaint(); } }); JComboBox modeBox = ModeControls.getEditingModeComboBox(graphMouse); // .getStandardModeComboBox(graphMouse); JButton recalculate = new JButton("Recalculate"); recalculate.addActionListener(e -> vv.getVertexSpatial().recalculate()); vv.scaleToLayout(); this.add(vv.getComponent()); JPanel buttons = new JPanel(); JButton search = new JButton("Test 1000 Searches"); buttons.add(search); buttons.add(showSpatialEffects); buttons.add(recalculate); buttons.add(modeBox); Spatial spatial = vv.getVertexSpatial(); if (spatial instanceof SpatialQuadTree) { search.addActionListener( e -> testClosestVertices( vv, g, model.getLayoutModel(), (SpatialQuadTree) spatial)); } else if (spatial instanceof SpatialRTree.Vertices) { search.addActionListener( e -> testClosestVertices( vv, g, model.getLayoutModel(), (SpatialRTree.Vertices) spatial)); } this.add(buttons, BorderLayout.SOUTH); } public void testClosestVertices( VisualizationViewer vv, Graph graph, LayoutModel layoutModel, SpatialQuadTree tree) { vv.getSelectedVertexState().clear(); VertexAccessor slowWay = new RadiusVertexAccessor<>(Double.MAX_VALUE); // look for vertices closest to 1000 random locations for (int i = 0; i < 1000; i++) { double x = Math.random() * layoutModel.getWidth(); double y = Math.random() * layoutModel.getHeight(); // use the slowWay String winnerOne = slowWay.getVertex(layoutModel, x, y); // use the quadtree String winnerTwo = tree.getClosestElement(x, y); log.trace("{} and {} should be the same...", winnerOne, winnerTwo); if (!winnerOne.equals(winnerTwo)) { log.info( "the radius distanceSq from winnerOne {} at {} to {},{} is {}", winnerOne, layoutModel.apply(winnerOne), x, y, layoutModel.apply(winnerOne).distanceSquared(x, y)); log.info( "the radius distanceSq from winnerTwo {} at {} to {},{} is {}", winnerTwo, layoutModel.apply(winnerTwo), x, y, layoutModel.apply(winnerTwo).distanceSquared(x, y)); log.info( "the cell for winnerOne {} is {}", winnerOne, tree.getContainingQuadTreeLeaf(winnerOne)); log.info( "the cell for winnerTwo {} is {}", winnerTwo, tree.getContainingQuadTreeLeaf(winnerTwo)); log.info( "the cell for the search point {},{} is {}", x, y, tree.getContainingQuadTreeLeaf(x, y)); vv.getSelectedVertexState().select(winnerOne); vv.getSelectedVertexState().select(winnerTwo); graph.addVertex("P"); layoutModel.set("P", x, y); vv.getRenderContext().getSelectedVertexState().select("P"); break; } } } public void testClosestVertices( VisualizationViewer vv, Graph graph, LayoutModel layoutModel, SpatialRTree.Vertices tree) { vv.getSelectedVertexState().clear(); VertexAccessor slowWay = new RadiusVertexAccessor<>(Double.MAX_VALUE); // look for vertices closest to 1000 random locations for (int i = 0; i < 1000; i++) { double x = Math.random() * layoutModel.getWidth(); double y = Math.random() * layoutModel.getHeight(); // use the slowWay String winnerOne = slowWay.getVertex(layoutModel, x, y); // use the quadtree String winnerTwo = tree.getClosestElement(x, y); log.trace("{} and {} should be the same...", winnerOne, winnerTwo); if (!winnerOne.equals(winnerTwo)) { log.info( "the radius distanceSq from winnerOne {} at {} to {},{} is {}", winnerOne, layoutModel.apply(winnerOne), x, y, layoutModel.apply(winnerOne).distanceSquared(x, y)); log.info( "the radius distanceSq from winnerTwo {} at {} to {},{} is {}", winnerTwo, layoutModel.apply(winnerTwo), x, y, layoutModel.apply(winnerTwo).distanceSquared(x, y)); log.info("the cell for winnerOne {} is {}", winnerOne, tree.getContainingLeaf(winnerOne)); log.info("the cell for winnerTwo {} is {}", winnerTwo, tree.getContainingLeaf(winnerTwo)); log.info("the cell for the search point {},{} is {}", x, y, tree.getContainingLeafs(x, y)); vv.getSelectedVertexState().select(winnerOne); vv.getSelectedVertexState().select(winnerTwo); graph.addVertex("P"); layoutModel.set("P", x, y); vv.getRenderContext().getSelectedVertexState().select("P"); break; } } } static class VertexFactory implements Supplier { int i = 0; public String get() { return "N" + i++; } } public static void main(String[] args) { JFrame jf = new JFrame(); jf.getContentPane().add(new SpatialRTreeTest()); jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy