ProSnippets ParcelFabric - kataya/arcgis-pro-sdk GitHub Wiki

Language:              C#  
Subject:               ParcelFabric  
Contributor:           ArcGIS Pro SDK Team <[email protected]>  
Organization:          esri, http://www.esri.com  
Date:                  12/11/2020  
ArcGIS Pro:            2.7  
Visual Studio:         2017, 2019  
.NET Target Framework: 4.8  

Get the active record

string errorMessage = await QueuedTask.Run(() =>
{
  try
  {
    var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
    //if there is no fabric in the map then bail
    if (myParcelFabricLayer == null)
      return "There is no fabric in the map.";
    var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
    if (theActiveRecord == null)
      return "There is no Active Record. Please set the active record and try again.";
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Get Active Record.");

Set the active record

string errorMessage = await QueuedTask.Run(async () =>
{
  try
  {
    string sExistingRecord = "MyRecordName";
    var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
    //if there is no fabric in the map then bail
    if (myParcelFabricLayer == null)
      return "There is no fabric in the map.";

    bool bSuccess = await myParcelFabricLayer.SetActiveRecordAsync(sExistingRecord);
    if (!bSuccess)
      return "No record called " + sExistingRecord + " was found.";
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Set Active Record.");

Create a new record

string errorMessage = await QueuedTask.Run(async () =>
{
  Dictionary<string, object> RecordAttributes = new Dictionary<string, object>();
  string sNewRecord = "MyRecordName";
  try
  {
    var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
    //if there is no fabric in the map then bail
    if (myParcelFabricLayer == null)
      return "There is no fabric in the map.";
    var recordsLayer = await myParcelFabricLayer.GetRecordsLayerAsync();
    var editOper = new EditOperation()
    {
      Name = "Create Parcel Fabric Record",
      ProgressMessage = "Create Parcel Fabric Record...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = false,
      SelectModifiedFeatures = false
    };
    RecordAttributes.Add("Name", sNewRecord);
    var editRowToken = editOper.CreateEx(recordsLayer.FirstOrDefault(), RecordAttributes);
    if (!editOper.Execute())
      return editOper.ErrorMessage;

    var defOID = -1;
    var lOid = editRowToken.ObjectID.HasValue ? editRowToken.ObjectID.Value : defOID;
    await myParcelFabricLayer.SetActiveRecordAsync(lOid);
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Create New Record.");

Copy standard line features into a parcel type

string errorMessage = await QueuedTask.Run( async () =>
{
  // check for selected layer
  if (MapView.Active.GetSelectedLayers().Count == 0)
    return "Please select a target parcel polygon layer in the table of contents.";
  //get the feature layer that's selected in the table of contents
  var destPolygonL = MapView.Active.GetSelectedLayers().OfType<FeatureLayer>().FirstOrDefault();
  try
  {
    var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
    //if there is no fabric in the map then bail
    if (myParcelFabricLayer == null)
      return "There is no fabric in the map.";
    var pRec = myParcelFabricLayer.GetActiveRecord();
    if (pRec == null)
      return "There is no Active Record. Please set the active record and try again.";
    string ParcelTypeName = "";
    IEnumerable<string> parcelTypeNames = await myParcelFabricLayer.GetParcelTypeNames();
    foreach (string parcelTypeNm in parcelTypeNames)
    {
      var polygonLyrParcelTypeEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName(parcelTypeNm);
      foreach (FeatureLayer lyr in polygonLyrParcelTypeEnum)
        if (lyr == destPolygonL)
        {
          ParcelTypeName = parcelTypeNm;
          break;
        }
    }
    if (String.IsNullOrEmpty(ParcelTypeName))
      return "Please select a target parcel polygon layer in the table of contents.";
    var srcFeatLyr = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name.Contains("MySourceLines") && l.IsVisible);
    if (srcFeatLyr == null)
      return "Looking for a layer named 'MySourceLines' in the table of contents.";
    //now get the line layer for this parcel type
    var destLineLyrEnum = await myParcelFabricLayer.GetParcelLineLayerByTypeName(ParcelTypeName);
    if (destLineLyrEnum.Count() == 0) //make sure there is one in the map
      return ParcelTypeName + " not found.";
    var destLineL = destLineLyrEnum.FirstOrDefault();
    if (destLineL == null || destPolygonL == null)
      return "";
    var editOper = new EditOperation()
    {
      Name = "Copy Line Features To Parcel Type",
      ProgressMessage = "Copy Line Features To Parcel Type...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = true,
      SelectModifiedFeatures = false
    };
    var ids = new List<long>((srcFeatLyr as FeatureLayer).GetSelection().GetObjectIDs());
    if (ids.Count == 0)
      return "No selected lines were found. Please select line features and try again.";
    editOper.CopyLineFeaturesToParcelType(srcFeatLyr, ids, destLineL, destPolygonL);
    if (!editOper.Execute())
      return editOper.ErrorMessage;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Copy Line Features To Parcel Type.");

Copy parcel lines to a parcel type

string errorMessage = await QueuedTask.Run( async () =>
{
  // check for selected layer
  if (MapView.Active.GetSelectedLayers().Count == 0)
    return "Please select a source parcel polygon feature layer in the table of contents.";
  try
  {
    var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
    if (myParcelFabricLayer == null)
      return "No parcel layer found in the map.";

    //get the feature layer that's selected in the table of contents
    var srcParcelFeatLyr = MapView.Active.GetSelectedLayers().OfType<FeatureLayer>().FirstOrDefault();
    string sTargetParcelType = "Tax";
    var destLineLEnum = await myParcelFabricLayer.GetParcelLineLayerByTypeName(sTargetParcelType);
    if (destLineLEnum.Count() == 0)
      return "";
    var destLineL = destLineLEnum.FirstOrDefault();
    var destPolygonLEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName(sTargetParcelType);
    if (destPolygonLEnum.Count() == 0)
      return "";
    var destPolygonL = destPolygonLEnum.FirstOrDefault();
    if (destLineL == null || destPolygonL == null)
      return "";
    var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
    if (theActiveRecord == null)
      return "There is no Active Record. Please set the active record and try again.";
    var editOper = new EditOperation()
    {
      Name = "Copy Lines To Parcel Type",
      ProgressMessage = "Copy Lines To Parcel Type ...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = true,
      SelectModifiedFeatures = false
    };
    var ids = new List<long>(srcParcelFeatLyr.GetSelection().GetObjectIDs());
    if (ids.Count == 0)
      return "No selected parcels found. Please select parcels and try again.";
    //add the standard feature line layers source, and their feature ids to a new KeyValuePair
    var kvp = new KeyValuePair<MapMember, List<long>>(srcParcelFeatLyr, ids);
    var sourceParcelFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };
    editOper.CopyParcelLinesToParcelType(myParcelFabricLayer, sourceParcelFeatures, destLineL, destPolygonL, true, false, true);
    if (!editOper.Execute())
      return editOper.ErrorMessage;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Copy Parcel Lines To Parcel Type.");

Assign features to active record

string errorMessage = await QueuedTask.Run( () =>
{
  //check for selected layer
  if (MapView.Active.GetSelectedLayers().Count == 0)
    return "Please select a source feature layer in the table of contents.";
  //first get the feature layer that's selected in the table of contents
  var srcFeatLyr = MapView.Active.GetSelectedLayers().OfType<FeatureLayer>().FirstOrDefault();
  var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
  if (myParcelFabricLayer == null)
    return "No parcel layer found in the map.";
  try
  {
    var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
    if (theActiveRecord == null)
      return "There is no Active Record. Please set the active record and try again.";
    var editOper = new EditOperation()
    {
      Name = "Assign Features to Record",
      ProgressMessage = "Assign Features to Record...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = true,
      SelectModifiedFeatures = false
    };
    //add parcel type layers and their feature ids to a new KeyValuePair
    var ids = new List<long>(srcFeatLyr.GetSelection().GetObjectIDs());
    var kvp = new KeyValuePair<MapMember, List<long>>(srcFeatLyr, ids);
    var sourceFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };

    editOper.AssignFeaturesToRecord(myParcelFabricLayer, sourceFeatures, theActiveRecord);
    if (!editOper.Execute())
      return editOper.ErrorMessage;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Assign Features To Record.");

Create parcel seeds

try
{
  var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
  if (theActiveRecord == null)
    return "There is no Active Record. Please set the active record and try again.";

  var guid = theActiveRecord.Guid;
  var editOper = new EditOperation()
  {
    Name = "Create Parcel Seeds",
    ProgressMessage = "Create Parcel Seeds...",
    ShowModalMessageAfterFailure = true,
    SelectNewFeatures = true,
    SelectModifiedFeatures = false
  };
  editOper.CreateParcelSeedsByRecord(myParcelFabricLayer, guid, MapView.Active.Extent);
  if (!editOper.Execute())
    return editOper.ErrorMessage;
}
catch (Exception ex)
{
  return ex.Message;
}
return "";

Build parcels

try
{
  var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
  if (myParcelFabricLayer == null)
    return "Parcel layer not found in map.";

  var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
  var guid = theActiveRecord.Guid;
  var editOper = new EditOperation()
  {
    Name = "Build Parcels",
    ProgressMessage = "Build Parcels...",
    ShowModalMessageAfterFailure = true,
    SelectNewFeatures = true,
    SelectModifiedFeatures = true
  };
  editOper.BuildParcelsByRecord(myParcelFabricLayer, guid);
  if (!editOper.Execute())
    return editOper.ErrorMessage;
}
catch (Exception ex)
{
  return ex.Message;
}
return "";

Duplicate parcels

var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
if (myParcelFabricLayer == null)
  return "Parecl layer not found in the map.";
//get the source polygon layer from the parcel fabric layer type, in this case a layer called Lot
var srcFeatLyrEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName("Lot");
if (srcFeatLyrEnum.Count() == 0)
  return "";
var sourcePolygonL = srcFeatLyrEnum.FirstOrDefault();
//get the target polygon layer from the parcel fabric layer type, in this case a layer called Tax
var targetFeatLyrEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName("Tax");
if (targetFeatLyrEnum.Count() == 0)
  return "";
var targetFeatLyr = targetFeatLyrEnum.FirstOrDefault();
var ids = new List<long>(sourcePolygonL.GetSelection().GetObjectIDs());
if (ids.Count == 0)
  return "No selected parcels found. Please select parcels and try again.";
//add polygon layers and the feature ids to be duplicated to a new KeyValuePair
var kvp = new KeyValuePair<MapMember, List<long>>(sourcePolygonL, ids);
var sourceFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };
try
{
  var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
  if (theActiveRecord == null)
    return "There is no Active Record. Please set the active record and try again.";
  var editOper = new EditOperation()
  {
    Name = "Duplicate Parcels",
    ProgressMessage = "Duplicate Parcels...",
    ShowModalMessageAfterFailure = true,
    SelectNewFeatures = true,
    SelectModifiedFeatures = false
  };
  editOper.DuplicateParcels(myParcelFabricLayer, sourceFeatures, theActiveRecord, targetFeatLyr);
  if (!editOper.Execute())
    return editOper.ErrorMessage;
}
catch (Exception ex)
{
  return ex.Message;
}

Set parcels historic

string errorMessage = await QueuedTask.Run(async () =>
{
  var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
  if (myParcelFabricLayer == null)
    return "Please add a parcel fabric to the map";
  try
  {
    FeatureLayer destPolygonL = null;
    //find the first layer that is a parcel type, is non-historic, and has a selection
    bool bFound = false;
    var ParcelTypesEnum = await myParcelFabricLayer.GetParcelTypeNames();
    foreach (FeatureLayer mapFeatLyr in MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
    {
      foreach (string ParcelType in ParcelTypesEnum)
      {
        var layerEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName(ParcelType);
        foreach (FeatureLayer flyr in layerEnum)
        {
          if (flyr == mapFeatLyr)
          {
            bFound = mapFeatLyr.SelectionCount > 0;
            destPolygonL = mapFeatLyr;
            break;
          }
        }
        if (bFound) break;
      }
      if (bFound) break;
    }
    if (!bFound)
      return "Please select parcels to set as historic.";

    var theActiveRecord = myParcelFabricLayer.GetActiveRecord();
    if (theActiveRecord == null)
      return "There is no Active Record. Please set the active record and try again.";

    var ids = new List<long>(destPolygonL.GetSelection().GetObjectIDs());
    //can do multi layer selection but using single per code above
    var kvp = new KeyValuePair<MapMember, List<long>>(destPolygonL, ids);
    var sourceFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };
    var editOper = new EditOperation()
    {
      Name = "Set Parcels Historic",
      ProgressMessage = "Set Parcels Historic...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = true,
      SelectModifiedFeatures = false
    };
    editOper.SetParcelHistoryRetired(myParcelFabricLayer, sourceFeatures, theActiveRecord);
    if (!editOper.Execute())
      return editOper.ErrorMessage;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Set Parcels Historic.");

Shrink parcels to seeds

string errorMessage = await QueuedTask.Run(async () =>
{
  var myParcelFabricLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<ParcelLayer>().FirstOrDefault();
  if (myParcelFabricLayer == null)
    return "Please add a parcel fabric to the map";
  try
  {
    FeatureLayer parcelPolygonLyr = null;
    //find the first layer that is a polygon parcel type, is non-historic, and has a selection
    bool bFound = false;
    var ParcelTypesEnum = await myParcelFabricLayer.GetParcelTypeNames();
    foreach (FeatureLayer mapFeatLyr in MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>())
    {
      foreach (string ParcelType in ParcelTypesEnum)
      {
        var layerEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName(ParcelType);
        foreach (FeatureLayer flyr in layerEnum)
        {
          if (flyr == mapFeatLyr)
          {
            bFound = mapFeatLyr.SelectionCount > 0;
            parcelPolygonLyr = mapFeatLyr;
            break;
          }
        }
        if (bFound) break;
      }
      if (bFound) break;
    }
    if (!bFound)
      return "Please select parcels to shrink to seeds.";
    var editOper = new EditOperation()
    {
      Name = "Shrink Parcels To Seeds",
      ProgressMessage = "Shrink Parcels To Seeds...",
      ShowModalMessageAfterFailure = true,
      SelectNewFeatures = true,
      SelectModifiedFeatures = false
    };
    var ids = new List<long>(parcelPolygonLyr.GetSelection().GetObjectIDs());
    var kvp = new KeyValuePair<MapMember, List<long>>(parcelPolygonLyr, ids);
    var sourceParcelFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };
    editOper.ShrinkParcelsToSeeds(myParcelFabricLayer, sourceParcelFeatures);
    if (!editOper.Execute())
      return editOper.ErrorMessage;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
  return "";
});
if (!string.IsNullOrEmpty(errorMessage))
  MessageBox.Show(errorMessage, "Shrink Parcels To Seeds.");

Change parcel type

//add polygon layers and the feature ids to change the type on to a new KeyValuePair
var ids = new List<long>(sourcePolygonL.GetSelection().GetObjectIDs());
var kvp = new KeyValuePair<MapMember, List<long>>(sourcePolygonL, ids);
var sourceFeatures = new List<KeyValuePair<MapMember, List<long>>> { kvp };
try
{
  var editOper = new EditOperation()
  {
    Name = "Change Parcel Type",
    ProgressMessage = "Change Parcel Type...",
    ShowModalMessageAfterFailure = true,
    SelectNewFeatures = true,
    SelectModifiedFeatures = false
  };
  editOper.ChangeParcelType(myParcelFabricLayer, sourceFeatures, targetFeatLyr);
  if (!editOper.Execute())
    return editOper.ErrorMessage;
}
catch (Exception ex)
{
  return ex.Message;
}
return "";

Get parcel type name from feature layer

private async Task<string> GetParcelTypeNameFromFeatureLayer(ParcelLayer myParcelFabricLayer, FeatureLayer featLayer, GeometryType geomType)
{
  if (featLayer == null) //nothing to do, return empty string
    return String.Empty;
  IEnumerable<string> parcelTypeNames = await myParcelFabricLayer.GetParcelTypeNames();
  foreach (string parcelTypeName in parcelTypeNames)
  {
    if (geomType == GeometryType.Polygon)
    {
      var polygonLyrParcelTypeEnum = await myParcelFabricLayer.GetParcelPolygonLayerByTypeName(parcelTypeName);
      foreach (FeatureLayer lyr in polygonLyrParcelTypeEnum)
        if (lyr == featLayer)
          return parcelTypeName;

      polygonLyrParcelTypeEnum = await myParcelFabricLayer.GetHistoricParcelPolygonLayerByTypeName(parcelTypeName);
      foreach (FeatureLayer lyr in polygonLyrParcelTypeEnum)
        if (lyr == featLayer)
          return parcelTypeName;
    }
    if (geomType == GeometryType.Polyline)
    {
      var lineLyrParcelTypeEnum = await myParcelFabricLayer.GetParcelLineLayerByTypeName(parcelTypeName);
      foreach (FeatureLayer lyr in lineLyrParcelTypeEnum)
        if (lyr == featLayer)
          return parcelTypeName;

      lineLyrParcelTypeEnum = await myParcelFabricLayer.GetHistoricParcelLineLayerByTypeName(parcelTypeName);
      foreach (FeatureLayer lyr in lineLyrParcelTypeEnum)
        if (lyr == featLayer)
          return parcelTypeName;
    }
  }
  return String.Empty;
}
⚠️ **GitHub.com Fallback** ⚠️