2020import java .util .Arrays ;
2121import java .util .Collections ;
2222import java .util .Random ;
23+ import org .gephi .graph .api .Configuration ;
2324import org .gephi .graph .api .DirectedSubgraph ;
2425import org .gephi .graph .api .Edge ;
2526import org .gephi .graph .api .Element ;
2627import org .gephi .graph .api .ElementIterable ;
2728import org .gephi .graph .api .Interval ;
2829import org .gephi .graph .api .Node ;
30+ import org .gephi .graph .api .Rect2D ;
31+ import org .gephi .graph .api .SpatialIndex ;
2932import org .gephi .graph .api .UndirectedSubgraph ;
3033import org .testng .Assert ;
3134import org .testng .annotations .Test ;
@@ -918,6 +921,189 @@ private GraphStore convertToStore(GraphViewImpl view) {
918921 return store ;
919922 }
920923
924+ @ Test
925+ public void testGetBoundariesEmptyView () {
926+ GraphStore graphStore = GraphGenerator .generateEmptyGraphStore (getSpatialConfig ());
927+ GraphViewStore store = graphStore .viewStore ;
928+ GraphViewImpl view = store .createView ();
929+
930+ DirectedSubgraph graph = store .getDirectedGraph (view );
931+
932+ Assert .assertEquals (new Rect2D (Float .NEGATIVE_INFINITY , Float .NEGATIVE_INFINITY , Float .POSITIVE_INFINITY ,
933+ Float .POSITIVE_INFINITY ), graph .getSpatialIndex ().getBoundaries ());
934+ }
935+
936+ @ Test
937+ public void testGetBoundariesSingleNodeInView () {
938+ GraphStore graphStore = GraphGenerator .generateEmptyGraphStore (getSpatialConfig ());
939+ GraphViewStore store = graphStore .viewStore ;
940+ GraphViewImpl view = store .createView ();
941+
942+ // Add a node to the graph store
943+ NodeImpl node1 = (NodeImpl ) graphStore .factory .newNode ("1" );
944+ node1 .setPosition (100 , 200 );
945+ node1 .setSize (10 );
946+ graphStore .addNode (node1 );
947+
948+ NodeImpl node2 = (NodeImpl ) graphStore .factory .newNode ("2" );
949+ node2 .setPosition (500 , 600 );
950+ node2 .setSize (20 );
951+ graphStore .addNode (node2 );
952+
953+ // Add only node1 to the view
954+ view .addNode (node1 );
955+
956+ DirectedSubgraph graph = store .getDirectedGraph (view );
957+
958+ // Should return boundaries only for node1
959+ Rect2D boundaries = graph .getSpatialIndex ().getBoundaries ();
960+ Assert .assertNotNull (boundaries );
961+ Assert .assertEquals (boundaries .minX , 90f ); // 100 - 10
962+ Assert .assertEquals (boundaries .minY , 190f ); // 200 - 10
963+ Assert .assertEquals (boundaries .maxX , 110f ); // 100 + 10
964+ Assert .assertEquals (boundaries .maxY , 210f ); // 200 + 10
965+ }
966+
967+ @ Test
968+ public void testGetBoundariesMultipleNodesInView () {
969+ GraphStore graphStore = GraphGenerator .generateEmptyGraphStore (getSpatialConfig ());
970+ GraphViewStore store = graphStore .viewStore ;
971+ GraphViewImpl view = store .createView ();
972+
973+ // Add nodes to the graph store
974+ NodeImpl node1 = (NodeImpl ) graphStore .factory .newNode ("1" );
975+ node1 .setPosition (0 , 0 );
976+ node1 .setSize (5 );
977+ graphStore .addNode (node1 );
978+
979+ NodeImpl node2 = (NodeImpl ) graphStore .factory .newNode ("2" );
980+ node2 .setPosition (100 , 200 );
981+ node2 .setSize (10 );
982+ graphStore .addNode (node2 );
983+
984+ NodeImpl node3 = (NodeImpl ) graphStore .factory .newNode ("3" );
985+ node3 .setPosition (500 , 600 ); // This node won't be in the view
986+ node3 .setSize (20 );
987+ graphStore .addNode (node3 );
988+
989+ // Add only node1 and node2 to the view
990+ view .addNode (node1 );
991+ view .addNode (node2 );
992+
993+ DirectedSubgraph graph = store .getDirectedGraph (view );
994+
995+ // Should return boundaries only for node1 and node2
996+ Rect2D boundaries = graph .getSpatialIndex ().getBoundaries ();
997+ Assert .assertNotNull (boundaries );
998+ Assert .assertEquals (boundaries .minX , -5f ); // node1: 0 - 5
999+ Assert .assertEquals (boundaries .minY , -5f ); // node1: 0 - 5
1000+ Assert .assertEquals (boundaries .maxX , 110f ); // node2: 100 + 10
1001+ Assert .assertEquals (boundaries .maxY , 210f ); // node2: 200 + 10
1002+ }
1003+
1004+ @ Test
1005+ public void testGetBoundariesViewSubsetVsFullGraph () {
1006+ GraphStore graphStore = GraphGenerator .generateEmptyGraphStore (getSpatialConfig ());
1007+ GraphViewStore store = graphStore .viewStore ;
1008+ GraphViewImpl view = store .createView ();
1009+
1010+ // Add nodes to the graph store
1011+ NodeImpl node1 = (NodeImpl ) graphStore .factory .newNode ("1" );
1012+ node1 .setPosition (0 , 0 );
1013+ node1 .setSize (5 );
1014+ graphStore .addNode (node1 );
1015+
1016+ NodeImpl node2 = (NodeImpl ) graphStore .factory .newNode ("2" );
1017+ node2 .setPosition (100 , 200 );
1018+ node2 .setSize (10 );
1019+ graphStore .addNode (node2 );
1020+
1021+ NodeImpl node3 = (NodeImpl ) graphStore .factory .newNode ("3" );
1022+ node3 .setPosition (-50 , -100 );
1023+ node3 .setSize (15 );
1024+ graphStore .addNode (node3 );
1025+
1026+ // Add only first two nodes to the view
1027+ view .addNode (node1 );
1028+ view .addNode (node2 );
1029+
1030+ DirectedSubgraph viewGraph = store .getDirectedGraph (view );
1031+ DirectedSubgraph fullGraph = graphStore ;
1032+
1033+ // Get boundaries for both
1034+ Rect2D viewBoundaries = viewGraph .getSpatialIndex ().getBoundaries ();
1035+ Rect2D fullBoundaries = graphStore .spatialIndex .getBoundaries ();
1036+
1037+ // View boundaries should only include node1 and node2
1038+ Assert .assertNotNull (viewBoundaries );
1039+ Assert .assertEquals (viewBoundaries .minX , -5f ); // node1: 0 - 5
1040+ Assert .assertEquals (viewBoundaries .minY , -5f ); // node1: 0 - 5
1041+ Assert .assertEquals (viewBoundaries .maxX , 110f ); // node2: 100 + 10
1042+ Assert .assertEquals (viewBoundaries .maxY , 210f ); // node2: 200 + 10
1043+
1044+ // Full graph boundaries should include all nodes
1045+ Assert .assertNotNull (fullBoundaries );
1046+ Assert .assertEquals (fullBoundaries .minX , -65f ); // node3: -50 - 15
1047+ Assert .assertEquals (fullBoundaries .minY , -115f ); // node3: -100 - 15
1048+ Assert .assertEquals (fullBoundaries .maxX , 110f ); // node2: 100 + 10
1049+ Assert .assertEquals (fullBoundaries .maxY , 210f ); // node2: 200 + 10
1050+
1051+ // They should be different
1052+ Assert .assertFalse (viewBoundaries .minX == fullBoundaries .minX );
1053+ Assert .assertFalse (viewBoundaries .minY == fullBoundaries .minY );
1054+ }
1055+
1056+ @ Test
1057+ public void testGetBoundariesAfterViewChanges () {
1058+ GraphStore graphStore = GraphGenerator .generateEmptyGraphStore (getSpatialConfig ());
1059+ GraphViewStore store = graphStore .viewStore ;
1060+ GraphViewImpl view = store .createView ();
1061+
1062+ // Add nodes to the graph store
1063+ NodeImpl node1 = (NodeImpl ) graphStore .factory .newNode ("1" );
1064+ node1 .setPosition (0 , 0 );
1065+ node1 .setSize (5 );
1066+ graphStore .addNode (node1 );
1067+
1068+ NodeImpl node2 = (NodeImpl ) graphStore .factory .newNode ("2" );
1069+ node2 .setPosition (100 , 200 );
1070+ node2 .setSize (10 );
1071+ graphStore .addNode (node2 );
1072+
1073+ DirectedSubgraph graph = store .getDirectedGraph (view );
1074+
1075+ // Initially empty view
1076+ Rect2D boundaries = graph .getSpatialIndex ().getBoundaries ();
1077+ Rect2D expected = new Rect2D (Float .NEGATIVE_INFINITY , Float .NEGATIVE_INFINITY , Float .POSITIVE_INFINITY ,
1078+ Float .POSITIVE_INFINITY );
1079+ Assert .assertEquals (expected , boundaries );
1080+
1081+ // Add first node to view
1082+ view .addNode (node1 );
1083+ Rect2D boundaries1 = graph .getSpatialIndex ().getBoundaries ();
1084+ Assert .assertNotNull (boundaries1 );
1085+ Assert .assertEquals (boundaries1 .minX , -5f );
1086+ Assert .assertEquals (boundaries1 .maxX , 5f );
1087+
1088+ // Add second node to view
1089+ view .addNode (node2 );
1090+ Rect2D boundaries2 = graph .getSpatialIndex ().getBoundaries ();
1091+ Assert .assertNotNull (boundaries2 );
1092+ Assert .assertEquals (boundaries2 .minX , -5f );
1093+ Assert .assertEquals (boundaries2 .maxX , 110f );
1094+
1095+ // Remove first node from view
1096+ view .removeNode (node1 );
1097+ Rect2D boundaries3 = graph .getSpatialIndex ().getBoundaries ();
1098+ Assert .assertNotNull (boundaries3 );
1099+ Assert .assertEquals (boundaries3 .minX , 90f ); // Only node2 remains
1100+ Assert .assertEquals (boundaries3 .maxX , 110f );
1101+
1102+ // Remove last node from view
1103+ view .removeNode (node2 );
1104+ Assert .assertEquals (expected , graph .getSpatialIndex ().getBoundaries ());
1105+ }
1106+
9211107 private void addSomeElements (GraphStore store , GraphViewImpl view ) {
9221108 double perc = 0.8 ;
9231109 Random rand = new Random (98324 );
@@ -934,4 +1120,9 @@ private void addSomeElements(GraphStore store, GraphViewImpl view) {
9341120 }
9351121 }
9361122 }
1123+
1124+ // Configuration with spatial index enabled
1125+ private Configuration getSpatialConfig () {
1126+ return Configuration .builder ().enableSpatialIndex (true ).build ();
1127+ }
9371128}
0 commit comments