public void AddSegment(IndexSegment s)
        {
            ArrayList cells = this.get_GridCells(s.XMin, s.YMin, s.XMax, s.YMax);

            this._segs.Add(s);

            ArrayList theCellContents;
            foreach (object cell in cells)
            {
                if (this._index.ContainsKey(cell) == false)
                {
                    theCellContents = new ArrayList();
                    theCellContents.Add(this._segs.Count - 1);
                    this._index.Add(cell, theCellContents);
                }
                else
                {
                    theCellContents = (ArrayList)this._index[cell];
                    theCellContents.Add(this._segs.Count - 1);
                }
            }
        }
Exemple #2
0
        public override int Execute(string logfileName)
        {
            this.InitLogging(logfileName);
            this.LogMessage(this.Name + " QA test execution started.");

            int currentOid = -1;
            bool bProblemsRunning = false;

            try
            {
                this.LogMessage(this.Name + " Parameters:");
                for (int i = 0; i < this.ParameterCount; i++)
                    this.LogMessage(this.get_ParameterText(i) + ": " + this.get_ParameterValue(i));

                this.ClearErrors();

                int index = this.FindParameter("search-radius");
                double searchRadius = Math.Abs((double)((ParameterInfo)this._params[index]).ParamValue);

                index = this.FindParameter("aspect-ratio-limit");
                double aspectRatio = Math.Abs((double)((ParameterInfo)this._params[index]).ParamValue);
                if (aspectRatio <= 1)
                {
                    aspectRatio = 10;
                    this.LogMessage("Segment length to distance ratio set under 1.0, using 10 instead.");
                }

                index = this.FindParameter(ParameterInfo.PARAM_CANDEFER);
                bool canDefer = (bool)((ParameterInfo)this._params[index]).ParamValue;
                index = this.FindParameter(ParameterInfo.PARAM_CANEXCEPT);
                bool canExcept = (bool)((ParameterInfo)this._params[index]).ParamValue;
                index = this.FindParameter("limit-neatline-index");
                bool limitNeatline = (bool)((ParameterInfo)this._params[index]).ParamValue;

                // Convert gap limits to metres
                UnitsParameterInfo theUnits = (UnitsParameterInfo)this._params[this.FindParameter("search-units")];
                IUnitConverter theConverter = new UnitConverterClass();
                searchRadius = theConverter.ConvertUnits(searchRadius, theUnits.ParamValueInUnits, esriUnits.esriMeters);

                IFeatureLayer theNeatlineLayer = this.NeatlineLayer;
                if (theNeatlineLayer == null)
                {
                    this.LogMessage("Missing valid neatline layer. Exiting Execute.");
                    bProblemsRunning = true;
                }
                else
                {
                    // Create index of neatline segments
                    this.LogMessage("Building neatline index");

                    // Calc cell size by taking some segment lengths
                    double sum = 0;
                    int segCount = 0;
                    IFeatureCursor theNLCursor = this.NeatlineLayer.Search(null, true);
                    IFeature theNeatline = theNLCursor.NextFeature();

                    while (theNeatline != null)
                    {
                        IGeometry theGeometry = theNeatline.Shape;
                        theGeometry.Project(SpatialReferenceHelper.BCAlbersSpatialReference);
                        ISegmentCollection theSegColl = (ISegmentCollection)theGeometry;
                        for (int i = 0; i < theSegColl.SegmentCount; i++)
                        {
                            sum += theSegColl.get_Segment(i).Length;
                            segCount++;
                        }
                        theNeatline = theNLCursor.NextFeature();
                        if (segCount > 100)
                            break;
                    }
                    Marshal.ReleaseComObject(theNLCursor);
                    theNLCursor = null;

                    double cellsize = (sum / segCount) * 5;
                    this.LogMessage("Cellsize: (" + sum + " / " + segCount + ") = " + cellsize);

                    // Determine the bounding env for the features to analyze
                    // If this is significantly smaller than the bounds of the neatline
                    // layer, this will save time building the cache
                    ISpatialFilter theSF = null;
                    if (limitNeatline)
                    {
                        IEnvelope theAOI = null;
                        for (int layerIdx = 0; layerIdx < this.LayerCount; layerIdx++)
                        {
                            IFeatureLayer theFLayer = this.get_Layer(layerIdx);
                            IFeatureClass theFClass = theFLayer.FeatureClass;
                            if (theFLayer != theNeatlineLayer
                                && this.SupportsGeometryType(theFClass.ShapeType))
                            {
                                if (this.ConstrainToSelection)
                                {
                                    IFeatureCursor theFCursor;
                                    ICursor theCursor;
                                    IFeatureSelection theFSel = (IFeatureSelection)theFLayer;
                                    theFSel.SelectionSet.Search(null, true, out theCursor);
                                    theFCursor = (IFeatureCursor)theCursor;
                                    IFeature theFeature = theFCursor.NextFeature();
                                    while (theFeature != null)
                                    {
                                        if (theFeature.Shape != null && theFeature.Shape.IsEmpty == false)
                                        {
                                            if (theAOI != null)
                                                theAOI.Union(theFeature.Shape.Envelope);
                                            else
                                                theAOI = theFeature.Shape.Envelope;
                                        }
                                        theFeature = theFCursor.NextFeature();
                                    }
                                    Marshal.ReleaseComObject(theFCursor);
                                }
                                else
                                {
                                    if (theAOI != null)
                                        theAOI.Union(theFLayer.AreaOfInterest);
                                    else
                                        theAOI = theFLayer.AreaOfInterest;
                                }
                            }
                        }

                        theSF = new SpatialFilterClass();
                        theSF.Geometry = theAOI;
                        theSF.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
                    }

                    SegmentCollectionIndex theIndex = new SegmentCollectionIndex(cellsize);
                    theNLCursor = this.NeatlineLayer.Search(theSF, true);
                    theNeatline = theNLCursor.NextFeature();
                    while (theNeatline != null)
                    {
                        ISegmentCollection theSegColl = theNeatline.Shape as ISegmentCollection;
                        for (int i = 0; i < theSegColl.SegmentCount; i++)
                        {
                            IndexSegment theSegment = new IndexSegment(theNeatline.OID, theSegColl.get_Segment(i));
                            theIndex.AddSegment(theSegment);
                        }
                        theNeatline = theNLCursor.NextFeature();
                    }

                    for (int layerIdx = 0; layerIdx < this.LayerCount; layerIdx++)
                    {
                        IFeatureLayer theFLayer = this.get_Layer(layerIdx);
                        IFeatureClass theFClass = theFLayer.FeatureClass;
                        IDataset theDataset = (IDataset)theFClass;

                        if (theFLayer != theNeatlineLayer
                            && this.SupportsGeometryType(theFClass.ShapeType))
                        {
                            this.LogMessage("Detecting neatline artifacts in featureclass " + theDataset.Name);

                            int nFeatures = 0;

                            IFeatureCursor theFCursor = null;
                            IFeatureSelection theFSel = (IFeatureSelection)theFLayer;

                            if (this.ConstrainToSelection)
                            {
                                this.LogMessage("Constraining analysis to selected features.");
                                ICursor theCursor;
                                theFSel.SelectionSet.Search(null, true, out theCursor);
                                theFCursor = (IFeatureCursor)theCursor;
                                nFeatures = theFSel.SelectionSet.Count;
                            }
                            else
                            {
                                theFCursor = theFClass.Search(null, true);
                                nFeatures = theFClass.FeatureCount(null);
                            }

                            this.LogMessage("Number of features to process: " + nFeatures);

                            int count = 0;
                            int countIncrement = Math.Max(1, nFeatures / 10);

                            IFeature theFeature = theFCursor.NextFeature();

                            while (theFeature != null)
                            {
                                if (theFeature.HasOID)
                                    currentOid = theFeature.OID; // for error trapping and debugging

                                ArrayList theList = this.ProcessFeature(theFeature, theIndex,
                                    searchRadius, aspectRatio, canDefer, canExcept);

                                if (theList != null)
                                {
                                    foreach (DataQualityError dqe in theList)
                                        this._errors.Add(dqe);
                                }

                                if (++count % countIncrement == 0)
                                {
                                    this.LogMessage("Processed " + count + " polygons...");
                                }
                                theFeature = theFCursor.NextFeature();
                            }

                            Marshal.ReleaseComObject(theFCursor);
                        }
                    }
                }

                this.LogMessage("Number of errors found: " + this.ErrorCount);
                this.LogMessage("Test " + this.Name + " successful.");
            }
            catch (Exception ex)
            {
                this.LogMessage("Exception caught: \n" + ex.Message + "\n" + ex.StackTrace.ToString());
                this.LogMessage("id of the current polygon: " + currentOid);
                return -1;
            }
            finally
            {
                this.StopLogging();
            }

            if (bProblemsRunning)
                return -1;

            return this.ErrorCount;
        }