Exemple #1
0
        /// <summary>
        /// Removes a spatial object from the index
        /// </summary>
        /// <param name="o">The object to remove from the index</param>
        /// <returns>
        /// True if object removed. False if it couldn't be found.
        /// </returns>
        public bool Remove(ISpatialObject o)
        {
            if (o is IPoint)
            {
                return(m_Points.Remove(o as IPoint));
            }

            Item        item = new Item(o);
            SpatialType t    = o.SpatialType;

            if (t == SpatialType.Line)
            {
                return(m_Lines.Remove(item));
            }

            if (t == SpatialType.Text)
            {
                bool isRemoved = m_Text.Remove(item);
                Debug.Assert(isRemoved);
                return(isRemoved);
            }

            if (t == SpatialType.Polygon)
            {
                return(m_Polygons.Remove(item));
            }

            throw new NotSupportedException("Unexpected object type: " + o.SpatialType);
        }
Exemple #2
0
        bool WriteText(ISpatialObject item)
        {
            TextFeature text = (item as TextFeature);

            if (this.IsTopological)
            {
                ExportKey(text);
            }
            else
            {
            }

            // Skip if the AutoCad layer cannot be determined
            Layer layer = m_Layers.GetLayer(text, m_ContinuousLineType, this.IsTopological);

            if (layer != null)
            {
                TextGeometry geom   = text.TextGeometry;
                Text         acText = new Text(geom.Text, GetVector(geom.Position), geom.Height);
                acText.Rotation = (float)geom.Rotation.Degrees;
                acText.Layer    = layer;

                m_Dxf.AddEntity(acText);
            }
            return(true);
        }
        /// <summary>
        /// Obtains any miscellaneous attribute data for a specific spatial object
        /// </summary>
        /// <param name="so">The object of interest</param>
        /// <returns>Any attributes for the spatial object (never null, but may be an empty list)</returns>
        List <Row> GetRows(ISpatialObject so)
        {
            List <Row> result = new List <Row>();

            Feature f = (so as Feature);

            if (f == null && so is Polygon)
            {
                f = (so as Polygon).Label;
            }

            if (f != null && f.FeatureId != null)
            {
                FeatureId           fid  = f.FeatureId;
                IPossibleList <Row> rows = fid.Rows;
                if (rows != null)
                {
                    foreach (Row r in rows)
                    {
                        result.Add(r);
                    }
                }
            }

            return(result);
        }
        /// <summary>
        /// Checks if an object is acceptable for trimming.
        /// </summary>
        /// <param name="thing">The candidate object.</param>
        /// <returns>The supplied candidate, cast to a line (given that the candidate is
        /// suitable for trimming). Null if the candidate is not a line, or not suitable
        /// for trimming.</returns>
        static LineFeature PreCheck(ISpatialObject thing)
        {
            // It has no be a line
            LineFeature line = (thing as LineFeature);

            if (line == null)
            {
                return(null);
            }

            // It has to be topological
            Topology t = line.Topology;

            if (t == null)
            {
                return(null);
            }

            // The line should have system-defined topological line
            // sections (if it doesn't that would mean that the complete
            // line dangles).
            SectionTopologyList sectionList = (t as SectionTopologyList);

            if (sectionList == null)
            {
                return(null);
            }

            if (sectionList.CanTrim())
            {
                return(line);
            }

            return(null);
        }
Exemple #5
0
        /// <summary>
        /// Delegate called to process each polygon found within the build window.
        /// Called by <c>BuildIslands</c>
        /// </summary>
        /// <param name="o">An item found in the spatial index.</param>
        /// <returns>True (always), indicating that the spatial query should keep going.</returns>
        bool ProcessPolygon(ISpatialObject o)
        {
            if (!(o is Island))
            {
                return(true);
            }

            // Just return if the enclosing polygon is already known
            Island pol = (Island)o;

            if (pol.Container != null)
            {
                return(true);
            }

            // If the island is marked as floating, and it has a window
            // that encloses the build window, mark it as not floating.
            // This covers situations where a previously floating island
            // is now enclosed by something.
            if (pol.IsFloating && pol.Extent.IsOverlap(m_NewPolygonExtent))
            {
                pol.IsFloating = false;
            }

            pol.SetContainer();
            return(true);
        }
Exemple #6
0
        /// <summary>
        /// Delegate called to process every polygon in the map.
        /// Called by <see cref="BuildLabels"/>.
        /// </summary>
        /// <param name="o">A polygon ring in the spatial index</param>
        /// <returns>True (always), to force examination of the entire spatial index</returns>
        bool FindLabelForPolygon(ISpatialObject o)
        {
            Debug.Assert(o is Ring);

            if (o is Polygon)
            {
                // Only process polygons that don't already have a label, and which
                // don't contain any islands (polygons with islands tend to cover
                // much larget areas, so trying to find the label this way will
                // probably not be very efficient).

                Polygon p = (Polygon)o;
                if (p.Label == null && !p.HasAnyIslands)
                {
                    TextFeature label = new FindPolygonLabelQuery(m_Model.Index, p).Result;
                    if (label != null)
                    {
                        p.ClaimLabel(label);
                        label.SetBuilt(true);
                    }
                }
            }

            return(true);
        }
Exemple #7
0
        /// <summary>
        /// Override does the same as <c>SpatialController.SetSelection</c>, and additionally
        /// tells the application's main window (the main window goes on to display a property
        /// grid for the current selection).
        /// </summary>
        public override bool SetSelection(ISpatialSelection newSel)
        {
            if (!base.SetSelection(newSel))
            {
                return(false);
            }

            if (m_Main != null)
            {
                Debug.Assert(newSel != null);
                ISpatialObject so = newSel.Item;
                if (so is GeometryWrapper)
                {
                    GeometryWrapper g = (GeometryWrapper)so;
                    object          o = (g == null ? null : g.UserData);
                    m_Main.SetSelection(o);
                }
                else
                {
                    m_Main.SetSelection(null);
                }
            }

            return(true);
        }
        /// <summary>
        /// Creates a new <c>FindClosestQuery</c> (and executes it). The result of the query
        /// can then be obtained through the <c>Result</c> property.
        /// </summary>
        /// <param name="index">The spatial index to search</param>
        /// <param name="p">The search position.</param>
        /// <param name="radius">The search tolerance (expected to be greater than zero).</param>
        /// <param name="types">The type of objects to look for.</param>
        internal FindClosestQuery(ISpatialIndex index, IPosition p, ILength radius, SpatialType types)
        {
            if (types == 0)
            {
                throw new ArgumentNullException("Spatial type(s) not specified");
            }

            // If the user hasn't been specific, ensure we don't search for polygons!
            SpatialType useTypes = (types == SpatialType.All ? SpatialType.Feature : types);

            Debug.Assert((useTypes & SpatialType.Polygon) == 0);

            // It's important to round off to the nearest micron. Otherwise you might not
            // get the desired results in situations where the search radius is zero.
            m_Position = PositionGeometry.Create(p);

            m_Radius   = radius;
            m_Types    = types;
            m_Result   = null;
            m_Distance = m_Radius.Meters;

            // The query will actually involve a square window, not a circle.
            IWindow x = new Window(m_Position, radius.Meters * 2.0);

            index.QueryWindow(x, useTypes, OnQueryHit);
        }
Exemple #9
0
        /// <summary>
        /// Delegate that's called whenever the index finds a line.
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool CheckLine(ISpatialObject item)
        {
            Debug.Assert(item is LineFeature);
            LineFeature line = (LineFeature)item;

            // Return if the line is non-topological
            if (!line.IsTopological)
            {
                return(true);
            }

            Topology t = line.Topology;

            if (t != null)
            {
                foreach (IDivider d in t)
                {
                    CheckType types = (m_Options & DividerCheck.Check(d));
                    if (types != CheckType.Null)
                    {
                        DividerCheck check = new DividerCheck(d, types);
                        m_Result.Add(check);
                    }
                }
            }

            return(OnCheck());
        }
Exemple #10
0
            public SpatialNode FindChildLeastEnlargement(ISpatialObject obj)
            {
                SpatialNode bestChild        = null;
                var         leastEnlargement = float.MaxValue;
                var         leastVolume      = float.MaxValue;

                foreach (var child in children)
                {
                    var volume    = CalculateVolume(child.min, child.max);
                    var newVolume = CalculateVolume(Vector3.Min(child.min, obj.min),
                                                    Vector3.Max(child.max, obj.max));
                    var enlargement = newVolume - volume;
                    if (enlargement > leastEnlargement ||
                        Mathf.Approximately(enlargement, leastEnlargement) && volume >= leastVolume)
                    {
                        continue;
                    }

                    bestChild        = child as SpatialNode;
                    leastEnlargement = enlargement;
                    leastVolume      = volume;
                }

                return(bestChild);
            }
Exemple #11
0
        /*
         *
         * //
         * //	@parm	AutoCad entity.
         * //	@parm	Cross-reference of CED entity types to AutoCad layers.
         * //	@parm	The style for the annotations.
         * //	@parm	The point involved.
         * //
         * //	@rdesc	TRUE if annotation was written.
         * LOGICAL CeAutoCad::ExportAngles ( const AD_DB_HANDLE DwgHandle
         *                                                      , AD_VMADDR pEntityList
         *                                                      , PAD_ENT_HDR pEntityHeader
         *                                                      , PAD_ENT pEntity
         *                                                      , CacadLayerEntitySet* pLESet
         *                                                      , AD_SHPTB* pStyle
         *                                                      , const CePoint& pt ) const {
         *
         * // Skip if there is no AutoCad layer for the specified point
         * // (the annotations will be going onto the same layer).
         * AD_OBJHANDLE* pLayerHandle = pLESet->GetpLayerHandle(&pt,
         *      m_ContinuousLineTypeHandle,TRUE);
         * if ( !pLayerHandle ) return FALSE;
         *
         * // Get the point to create a set of miscellaneous text
         * // objects.
         * CPtrList text;
         * UINT4 nAngle = pt.CreateAngleText(text,FALSE);
         * if ( nAngle==0 ) return FALSE;
         *
         * // Export each item of text (deleting each item as we go).
         * POSITION pos = text.GetHeadPosition();
         * while ( pos ) {
         *      CeMiscText* pText = (CeMiscText*)text.GetNext(pos);
         *
         *      // What's the actual text string?
         *      CString text;
         *      pText->GetText(text);
         *
         *      // If the text position is to the west of the point,
         *      // align it on the right.
         *      FLOAT8 xt = pText->GetEasting();
         *      FLOAT8 yt = pText->GetNorthing();
         *      INT4 halign = AD_TEXT_JUST_LEFT;
         *
         *      // Take special care with vertical text (allow up to 1mm
         *      // of roundoff).
         *      if ( (xt+0.001) < pt.GetEasting() ) halign = AD_TEXT_JUST_RIGHT;
         *
         *      // Pull out values for function call below.
         *      CeVertex posn(xt,yt);
         *      FLOAT8 grheight = pText->GetHeight();
         *      FLOAT8 rotation = pText->GetRotation();
         *
         *      CacadText AcadText(DwgHandle,pEntityList,pEntityHeader,pEntity);
         *      AcadText.ExportAngleDistText(pStyle,pLayerHandle,pText,text,posn
         *                                                              ,grheight,rotation
         *                                                              ,halign,AD_TEXT_VALIGN_MIDDLE);
         *
         *      delete pText;
         * }
         *
         * // Ensure pointer to the text have been removed too.
         * text.RemoveAll();
         *
         * return TRUE;
         */

        bool WriteLine(ISpatialObject item)
        {
            LineFeature line = (LineFeature)item;

            WriteLineGeometry(line.LineGeometry);
            return(true);
        }
        /// <summary>
        /// Delegate that's called whenever the index finds text with a window that overlaps the query window
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>TextFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnTextFound(ISpatialObject item)
        {
            // Ignore test that's already been built
            TextFeature text = (TextFeature)item;

            if (text.IsBuilt)
            {
                return(true);
            }

            if (text.IsTopological)
            {
                // Get the label's reference position.
                IPointGeometry posn = text.GetPolPosition();

                // Try to find enclosing polygon
                if (m_Polygon.IsEnclosing(posn))
                {
                    m_Result = text;
                    return(false);
                }
            }

            return(true);
        }
Exemple #13
0
        /// <summary>
        /// Delegate called to process each text feature found within the build window.
        /// Called by <see cref="BuildLabels"/>.
        /// </summary>
        /// <param name="o">An item found in the spatial index.</param>
        /// <returns>True (always), indicating that the spatial query should keep going.</returns>
        bool ProcessLabel(ISpatialObject o)
        {
            Debug.Assert(o is TextFeature);
            TextFeature f = (TextFeature)o;

            f.SetPolygon();
            return(true);
        }
Exemple #14
0
        /// <summary>
        /// Adds a spatial object to this selection, given that it is not already
        /// part of the selection.
        /// </summary>
        /// <param name="so">The object to remember as part of this selection (not null)</param>
        /// <exception cref="ArgumentNullException">If the specified object is null</exception>
        internal void Add(ISpatialObject so)
        {
            if (so==null)
                throw new ArgumentNullException();

            if (!m_Items.Contains(so))
                m_Items.Add(so);
        }
        internal void SetSelectedObject(ISpatialObject so)
        {
            try
            {
                editButton.Visible = false;
                string oldLastPage = m_LastPageName;

                // Grab the attributes we'll be displaying
                List <Row> rows = GetRows(so);

                // Require a page for each attribute, plus 1 for standard properties.
                // If we have an excess number of property pages, get rid of the redundant ones
                while (tabControl.TabCount > (1 + rows.Count))
                {
                    tabControl.TabPages.RemoveAt(1);
                }

                // Reuse any remaining PropertyPages, add any additional pages
                int toReuse = (tabControl.TabCount - 1);
                foreach (Row r in rows)
                {
                    if (toReuse > 0)
                    {
                        PropertyPage pp = (tabControl.TabPages[toReuse] as PropertyPage);
                        Debug.Assert(pp != null);
                        pp.SetRow(r);
                        toReuse--;
                    }
                    else
                    {
                        tabControl.TabPages.Add(new PropertyPage(r));
                    }
                }

                propertyGrid1.SelectedObject = so;

                // If a non-standard tab was previously on top, and we still have
                // a page with the same tab text, ensure it's on top. Failing
                // that, go for the first tab that shows any database attributes
                // (since that info will likely have more relevance to the user).
                if (!SelectPage(oldLastPage))
                {
                    if (tabControl.TabCount > 1)
                    {
                        tabControl.SelectedIndex = 1;
                    }
                }
            }

            catch
            {
                propertyGrid1.SelectedObject = null;
            }

            propertyGrid1.Refresh();
        }
Exemple #16
0
        bool DefaultVisibilityPredicate(ISpatialObject obj)
        {
            if (m_Settings.UseCulling)
            {
                return(m_Culling.IsVisible(obj));
            }

            m_Bounds.SetMinMax(obj.Min, obj.Max);
            return(m_Bounds.SqrDistance(m_CamPos) < m_VisibilitySqrDist);
        }
 /// <summary>
 /// Creates a new <c>SpatialSelection</c> that contains a single item (or nothing).
 /// </summary>
 /// <param name="so">The object to remember as part of this selection (if null, it
 /// will not be added to the selection)</param>
 public SpatialSelection(ISpatialObject so)
 {
     if (so==null)
         m_Items = new List<ISpatialObject>();
     else
     {
         m_Items = new List<ISpatialObject>(1);
         m_Items.Add(so);
     }
 }
Exemple #18
0
        /// <summary>
        /// Checks whether this selection refers to one specific spatial object.
        /// </summary>
        /// <param name="so">The object to compare with</param>
        /// <returns>True if this selection refers to a single item that corresponds
        /// to the specified spatial object</returns>
        public bool Equals(ISpatialObject so)
        {
            if (so==null)
                return false;

            if (this.Count!=1)
                return false;

            return Object.ReferenceEquals(so, m_Items[0]);
        }
Exemple #19
0
        bool CheckIntersectRay(ISpatialObject obj)
        {
            m_Bounds.SetMinMax(obj.Min, obj.Max);
            if (!m_Bounds.IntersectRay(m_SelectionRay, out var distance))
            {
                return(false);
            }

            obj.Priority = distance;
            return(true);
        }
Exemple #20
0
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), meaning the query should continue.</returns>
        bool OnQueryHit(ISpatialObject item)
        {
            if (m_DoPaint)
            {
                m_DoPaint = false;
                m_Display.PaintNow();
            }

            item.Render(m_Display, m_Style);
            return(true);
        }
Exemple #21
0
        void AddOrRemoveFromSelection(ISpatialObject so)
        {
            Selection sel = new Selection(this.SpatialSelection.Items);

            if (!sel.Remove(so))
            {
                sel.Add(so);
            }

            SetSelection(sel);
        }
        /// <summary>
        /// Delegate that's called whenever the index finds a point that's inside the query window
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>PointFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnPointFound(ISpatialObject item)
        {
            PointFeature p = (PointFeature)item;

            if (m_ClosedShape.IsOverlap(p))
            {
                m_Points.Add(p);
            }

            return(true);
        }
Exemple #23
0
        public bool IsVisible(ISpatialObject obj)
        {
            m_BoundsMin = obj.Min;
            m_BoundsMax = obj.Max;

            if (m_Settings.UseDistanceCullingAvoidance)
            {
                m_Bounds.SetMinMax(m_BoundsMin, m_BoundsMax);
                if (m_Bounds.SqrDistance(m_CamPos) < m_AvoidCullingWithinSqrDistance)
                {
                    return(true);
                }
            }

            if (m_UseShadowCullingAvoidance) // use member because we check if shadows are enabled in QualitySettings
            {
                // expand bounds to include potential shadow casting area
                m_Distance = m_Settings.ShadowDistanceFactor * Mathf.Max(m_BoundsMax.x - m_BoundsMin.x,
                                                                         m_BoundsMax.y - m_BoundsMin.y, m_BoundsMax.z - m_BoundsMin.z);
                m_DirectionalLightForwardOffset = m_DirectionalLightForward * m_Distance;
                m_BoundsMin = Vector3.Min(m_BoundsMin, m_BoundsMin + m_DirectionalLightForwardOffset);
                m_BoundsMax = Vector3.Max(m_BoundsMax, m_BoundsMax + m_DirectionalLightForwardOffset);
            }

            // do the frustum check, necessary for size and depth culling since both techniques are based on the screen projection
            if (!IsInCameraFrustum(m_BoundsMin, m_BoundsMax))
            {
                return(false);
            }

            // early exit before screen projection if it won't be used
            if (!m_Settings.UseSizeCulling && !m_Settings.UseDepthCulling)
            {
                return(true);
            }

            // if screen rect is invalid, safer to assume object is visible
            if (!TryCalculateScreenRect(m_BoundsMin, m_BoundsMax, out m_ScreenMin, out m_ScreenMax))
            {
                return(true);
            }

            if (m_Settings.UseSizeCulling)
            {
                m_ScreenAreaRatio = (m_ScreenMax.x - m_ScreenMin.x) * (m_ScreenMax.y - m_ScreenMin.y);
                if (m_ScreenAreaRatio < m_MinScreenAreaRatioMesh)
                {
                    return(false);
                }
            }

            return(!m_Settings.UseDepthCulling || !IsDepthOccluded(m_ScreenMin, m_ScreenMax));
        }
Exemple #24
0
 /// <summary>
 /// Creates a new <c>SpatialSelection</c> that contains a single item (or nothing).
 /// </summary>
 /// <param name="so">The object to remember as part of this selection (if null, it
 /// will not be added to the selection)</param>
 public SpatialSelection(ISpatialObject so)
 {
     if (so == null)
     {
         m_Items = new List <ISpatialObject>();
     }
     else
     {
         m_Items = new List <ISpatialObject>(1);
         m_Items.Add(so);
     }
 }
Exemple #25
0
        /// <summary>
        /// Attempts to locate the circle closest to a position of interest.
        /// </summary>
        /// <param name="p">The search position (on the circumference of the circle)</param>
        /// <param name="tol">The search tolerance</param>
        /// <returns>The circle closest to the search position (null if nothing found)</returns>
        internal Circle QueryClosestCircle(IPosition p, ILength tol)
        {
            ISpatialObject so = m_ExtraData.QueryClosest(p, tol, SpatialType.Line);

            if (so == null)
            {
                return(null);
            }

            Debug.Assert(so is Circle);
            return(so as Circle);
        }
        internal void SetSelectedObject(ISpatialObject so)
        {
            try
            {
                editButton.Visible = false;
                string oldLastPage = m_LastPageName;

                // Grab the attributes we'll be displaying
                List<Row> rows = GetRows(so);

                // Require a page for each attribute, plus 1 for standard properties.
                // If we have an excess number of property pages, get rid of the redundant ones
                while (tabControl.TabCount > (1+rows.Count))
                    tabControl.TabPages.RemoveAt(1);

                // Reuse any remaining PropertyPages, add any additional pages
                int toReuse = (tabControl.TabCount - 1);
                foreach (Row r in rows)
                {
                    if (toReuse > 0)
                    {
                        PropertyPage pp = (tabControl.TabPages[toReuse] as PropertyPage);
                        Debug.Assert(pp!=null);
                        pp.SetRow(r);
                        toReuse--;
                    }
                    else
                    {
                        tabControl.TabPages.Add(new PropertyPage(r));
                    }
                }

                propertyGrid1.SelectedObject = so;

                // If a non-standard tab was previously on top, and we still have
                // a page with the same tab text, ensure it's on top. Failing
                // that, go for the first tab that shows any database attributes
                // (since that info will likely have more relevance to the user).
                if (!SelectPage(oldLastPage))
                {
                    if (tabControl.TabCount > 1)
                        tabControl.SelectedIndex = 1;
                }
            }

            catch
            {
                propertyGrid1.SelectedObject = null;
            }

            propertyGrid1.Refresh();
        }
Exemple #27
0
        bool CheckColliderDistance(ISpatialObject obj)
        {
            m_Bounds.SetMinMax(obj.Min, obj.Max);
            var distance = m_Bounds.SqrDistance(m_Camera.transform.position);

            if (distance > m_Settings.ColliderObjectsMaxDistance)
            {
                return(false);
            }

            obj.Priority = distance;
            return(true);
        }
Exemple #28
0
        public override void Select(ISpatialDisplay display, IPosition p, SpatialType spatialType)
        {
            ISpatialObject so = SelectObject(display, p, spatialType);

            if (so != null)
            {
                SetSelection(new Selection(so, p));
            }
            else
            {
                SetSelection(null);
            }
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Feature</c>)</param>
        /// <returns>True if the query should continue. False if the item is exactly coincident with
        /// the query position.</returns>
        bool OnQueryHit(ISpatialObject item)
        {
            double d = item.Distance(m_Position).Meters;

            if (d <= m_Distance)
            {
                m_Distance = d;
                m_Result   = item;
                return(m_Distance > Double.Epsilon);
            }

            return(true);
        }
Exemple #30
0
        /// <summary>
        /// Delegate that's called whenever the index finds a polygon
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool CleanupPolygon(ISpatialObject item)
        {
            Debug.Assert(item is Ring);
            Ring r = (Ring)item;

            if (r.IsDeleted)
            {
                m_Deletions.Add(r);
            }

            r.Clean();
            return(true);
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>PointFeature</c>)</param>
        /// <returns>True if the query should continue. False if a coincident point has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is PointFeature);

            PointFeature p = (PointFeature)item;
            if (p.Geometry.IsCoincident(m_Point))
            {
                m_Result = p;
                return false;
            }

            return true;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>PointFeature</c>)</param>
        /// <returns>True if the query should continue. False if a matching point has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is PointFeature);

            PointFeature p = (PointFeature)item;
            if (p.FormattedKey == m_Key)
            {
                m_Result = p;
                return false;
            }

            return true;
        }
Exemple #33
0
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Ring</c>)</param>
        /// <returns>True if the query should continue. False if the enclosing polygon has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            // We're only interested in real polygons (not islands)
            if (!(item is Polygon))
            {
                return(true);
            }

            // The area of the polygon MUST be bigger than the area of the island.
            Polygon p = (Polygon)item;

            if (p.Area < m_Island.Area)
            {
                return(true);
            }

            // Skip if the window does not actually overlap the search point.
            if (!p.Extent.IsOverlap(m_EastPoint))
            {
                return(true);
            }

            // The window of the island must be ENTIRELY within the window
            // of the candidate polygon.
            if (!m_Island.Extent.IsEnclosedBy(p.Extent))
            {
                return(true);
            }

            // Skip if the polygon doesn't enclose the east point.
            if (!p.IsRingEnclosing(m_EastPoint))
            {
                return(true);
            }

            // Skip if we previously found something, and the area of the candidate
            // polygon is bigger. Take care here - the polygons may not yet know about
            // all their islands (which might lead to an incorrect enclosing polygon),
            // so this test should EXCLUDE the area of any islands that they already
            // know about).
            if (m_Result != null && p.AreaExcludingIslands > m_Result.AreaExcludingIslands)
            {
                return(true);
            }

            m_Result = p;

            // Keep going after finding a result, since a different (smaller) polygon
            // may be found further on in the search.
            return(true);
        }
        public virtual void Select(ISpatialDisplay display, IPosition p, SpatialType spatialType)
        {
            if (m_Data == null)
            {
                return;
            }

            // Use a tolerance of 2mm at the map scale of the supplied display
            ILength size = new Length(0.002 * display.MapScale);

            ISpatialObject so = m_Data.QueryClosest(p, size, spatialType);

            SetSelection(new SpatialSelection(so));
        }
        /// <summary>
        /// Something that processes an item in the index (for use with implementations
        /// of the <c>ISpatialIndex.QueryWindow</c> method).
        /// </summary>
        /// <param name="item">An object associated with the spatial index</param>
        /// <returns>True if the query should be continued. False if the query should be
        /// terminated (e.g. a result may have been obtained).</returns>
        public bool ExportFeature(ISpatialObject item)
        {
            // Islands only get exported in the context of their enclosing polygon
            if (item is Island)
                return true;

            if (item.SpatialType == SpatialType.Point)
                ExportPoint((PointFeature)item);
            else if (item.SpatialType == SpatialType.Polygon)
                //ExportCurvePolygon((Polygon)item);
                ExportPolygon((Polygon)item);
            else
                throw new NotSupportedException("Unexpected spatial type: " + item.SpatialType);

            return true;
        }
Exemple #36
0
        bool WriteText(ISpatialObject item)
        {
            TextFeature text = (item as TextFeature);

            if (this.IsTopological)
            {
                ExportKey(text);

            }
            else
            {
            }

            // Skip if the AutoCad layer cannot be determined
            Layer layer = m_Layers.GetLayer(text, m_ContinuousLineType, this.IsTopological);
            if (layer != null)
            {
                TextGeometry geom = text.TextGeometry;
                Text acText = new Text(geom.Text, GetVector(geom.Position), geom.Height);
                acText.Rotation = (float)geom.Rotation.Degrees;
                acText.Layer = layer;

                m_Dxf.AddEntity(acText);
            }
            return true;
        }
Exemple #37
0
        public void Explore(ISpatialObject spatial, ExploreDelegate exploreDelegate, Type agentType = null)
        {
            IEnumerable<ISpatialEntity> res;
            var entity = spatial;
            if (gpuActive) gpuActiveWait.WaitOne();
            Interlocked.Increment(ref m_ActiveOperationCount);
            int objId = Interlocked.Increment(ref exploreIdGenBase);
            long objData = objId | FLAG_EXLORE;
            objIdList.Add(objId);
            /*spatialObjIdMap.Add(entity, objId);
            objIdSpatialMap.Add(objId, entity);
            */
            clShapeObject act;
            clPoint center;
            center.x = (float)entity.Shape.Bounds.Position.X;
            center.y = (float)entity.Shape.Bounds.Position.Y;
            center.z = (float)entity.Shape.Bounds.Position.Z;
            clPoint front;
            front.x = (float)entity.Shape.Bounds.LeftBottomFront.X;
            front.y = (float)entity.Shape.Bounds.LeftBottomFront.Y;
            front.z = (float)entity.Shape.Bounds.LeftBottomFront.Z;
            clPoint rear;
            rear.x = (float)entity.Shape.Bounds.RightTopRear.X;
            rear.y = (float)entity.Shape.Bounds.RightTopRear.Y;
            rear.z = (float)entity.Shape.Bounds.RightTopRear.Z;
            act.center = center;
            act.leftBottomFront = front;
            act.rigthTopRear = rear;

            envExploreObjs.Add(objData, act);
            /*
                        shapeList.Add(act);
                        objIdClShapeMap.Add(objId, act);
                        */

            Interlocked.Decrement(ref m_ActiveOperationCount);
        }
 /// <summary>
 /// Creates new <c>SimpleCommandUI</c> that isn't an update.
 /// </summary>
 /// <param name="cc">The container that may be used to display any sort of
 /// user dialog (null if no dialog is involved)</param>
 /// <param name="cmdId">The item used to invoke the command.</param>
 /// <param name="update">The object (if any) that was selected for update</param>
 /// <param name="recall">An operation that is being recalled (null if this is an update).</param>
 protected SimpleCommandUI(IControlContainer cc, IUserAction cmdId, ISpatialObject update, Operation recall)
     : base(cc, cmdId, update, recall)
 {
 }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>LineFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is LineFeature);

            // Ignore if we're intersecting a line feature & the line we've found is that line
            LineFeature f = (LineFeature)item;
            if (Object.ReferenceEquals(m_Feature, f))
                return true;

            // Ignore lines that don't have any topology
            Topology t = f.Topology;
            if (t == null)
                return true;

            Debug.Assert(f.IsTopological);

            // Ignore lines that are marked as "moved"
            if (f.IsMoved)
                return true;

            // Intersect each divider
            foreach (IDivider d in t)
            {
                // Ignore divider overlaps (regarded as non-topological)
                if (d.IsOverlap)
                    continue;

                // Search for intersections
                IntersectionResult other = new IntersectionResult(d);
                m_Geom.Intersect(other);

                if (other.IntersectCount>0)
                {
                    // Determine the context of each intersection.
                    other.SetContext(m_Geom);

                    // If end-to-end simple intersections are not required, weed them out.
                    if (!m_WantEndEnd)
                        other.CutEndEnd();

                    if (other.IntersectCount>0)
                        m_Result.Add(other);
                }
            }

            return true;
        }
        /// <summary>
        /// Delegate called to process each polygon found within the build window.
        /// Called by <c>BuildIslands</c>
        /// </summary>
        /// <param name="o">An item found in the spatial index.</param>
        /// <returns>True (always), indicating that the spatial query should keep going.</returns>
        bool ProcessPolygon(ISpatialObject o)
        {
            if (!(o is Island))
                return true;

            // Just return if the enclosing polygon is already known
            Island pol = (Island)o;
            if (pol.Container!=null)
                return true;

            // If the island is marked as floating, and it has a window
            // that encloses the build window, mark it as not floating.
            // This covers situations where a previously floating island
            // is now enclosed by something.
            if (pol.IsFloating && pol.Extent.IsOverlap(m_NewPolygonExtent))
                pol.IsFloating = false;

            pol.SetContainer();
            return true;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds a polygon
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool CleanupPolygon(ISpatialObject item)
        {
            Debug.Assert(item is Ring);
            Ring r = (Ring)item;

            if (r.IsDeleted)
                m_Deletions.Add(r);

            r.Clean();
            return true;
        }
 /// <summary>
 /// Delegate called to process each text feature found within the build window.
 /// Called by <see cref="BuildLabels"/>.
 /// </summary>
 /// <param name="o">An item found in the spatial index.</param>
 /// <returns>True (always), indicating that the spatial query should keep going.</returns>
 bool ProcessLabel(ISpatialObject o)
 {
     Debug.Assert(o is TextFeature);
     TextFeature f = (TextFeature)o;
     f.SetPolygon();
     return true;
 }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>PointFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            Debug.Assert(item is PointFeature);
            PointFeature p = (PointFeature)item;

            if (m_Line.Distance(p).Meters > m_Tolerance)
                return true;

            if (!m_WantEnds && (m_Line.Start.IsCoincident(p) || m_Line.End.IsCoincident(p)))
                return true;

            m_Result.Add(p);
            return true;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Feature</c>)</param>
        /// <returns>True if the query should continue. False if the item is exactly coincident with
        /// the query position.</returns>
        bool OnQueryHit(ISpatialObject item)
        {
            double d = item.Distance(m_Position).Meters;
            if (d<=m_Distance)
            {
                m_Distance = d;
                m_Result = item;
                return (m_Distance > Double.Epsilon);
            }

            return true;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds a feature
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool CleanupFeature(ISpatialObject item)
        {
            Debug.Assert(item is Feature);
            Feature f = (Feature)item;

            if (f.IsInactive)
                m_Deletions.Add(f);
            else if (f.IsMoved)
                m_Moves.Add(f);

            f.Clean();
            return true;
        }
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>Ring</c>)</param>
        /// <returns>True if the query should continue. False if the enclosing polygon has been found.</returns>
        private bool OnQueryHit(ISpatialObject item)
        {
            // We're only interested in real polygons (not islands)
            if (!(item is Polygon))
                return true;

            // The window of the polygon has to overlap.
            Polygon p = (Polygon)item;
            if (!p.Extent.IsOverlap(m_Point))
                return true;

            // Skip if it doesn't enclose the search position
            if (!p.IsRingEnclosing(m_Point))
                return true;

            // If the polygon contains any islands, remember the polygon
            // for a further look. Things like an unclosed street network
            // can have MANY islands, so checking whether the position falls
            // inside any of them is a bit laborious. We'll comes back to
            // this polygon if we can't find an easy match.

            if (p.HasAnyIslands)
            {
                if (m_Candidates==null)
                    m_Candidates = new List<Polygon>(1);

                m_Candidates.Add(p);
                return true;
            }

            m_Result = p;
            return false;
        }
        /// <summary>
        /// Creates a new <c>FindClosestQuery</c> (and executes it). The result of the query
        /// can then be obtained through the <c>Result</c> property.
        /// </summary>
        /// <param name="index">The spatial index to search</param>
        /// <param name="p">The search position.</param>
        /// <param name="radius">The search tolerance (expected to be greater than zero).</param>
        /// <param name="types">The type of objects to look for.</param>
        internal FindClosestQuery(ISpatialIndex index, IPosition p, ILength radius, SpatialType types)
        {
            if (types==0)
                throw new ArgumentNullException("Spatial type(s) not specified");

            // If the user hasn't been specific, ensure we don't search for polygons!
            SpatialType useTypes = (types==SpatialType.All ? SpatialType.Feature : types);
            Debug.Assert((useTypes & SpatialType.Polygon)==0);

            // It's important to round off to the nearest micron. Otherwise you might not
            // get the desired results in situations where the search radius is zero.
            m_Position = PositionGeometry.Create(p);

            m_Radius = radius;
            m_Types = types;
            m_Result = null;
            m_Distance = m_Radius.Meters;

            // The query will actually involve a square window, not a circle.
            IWindow x = new Window(m_Position, radius.Meters * 2.0);
            index.QueryWindow(x, useTypes, OnQueryHit);
        }
        /// <summary>
        /// Checks if an object is acceptable for trimming.
        /// </summary>
        /// <param name="thing">The candidate object.</param>
        /// <returns>The supplied candidate, cast to a line (given that the candidate is
        /// suitable for trimming). Null if the candidate is not a line, or not suitable
        /// for trimming.</returns>
        static LineFeature PreCheck(ISpatialObject thing)
        {
            // It has no be a line
            LineFeature line = (thing as LineFeature);
            if (line==null)
                return null;

            // It has to be topological
            Topology t = line.Topology;
            if (t==null)
                return null;

            // The line should have system-defined topological line
            // sections (if it doesn't that would mean that the complete
            // line dangles).
            SectionTopologyList sectionList = (t as SectionTopologyList);
            if (sectionList==null)
                return null;

            if (sectionList.CanTrim())
                return line;

            return null;
        }
        /// <summary>
        /// Delegate called to process every polygon in the map.
        /// Called by <see cref="BuildLabels"/>.
        /// </summary>
        /// <param name="o">A polygon ring in the spatial index</param>
        /// <returns>True (always), to force examination of the entire spatial index</returns>
        bool FindLabelForPolygon(ISpatialObject o)
        {
            Debug.Assert(o is Ring);

            if (o is Polygon)
            {
                // Only process polygons that don't already have a label, and which
                // don't contain any islands (polygons with islands tend to cover
                // much larget areas, so trying to find the label this way will
                // probably not be very efficient).

                Polygon p = (Polygon)o;
                if (p.Label == null && !p.HasAnyIslands)
                {
                    TextFeature label = new FindPolygonLabelQuery(m_Model.Index, p).Result;
                    if (label != null)
                    {
                        p.ClaimLabel(label);
                        label.SetBuilt(true);
                    }
                }
            }

            return true;
        }
Exemple #50
0
        /// <summary>
        /// Delegate that's called whenever the index finds an object with an extent that
        /// overlaps the query window.
        /// </summary>
        /// <param name="item">The item to process</param>
        /// <returns>True (always), meaning the query should continue.</returns>
        bool OnQueryHit(ISpatialObject item)
        {
            if (m_DoPaint)
            {
                m_DoPaint = false;
                m_Display.PaintNow();
            }

            item.Render(m_Display, m_Style);
            return true;
        }
        /// <summary>
        /// Delegate called to process every line feature in the model.
        /// Called by <c>Build</c>
        /// </summary>
        /// <param name="o">An item found in the spatial index.</param>
        /// <returns>True (always), indicating that the spatial query should keep going.</returns>
        /// <exception cref="Exception">If an error occurred building a polygon.</exception>
        bool ProcessLine(ISpatialObject o)
        {
            Debug.Assert(o is LineFeature);
            LineFeature line = (LineFeature)o;

            try
            {
                line.BuildPolygons(m_NewPolygonExtent, m_Index);
                return true;
            }

            catch (Exception e)
            {
                string msg = String.Format("Error building polygon starting at line {0} ({1})",
                                            line.ToString(), e.Message);
                throw new Exception(msg);
            }
        }
        /// <summary>
        /// Checks whether this selection refers to one specific spatial object.
        /// </summary>
        /// <param name="so">The object to compare with</param>
        /// <returns>True if this selection refers to a single item that corresponds
        /// to the specified spatial object</returns>
        public bool Equals(ISpatialObject so)
        {
            if (so==null)
                return false;

            if (this.Count!=1)
                return false;

            return Object.ReferenceEquals(so, m_Items[0]);
        }
Exemple #53
0
        /// <summary>
        /// Displays properties of currently selected spatial object (so long as
        /// the properties grid is shown).
        /// </summary>
        /// <param name="o"></param>
        internal void SetSelection(ISpatialObject o)
        {
            /*
            // TEST...
            Polygon p = (o as Polygon);
            if (p != null)
            {
                IPosition[] edge = p.GetOutline(new Length(0.001));
                double ga1 = CadastralMapModel.Current.SpatialSystem.GetGroundArea(edge);
                double ga2 = CadastralMapModel.Current.CS.GetGroundArea(edge);
                MessageBox.Show(String.Format("ground area: {0:0.000000} vs {1:0.000000} - diff = {2:0.000000}",
                            ga1, ga2, ga1 - ga2));
            }
            */
            if (vSplitContainer.Panel2Collapsed)
                return;

            propertyDisplay.SetSelectedObject(o);
        }
Exemple #54
0
        /// <summary>
        /// Creates new <c>CommandUI</c> that isn't an update.
        /// </summary>
        /// <param name="cc">The container that may be used to display any sort of
        /// user dialog (null if no dialog is involved)</param>
        /// <param name="cmdId">The item used to invoke the command.</param>
        /// <param name="update">The object (if any) that was selected for update</param>
        /// <param name="recall">An operation that is being recalled (null if this is an update).</param>
        protected CommandUI(IControlContainer cc, IUserAction cmdId, ISpatialObject update, Operation recall)
        {
            m_Container = cc;
            m_Draw = EditingController.Current.ActiveDisplay;
            //m_Update = update;
            m_UpdCmd = null;
            m_Recall = recall;

            if (cmdId is EditingAction)
                m_EditId = (cmdId as EditingAction).EditId;
            else
                m_EditId = EditingActionId.Null;

            if (cmdId is RecalledEditingAction)
                m_Recall = (cmdId as RecalledEditingAction).RecalledEdit;

            Debug.Assert(m_Draw!=null);
        }
        /// <summary>
        /// Delegate that's called whenever the index finds a line with a window that overlaps the query window
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>LineFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnLineFound(ISpatialObject item)
        {
            LineFeature line = (LineFeature)item;

            // If either line end point is in the list of selected points, just accept the line.
            // Otherwise check whether the closed shape overlaps (or intersects) the line.
            if (m_Points.Contains(line.StartPoint) ||
                m_Points.Contains(line.EndPoint) ||
                m_ClosedShape.IsOverlap(line.LineGeometry))
                m_Result.Add(line);

            return true;
        }
        void AddOrRemoveFromSelection(ISpatialObject so)
        {
            Selection sel = new Selection(this.SpatialSelection.Items);
            if (!sel.Remove(so))
                sel.Add(so);

            SetSelection(sel);
        }
        /// <summary>
        /// Delegate that's called whenever the index finds a point that's inside the query window
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>PointFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnPointFound(ISpatialObject item)
        {
            PointFeature p = (PointFeature)item;

            if (m_ClosedShape.IsOverlap(p))
                m_Points.Add(p);

            return true;
        }
        /// <summary>
        /// Starts some sort of update. If the selected item is a polygon that has associated
        /// database attributes, a dialog will be displayed to let the user change the attributes.
        /// For any other spatial feature, the dialog for updating an editing operation will be
        /// displayed.
        /// </summary>
        /// <param name="so">The item selected for update</param>
        internal void RunUpdate(IUserAction action, ISpatialObject so)
        {
            if (so==null)
                return;

            // There can't be any command currently running.
            if (m_Command != null)
                return;

            // If we're currently auto-highlighting, get rid of it.
            AutoSelect = false;

            // If a polygon has been selected, invoke the attribute update dialog. Otherwise
            // start an update command.
            if (so.SpatialType == SpatialType.Polygon)
            {
                m_Main.UpdatePolygon((Polygon)so);
            }
            else
            {
                ClearSelection();
                UpdateUI upui = new UpdateUI(action);
                m_Command = upui;

                // We will have a DividerObject if the user selected a line
                // that has been intersected against other lines. In that case,
                // run the update using the underlying line.
                if (so is DividerObject)
                    upui.Run((so as DividerObject).Divider.Line);
                else
                    upui.Run((Feature)so);
            }
        }
        /// <summary>
        /// Delegate that's called whenever the index finds text with a window that overlaps the query window
        /// </summary>
        /// <param name="item">The item to process (expected to be some sort of <c>TextFeature</c>)</param>
        /// <returns>True (always), indicating that the query should continue.</returns>
        private bool OnTextFound(ISpatialObject item)
        {
            TextFeature text = (TextFeature)item;

            // Get the outline for the text
            IPosition[] outline = text.TextGeometry.Outline;

            // If any corner of the text outline is inside the closed shape (or any edge of
            // the outline intersects), remember the text in the results
            ClosedShape cs = new ClosedShape(outline);
            if (cs.IsOverlap(m_ClosedShape))
                m_Result.Add(text);

            return true;
        }
        /// <summary>
        /// Obtains any miscellaneous attribute data for a specific spatial object
        /// </summary>
        /// <param name="so">The object of interest</param>
        /// <returns>Any attributes for the spatial object (never null, but may be an empty list)</returns>
        List<Row> GetRows(ISpatialObject so)
        {
            List<Row> result = new List<Row>();

            Feature f = (so as Feature);
            if (f == null && so is Polygon)
                f = (so as Polygon).Label;

            if (f != null && f.FeatureId != null)
            {
                FeatureId fid = f.FeatureId;
                IPossibleList<Row> rows = fid.Rows;
                if (rows != null)
                {
                    foreach (Row r in rows)
                        result.Add(r);
                }
            }

            return result;
        }