/// <summary> /// Traverse the topology graph, <see cref="ITopologyGraph"/>, to visit topology elements <see cref="ITopologyElement"/> /// </summary> /// <param name="featureDataset">Feature dataset object</param> /// <param name="topologyName">The topology name</param> /// <param name="featureClassName">The feature class name</param> /// <param name="originFeatureObjectId">Feature ObjectId from the feature class, <paramref name="featureClassName"/></param> /// <returns>A JSON object <see cref="JsonObject"/> containing parcels' id and address</returns> /// <remarks> /// This method builds the topology graph around origin parcel feature and traverse the topology graph to fetch its adjoining parcels and their addresses /// </remarks> public JsonObject TraverseTopologyGraph(IFeatureDataset featureDataset, string topologyName, string featureClassName, int originFeatureObjectId) { // Fetch feature class by name IFeatureClass parcelFeatureClass = GetFeatureClass(featureDataset, featureClassName); // Fetch topology by name from feature dataset ITopology topology = GetTopologyFromFeatureDataset(featureDataset, topologyName); // Get the origin parcel feature identified by ObjectID IFeature parcelFeature = GetFeature(parcelFeatureClass, originFeatureObjectId); ITopologyGraph topologyGraph = topology.Cache; // Build the topology graph around the origin parcel feature topologyGraph.Build(parcelFeature.Shape.Envelope, false); IEnumTopologyEdge enumTopologyEdge = topologyGraph.GetParentEdges(parcelFeatureClass, originFeatureObjectId); enumTopologyEdge.Reset(); List <dynamic> taxParcelIds = new List <dynamic>(); IEnvelope topologyParentsEnvelope = new EnvelopeClass(); Dictionary <int, IPoint> parcelsToCentroidMap = new Dictionary <int, IPoint>(); for (int topoEdgeCount = 0; topoEdgeCount < enumTopologyEdge.Count; topoEdgeCount++) { ITopologyEdge topologyEdge = enumTopologyEdge.Next(); // Parents of the topology edge IEnumTopologyParent parents = topologyEdge.Parents; parents.Reset(); for (int parentsCount = 0; parentsCount < parents.Count; parentsCount++) { esriTopologyParent parent = parents.Next(); int parentFID = parent.m_FID; IFeatureClass parentFC = parent.m_pFC; IFeature parentParcelFeature = parentFC.GetFeature(parentFID); // Get the index of 'ParcelType' field from the parcel feature class int parcelTypeIndex = parentParcelFeature.Fields.FindField("PARCELTYPE"); // Get parcel type value int parcelTypeValue = Convert.ToInt32(parentParcelFeature.Value[parcelTypeIndex]); // Avoid duplicates and skip parcels with 'RowOverlap' subtype if (parentFC == parcelFeatureClass && !taxParcelIds.Contains(parentFID) && parentFID != originFeatureObjectId && (parcelTypeValue < 8 && parcelTypeValue > 0)) { taxParcelIds.Add(parentFID); // Envelope of a parcel IEnvelope parcelEnvelope = parentParcelFeature.Extent.Envelope; // Centroid of a parcel IArea parcelArea = parcelEnvelope as IArea; IPoint parcelCentroid = parcelArea.Centroid; // Add parcel id and centroid to the mapping dictionary parcelsToCentroidMap.Add(parentFID, parcelCentroid); // Union of the adjoining parcels' envelope topologyParentsEnvelope.Union(parcelEnvelope); } } } // Update topology graph to include adjoining parcels topologyGraph.Build(topologyParentsEnvelope, false); JsonObject jsonObject = new JsonObject(); // Get adjoining parcels and their addresses List <string> parcelWithAddressList = GetParcelsWithAddress(topologyGraph, parcelsToCentroidMap); // Format JSON array jsonObject.AddArray($"Adjoining parcels of {originFeatureObjectId}", parcelWithAddressList?.ToArray()); return(jsonObject); }