ArcGIS Pro 3.6 API Reference Guide
ArcGIS.Core.Data.Knowledge.Analytics Namespace / KnowledgeGraphFilteredFindPathsResults Class / ExtractPathsEntitiesAndRelationships Method
This can be null. When null, all paths are used. When non-null, only paths with indices in filterPathIndices are used.
Valid path indices verify: 0 <= index < 'CountPaths'
Example

In This Topic
    ExtractPathsEntitiesAndRelationships Method
    In This Topic
    Computes the entities and relationships associated to all or some of the result paths.
    Syntax
    public PathsEntitiesAndRelationships ExtractPathsEntitiesAndRelationships( 
       SortedSet<ulong> filterPathIndices
    )
    Public Function ExtractPathsEntitiesAndRelationships( _
       ByVal filterPathIndices As SortedSet(Of ULong) _
    ) As PathsEntitiesAndRelationships

    Parameters

    filterPathIndices
    This can be null. When null, all paths are used. When non-null, only paths with indices in filterPathIndices are used.
    Valid path indices verify: 0 <= index < 'CountPaths'

    Return Value

    Exceptions
    ExceptionDescription
     
    Remarks
    This method can throw exceptions if errors are found in the result paths Note: ExtractPathsEntitiesAndRelationships(null) will use all paths otherwise just the paths indentified by the path indices in filterPathIndices are used.
    Example
    Create Link Chart from FFP Results
        //using ArcGIS.Core.Data.Knowledge.Extensions;
    
        await QueuedTask.Run(async() =>
        {
            var ffp_config = new CIMFilteredFindPathsConfiguration();
            ffp_config.Name = "Create Link Chart from FFP Results";
    //set up config
    //...
            
            var results = kg.RunFilteredFindPaths(ffp_config);
    
            var pathsEntitiesAndRelationships = results.ExtractPathsEntitiesAndRelationships(null);
    
            //Create a KG layer id set
            var kgLayerIdSet = KnowledgeGraphLayerIDSet.FromKnowledgeGraphIDSet(
                pathsEntitiesAndRelationships.ToKnowledgeGraphIDSet(
                    KGResultContentFromFFP.EntitiesAndRelationships));
    
            //Create a brand new link chart with the results and show it
            var linkChart = MapFactory.Instance.CreateLinkChart(
                                                "KG Intro", kg, kgLayerIdSet);
    
            var mapPane = await FrameworkApplication.Panes.CreateMapPaneAsync(linkChart);
            var linkChartView = mapPane.MapView;
    
            //Change layout algo to match the default used by the UI after FFP
            await linkChartView.SetLinkChartLayoutAsync(
                KnowledgeLinkChartLayoutAlgorithm.Hierarchical_TopToBottom);
    
            //Set root nodes - they correspond to the origin nodes of the result paths
            var kgLayerIdSetForRootNodes = KnowledgeGraphLayerIDSet.FromKnowledgeGraphIDSet(
                pathsEntitiesAndRelationships.ToKnowledgeGraphIDSet(
                    KGResultContentFromFFP.OnlyPathsOriginEntities));
    
            //To correctly identify the ids in the link chart we must change the ids
            //from Geodatabase oids returned in the KnowledgeGraphLayerIDSet to the
    //temporary/synthetic oids used by layers in the link chart...
            var kg_layer = linkChart.GetLayersAsFlattenedList().OfType<KnowledgeGraphLayer>().First();
            var mapMembers = kg_layer.GetMapMembersAsFlattenedList();
            var oidDict = kgLayerIdSetForRootNodes.ToOIDDictionary();
            var mmDict = new Dictionary<MapMember, List<long>>();
            foreach (var kvp in oidDict)
            {
                var named_type = kvp.Key;
                foreach (var mm in mapMembers)
                {
                    if (mm is LinkChartFeatureLayer fl_lc && fl_lc.IsEntity)
                    {
                        if (fl_lc.GetTypeName().ToLower() == named_type.ToLower())
                        {
                            var lc_oids = new List<long>();
                            //these oids are from the geodatabase
                            var oid_field = $"{fl_lc.GetTypeName()}.objectid";
                            var id_list = string.Join(',', kvp.Value.ToArray());
                            var where = $"{fl_lc.GetTypeName()}.objectid IN ({id_list})";
    
                            var qf = new ArcGIS.Core.Data.QueryFilter()
                            {
                                WhereClause = where,
                                SubFields = $"LC.OID,{oid_field}"//the 'LC.OID' oids are the ones
                                               //we need for the mapmember id set
                                               //in the link chart
                            };
                            var rc = fl_lc.Search(qf);
                            var oid_idx = rc.FindField(oid_field);
                            while (rc.MoveNext())
                            {
                                var oid = (long)rc.Current[oid_idx];
                                var lc_oid = rc.Current.GetObjectID();
                                lc_oids.Add(lc_oid);
                            }
                            rc.Dispose();
                            mmDict[fl_lc] = lc_oids;
                            break;
                        }
                    }
                }
            }
    
            var mmIdSet = MapMemberIDSet.FromDictionary(mmDict);
            linkChartView.SetRootNodes(mmIdSet);
        });
    Append to Link Chart from FFP Results
    //using ArcGIS.Core.Data.Knowledge.Extensions;
    
    var linkChartView = MapView.Active;
    
    await QueuedTask.Run(async () =>
    {
        var ffp_config = new CIMFilteredFindPathsConfiguration();
        ffp_config.Name = "Append to Link Chart from FFP Results";
        //set up config
        //...
    
        var results = kg.RunFilteredFindPaths(ffp_config);
    
        var pathsEntitiesAndRelationships = results.ExtractPathsEntitiesAndRelationships(null);
    
        //Create a KG layer id set
        var kgLayerIdSet = KnowledgeGraphLayerIDSet.FromKnowledgeGraphIDSet(
            pathsEntitiesAndRelationships.ToKnowledgeGraphIDSet(
                KGResultContentFromFFP.EntitiesAndRelationships));
    
        var map = linkChartView.Map;
    
        if (!map.CanAppendToLinkChart(kgLayerIdSet))
            return;//not compatible
    
        map.AppendToLinkChart(kgLayerIdSet);
        //switch layout algo
        var algo = linkChartView.GetLinkChartLayout();
        if (algo != KnowledgeLinkChartLayoutAlgorithm.Hierarchical_TopToBottom)
        {
            //Change layout algo to match the default used by the UI after FFP
            await linkChartView.SetLinkChartLayoutAsync(
                KnowledgeLinkChartLayoutAlgorithm.Hierarchical_TopToBottom);
        }
    
        //To set link chart root nodes see 'Create Link Chart from FFP Results'
    });
    List out FFP Results Origin, Destination, Other Entities
    //using ArcGIS.Core.Data.Knowledge.Extensions;
    
    await QueuedTask.Run(async () =>
    {
        var ffp_config = new CIMFilteredFindPathsConfiguration();
        ffp_config.Name = "List out FFP Results Origin, Destination, Other Entities";
        //set up config
        //...
    
        var results = kg.RunFilteredFindPaths(ffp_config);
    
        if (results.CountPaths == 0)
        {
            System.Diagnostics.Debug.WriteLine("FFP returned no paths");
            return;
        }
    
        //print out paths by increasing length, min cost, max cost
        var path_by_len_indices = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingPathLength
                                                                .Select(idx => idx.index);
        var path_by_min_cost = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingMinPathCost
                                                                .Select(idx => idx.index);
        var path_by_max_cost = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingMaxPathCost
                                                                .Select(idx => idx.index);
    
        var x = 0;
        StringBuilder sb = new StringBuilder();
    
        foreach (var path_indeces in new List<IEnumerable<long>> {
            path_by_len_indices,
            path_by_min_cost,
            path_by_max_cost})
        {
            if (x == 0)
                sb.AppendLine($"Entities by length: {path_by_len_indices.Count()}");
            else if (x == 1)
                sb.AppendLine($"Entities by min cost: {path_by_min_cost.Count()}");
            else if (x == 2)
                sb.AppendLine($"Entities by max cost: {path_by_max_cost.Count()}");
            x++;
            foreach (var path_idx in path_indeces)
            {
                var path = (ResultPath)results.MaterializePath(path_idx);
                sb.AppendLine(
                    $"Path[{path_idx}] length: {path.Length}, min: {path.MinCost} max: {path.MaxCost}");
    
                var sorted_set = new SortedSet<ulong>();
                sorted_set.Add((ulong)path_idx);
                var per = results.ExtractPathsEntitiesAndRelationships(sorted_set);
    
                var origin_dest_uids = new List<string>();
                var sep = "";
    
                sb.Append(" Origin EntitiesUIDs: ");
                foreach (var idx in per.PathsOriginEntitiesUIDsIndexes)
                {
                    //See 'List out FFP Results by Path Length, Min Cost, Max Cost' for
      //FormatID method above
                    var uid = FormatID(per.EntitiesUIDs[idx].ToString());
                    origin_dest_uids.Add(uid);
    
                    var origin =
                        $"{sep}{per.EntityTypeNames[per.EntityTypes[idx]]}:{uid}";
                    sep = ", ";
                    sb.Append($"{origin}");
                }
                sb.AppendLine("");
    
                sep = "";
                sb.Append(" Destination EntitiesUIDs: ");
                foreach (var idx in per.PathsDestinationEntitiesUIDsIndexes)
                {
                    var uid = FormatID(per.EntitiesUIDs[idx].ToString());
                    origin_dest_uids.Add(uid);
    
                    var dest =
                        $"{sep}{per.EntityTypeNames[per.EntityTypes[idx]]}:{uid}";
                    sep = ", ";
                    sb.Append($"{dest}");
                }
                sb.AppendLine("");
    
                sep = "";
                var idx2 = 0;
                sb.Append(" Other EntitiesUIDs: ");
                bool wereAnyOthers = false;
                foreach (var raw_uid in per.EntitiesUIDs)
                {
                    var uid = FormatID(raw_uid.ToString());
                    if (!origin_dest_uids.Contains(uid))
                    {
                        var other =
                        $"{sep}{per.EntityTypeNames[per.EntityTypes[idx2]]}:{uid}";
                        sep = ", ";
                        sb.Append($"{other}");
                        wereAnyOthers = true;
                    }
                    idx2++;
                }
                if (!wereAnyOthers)
                    sb.Append(" <<none>>");
    
                //sb.AppendLine("");
    
                var entity_str = sb.ToString();
                System.Diagnostics.Debug.WriteLine(entity_str);
    
                sb.Clear();
                sep = "";
            }
        }
    
    });
    
    List out FFP Results Relationships
    //using ArcGIS.Core.Data.Knowledge.Extensions;
    
    await QueuedTask.Run(async () =>
    {
        var ffp_config = new CIMFilteredFindPathsConfiguration();
        ffp_config.Name = "List out FFP Results Relationships";
        //set up config
        //...
    
        var results = kg.RunFilteredFindPaths(ffp_config);
    
        if (results.CountPaths == 0)
        {
            System.Diagnostics.Debug.WriteLine("FFP returned no paths");
            return;
        }
    
        //print out paths by increasing length, min cost, max cost
        var path_by_len_indices = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingPathLength
                                                                .Select(idx => idx.index);
        var path_by_min_cost = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingMinPathCost
                                                                .Select(idx => idx.index);
        var path_by_max_cost = (IEnumerable<long>)results.PathIndicesOrderedByIncreasingMaxPathCost
                                                                .Select(idx => idx.index);
    
        var x = 0;
        StringBuilder sb = new StringBuilder();
    
        foreach (var path_indeces in new List<IEnumerable<long>> {
            path_by_len_indices,
            path_by_min_cost,
            path_by_max_cost})
        {
            if (x == 0)
                sb.AppendLine($"Relationships by length: {path_by_len_indices.Count()}");
            else if (x == 1)
                sb.AppendLine($"Relationships by min cost: {path_by_min_cost.Count()}");
            else if (x == 2)
                sb.AppendLine($"Relationships by max cost: {path_by_max_cost.Count()}");
            x++;
            foreach (var path_idx in path_indeces)
            {
                var path = (ResultPath)results.MaterializePath(path_idx);
                sb.AppendLine(
                    $"Path[{path_idx}] length: {path.Length}, min: {path.MinCost} max: {path.MaxCost}");
    
                var sorted_set = new SortedSet<ulong>();
                sorted_set.Add((ulong)path_idx);
                var per = results.ExtractPathsEntitiesAndRelationships(sorted_set);
    
                var idx = 0;
                foreach (var rel_uid in per.RelationshipsUIDs)
                {
                    sb.Append($" RelationshipsUIDs[{idx}]: ");
    
                    var uid = FormatID(rel_uid.ToString());
                    var rel_info =
                        $"{per.RelationshipTypeNames[per.RelationshipTypes[idx]]}:{uid}";
                    sb.Append($"{rel_info}\r\n");
                    //From entity:
                    var entity_idx = per.RelationshipsFrom[idx];
                    var origin_uid = FormatID(per.EntitiesUIDs[entity_idx].ToString());
                    var origin = $"{per.EntityTypeNames[per.EntityTypes[entity_idx]]}:{origin_uid}";
                    sb.Append($"   RelationshipsFrom: {origin}\r\n");
                    //To entity
                    entity_idx = per.RelationshipsTo[idx];
                    var dest_uid = FormatID(per.EntitiesUIDs[entity_idx].ToString());
                    var dest = $"{per.EntityTypeNames[per.EntityTypes[entity_idx]]}:{dest_uid}";
                    sb.Append($"   RelationshipsTo: {dest}\r\n");
                    idx++;
                }
    
                var rel_str = sb.ToString();
                System.Diagnostics.Debug.WriteLine(rel_str);
    sb.Clear();
            }
        }
    
    });
    
    Requirements

    Target Platforms: Windows 11, Windows 10

    ArcGIS Pro version: 3.6 or higher.
    See Also