📄 miscutils.cs
字号:
using System;
using System.Collections;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.MapControl;
using ESRI.ArcGIS.NetworkAnalyst;
//Ismael Chivite
//ESRI Redlands
//March 2005
namespace EvacuationRoutes
{
/// <summary>
/// Summary description for ESRIControlUtils.
/// </summary>
public class MiscUtils
{
public MiscUtils()
{
//
// TODO: Add constructor logic here
//
}
public static double GetFloorHeight(string[] FloorNames,double[] FloorHeights,string sFloorName)
{
for (int n = 0;n<FloorNames.Length;n++)
{
if (FloorNames[n]==sFloorName)
{
return FloorHeights[n];
}
}
return -1;
}
public static void CleanupFC(IFeatureClass pFC)
{
IFeatureCursor pFCursor = pFC.Search(null,false);
IFeature pF = pFCursor.NextFeature();
while (pF!=null)
{
pF.Delete();
pF = pFCursor.NextFeature();
}
}
public static void RemoveNAObjects(INALayer pNALayer,string sNLocationClassName)
{
//This function does not work on the server
try
{
//GetNAContext
INAContext pNAContext = pNALayer.Context;
//Remove all rows
INAClass pNAClass = pNAContext.NAClasses.get_ItemByName(sNLocationClassName)as INAClass;
if (pNAClass == null)
{
throw new Exception(sNLocationClassName + " class does not exist. No objects can be removed");
}
pNAClass.DeleteAllRows();
}
catch (Exception exx)
{
throw new Exception(exx.Message);
}
}
public static void Add3DServiceArea(IFeatureClass pFCSA3D,IFeatureClass pFCNAServiceAreas,string sFloorName,double dHeight)
{
if (pFCNAServiceAreas.FeatureCount(null)==0)return;
int idxFloorName = pFCSA3D.Fields.FindField("Floor");
IFeatureCursor pServiceAreasCursor = pFCNAServiceAreas.Search(null,false);
IFeature pServiceAreaF = pServiceAreasCursor.NextFeature();
while (pServiceAreaF!=null)
{
IGeometry pGeom = pServiceAreaF.ShapeCopy;
((IPolycurve)pGeom).Generalize(1); //1 feet
((IPolycurve)pGeom).Smooth(.5); //0.5 feet
((IZAware)pGeom).ZAware = true;
((IZ)pGeom).SetConstantZ(dHeight);
IFeature pSA3D = pFCSA3D.CreateFeature();
pSA3D.Shape = pGeom; //Todo: Might want to add the FloorID here to filter 3D polygons based on Floor
if (idxFloorName>0)pSA3D.set_Value(idxFloorName,sFloorName);
pSA3D.Store();
pServiceAreaF = pServiceAreasCursor.NextFeature();
}
}
public static void Create3DRoute(IFeatureClass pFCRoute3D,INALayer pNALayer)
{
try
{
MiscUtils.CleanupFC(pFCRoute3D);
//Initialize Traversal Result
INATraversalResultQuery pTraverse = pNALayer.Context.Result as INATraversalResultQuery;
INATraversalResult pNATraversalResult = pTraverse as INATraversalResult;
IFeatureClass pFCEdges = pTraverse.get_FeatureClass(ESRI.ArcGIS.Geodatabase.esriNetworkElementType.esriNETEdge);
int idxEdgeSourceID = pFCEdges.Fields.FindField("SourceID");
int idxEdgeSourceOID = pFCEdges.Fields.FindField("SourceOID");
int idxPathID = pFCEdges.Fields.FindField("PathID");
IFeatureCursor pInsertCursor = pFCRoute3D.Insert(true);
IFeatureBuffer pNewFeature = null;
if(idxPathID>0)
{
int iTotalPaths = GetTotalPathIds(pNALayer);
for (int i = 1; i <= iTotalPaths;i++)
{
pNewFeature = pFCRoute3D.CreateFeatureBuffer();
IFeatureCursor pFCursorEdges = GetEdgesByPathID(pFCEdges,i);
IPolyline pNewShape = BuildPolylineFromEdgesFC(pFCursorEdges,pNATraversalResult,idxEdgeSourceID,idxEdgeSourceOID,idxPathID);
pNewFeature.Shape = pNewShape;
pInsertCursor.InsertFeature(pNewFeature);
//Release
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFCursorEdges);
}
}
else
{
pNewFeature = pFCRoute3D.CreateFeatureBuffer();
IFeatureCursor pFCursorEdges = pFCEdges.Search(null,true);
IPolyline pNewShape = BuildPolylineFromEdgesFC(pFCursorEdges,pNATraversalResult,idxEdgeSourceID,idxEdgeSourceOID,idxPathID);
pNewFeature.Shape = pNewShape;
pInsertCursor.InsertFeature(pNewFeature);
//Release
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFCursorEdges);
}
pInsertCursor.Flush();
}
catch (Exception exx)
{
System.Diagnostics.Debug.WriteLine(exx.Message);
}
}
private static IPolyline BuildPolylineFromEdgesFC(IFeatureCursor pFCursorEdges,INATraversalResult pNATraversalResult,int idxEdgeSourceID,int idxEdgeSourceOID,int idxPathID)
{
IFeature pSourceEdgeF = null;
IFeatureClass pSourceEdgeFC = null;
int iSourceID = 0,iSourceOID = 0;
ISegmentCollection pSegCol = new PolylineClass() as ISegmentCollection;
((IZAware)pSegCol).ZAware = true;
IFeature pEdge = pFCursorEdges.NextFeature();
while (pEdge!=null)
{
//GetSourceFeature
iSourceID = Convert.ToInt32(pEdge.get_Value(idxEdgeSourceID));
iSourceOID = Convert.ToInt32(pEdge.get_Value(idxEdgeSourceOID));
pSourceEdgeFC = pNATraversalResult.get_SourceByID(iSourceID).Table as IFeatureClass;
pSourceEdgeF = pSourceEdgeFC.GetFeature(iSourceOID);
pSegCol.AddSegmentCollection(pSourceEdgeF.Shape as ISegmentCollection);
pEdge = pFCursorEdges.NextFeature();
}
((IPolyline)pSegCol).SimplifyNetwork();
return pSegCol as IPolyline;
}
public static void Create3DRoute(IFeatureClass pFCRoute3D,IFeatureClass pFCEdges,string[] FloorNames,double[] FloorHeights,INetworkDataset pNetworkDS)
{
MiscUtils.CleanupFC(pFCRoute3D);
if (pFCEdges.FeatureCount(null)==0)return;
int idxPathID = pFCEdges.Fields.FindField("PathID");
int idxEdgeSourceID = pFCEdges.Fields.FindField("SourceID");
IFeatureCursor pEdgesCursor = pFCEdges.Search(null,false);
IFeature pFEdge = pEdgesCursor.NextFeature();
IFeature pNew3DFeat = pFCRoute3D.CreateFeature();
IPointCollection pPointCol = new PolylineClass() as IPointCollection;
((IZAware)pPointCol).ZAware = true;
if (idxPathID>0) //Will be greater if output is closest facility
{ //Will build one 3D line per Path (edges come sorted by incicident and then facility)
int iPathId =1;
int iOldPathId= 1;
if (pFEdge!=null) iOldPathId = Convert.ToInt32(pFEdge.get_Value(idxPathID));
while (pFEdge != null)
{
iPathId = Convert.ToInt32(pFEdge.get_Value(idxPathID));
if (iPathId!=iOldPathId)
{
pNew3DFeat.Shape = pPointCol as IGeometry;
pNew3DFeat.Store();
pNew3DFeat = pFCRoute3D.CreateFeature();
pPointCol = new PolylineClass() as IPointCollection;
((IZAware)pPointCol).ZAware = true;
iOldPathId = iPathId;
}
int iSourceID = Convert.ToInt32(pFEdge.get_Value(idxEdgeSourceID));
string sSourceID = pNetworkDS.get_SourceByID(iSourceID).Name;
IPolyline pPolyline = pFEdge.ShapeCopy as IPolyline;
((IZAware)pPolyline).ZAware = true;
double dH = MiscUtils.GetFloorHeight(FloorNames,FloorHeights,sSourceID);
((IZ)pPolyline).SetConstantZ(dH);
pPointCol.AddPointCollection(pPolyline as IPointCollection);
pFEdge = pEdgesCursor.NextFeature();
}
pNew3DFeat.Shape = pPointCol as IGeometry;
pNew3DFeat.Store();
}
else //will build a single 3D polyline by merging all the edges in the traversal result
{
while (pFEdge != null)
{
int iSourceID = Convert.ToInt32(pFEdge.get_Value(idxEdgeSourceID));
string sSourceID = pNetworkDS.get_SourceByID(iSourceID).Name;
IPolyline pPolyline = pFEdge.ShapeCopy as IPolyline;
((IZAware)pPolyline).ZAware = true;
double dH = MiscUtils.GetFloorHeight(FloorNames,FloorHeights,sSourceID);
((IZ)pPolyline).SetConstantZ(dH);
pPointCol.AddPointCollection(pPolyline as IPointCollection);
pFEdge = pEdgesCursor.NextFeature();
}
pNew3DFeat.Shape = pPointCol as IGeometry;
pNew3DFeat.Store();
}
}
public static void Create2DRoutes(IFeatureClass pFCRoute2D,IFeatureClass pFCEdges,string[] FloorNames,double[] FloorHeights,INetworkDataset pNetworkDS)
{
MiscUtils.CleanupFC(pFCRoute2D);
int idxEdgeSourceID = pFCEdges.Fields.FindField("SourceID");
int idxFloorName = pFCRoute2D.Fields.FindField("Floor");
IFeatureCursor pEdgesCursor = pFCEdges.Search(null,false);
IFeature pFEdge = pEdgesCursor.NextFeature();
IPointCollection pPointCol = new PolylineClass() as IPointCollection;
((IZAware)pPointCol).ZAware = true;
while (pFEdge != null)
{
int iSourceID = Convert.ToInt32(pFEdge.get_Value(idxEdgeSourceID));
string sSourceID = pNetworkDS.get_SourceByID(iSourceID).Name;
//Assign elevation to edge
IPolyline pPolyline = pFEdge.ShapeCopy as IPolyline;
// ((IZAware)pPolyline).ZAware = true;
// double dH = MiscUtils.GetFloorHeight(FloorNames,FloorHeights,sSourceID);
// ((IZ)pPolyline).SetConstantZ(dH);
//Create featurebuffer
IFeature pNew3DFeatBuffer = pFCRoute2D.CreateFeature();
pNew3DFeatBuffer.Shape = pPolyline as IGeometry;
pNew3DFeatBuffer.set_Value(idxFloorName,sSourceID);
pNew3DFeatBuffer.Store();
pFEdge = pEdgesCursor.NextFeature();
}
}
public static void SwitchToInMemoryFC(IFeatureLayer pFLToSwitch,INALayer pHostLayer)
{
string sName = ((ILayer)pFLToSwitch).Name;
INAContext pNAContext = pHostLayer.Context;
INAClassDefinitionEdit pNAClassDef = new NAClassDefinitionClass() as INAClassDefinitionEdit;
pNAClassDef.Name = sName;
IFields pFields = ((IClone)pFLToSwitch.FeatureClass.Fields).Clone() as IFields;
pNAClassDef.Fields = pFields;
pNAClassDef.IsInput = true;
INAContextEdit pNAContextEdit = pNAContext as INAContextEdit;
IDataset pInMDS = pNAContextEdit.CreateAnalysisClass(pNAClassDef as INAClassDefinition) as IDataset;
((IDataLayer2)pFLToSwitch).Disconnect();
((IDataLayer2)pFLToSwitch).DataSourceName = pInMDS.FullName;
pNAContext.NAClasses.Add(sName,pInMDS);
}
public static int GetTotalPathIds(INALayer pNALayer)
{
INAContext pNAContext = pNALayer.Context;
IFeatureClass pFC = pNAContext.NAClasses.get_ItemByName("CFRoutes") as IFeatureClass;
return pFC.FeatureCount(null);
}
public static string GetAgentTypeByID(INALayer pCFLayer,int iAgentOID)
{
INAContext pNAContext = pCFLayer.Context;
IFeatureClass pFC = pNAContext.NAClasses.get_ItemByName("Incidents") as IFeatureClass;
if (pFC == null)
{
System.Diagnostics.Debug.WriteLine("GetAgentPathNameByID only works with ClosestFacility Layers");
return "Error. GetAgentPathNameByID only works with ClosestFacility Layers";
}
IFeature pF = pFC.GetFeature(iAgentOID);
if (pF == null)
{
return "Error. Feature not found";
}
else
{
return Convert.ToString(pF.get_Value(pF.Fields.FindField("AgentType")) );
}
}
public static long GetTargetFacilityByID(INALayer pCFLayer,int iAgentOID)
{
INAContext pNAContext = pCFLayer.Context;
// for(int iii = 0;iii<pNAContext.NAClasses.Count;iii++)
// {
// string s = ((IFeatureClass)pNAContext.NAClasses.get_Item(iii)).AliasName;
// string ss = "";
// }
IFeatureClass pFC = pNAContext.NAClasses.get_ItemByName("CFRoutes") as IFeatureClass;
if (pFC == null)
{
System.Diagnostics.Debug.WriteLine("GetTargetFacilityByID only works with ClosestFacility Layers");
throw new Exception("GetTargetFacilityByID only works with ClosestFacility Layers");
}
IQueryFilter pQF = new QueryFilterClass();
pQF.AddField("FacilityID");
pQF.WhereClause = "IncidentID = " + iAgentOID.ToString();
IFeatureCursor pFCur = pFC.Search(pQF,true);
IFeature pF = pFCur.NextFeature();
if (pF == null)
{
throw new Exception("Error. Feature not found");
}
else
{
return Convert.ToInt64(pF.get_Value(pF.Fields.FindField("FacilityID")) );
}
}
//long[] pPositions = GetSimilarRoute(pAgents,iFacilityID,lUniqueID);
public static bool GetSimilarRoute(ArrayList pAgents,long iFacilityID,long lUniqueID,ref ArrayList pPositions)
{
for(int i = 0;i<pAgents.Count;i++)
{
IAgent pAgent = pAgents[i] as IAgent;
if (pAgent == null) return false;
if(pAgent.TargetFacility == iFacilityID && pAgent.GoesThrough(lUniqueID))
{
long[] pPos = pAgent.GetPositions();
for(int i2 = 0;i2<pPos.Length;i2++)
{
long lPos = pPos[i2];
if (lPos==lUniqueID)
{
for(int i3 = i2;i3<pPos.Length;i3++)
{
pPositions.Add(pPos[i3]);
}
return true;
}
}
}
}
return false;
}
public static IFeatureCursor GetEdgesByPathID(IFeatureClass pFCEdges, int iPathID)
{
IQueryFilter pQF = new QueryFilterClass();
pQF.WhereClause = "PathID = " + iPathID.ToString();
ITableSort pTableSort = new TableSortClass();
pTableSort.Fields = pFCEdges.OIDFieldName;
pTableSort.set_Ascending(pFCEdges.OIDFieldName,true);
pTableSort.QueryFilter = pQF;
pTableSort.Table = pFCEdges as ITable;
pTableSort.Sort(null);
return pTableSort.Rows as IFeatureCursor;
}
public static void ConnectoToFC(IFeatureLayer pFLToConnect,IFeatureClass pFC)
{
IDataset pInMDS = pFC as IDataset;
((IDataLayer2)pFLToConnect).Disconnect();
((IDataLayer2)pFLToConnect).DataSourceName = pInMDS.FullName;
}
public static string SecondsToString(double dTotalSecs)
{
double dTotalMins = 0;
dTotalMins = Convert.ToInt32(dTotalSecs/60);
if ((dTotalMins*60)>dTotalSecs)dTotalMins = dTotalMins - 1;
if (dTotalMins>0)
{
int iRemainingSeconds = Convert.ToInt32(dTotalSecs - (dTotalMins*60));
return dTotalMins.ToString() + " mins " + iRemainingSeconds.ToString() + " secs";
}
return Convert.ToInt32(dTotalSecs) + " seconds";
}
public static void AddField(IFeatureClass pFC,string sName, ESRI.ArcGIS.Geodatabase.esriFieldType pFieldType)
{
if (pFC.FindField(sName)==-1)
{
IFieldEdit pNewField = new FieldClass() as IFieldEdit;
pNewField.Name_2 = sName;
pNewField.Type_2 =pFieldType;
pNewField.Length_2 = 20;
pFC.AddField(pNewField);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -