/// <summary> /// create a contour transect from a source point /// </summary> public static IPolyline GetContourLineFromPoint(IPoint npsPoint, double MaxLineLength, double MinLineLength, IGeoDataset npsDemDataset, int SurveyID, IFeatureClass BndPolyFC, IFeatureClass ExclPolyFC) { ESRI.ArcGIS.GeoAnalyst.ISurfaceOp2 npsSurfaceOp; IPolyline npsPolyline, npsClippedPolyline, PrevTryPolyline = null; bool DidMaxLengthFit, IsInBndPoly, IsInExcludedAreas; int LengthAttempts; double CurTransLength, LengthTryIncrements, ElevValue; //determine a set number of times to try generating intermidiate lengths in both min and max //lengths were successful LengthAttempts = 20; LengthTryIncrements = (MaxLineLength - MinLineLength) / LengthAttempts; //create a polyline from the elevation for the random point npsSurfaceOp = new ESRI.ArcGIS.GeoAnalyst.RasterSurfaceOpClass(); npsPolyline = new PolylineClass(); npsSurfaceOp.ContourAsPolyline(npsDemDataset, npsPoint, out npsPolyline, out ElevValue); npsSurfaceOp = null; GC.Collect(); if (npsPolyline == null) return null; DidMaxLengthFit = false; //try to cut the contour into the max length specified npsClippedPolyline = Util.ClipContour(npsPoint, npsPolyline, (MaxLineLength / 2), (MaxLineLength / 2)); IsInBndPoly = false; IsInExcludedAreas = false; if (npsClippedPolyline != null) { //check if contour is within boundary IsInBndPoly = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelWithin, BndPolyFC, "SurveyID=" + SurveyID); //check if contour falls in excluded areas IsInExcludedAreas = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelCrosses, ExclPolyFC, "SurveyID=" + SurveyID); } //if contour obtained falls in excluded areas, abandon poyline if (IsInBndPoly == false || IsInExcludedAreas == true) npsClippedPolyline = null; //remember if max length fit if (npsClippedPolyline != null) DidMaxLengthFit = true; //if the max length did not fit, try the min length if (npsClippedPolyline == null) npsClippedPolyline = Util.ClipContour(npsPoint, npsPolyline, (MinLineLength / 2), (MinLineLength / 2)); //check if the shortest length can fit if (npsClippedPolyline != null) { //check if contour is within boundary IsInBndPoly = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelWithin, BndPolyFC, "SurveyID=" + SurveyID); //check if contour falls in excluded areas IsInExcludedAreas = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelCrosses, ExclPolyFC, "SurveyID=" + SurveyID); } //if the min failed then clear it if (IsInBndPoly == false || IsInExcludedAreas == true) npsClippedPolyline = null; //if the max length failed but the min length fit, then try various lengths if (npsClippedPolyline != null && DidMaxLengthFit == false) { CurTransLength = (MinLineLength / 2) + LengthTryIncrements; while (npsClippedPolyline != null) { PrevTryPolyline = npsClippedPolyline; npsClippedPolyline = Util.ClipContour(npsPoint, npsPolyline, CurTransLength, CurTransLength); IsInBndPoly = false; IsInExcludedAreas = false; if (npsClippedPolyline != null) { //check if contour is within boundary IsInBndPoly = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelWithin, BndPolyFC, "SurveyID=" + SurveyID); //check if contour falls in excluded areas IsInExcludedAreas = Util.HasRelationshipWithFC(npsClippedPolyline as IGeometry, esriSpatialRelEnum.esriSpatialRelCrosses, ExclPolyFC, "SurveyID=" + SurveyID); } //if contour obtained falls in excluded areas, abandon poyline if (IsInBndPoly == false || IsInExcludedAreas == true) npsClippedPolyline = null; CurTransLength = CurTransLength + LengthTryIncrements; } //set the last successful as the clipped polyline npsClippedPolyline = PrevTryPolyline; } return npsClippedPolyline; }
public void LoadTempImportFC(int SurveyID, int BatchID, int NextTransectID, IFeatureCursor ImportFCursor, IFeatureClass TempImportFC, IGeoDataset ThisDEM, double TargetLength, ref List<int> NewOIDs, ref int TotalInExcluded, ref int TotalOutsideBndy, ref int TotalPassed,string ThisDEMUnits, ref string ErrorMessage) { IFeature ImportFeature; IFeatureCursor ImportToCursor = null; IFeatureBuffer ImportToBuffer = null; esriGeometryType FType; bool IsInExcludedAreas, IsInBndPoly; ESRI.ArcGIS.GeoAnalyst.ISurfaceOp2 npsSurfaceOp = null; int ThisFieldIndex; IPoint TempPoint; IPolyline NewTrnPolyline; double Elev; IPolyline CPolyline; IPoint centerPoint; IFeatureClass ExclPolyFC, BndPolyFC; ThisDEMUnits = ThisDEMUnits.ToLower(); NewOIDs = new List<int>(); TotalInExcluded = 0; TotalOutsideBndy = 0; TotalPassed = 0; ExclPolyFC = Util.GetFeatureClass(m_NPS.LYR_EXCLUDED_AREAS, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) return; BndPolyFC = Util.GetFeatureClass(m_NPS.LYR_SURVEY_BOUNDARY, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) return; FType = TempImportFC.ShapeType; //get insert cursor in the nps feature class we are going to insert into ImportToCursor = TempImportFC.Insert(true); ImportToBuffer = TempImportFC.CreateFeatureBuffer(); if (FType == esriGeometryType.esriGeometryPolyline) npsSurfaceOp = new ESRI.ArcGIS.GeoAnalyst.RasterSurfaceOpClass(); //loop through each import feature and import it to it's appropriate featureclass while ((ImportFeature = ImportFCursor.NextFeature()) != null) { //make sure the shape is valid if (ImportFeature.ShapeCopy == null) { TotalOutsideBndy++; continue; } if (FType == esriGeometryType.esriGeometryPoint) { //check if rand point falls in excluded areas IsInExcludedAreas = Util.HasRelationshipWithFC(ImportFeature.ShapeCopy, esriSpatialRelEnum.esriSpatialRelWithin, ExclPolyFC, "SurveyID=" + SurveyID); //if point is in excluded areas, don't add if (IsInExcludedAreas) { TotalInExcluded++; continue; } //check if rand point is within boundary IsInBndPoly = Util.HasRelationshipWithFC(ImportFeature.ShapeCopy, esriSpatialRelEnum.esriSpatialRelWithin, BndPolyFC, "SurveyID=" + SurveyID); //if random point is not in boundary, dont add it if (IsInBndPoly == false) { TotalOutsideBndy++; continue; } } if (FType == esriGeometryType.esriGeometryPolyline) { //check if new line falls in excluded areas IsInExcludedAreas = Util.HasRelationshipWithFC(ImportFeature.ShapeCopy, esriSpatialRelEnum.esriSpatialRelCrosses, ExclPolyFC, "SurveyID=" + SurveyID); //if point is in excluded areas, don't add if (IsInExcludedAreas) { TotalInExcluded++; continue; } //check if new line is within in boundary IsInBndPoly = Util.HasRelationshipWithFC(ImportFeature.ShapeCopy, esriSpatialRelEnum.esriSpatialRelWithin, BndPolyFC, "SurveyID=" + SurveyID); //if random point is not in boundary, dont add it if (IsInBndPoly == false) { TotalOutsideBndy++; continue; } } TotalPassed++; //add feature to temp feature class ImportToBuffer.Shape = ImportFeature.ShapeCopy; ImportToBuffer.set_Value(ImportToBuffer.Fields.FindField("SurveyID"), SurveyID); ImportToBuffer.set_Value(ImportToBuffer.Fields.FindField("BATCH_ID"), BatchID); if (FType == esriGeometryType.esriGeometryPolyline) { ThisFieldIndex = ImportToBuffer.Fields.FindField("Flown"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ImportToBuffer.Fields.FindField("Flown"), "N"); ThisFieldIndex = ImportToBuffer.Fields.FindField("TransectID"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ImportToBuffer.Fields.FindField("TransectID"), NextTransectID); NextTransectID++; NewTrnPolyline = ImportToBuffer.Shape as IPolyline; ThisFieldIndex = ImportToBuffer.Fields.FindField("LENGTH_MTR"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, NewTrnPolyline.Length); //add the name of the default projection ThisFieldIndex = ImportToBuffer.Fields.FindField("PROJECTION"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, NewTrnPolyline.SpatialReference.Name); ThisFieldIndex = ImportToBuffer.Fields.FindField("TARGETLEN"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TargetLength); //clone from point TempPoint = ((ESRI.ArcGIS.esriSystem.IClone)NewTrnPolyline.FromPoint).Clone() as IPoint; //add from point projected coords ThisFieldIndex = ImportToBuffer.Fields.FindField("PROJTD_X1"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.X); ThisFieldIndex = ImportToBuffer.Fields.FindField("PROJTD_Y1"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.Y); //add from point geo coords ((IGeometry2)TempPoint).ProjectEx(Util.GetWGSSpatRef(), esriTransformDirection.esriTransformForward, null, false, 0, 0); ThisFieldIndex = ImportToBuffer.Fields.FindField("DD_LONG1"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.X); ThisFieldIndex = ImportToBuffer.Fields.FindField("DD_LAT1"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.Y); //clone to point TempPoint = ((ESRI.ArcGIS.esriSystem.IClone)NewTrnPolyline.ToPoint).Clone() as IPoint; //add to point projected coords ThisFieldIndex = ImportToBuffer.Fields.FindField("PROJTD_X2"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.X); ThisFieldIndex = ImportToBuffer.Fields.FindField("PROJTD_Y2"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.Y); //add to point geo coords ((IGeometry2)TempPoint).ProjectEx(Util.GetWGSSpatRef(), esriTransformDirection.esriTransformForward, null, false, 0, 0); ThisFieldIndex = ImportToBuffer.Fields.FindField("DD_LONG2"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.X); ThisFieldIndex = ImportToBuffer.Fields.FindField("DD_LAT2"); if (ThisFieldIndex > -1) ImportToBuffer.set_Value(ThisFieldIndex, TempPoint.Y); //get center point centerPoint = new PointClass(); ((ICurve)NewTrnPolyline).QueryPoint(esriSegmentExtension.esriNoExtension, 0.5, true, centerPoint); //get elevation for transect center CPolyline = new PolylineClass(); npsSurfaceOp.ContourAsPolyline(ThisDEM, centerPoint, out CPolyline, out Elev); //set elevation in meters ThisFieldIndex = ImportToBuffer.Fields.FindField("ELEV_M"); if (ThisFieldIndex > -1) { if (ThisDEMUnits == "feet") ImportToBuffer.set_Value(ThisFieldIndex, 0.3048 * Elev); if (ThisDEMUnits == "meters") ImportToBuffer.set_Value(ThisFieldIndex, Elev); } //get elevation in feet ThisFieldIndex = ImportToBuffer.Fields.FindField("ELEVFT"); if (ThisFieldIndex > -1) { if (ThisDEMUnits == "feet") ImportToBuffer.set_Value(ThisFieldIndex, Elev); if (ThisDEMUnits == "meters") ImportToBuffer.set_Value(ThisFieldIndex, Elev * 3.2808399); } } NewOIDs.Add((int)Util.SafeConvert(ImportToCursor.InsertFeature(ImportToBuffer), typeof(int))); } ImportFCursor = null; ImportToCursor = null; ImportToBuffer = null; }
/// <summary> /// generate flatarea poylgons for the specified survey using the specified raster /// </summary> public static void GenerateFlatAreaPolygons(int SurveyID, double MinSlope, double MaxSlope, IGeoDataset ClippedRasterDS, ref string ErrorMessage) { ESRI.ArcGIS.Geoprocessing.IGeoProcessorResult GeoResult = null; ESRI.ArcGIS.Geoprocessing.IGeoProcessor ThisGeoProcessor = null; ESRI.ArcGIS.GeoAnalyst.IRasterDescriptor ThisRasterDescriptor; ESRI.ArcGIS.GeoAnalyst.IConversionOp ThisConversionOp; IGeoDataset FloatRasterDS = null, IntRasterDS = null; ESRI.ArcGIS.esriSystem.IVariantArray GPParams; ESRI.ArcGIS.GeoAnalyst.ISurfaceOp ThisSurfaceOp; ESRI.ArcGIS.SpatialAnalyst.IMathOp ThisMathOp; IFeatureClass TempFlatAreasPolyFC = null, TempAggregateFC = null, TempAggregateClipFC = null, BoundaryFC = null, FlatAreasFC = null; IQueryFilter ThisQueryFilter; IFeatureCursor FlatAreasCursor, TempAggregateClipCursor; IFeatureBuffer FlatAreasFBuffer; IFeature TempAggregateClipFeature; string TempFlatAreasPolyFCName, TempAggregateFCName, InternalErrors = "", TempClipFCName; object zFactor; NPSGlobal NPS; int SurveyIDIndex; TempClipFCName = "NPS_TEMP_ClippedFC"; TempAggregateFCName = "NPS_TEMP_FlatAreasAggrFC"; TempFlatAreasPolyFCName = "NPS_TEMP_FlatAreasFC"; NPS = NPSGlobal.Instance; zFactor = 1; BoundaryFC = Util.GetFeatureClass(NPS.LYR_SURVEY_BOUNDARY, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) return; FlatAreasFC = Util.GetFeatureClass(NPS.LYR_FLAT_AREAS, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) return; SurveyIDIndex = FlatAreasFC.FindField("SurveyID"); if (SurveyIDIndex == -1) { ErrorMessage = "Could not find a SurveyID field on the " + ((IDataset)FlatAreasFC).Name + " FeatureClass."; return; } Util.SetProgressMessage("Deleting old temp files"); Util.DeleteDataset(TempFlatAreasPolyFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempAggregateFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempClipFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempAggregateFCName + "_Tbl", esriDatasetType.esriDTTable, ref InternalErrors); Util.DeleteDataset(TempClipFCName + "_Tbl", esriDatasetType.esriDTTable, ref InternalErrors); ThisSurfaceOp = new ESRI.ArcGIS.GeoAnalyst.RasterSurfaceOpClass(); try { Util.SetProgressMessage("Computing slope values from DEM"); FloatRasterDS = ThisSurfaceOp.Slope(ClippedRasterDS, ESRI.ArcGIS.GeoAnalyst.esriGeoAnalysisSlopeEnum.esriGeoAnalysisSlopeDegrees, ref zFactor); } catch (Exception ex) { ErrorMessage = "Error occured while converting DEM evelation values to float slope values. " + ex.Message; return; } try { Util.SetProgressMessage("Converting DEM values to integers"); ThisMathOp = new ESRI.ArcGIS.SpatialAnalyst.RasterMathOpsClass(); IntRasterDS = ThisMathOp.Int(FloatRasterDS); } catch (Exception ex) { ErrorMessage = "Error occured while converting DEM float slope values to slope integer values. " + ex.Message; return; } try { Util.SetProgressMessage("Building flat area polygons from DEM"); ThisQueryFilter = new QueryFilterClass(); ThisQueryFilter.WhereClause = " Value >= " + MinSlope + " AND Value <= " + MaxSlope; ThisRasterDescriptor = new ESRI.ArcGIS.GeoAnalyst.RasterDescriptorClass(); ThisRasterDescriptor.Create(IntRasterDS as IRaster, ThisQueryFilter, "Value"); ThisConversionOp = new ESRI.ArcGIS.GeoAnalyst.RasterConversionOpClass(); TempFlatAreasPolyFC = ThisConversionOp.RasterDataToPolygonFeatureData(ThisRasterDescriptor as IGeoDataset, NPS.Workspace, TempFlatAreasPolyFCName, true) as IFeatureClass; } catch (Exception ex) { ErrorMessage = "Error occured while generating a FeatureClass of flat " + "areas from the default DEM file. " + ex.Message; return; } try { Util.SetProgressMessage("Aggregating flat area polygons"); ThisGeoProcessor = new ESRI.ArcGIS.Geoprocessing.GeoProcessor(); GPParams = new ESRI.ArcGIS.esriSystem.VarArrayClass(); GPParams.Add(System.IO.Path.Combine(NPS.DatabasePath, TempFlatAreasPolyFCName)); GPParams.Add(System.IO.Path.Combine(NPS.DatabasePath, TempAggregateFCName)); GPParams.Add("1 Meters"); GeoResult = ThisGeoProcessor.Execute("AggregatePolygons_management", GPParams, null); } catch (Exception ex) { ErrorMessage = string.Format("Geoprocessor error:\r\nTask:AggregatePolygons_management\r\n" + "Params:{0},{1},{2}\r\nException:{3}", System.IO.Path.Combine(NPS.DatabasePath, TempFlatAreasPolyFCName), System.IO.Path.Combine(NPS.DatabasePath, TempAggregateFCName), "1 Meters", ex.Message); ThisGeoProcessor = null; return; } ThisGeoProcessor = null; Util.DeleteLayerFromMap(TempAggregateFCName); TempAggregateFC = Util.GetFeatureClass(TempAggregateFCName, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) { ErrorMessage = "Could not find temporary FeatureClass " + TempAggregateFCName + ". " + ErrorMessage; return; } Util.SetProgressMessage("Validating flat area polygons"); TempAggregateClipFC = Util.GP_Clip_analysis(TempClipFCName, TempAggregateFC, BoundaryFC, ref ErrorMessage); if (string.IsNullOrEmpty(ErrorMessage) == false) return; FlatAreasFBuffer = FlatAreasFC.CreateFeatureBuffer(); FlatAreasCursor = FlatAreasFC.Insert(true); ThisQueryFilter = null; ThisQueryFilter = new QueryFilterClass(); ThisQueryFilter.WhereClause = "SHAPE_AREA > 25000"; TempAggregateClipCursor = TempAggregateClipFC.Search(ThisQueryFilter, false); Util.SetProgressMessage("Importing flat area polygons to Survey"); while ((TempAggregateClipFeature = TempAggregateClipCursor.NextFeature()) != null) { if (TempAggregateClipFeature.Shape == null) continue; FlatAreasFBuffer.Shape = TempAggregateClipFeature.ShapeCopy; FlatAreasFBuffer.set_Value(SurveyIDIndex, SurveyID); FlatAreasCursor.InsertFeature(FlatAreasFBuffer); } TempAggregateClipCursor = null; FlatAreasCursor = null; Util.SetProgressMessage("Cleaning up temp files"); Util.DeleteDataset(TempFlatAreasPolyFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempAggregateFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempClipFCName, esriDatasetType.esriDTFeatureClass, ref InternalErrors); Util.DeleteDataset(TempAggregateFCName + "_Tbl", esriDatasetType.esriDTTable, ref InternalErrors); Util.DeleteDataset(TempClipFCName + "_Tbl", esriDatasetType.esriDTTable, ref InternalErrors); Util.CreateFillerPolygon(FlatAreasFC, SurveyID, ref InternalErrors); }