private void btnOK_Click(object sender, EventArgs e) { try { //Record settings SetupOp setupOp = UrbanDelineationExtension.Extension.Setup; setupOp.GeometricNetwork = cbxNetwork.SelectedValue as IGeometricNetwork; IFeatureLayer inletLayer = cbxInlets.SelectedValue as IFeatureLayer; setupOp.InletClass = inletLayer == null ? null : inletLayer.FeatureClass; setupOp.SmoothBoundaries = chkSmooth.Checked; IRasterLayer demLayer = cbxDEM.SelectedValue as IRasterLayer; setupOp.DEM = demLayer == null ? null : demLayer.Raster; setupOp.IncludeUpstreamPipeEnds = chkIncludeUp.Checked; setupOp.ExcludeDisabledNodes = chkExcludeDisabled.Checked; setupOp.ExcludeDownstreamPipeEnds = chkExcludeDown.Checked; IRasterLayer flowDirLayer = cbxFlowDirGrid.SelectedValue as IRasterLayer; setupOp.FlowDirection = flowDirLayer == null ? null : flowDirLayer.Raster; IFeatureLayer catchmentLayer = cbxCatchments.SelectedValue as IFeatureLayer; setupOp.Catchments = catchmentLayer == null ? null : catchmentLayer.FeatureClass; this.Close(); } catch (Exception ex) { MessageBox.Show(this, ex.Message, Properties.Resources.Caption_Error); } }
protected override void OnShutdown() { if (_setupOp != null) { _setupOp.Dispose(); _setupOp = null; } }
private void SetupForm_Load(object sender, EventArgs e) { if (_document != null) { _SetupDocumentEvents(); } _UpdateComboBoxes(); // Retrieve saved layers List <ILayer> layers = _GetLayers(_document); SetupOp setupOp = UrbanDelineationExtension.Extension.Setup; if (setupOp.GeometricNetwork != null) { cbxNetwork.SelectedValue = setupOp.GeometricNetwork; } ILayer inletLayer = _FindFeatureLayer(setupOp.InletClass, layers); if (inletLayer != null) { cbxInlets.SelectedValue = inletLayer; } chkSmooth.Checked = setupOp.SmoothBoundaries; ILayer demLayer = _FindRasterLayer(setupOp.DEM, layers); if (demLayer != null) { cbxDEM.SelectedValue = demLayer; } chkIncludeUp.Checked = setupOp.IncludeUpstreamPipeEnds; chkExcludeDisabled.Checked = setupOp.ExcludeDisabledNodes; chkExcludeDown.Checked = setupOp.ExcludeDownstreamPipeEnds; ILayer flowDirLayer = _FindRasterLayer(setupOp.FlowDirection, layers); if (flowDirLayer != null) { cbxFlowDirGrid.SelectedValue = flowDirLayer; } ILayer catchmentLayer = _FindFeatureLayer(setupOp.Catchments, layers); if (catchmentLayer != null) { cbxCatchments.SelectedValue = catchmentLayer; } _UpdateButtons(); }
internal IFeatureClass RasterToPolygon(IRaster inputRaster, string outputName, string outputDir, bool smoothShapes) { IWorkspace workspace = SetupOp.OpenShapeFileWorkspace(outputDir); IConversionOp conversionOp = new RasterConversionOpClass(); try { IFeatureWorkspace featureWorkspace = workspace as IFeatureWorkspace; //Delete any existing IEnumDatasetName datasets = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass); datasets.Reset(); IDataset existing = null; IDatasetName datasetName = datasets.Next(); while (datasetName != null) { if (string.Compare(outputName, datasetName.Name, true) == 0) { existing = (IDataset)((IName)datasetName).Open(); break; } datasetName = datasets.Next(); } if (existing != null) { try { existing.Delete(); } finally { UrbanDelineationExtension.ReleaseComObject(existing); } } //Convert to polygon feature SetAnalysisEnvironment((IRasterAnalysisEnvironment)conversionOp); IGeoDataset polygons = conversionOp.RasterDataToPolygonFeatureData((IGeoDataset)inputRaster, workspace, outputName, smoothShapes); return((IFeatureClass)polygons); } finally { UrbanDelineationExtension.ReleaseComObject(workspace); UrbanDelineationExtension.ReleaseComObject(conversionOp); } }
private void _PunchDEM() { OnProgress("Punching DEM with drainage points..."); IConversionOp conversionOp = new RasterConversionOpClass(); ILogicalOp logicalOp = new RasterMathOpsClass(); IGeoDataset inletLocations = null; IWorkspace tempWorkspace = null; try { tempWorkspace = GetTempRasterWorkspace(); SetAnalysisEnvironment((IRasterAnalysisEnvironment)conversionOp); SetAnalysisEnvironment((IRasterAnalysisEnvironment)logicalOp); IFeatureClassDescriptor sourceDescriptor = new FeatureClassDescriptorClass(); sourceDescriptor.Create(_drainClass, null, _drainClass.OIDFieldName); string gridPath = SetupOp.CreateTempFileName(_GetTempDir(), "TmpInlets", null); string gridName = System.IO.Path.GetFileName(gridPath); IRasterDataset pRasterDataset = null; try { pRasterDataset = conversionOp.ToRasterDataset((IGeoDataset)sourceDescriptor, "GRID", tempWorkspace, gridName); inletLocations = logicalOp.BooleanNot(logicalOp.IsNull((IGeoDataset)pRasterDataset)); string outputPath = CreateTempFileName(_GetResultDir(), "punchdem", ""); _punchedDEM = GeoprocessingTools.SetNull((IRaster)inletLocations, _dem, outputPath); } finally { _MarkForDisposal((IDataset)pRasterDataset); } } finally { UrbanDelineationExtension.ReleaseComObject(tempWorkspace); UrbanDelineationExtension.ReleaseComObject(conversionOp); UrbanDelineationExtension.ReleaseComObject(logicalOp); } OnProgress("DEM punched."); }
private IRaster _DrainagePointsToSeedGrid(IFeatureClass featureClass, string baseName, string valueField) { Geoprocessor gp = new Geoprocessor(); bool addOutputs = gp.AddOutputsToMap; try { IRasterDataset demRasterDataset = ((IRasterAnalysisProps)DEM).RasterDataset; IDataset demDataset = (IDataset)demRasterDataset; string path = System.IO.Path.Combine(demDataset.Workspace.PathName, demDataset.Name); gp.SetEnvironmentValue("snapRaster", path); string extent = string.Format("{0} {1} {2} {3}", ((IGeoDataset2)demRasterDataset).Extent.XMin, ((IGeoDataset2)demRasterDataset).Extent.YMin, ((IGeoDataset2)demRasterDataset).Extent.XMax, ((IGeoDataset2)demRasterDataset).Extent.YMax); gp.SetEnvironmentValue("extent", extent); gp.AddOutputsToMap = false; FeatureToRaster featureToRasterTool = new FeatureToRaster(); featureToRasterTool.cell_size = ((IRasterAnalysisProps)DEM).PixelHeight; featureToRasterTool.field = valueField; IDataset dataset = (IDataset)featureClass; string featureClassPath = System.IO.Path.Combine(dataset.Workspace.PathName, dataset.Name + ".shp"); featureToRasterTool.in_features = featureClassPath; string outputName = SetupOp.CreateTempFileName(this.ScratchDirectory, baseName, null); featureToRasterTool.out_raster = outputName; string outputShortName = System.IO.Path.GetFileNameWithoutExtension(outputName); RunTool(gp, featureToRasterTool, null); IRasterWorkspace rws = this.GetTempRasterWorkspace() as IRasterWorkspace; return(rws.OpenRasterDataset(outputShortName).CreateDefaultRaster()); } finally { gp.AddOutputsToMap = addOutputs; } }
private void _DelineateInletCatchments() { OnProgress("Delineating inlet catchments..."); //Determine output path string outputDir = _GetResultDir(); string outputPathSmooth = SetupOp.CreateTempFileName(outputDir, "Catchments_smooth", ".shp"); string outputPathDetailed = SetupOp.CreateTempFileName(outputDir, "Catchments_detailed", ".shp"); string outputNameSmooth = System.IO.Path.GetFileNameWithoutExtension(outputPathSmooth); string outputNameDetailed = System.IO.Path.GetFileNameWithoutExtension(outputPathDetailed); //Calculate catchments IHydrologyOp hydroOp = new RasterHydrologyOpClass(); IGeoDataset seedGrid = null; IGeoDataset catchmentGrid = null; try { SetAnalysisEnvironment((IRasterAnalysisEnvironment)hydroOp); seedGrid = (IGeoDataset)_DrainagePointsToSeedGrid(_drainClass, "SeedPts", SetupOp.EID_FIELD_NAME); catchmentGrid = hydroOp.Watershed((IGeoDataset)_flowDir, seedGrid); OnProgress("Converting catchments to polygon..."); IFeatureClass smoothCatchmentClass = RasterToPolygon(catchmentGrid, outputNameSmooth, outputDir, true); IFeatureClass detailedCatchmentClass = RasterToPolygon(catchmentGrid, outputNameDetailed, outputDir, false); if (_smooth) { _catchmentClass = smoothCatchmentClass; } else { _catchmentClass = detailedCatchmentClass; } _MarkForDisposal((IDataset)seedGrid); _MarkForDisposal(catchmentGrid as IDataset); } finally { UrbanDelineationExtension.ReleaseComObject(hydroOp); } OnProgress("Inlet catchments delineated."); }
private IEnvelope _GetSurfaceOutputExtent(IPoint mapPoint) { IEnvelope extent = null; SetupOp setupOp = UrbanDelineationExtension.Extension.Setup; if (setupOp.Catchments != null) { // Find all inlet catchments that intersect any source feature and union envelopes IFeatureCursor catchCursor = setupOp.Catchments.Search(null, false); try { IFeature catchment = catchCursor.NextFeature(); while (catchment != null) { try { IRelationalOperator relationOp = (IRelationalOperator)catchment.Shape; if (!relationOp.Disjoint(mapPoint)) { extent = new EnvelopeClass(); catchment.Extent.QueryEnvelope(extent); break; } } finally { UrbanDelineationExtension.ReleaseComObject(catchment); } catchment = catchCursor.NextFeature(); } } finally { UrbanDelineationExtension.ReleaseComObject(catchCursor); } } return(extent); }
private void _DelineateInletCatchments() { OnProgress("Delineating inlet catchments..."); //Determine output path string outputDir = _GetResultDir(); string outputPathSmooth = SetupOp.CreateTempFileName(outputDir, "Catchments_smooth", ".shp"); string outputPathDetailed = SetupOp.CreateTempFileName(outputDir, "Catchments_detailed", ".shp"); string outputNameSmooth = System.IO.Path.GetFileNameWithoutExtension(outputPathSmooth); string outputNameDetailed = System.IO.Path.GetFileNameWithoutExtension(outputPathDetailed); //Calculate catchments IRaster seedGrid = _DrainagePointsToSeedGrid(_drainClass, "SeedPts", SetupOp.EID_FIELD_NAME); string watershedPath = CreateTempFileName(_GetTempDir(), "inletws", ""); IRaster catchmentGrid = GeoprocessingTools.Watershed(_flowDir, seedGrid, watershedPath); OnProgress("Converting catchments to polygon..."); IFeatureClass smoothCatchmentClass = RasterToPolygon(catchmentGrid, outputNameSmooth, outputDir, true); IFeatureClass detailedCatchmentClass = RasterToPolygon(catchmentGrid, outputNameDetailed, outputDir, false); if (_smooth) { _catchmentClass = smoothCatchmentClass; } else { _catchmentClass = detailedCatchmentClass; } var seedDataset = ((IRasterAnalysisProps)seedGrid).RasterDataset; _MarkForDisposal((IDataset)seedDataset); var catchmentDataset = ((IRasterAnalysisProps)catchmentGrid).RasterDataset; _MarkForDisposal(catchmentGrid as IDataset); OnProgress("Inlet catchments delineated."); }
//TODO: Implement load and save protected override void OnLoad(Stream inStrm) { SetupOp setupOp = null; try { // NOTE: Do not close or dispose BinaryReader, as this will close the Stream BinaryReader reader = new BinaryReader(inStrm); int version = reader.ReadInt32(); // NOTE: With change to Add-In architecture, this extension is NOT backwards compatible with versions 1 and 2 if (version == 3) { //// Version 3: //// Item 1: FeatureClassName: The orphan junction feature class of the Geometric Network for the underground conveyance system. //// Item 2: FeatureClassName: The inlet feature class //// Item 3: RasterDatasetName: The DEM dataset //// Item 4: Boolean: Whether to smooth boundaries //// Item 5: Boolean: Whether to include upstream pipe ends //// Item 6: Boolean: Whether to exclude downstream pipe ends //// Item 7: RasterDatasetName: The flow direction dataset //// Item 8: FeatureClassName: The catchment feature class //// Item 9: Boolean: Whether to exclude disabled nodes setupOp = new SetupOp(); setupOp.ResultsDirectory = this.MxDocDirectoryName; setupOp.ScratchDirectory = this.TemporaryDirectory; FeatureClassName networkJunctionName = null; PersistenceHelper.Load <FeatureClassName>(inStrm, ref networkJunctionName); INetworkClass junctionClass = _SafeOpen(networkJunctionName) as INetworkClass; if (junctionClass != null) { setupOp.GeometricNetwork = junctionClass.GeometricNetwork; } FeatureClassName inletClassName = null; PersistenceHelper.Load <FeatureClassName>(inStrm, ref inletClassName); setupOp.InletClass = _SafeOpen(inletClassName) as IFeatureClass; RasterDatasetName demName = null; PersistenceHelper.Load <RasterDatasetName>(inStrm, ref demName); IRasterDataset demDataset = _SafeOpen(demName) as IRasterDataset; if (demDataset != null) { setupOp.DEM = demDataset.CreateDefaultRaster(); } setupOp.SmoothBoundaries = reader.ReadBoolean(); setupOp.IncludeUpstreamPipeEnds = reader.ReadBoolean(); setupOp.ExcludeDownstreamPipeEnds = reader.ReadBoolean(); RasterDatasetName flowDirName = null; PersistenceHelper.Load <RasterDatasetName>(inStrm, ref flowDirName); IRasterDataset flowDirDataset = _SafeOpen(flowDirName) as IRasterDataset; if (flowDirDataset != null) { setupOp.FlowDirection = flowDirDataset.CreateDefaultRaster(); } FeatureClassName catchmentClassName = null; PersistenceHelper.Load <FeatureClassName>(inStrm, ref catchmentClassName); setupOp.Catchments = _SafeOpen(catchmentClassName) as IFeatureClass; setupOp.ExcludeDisabledNodes = reader.ReadBoolean(); } _setupOp = setupOp; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.GetType().FullName + ": " + ex.Message); } }
private void _ClearProject() { // A null setup object indicates this document has not been used for catchment delineation _setupOp = null; }
protected override void OnMouseUp(MouseEventArgs arg) { base.OnMouseUp(arg); IMxDocument document = null; try { // Get user point document = ArcMap.Document; IPoint mapPoint = ArcMap.ThisApplication.Display.DisplayTransformation.ToMapPoint(arg.X, arg.Y); // Get flow direction SetupOp setupOp = UrbanDelineationExtension.Extension.Setup; IRaster flowDir = setupOp.FlowDirection; if (flowDir == null) { MessageBox.Show(_appWindow, Properties.Resources.Error_NoFlowDirection, Properties.Resources.Category_UrbanDelineation); return; } IGeoDataset flowDirDataset = (IGeoDataset)flowDir; // Process point IPointCollection pointCollection = new MultipointClass(); ((IGeometry)pointCollection).SpatialReference = flowDirDataset.SpatialReference; mapPoint.Project(flowDirDataset.SpatialReference); IPoint[] points = new IPoint[] { mapPoint }; pointCollection.AddPoints(1, ref points[0]); // Get flow path geometry IPolyline flowPath = null; string outputDir = null; IDistanceOp distanceOp = new RasterDistanceOpClass(); try { IEnvelope outputExtent = _GetSurfaceOutputExtent(mapPoint); if (outputExtent == null) { setupOp.SetAnalysisEnvironment((IRasterAnalysisEnvironment)distanceOp); } else { // Expand to ensure full boundary of watershed is included. double cellWidth = ((IRasterAnalysisProps)setupOp.FlowDirection).PixelWidth; double cellHeight = ((IRasterAnalysisProps)setupOp.FlowDirection).PixelHeight; outputExtent.Expand(cellWidth * 3.0, cellHeight * 3.0, false); setupOp.SetAnalysisEnvironment((IRasterAnalysisEnvironment)distanceOp, outputExtent); } // The RasterDistanceOpClass does not properly clean up after itself, so we have to do it ourselves // To do this, we need to track the output directory and delete it, since we don't have direct access to the // dataset that is left behind. To delete the directory, it must contain only the temp files generated by // the RasterDistanceOpClass and no others, so we create one here. The directory is then deleted in the // finally clause. ((IRasterAnalysisEnvironment)distanceOp).OutWorkspace = _GetUniqueOutputWorkspace(); outputDir = ((IRasterAnalysisEnvironment)distanceOp).OutWorkspace.PathName; IGeometryCollection flowPaths = distanceOp.CostPathAsPolyline(pointCollection, flowDirDataset, flowDirDataset); if (flowPaths.GeometryCount > 0) { flowPath = flowPaths.get_Geometry(0) as IPolyline; } } finally { UrbanDelineationExtension.ReleaseComObject(distanceOp); try { if (Directory.Exists(outputDir)) { Directory.Delete(outputDir, true); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("FlowTracingTool.OnMouseUp: " + ex.GetType().FullName + ": " + ex.Message); } } // Add flow path to map if (flowPath != null && !flowPath.IsEmpty) { // Create graphic element flowPath.SpatialReference = flowDirDataset.SpatialReference; // Weed removes points that are in-line since flow path is generated with vertices for every cell, even if they are exactly in-line ((IPolycurve)flowPath).Weed(0.001); IElement flowElement = new LineElementClass(); ((IElementProperties3)flowElement).Name = ELEMENT_NAME; flowElement.Geometry = flowPath; // Set color ILineSymbol lineSymbol = ((ILineElement)flowElement).Symbol; IRgbColor color = lineSymbol.Color as IRgbColor; Color systemColor = Color.Red; color.Blue = systemColor.B; color.Red = systemColor.R; color.Green = systemColor.G; lineSymbol.Color = color; ((ILineElement)flowElement).Symbol = lineSymbol; ((IGraphicsContainer)document.FocusMap.BasicGraphicsLayer).AddElement(flowElement, 0); ((IDocumentDirty)document).SetDirty(); document.ActiveView.Refresh(); } } catch (Exception ex) { MessageBox.Show(_appWindow, ex.Message, Properties.Resources.Caption_Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { UrbanDelineationExtension.ReleaseComObject(document); } }
private void btnPreprocess_Click(object sender, EventArgs e) { try { System.Windows.Forms.Application.DoEvents(); System.Windows.Forms.Cursor.Current = Cursors.WaitCursor; DialogResult choice = MessageBox.Show(this, "Depending on the size of the network and DEM, this operation may take a long time.", Properties.Resources.Caption_Notice, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1); if (choice == DialogResult.OK) { SetupOp setupOp = UrbanDelineationExtension.Extension.Setup; setupOp.GeometricNetwork = cbxNetwork.SelectedValue as IGeometricNetwork; IFeatureLayer inletLayer = cbxInlets.SelectedValue as IFeatureLayer; setupOp.InletClass = inletLayer.FeatureClass; IRasterLayer demLayer = cbxDEM.SelectedValue as IRasterLayer; setupOp.DEM = demLayer.Raster; setupOp.IncludeUpstreamPipeEnds = chkIncludeUp.Checked; setupOp.ExcludeDisabledNodes = chkExcludeDisabled.Checked; setupOp.ExcludeDownstreamPipeEnds = chkExcludeDown.Checked; setupOp.SmoothBoundaries = chkSmooth.Checked; setupOp.Preprocess(); //Add results to map EnumLayer layers = new EnumLayer(); IFeatureLayer drainLayer = new FeatureLayerClass(); drainLayer.FeatureClass = setupOp.DrainagePoints; drainLayer.Name = "Drainage Points"; drainLayer.Visible = false; layers.Add(drainLayer); IRasterLayer punchedLayer = new RasterLayerClass(); punchedLayer.CreateFromRaster(setupOp.PunchedDEM); punchedLayer.Name = "Punched DEM"; punchedLayer.Visible = false; layers.Add(punchedLayer); IRasterLayer fillLayer = new RasterLayerClass(); fillLayer.CreateFromRaster(setupOp.FilledDEM); fillLayer.Name = "Filled DEM"; fillLayer.Visible = false; layers.Add(fillLayer); IRasterLayer flowDirLayer = new RasterLayerClass(); flowDirLayer.CreateFromRaster(setupOp.FlowDirection); flowDirLayer.Name = "Flow Direction"; flowDirLayer.Visible = false; layers.Add(flowDirLayer); IFeatureLayer catchmentLayer = new FeatureLayerClass(); catchmentLayer.FeatureClass = setupOp.Catchments; catchmentLayer.Name = "Inlet Catchments"; catchmentLayer.Visible = false; ((ILayerEffects)catchmentLayer).Transparency = 50; layers.Add(catchmentLayer); IMap map = null; try { map = ArcMap.Document.FocusMap; map.AddLayers(layers, true); cbxFlowDirGrid.SelectedValue = flowDirLayer; cbxCatchments.SelectedValue = catchmentLayer; } finally { UrbanDelineationExtension.ReleaseComObject(map); } } } catch (Exception ex) { MessageBox.Show(this, ex.Message, Properties.Resources.Caption_Error); } finally { System.Windows.Forms.Cursor.Current = Cursors.Default; } }
private bool _CheckInput() { SetupOp pSetupOp = UrbanDelineationExtension.Extension.Setup; if (pSetupOp.GeometricNetwork == null) { MessageBox.Show(this, "The drainaige network has not been specified. Please check the setup and try again.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } if (pSetupOp.InletClass == null) { MessageBox.Show(this, "The inlet node layer has not been specified. Please check the setup and try again.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } if (cbxOutletSource.SelectedValue == null || chkExtendOverland.Checked) { if (pSetupOp.Catchments == null) { MessageBox.Show(this, "The preprocessed inlet catchments have not been calculated. Please check the setup and try again.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } } if (chkSnapToPourPoint.Enabled && chkSnapToPourPoint.Checked) { double snapDistance; if (!double.TryParse(tbxSnapDistance.Text, out snapDistance)) { MessageBox.Show(this, "The snap distance has not been specified, or is not a valid number. Please check the snap distance.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } else { if (snapDistance <= 0) { MessageBox.Show(this, "The snap distance is less than or equal to zero. Please enter a value greater than zero.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } } } IFeatureLayer sourceLayer = cbxOutletSource.SelectedValue as IFeatureLayer; if (sourceLayer != null) { if (pSetupOp.FlowDirection == null) { MessageBox.Show(this, "The flow direction layer has not been specified. Please check the setup and try again.", Properties.Resources.Caption_InvalidEntry, MessageBoxButtons.OK, MessageBoxIcon.Warning); return(false); } if (((IFeatureSelection)sourceLayer).SelectionSet.Count == 0) { DialogResult userResponse = MessageBox.Show(this, "There are no features selected in the chosen source feature layer. Are you sure you want to delineate from all features in the feature layer?", "No Selection", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2); if (userResponse != DialogResult.Yes) { return(false); } } } return(true); }