bhavanisankarnimmala

Sample code for AutoUpdater

Blog Post created by bhavanisankarnimmala on May 14, 2018

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Miner.ComCategories;

using System.Runtime.InteropServices;

using ESRI.ArcGIS.Framework;

using System.Diagnostics;

using SingPowerAutoUpdaters.Utils;

using ESRI.ArcGIS.Geodatabase;

using Miner.Interop;

using System.Text.RegularExpressions;

using SP.GEMS.DataValidation.Utils;

using ESRI.ArcGIS.Geometry;

using ESRI.ArcGIS.ArcMapUI;

using System.Configuration;

namespace SingPowerAutoUpdaters

{

[ComponentCategory(Miner.ComCategories.ComCategory.SpecialAutoUpdateStrategy)]

[Guid("5F226C3B-3DAC-4A5B-9F38-FA03150E92F5"), ProgId("MMSpecialAUStrategy.AutoCalPipeLengthAU")]

public class AutoCalPipeLengthAU : BaseSpecialAUStrategy

{

private const string _autoUpdaterName = "SP: AutoCalPipeLength";

private const string _eventLog = "Miner";

private IApplication _application;

string debugVal = "";

Logger _logger = new Logger();

private List<string> polygonFCList = new List<string>();

public AutoCalPipeLengthAU()

: base(_autoUpdaterName)

{

if (!EventLog.SourceExists(_autoUpdaterName))

EventLog.CreateEventSource(_autoUpdaterName, _eventLog);

_application = GetAppRef();

Configuration dllConfig = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);

AppSettingsSection dllConfigAppSettings = (AppSettingsSection)dllConfig.GetSection("appSettings");

string[] polyList = dllConfigAppSettings.Settings["PolygonFCList"].Value.ToString().Split(',');

polygonFCList.Clear();

for (int i = 0; i < polyList.Length; i++)

{

polygonFCList.Add(polyList[i].ToString());

}

Globals.polygonFCList = polygonFCList;

Globals.lengthField = dllConfigAppSettings.Settings["LengthField"].Value;

string temp = dllConfigAppSettings.Settings["isCenterlineRequired"].Value;

if (temp.ToUpper() == "FALSE")

{

Globals.isCenterlineRequired = false;

}

else

{

Globals.isCenterlineRequired = true;

}

Globals.centerLineFC = dllConfigAppSettings.Settings["CenterLineFC"].Value;

}

internal static AppRef GetAppRef()

{

Type type = Type.GetTypeFromProgID("esriFramework.AppRef");

return Activator.CreateInstance(type) as AppRef;

}

#region Private Methods

private IWorkspace GetWorkspace(IFeature pFeature, out bool isEdited)

{

IWorkspace pWorkSpace = null;

isEdited = false;

try

{

//get the featureclass and workspace from the selected polygon feature

IFeatureClass pFC = pFeature.Class as IFeatureClass;

pWorkSpace = GDBFunctions.GetWorkspaceFromFC(pFC);

//check if there is any active workspace or not

if (pWorkSpace != null)

{

//start edit operation

isEdited = GDBFunctions.StartEditWorkSpace(pWorkSpace);

}

else // popup message if no edit workspace found

System.Windows.Forms.MessageBox.Show("No Edit workspace found. Start editing and proceed.", "Auto Calculate Pipe Length", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);

}

catch { throw; }

return pWorkSpace;

}

#endregion

protected override void InternalExecute(IObject pObject, mmAutoUpdaterMode eAUMode, mmEditEvent eEvent)

{

IWorkspace pWorkSpace = null;

bool isEdited = false;

try

{

IFeature pFeature = pObject as IFeature;

if (pFeature != null)

{

pWorkSpace = GetWorkspace(pFeature, out isEdited);

if (pWorkSpace != null)

{

//check for selected feature is a polygon feature or not

if (pFeature.Shape.GeometryType == esriGeometryType.esriGeometryPolygon)

{

#region Create Event

if (eEvent == mmEditEvent.mmEventFeatureCreate)

{

//Calculate the center line and update the LengthOfPipe attribute value

PipeLength.UpdatePipeLength(pFeature, pWorkSpace, Globals.isCenterlineRequired);

}

#endregion

#region Update Event

if (eEvent == mmEditEvent.mmEventFeatureUpdate)

{

if (AutoupdaterUtilities.ShapeChanged(pObject))

{

//Calculate the center line and update the LengthOfPipe attribute value

PipeLength.UpdatePipeLength(pFeature, pWorkSpace, Globals.isCenterlineRequired);

}

}

#endregion

}

}

}

}

catch (COMException e)

{

EventLog.WriteEntry(_autoUpdaterName, e.Message);

throw e;

}

catch (Exception e)

{

EventLog.WriteEntry(_autoUpdaterName, e.Message);

throw e;

}

finally

{

//stop editing and save edits

GDBFunctions.StopEditWorkSpace(pWorkSpace, isEdited);

//refresh map

(_application.Document as IMxDocument).ActiveView.Refresh();

}

}

protected override bool InternalEnabled(IObjectClass pObjectClass, mmEditEvent eEvent)

{

//if (CommonVariables.PolygonFCList.Contains(((IDataset)pObjectClass).BrowseName.ToUpper().Split('.').LastOrDefault()))

if (Globals.polygonFCList.Contains(((IDataset)pObjectClass).BrowseName.ToUpper().Split('.').LastOrDefault()))

return true;

else

return false;

}

}

}

 

//Methods

/// <summary>

/// public method to calculate the centerline and update the pipe length attribute

/// </summary>

/// <param name="pOrgPolyFeat">Selected polygon feature</param>

/// <param name="isCenterlineRequired">Center line is required to create</param>

public static void UpdatePipeLength(IFeature pOrgPolyFeat, IWorkspace pWorkSpace, bool isCenterlineRequired=false)

{

try

{

//create a custom polygon object for selected feature

CustomPolygon pSourcePoly = new CustomPolygon();

pSourcePoly.Geometry = pOrgPolyFeat.ShapeCopy as IPolygon;

//calculate the centerline for the selected polygon

IPolyline pLine = CalculatePipeLength(pSourcePoly);

#region Comment the Centerline feature creation if not required

if (isCenterlineRequired)

{

//get the centerline featureclass

if (Globals.pCenterLineFC == null)

{

IWorkspace2 pWS = pWorkSpace as IWorkspace2;

if (pWS.NameExists[esriDatasetType.esriDTFeatureClass, Globals.centerLineFC])

{

Globals.pCenterLineFC = (pWorkSpace as IFeatureWorkspace).OpenFeatureClass(Globals.centerLineFC);

}

}

//create a centerline feature using calculated centerline

if (Globals.pCenterLineFC != null && pLine != null)

{

IFeature pLineFeat = GDBFunctions.CreateFeature(Globals.pCenterLineFC, pLine);

//update the attribute value

GDBFunctions.SetFieldValue(pLineFeat, Math.Round(pLine.Length, 6), Globals.lengthField, true);

}

}

#endregion

//update the polygon's LengthofPipe Attribute with the calculated centerline length.

GDBFunctions.SetFieldValue(pOrgPolyFeat, Math.Round(pLine.Length, 6), Globals.lengthField, false);

}

catch (Exception ex)

{

throw ex;

}

}

 

//Another Method is as follows:

private static IPolyline CalculatePipeLength(CustomPolygon pSourcePoly)

{

IPolyline pLine = null;

try

{

//get the minimum boundary rectangle for the input polygon feature

MimimumBoundingRectangle mbr = new MimimumBoundingRectangle(pSourcePoly.Geometry);

CustomPolygon pMBRPoly = mbr.BoundingBox;

//create imaginary middle line along the minor axis

IPolyline pMidIntersectonLine = new PolylineClass();

pMidIntersectonLine.FromPoint = GeometricFunctions.GetMidPoint(pMBRPoly.MajorEdgeList[0].FromPoint, pMBRPoly.MajorEdgeList[0].ToPoint);

pMidIntersectonLine.ToPoint = GeometricFunctions.GetMidPoint(pMBRPoly.MajorEdgeList[1].FromPoint, pMBRPoly.MajorEdgeList[1].ToPoint);

//split the minimum boundary polygon in to 2 poolygons using middle line

List<CustomPolygon> pMBRSpiltPolygons = pMBRPoly.Cut(pMidIntersectonLine);

//split the source selected polygon into 2 polygons by identifing the vertecies with in the splitted MBR polygons

List<CustomPolygon> pSplitPolygons = pSourcePoly.Divide(pMidIntersectonLine, pMBRSpiltPolygons);

#region Code for debuggin purpose only. To visualize the MBR and Splitted polygons correctness

//IFeatureClass pMbrFC = GDBFunctions.GetFeatureClassFromLayerName(m_map, "mbr");

//GDBFunctions.CreateFeature(pMbrFC, pMBRSpiltPolygons[0].Geometry);

//GDBFunctions.CreateFeature(pMbrFC, pMBRSpiltPolygons[1].Geometry);

//IFeatureClass pMbr1FC = GDBFunctions.GetFeatureClassFromLayerName(m_map, "mbr1");

//GDBFunctions.CreateFeature(pMbr1FC, pSplitPolygons[0].Geometry);

//GDBFunctions.CreateFeature(pMbr1FC, pSplitPolygons[1].Geometry);

////IFeatureClass pdummyFC = GDBFunctions.GetFeatureClassFromLayerName(m_map, "DummyPolygon");

#endregion

 

 

List<IPoint> pCenterLineVertexList = new List<IPoint>();

////identify the centerline points for the splitted polygon -- For 1st (Bottom or Left) polygon

List<IPoint> pLineVertexList = GeometricFunctions.GetCenterLinePointList(pSplitPolygons[0]);

//Reverse the point list as they are identified from the MBR Middle intersection / splitted location.

pLineVertexList.Reverse();

//add the point list to centerline points list

pCenterLineVertexList.AddRange(pLineVertexList);

////identify the centerline points for the splitted polygon -- For 2nd (Top or Right) polygon

List<IPoint> pLineVertexList2 = GeometricFunctions.GetCenterLinePointList(pSplitPolygons[1]);

//add the point list to centerline points list

pCenterLineVertexList.AddRange(pLineVertexList2);

//create point collection

IPointCollection pLinePointCol = new PolylineClass();

foreach (IPoint pt in pCenterLineVertexList)

{

pLinePointCol.AddPoint(pt);

}

//create polyline using poincollection

pLine = pLinePointCol as IPolyline;

}

catch { throw; }

return pLine;

}

Outcomes