Esempio n. 1
0
        /// <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;
        }
Esempio n. 3
0
        /// <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);
        }