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); } } }
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; }