Пример #1
0
        public List <SpatialObj <T> > WindowQuery(Rectangle window)
        {
            // Finds objects within a Rectangular range (window)
            List <SpatialObj <T> >     answer          = new List <SpatialObj <T> >();
            Queue <PartitionNode <T> > searching_nodes = new Queue <PartitionNode <T> >();

            searching_nodes.Enqueue(rootNode);
            while (searching_nodes.Count > 0)
            {
                PartitionNode <T> current_node = searching_nodes.Dequeue();
                if (current_node.IntersectsWith(window))
                {
                    answer.AddRange(current_node.GetRangeQueryObj(window));
                    if (current_node.HasChildren())
                    {
                        foreach (PartitionNode <T> child in current_node.GetChildren())
                        {
                            if (!searching_nodes.Contains(child))
                            {
                                searching_nodes.Enqueue(child);
                            }
                        }
                    }
                }
            }
            return(answer);
        }
Пример #2
0
        public PartitionNode <T> AddRectangle(SpatialObj <T> rect, bool reorganize = true)
        {
            PartitionNode <T> deepest_field = FindContainingField(rect, rootNode);

            if (deepest_field.IsFull() && !deepest_field.HasChildren())
            {
                PartitionField(deepest_field);
                PartitionNode <T> node = AddRectangle(rect);
                if (reorganize)
                {
                    ReorganizeOverflownNodes();
                }
                if (node != null)
                {
                    return(node);
                }
            }
            else
            {
                bool overflown = deepest_field.StoreRectangle(rect);
            }
            if (deepest_field != null)
            {
                Count += 1;
            }
            return(deepest_field);
        }
Пример #3
0
        /// <summary>
        /// Handles the Mouse Enter event for the highlight polygon
        /// </summary>
        /// <param name="sender">The polygon that raised the event</param>
        /// <param name="e">Specifies properties about the mouse click</param>
        private void OnHighlightPolygonMouseEnter(object sender, MouseEventArgs e)
        {
            Polygon       polygon        = (Polygon)sender;
            PartitionNode partitionNode  = _clusterPolygons[polygon];
            List <string> existingValues = new List <string>();
            List <KeyValuePair <string, string> >       attributes  = new List <KeyValuePair <string, string> >();
            IEnumerable <AttributeSimilarityDescriptor> descriptors = AttributeSimilarityManager.Instance.SimilarityDescriptors;

            if (!_mouseCaptured)
            {
                foreach (var descriptor in descriptors)
                {
                    foreach (var node in partitionNode.Nodes)
                    {
                        var nodeAttributes = from a in node.ParentNode.Attributes
                                             where a.Key == descriptor.AttributeName
                                             select a;

                        foreach (var attribute in nodeAttributes)
                        {
                            if (!existingValues.Contains(attribute.Value.Value))
                            {
                                attributes.Add(new KeyValuePair <string, string>(attribute.Key, attribute.Value.Value));
                                existingValues.Add(attribute.Value.Value);
                            }
                        }
                    }
                }
            }

            // Show the popup
            ViewModelLocator.AttributePopupVMStatic.Show(attributes);
        }
Пример #4
0
        public GraphComponents GetClusteredGraph()
        {
            IEnumerable <INodeShape> nodes = _sourceGraph.GetNodeViewModels();

            _partitionedGraph = new GraphComponents(_sourceGraph.Scope);

            // Loop over all the nodes in the list
            foreach (NodeViewModelBase nodeVM in nodes)
            {
                // Create a partition node for clusters
                PartitionNode pn = GetClusterAsPartitionNode(nodeVM);

                // Add the partition node to the graph
                _partitionedGraph.AddNodeViewModel(pn);
            }

            // Loop over all of the partition nodes in our partition graph
            foreach (PartitionNode pn in _partitionNodes)
            {
                // Loop over all the external connections
                foreach (Edge edge in pn.ExternalConnections)
                {
                    INodeShape targetNodeVM = GraphManager.Instance.GetGraphComponents(_sourceGraph.Scope).GetNodeViewModel(edge.Target);

                    // Check if the edge's target node is in our partition collection
                    if (_nodeToPartition.ContainsKey(targetNodeVM))
                    {
                        IEdge newEdge = edge.Copy(pn, _nodeToPartition[targetNodeVM]);
                        _partitionedGraph.Data.AddEdge(newEdge);
                    }
                }
            }

            return(_partitionedGraph);
        }
Пример #5
0
 private SpatialObj <T> RemoveRectangle(SpatialObj <T> rect, PartitionNode <T> node)
 {
     if (node.DeleteRectangle(rect))
     {
         Count -= 1;
     }
     MergeEmptyChildren(node);
     return(rect);
 }
Пример #6
0
        public Tuple <PartitionNode <T>, SpatialObj <T> > IncrementalNNFindNext()
        {
            if (incrNN_queue is null)
            {
                return(null);
            }

            while (incrNN_queue.Count > 0)
            {
                NodeOrObj current_element = incrNN_queue.Dequeue();
                while (incrNN_queue.Count > 0 && incrNN_queue.First().Equals(current_element))
                {
                    incrNN_queue.Dequeue();
                }

                if (current_element.IsObj())
                {
                    return(Tuple.Create(current_element.GetNode(), current_element.GetObj()));
                }
                else
                {
                    PartitionNode <T> current_node = current_element.GetNode();
                    double            current_dist = current_node.GetDistanceToPointSq(incrNN_origin);

                    if (!current_node.IsEmpty())
                    {
                        foreach (SpatialObj <T> obj in current_node.GetAllObjects())
                        {
                            double distance = obj.boundingBox.GetDistanceSqToPoint(incrNN_origin);
                            if (distance >= current_dist)
                            {
                                NodeOrObj obj_nodeOrObj = new NodeOrObj();
                                obj_nodeOrObj.SetNode(current_node);
                                obj_nodeOrObj.SetObj(obj);
                                incrNN_queue.Enqueue(obj_nodeOrObj, (float)distance);
                            }
                        }
                    }
                    if (current_node.HasChildren())
                    {
                        foreach (PartitionNode <T> child_node in current_node.GetChildren())
                        {
                            double distance = child_node.GetDistanceToPointSq(incrNN_origin);
                            if (distance >= current_dist)
                            {
                                NodeOrObj node_nodeOrObj = new NodeOrObj();
                                node_nodeOrObj.SetNode(child_node);
                                incrNN_queue.Enqueue(node_nodeOrObj, (float)distance);
                            }
                        }
                    }
                }
            }
            return(null);
        }
Пример #7
0
        private Dictionary <PartitionNode <T>, SpatialObj <T> > FindNearestRectToPoint(Point p, PartitionNode <T> node)
        {
            Dictionary <PartitionNode <T>, SpatialObj <T> > answer_dict     = new Dictionary <PartitionNode <T>, SpatialObj <T> >();
            SimplePriorityQueue <PartitionNode <T> >        searching_nodes = new SimplePriorityQueue <PartitionNode <T> >();

            searching_nodes.Enqueue(node, 0);

            SpatialObj <T>    answer      = default(SpatialObj <T>);
            PartitionNode <T> answer_node = null;
            bool used = false;

            double min_distance_sq = rootNode.GetMaxDistance();

            while (searching_nodes.Count > 0)
            {
                PartitionNode <T> current_node = searching_nodes.Dequeue();
                Dictionary <SpatialObj <T>, double> nearest_rect = current_node.GetNearestRectangle(p);
                if (nearest_rect.Count > 0)
                {
                    foreach (KeyValuePair <SpatialObj <T>, double> entry in nearest_rect)
                    {
                        if (entry.Value <= min_distance_sq || entry.Value < Statics.EPSILON)
                        {
                            min_distance_sq = entry.Value;
                            answer          = entry.Key;
                            answer_node     = current_node;
                            used            = false;
                            if (min_distance_sq < Statics.EPSILON)
                            {
                                answer_dict.Add(answer_node, answer);
                                used = true;
                            }
                        }
                    }
                }
                if (current_node.HasChildren())
                {
                    foreach (PartitionNode <T> child in current_node.GetChildren())
                    {
                        double field_dist = child.GetDistanceToPointSq(p);
                        if (field_dist <= min_distance_sq)
                        {
                            searching_nodes.Enqueue(child, (float)field_dist);
                        }
                    }
                }
            }
            if (!used)
            {
                answer_dict.Add(answer_node, answer);
            }
            return(answer_dict);
        }
Пример #8
0
 private void MergeEmptyChildren(PartitionNode <T> node)
 {
     if (node.HasChildren() && node.AreExistingChildrenEmpty())
     {
         node.MergeEmptyChildren();
     }
     if (node.IsRootNode() || !node.IsEmpty() || node.HasChildren())
     {
         return;
     }
     foreach (var parent in node.GetParent())
     {
         MergeEmptyChildren(parent);
     }
 }
Пример #9
0
        public ICollection <Point> CalculateConvexHullForCluster(PartitionNode pn)
        {
            double padding = 0;

            List <Point> points = new List <Point>();

            foreach (NodeViewModelBase nodeVM in pn.Nodes)
            {
                points.Add(new Point(nodeVM.Position.X - nodeVM.Width / 2 - padding, nodeVM.Position.Y - nodeVM.Height / 2 - padding));
                points.Add(new Point(nodeVM.Position.X - nodeVM.Width / 2 - padding, nodeVM.Position.Y + nodeVM.Height / 2 + padding));
                points.Add(new Point(nodeVM.Position.X + nodeVM.Width / 2 + padding, nodeVM.Position.Y + nodeVM.Height / 2 + padding));
                points.Add(new Point(nodeVM.Position.X + nodeVM.Width / 2 + padding, nodeVM.Position.Y - nodeVM.Height / 2 - padding));
            }

            return(ConvexHull.CalculateConvexHull(points));
        }
Пример #10
0
        public void GetOtherPartitionReturnsTheCorrectPartition()
        {
            var           factory = new PartitionEntityFactory();
            PartitionNode nodeA = new PartitionNode(factory);
            PartitionNode nodeB = new PartitionNode(factory);
            IPartition    p1, p2;

            nodeA.Partition = p1 = new DMT.Partition.Data.Partition(factory);;
            nodeB.Partition = p2 = new DMT.Partition.Data.Partition(factory);;

            PartitionEdge edge = new PartitionEdge(nodeA, nodeB, Core.Interfaces.EdgeDirection.Both, factory);

            nodeA.ConnectTo(nodeB, edge);

            Assert.Equal(p2, edge.GetOtherPartition(p1));
        }
Пример #11
0
        public void IsInnerReturnsTrueOnlyForInnerEdges()
        {
            var           factory   = new PartitionEntityFactory();
            IPartition    partition = new DMT.Partition.Data.Partition(factory);
            PartitionNode nodeA     = new PartitionNode(factory);
            PartitionNode nodeB     = new PartitionNode(factory);

            nodeA.Partition = partition;
            nodeB.Partition = partition;

            PartitionEdge edge = new PartitionEdge(nodeA, nodeB, Core.Interfaces.EdgeDirection.Both, factory);

            nodeA.ConnectTo(nodeB, edge);

            Assert.True(edge.IsInner);
        }
Пример #12
0
        public SpatialObj <T> FindNearestObjAndRemove(Point p)
        {
            SpatialObj <T>    obj  = default(SpatialObj <T>);
            PartitionNode <T> node = null;

            foreach (KeyValuePair <PartitionNode <T>, SpatialObj <T> > entry in FindNearestRectToPoint(p, rootNode))
            {
                obj  = entry.Value;
                node = entry.Key;
            }

            if (node != null)
            {
                return(RemoveRectangle(obj, node));
            }
            return(obj);
        }
Пример #13
0
        public SpatialObj <T> RemoveObject(SpatialObj <T> rect)
        {
            PartitionNode <T> node = null;

            foreach (KeyValuePair <PartitionNode <T>, SpatialObj <T> > entry in FindNearestRectToPoint(rect.boundingBox.Center, rootNode))
            {
                if (entry.Value.Equals(rect))
                {
                    node = entry.Key;
                }
            }

            if (node != null)
            {
                return(RemoveRectangle(rect, node));
            }
            return(rect);
        }
Пример #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="initialNode"></param>
        /// <returns></returns>
        private PartitionNode GetClusterAsPartitionNode(INodeShape initialNode)
        {
            // Determine if the provided node is already
            // stored in our internal collection.  If it
            // is, return it.
            if (_nodeToPartition.ContainsKey(initialNode))
            {
                return(_nodeToPartition[initialNode]);
            }

            PartitionNode pn = new PartitionNode(_sourceGraph.Scope, "Partition" + (_currentId++).ToString());

            _partitionNodes.Add(pn);

            Dictionary <INodeShape, bool> nodesInCluster     = new Dictionary <INodeShape, bool>();
            Queue <INodeShape>            nodesToTriangulate = new Queue <INodeShape>();

            nodesInCluster[initialNode] = true;
            nodesToTriangulate.Enqueue(initialNode);

            while (nodesToTriangulate.Count > 0)
            {
                List <INodeShape> tempList = FindTrianglesToAdd(nodesToTriangulate.Dequeue(), nodesInCluster);

                foreach (INodeShape nodeVM in tempList)
                {
                    // Add the node view model to our queue
                    nodesToTriangulate.Enqueue(nodeVM);
                }
            }

            // Loop over all the node view models in the dictionary
            foreach (NodeViewModelBase nodeVM in nodesInCluster.Keys)
            {
                // Add the node to the partition
                pn.AddNode(nodeVM);

                // Save the updated partition node
                _nodeToPartition[nodeVM] = pn;
            }

            return(pn);
        }
Пример #15
0
        /// <summary>
        /// Handles the MouseLeftButtonDown event for dragging and dropping of the highlight polygon
        /// </summary>
        /// <param name="sender">The polygon that raised the event</param>
        /// <param name="e">Specifies properties about the mouse click</param>
        private void OnHighlightPolygonMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Polygon       polygon        = (Polygon)sender;
            PartitionNode partitionNode  = _clusterPolygons[polygon];
            double        horizontalelta = _startMouseHorizontalPosition - (double)polygon.GetValue(Canvas.LeftProperty);
            double        verticleDelta  = _startMouseVerticalPosition - (double)polygon.GetValue(Canvas.TopProperty);

            // Update node positions
            foreach (NodeViewModelBase node in partitionNode.Nodes)
            {
                double x = node.Position.X;
                double y = node.Position.Y;

                x -= horizontalelta;
                y -= verticleDelta;

                node.Position = new Point(x, y);
            }

            _mouseCaptured = false;

            polygon.ReleaseMouseCapture();
        }
Пример #16
0
        public AtlasBuilder(IkonComposite sizes, int margin, Size bucketSize)
        {
            this.bucket = new PartitionNode(bucketSize);
            this.sizes  = new Dictionary <string, Rectangle>();
            this.margin = margin;

            var marginPoint = new Size(2 * margin, 2 * margin);

            foreach (var name in sizes.Keys)
            {
                var sizeData     = sizes[name].To <IkonArray[]>();
                var height       = (sizeData[2].To <double[]>()[1] - sizeData[0].To <double[]>()[1]) * bucketSize.Height;
                var width        = (sizeData[2].To <double[]>()[0] - sizeData[0].To <double[]>()[0]) * bucketSize.Width;
                var size         = new Size((int)Math.Round(width) + 2 * margin, (int)Math.Round(height) + 2 * margin);
                var itemPosition = bucket.Add(size);

                if (!itemPosition.HasValue)
                {
                    throw new Exception("Bucket is too small");
                }
                this.sizes[name] = new Rectangle(itemPosition.Value, size);
            }
        }
Пример #17
0
        private void ReorganizeNode(PartitionNode <T> node)
        {
            // After adding objects and creating new partitions, checks to see if any of the upper level objects can go deeper into the tree.
            Queue <PartitionNode <T> > all_nodes = new Queue <PartitionNode <T> >();

            all_nodes.Enqueue(node);

            while (all_nodes.Count > 0)
            {
                List <SpatialObj <T> > rects_removed = new List <SpatialObj <T> >();
                PartitionNode <T>      current_node  = all_nodes.Dequeue();

                foreach (SpatialObj <T> rect in current_node.GetOverflowObjs())
                {
                    PartitionNode <T> deepest_field = FindContainingField(rect, current_node);

                    if (!deepest_field.Equals(current_node))
                    {
                        bool overflown = deepest_field.StoreRectangle(rect);
                        rects_removed.Add(rect);
                    }
                }
                if (rects_removed.Count > 0)
                {
                    current_node.DeleteRectangles(rects_removed, true);
                }

                if (current_node.HasChildren())
                {
                    foreach (PartitionNode <T> child in current_node.GetChildren())
                    {
                        all_nodes.Enqueue(child);
                    }
                }
            }
        }
Пример #18
0
 public PartitionNode <T> FindContainingField(SpatialObj <T> rect, PartitionNode <T> starting_node)
 {
     if (starting_node.IsPointInNode(rect.boundingBox.Center))
     {
         bool contained_in_node = starting_node.IsObjectInNode(rect);
         if (contained_in_node && !starting_node.CanSink(rect))
         {
             return(starting_node);
         }
         foreach (PartitionNode <T> child in starting_node.GetChildren())
         {
             var potential_node = FindContainingField(rect, child);
             if (potential_node != null)
             {
                 return(potential_node);
             }
         }
         if (contained_in_node)
         {
             return(starting_node);
         }
     }
     return(null);
 }
Пример #19
0
 public PartitionFieldTreeStructure(Rectangle bounds, int capacity)
 {
     Bounds   = bounds;
     Capacity = capacity;
     rootNode = new PartitionNode <T>(bounds, capacity, 0, new List <PartitionNode <T> >());
 }
Пример #20
0
 private void PartitionField(PartitionNode <T> node)
 {
     node.CreateChildren();
 }
Пример #21
0
            public Point?Add(Size itemSize)
            {
                if (this.size.Width < itemSize.Width || this.size.Height < itemSize.Height || this.filledUp)
                {
                    return(null);
                }

                if (this.dividerPosition != NotSet)
                {
                    var result = this.leftChild.Add(itemSize);
                    if (result != null)
                    {
                        return(result);
                    }

                    result = this.rightChild.Add(itemSize);
                    if (result != null)
                    {
                        if (this.isDividerVertical)
                        {
                            return(result.Value + new Size(this.dividerPosition, 0));
                        }
                        else
                        {
                            return(result.Value + new Size(0, this.dividerPosition));
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                else if (this.size.Height > itemSize.Height)
                {
                    this.isDividerVertical = false;
                    this.dividerPosition   = itemSize.Height;

                    this.leftChild  = new PartitionNode(new Size(this.size.Width, itemSize.Height));
                    this.rightChild = new PartitionNode(new Size(this.size.Width, this.size.Height - itemSize.Height));

                    var result = this.leftChild.Add(itemSize);
                    if (result == null)
                    {
                        throw new Exception("Something is wrong with universe...");
                    }

                    return(result);
                }
                else if (this.size.Width > itemSize.Width)
                {
                    this.isDividerVertical = true;
                    this.dividerPosition   = itemSize.Width;

                    this.leftChild  = new PartitionNode(new Size(itemSize.Width, this.size.Height));
                    this.rightChild = new PartitionNode(new Size(this.size.Width - itemSize.Width, this.size.Height));

                    var result = this.leftChild.Add(itemSize);
                    if (result == null)
                    {
                        throw new Exception("Something is wrong with universe...");
                    }

                    return(result);
                }

                this.filledUp = true;
                return(new Point());
            }
Пример #22
0
 public AtlasBuilder(int margin, Size bucketSize)
 {
     this.bucket = new PartitionNode(bucketSize);
     this.margin = margin;
 }
Пример #23
0
        private static object[] GetPartitionNodeDimensionAndPosition(GraphMapData graphMapData, PartitionNode partitionNode)
        {
            Point topLeft     = new Point(double.MaxValue, double.MaxValue);
            Point bottomRight = new Point(double.MinValue, double.MinValue);

            // Loop through all node view models to get the bounding area
            foreach (NodeViewModelBase nodeViewModelBase in partitionNode.Nodes)
            {
                NodeMapData nodeMapData = graphMapData.Nodes[nodeViewModelBase.ParentNode.ID];

                topLeft.X = Math.Min(topLeft.X, nodeMapData.Position.X - nodeMapData.Dimension.Width / 2D);
                topLeft.Y = Math.Min(topLeft.Y, nodeMapData.Position.Y - nodeMapData.Dimension.Height / 2D);

                bottomRight.X = Math.Max(bottomRight.X, nodeMapData.Position.X + nodeMapData.Dimension.Width / 2D);
                bottomRight.Y = Math.Max(bottomRight.Y, nodeMapData.Position.Y + nodeMapData.Dimension.Height / 2D);
            }

            // Set the new dimensions based on the calculation performed
            double width  = Math.Max(bottomRight.X - topLeft.X, 1D);
            double height = Math.Max(bottomRight.Y - topLeft.Y, 1D);

            Size dimension = new Size(width, height);

            // get the center of the partitionNode
            Point position = new Point(topLeft.X + width / 2D, topLeft.Y + height / 2D);

            object[] result = new object[] { dimension, position };
            return(result);
        }
Пример #24
0
        /// <summary>
        /// Creates the polygons that represent the highlights for clustered data
        /// </summary>
        /// <param name="pn">The partition node containing nodes in the cluster</param>
        /// <returns>The polygon created for the highlight</returns>
        private Polygon CreateHighlightPolygon(PartitionNode pn)
        {
            PointCollection convexHull = ConvertListOfPointsToPointCollection(_cluster.CalculateConvexHullForCluster(pn));

            return(DrawHighlightPolygon(convexHull));
        }
Пример #25
0
 public void SetNode(PartitionNode <T> n)
 {
     node   = n;
     isNode = true;
 }