Last active
January 29, 2019 18:59
-
-
Save JeffJacobson/e81e0ddddf086ac7f798b343feac4b53 to your computer and use it in GitHub Desktop.
ArcObjects extension methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using ESRI.ArcGIS.Carto; | |
using ESRI.ArcGIS.esriSystem; | |
using ESRI.ArcGIS.Geodatabase; | |
using System; | |
using System.Collections.Generic; | |
using System.Text.RegularExpressions; | |
namespace Wsdot.ArcGis.Extensions | |
{ | |
public static class Extensions | |
{ | |
/// <summary> | |
/// Converts a dictionary into a <see cref="PropertySetClass"/>. | |
/// </summary> | |
/// <typeparam name="T">The type of values the property set will contain. Set to <see cref="object"/> if it will contain multiple types.</typeparam> | |
/// <param name="dict">The dictionary used to populate the <see cref="IPropertySet"/></param> | |
/// <returns>Returns a <see cref="IPropertySet"/> containing the contents of the input dictionary.</returns> | |
public static IPropertySet DictToPropertySet<T>(this IDictionary<string, T> dict) | |
{ | |
IPropertySet propSet = new PropertySetClass(); | |
foreach (var kvp in dict) | |
{ | |
propSet.SetProperty(kvp.Key, kvp.Value); | |
} | |
return propSet; | |
} | |
/// <summary> | |
/// Creates an <see cref="IEnumerable{string}"/> of the elements of a <see cref="IStringArray"/>. | |
/// </summary> | |
/// <param name="stringArray">An <see cref="IStringArray"/></param> | |
/// <returns>Returns an <see cref="IEnumerable{string}"/></returns> | |
public static IEnumerable<string> AsEnumerable(this IStringArray stringArray) | |
{ | |
for (int i = 0, l = stringArray.Count; i < l; i++) | |
{ | |
yield return stringArray.Element[i]; | |
} | |
} | |
/// <summary> | |
/// Iterates over the objects in an <see cref="IVariantArray"/>. | |
/// </summary> | |
/// <param name="variantArray">An <see cref="IVariantArray"/></param> | |
/// <returns>Returns an <see cref="IEnumerable{object}"/>.</returns> | |
public static IEnumerable<object> AsEnumerable(this IVariantArray variantArray) | |
{ | |
for (int i = 0, l = variantArray.Count; i < l; i++) | |
{ | |
yield return variantArray.Element[i]; | |
} | |
} | |
/// <summary> | |
/// Iterates over the objects in an <see cref="ILongArray"/>. | |
/// </summary> | |
/// <param name="longArray"> | |
/// An ArcObjects <see cref="ILongArray"/> (which contains <see cref="int"/> values). | |
/// </param> | |
/// <returns>Returns an <see cref="IEnumerable{int}"/></returns> | |
public static IEnumerable<int> AsEnumerable(this ILongArray longArray) | |
{ | |
for (int i = 0, l = longArray.Count; i < l; i++) | |
{ | |
yield return longArray.Element[i]; | |
} | |
} | |
/// <summary> | |
/// Enumerates the values returned from <see cref="ISqlWorkspace.GetColumns(string, out IStringArray, out IStringArray, out IVariantArray, out ILongArray, out ILongArray, out ILongArray)"/>. | |
/// </summary> | |
/// <param name="ppColumnName">An <see cref="IStringArray"/> containing column names</param> | |
/// <param name="ppColumnType">An <see cref="IStringArray"/> containing column type strings.</param> | |
/// <param name="ppIsNullable">An <see cref="IVariantArray"/> containing <see cref="bool"/> values.</param> | |
/// <param name="ppSize">An <see cref="ILongArray"/> containing <see cref="int"/>values</param> | |
/// <param name="ppPrecision">An <see cref="ILongArray"/> containing <see cref="int"/>values</param> | |
/// <param name="ppScale">An <see cref="ILongArray"/> containing <see cref="int"/>values</param> | |
/// <returns></returns> | |
public static IEnumerable<( | |
string columnName, string columnType, bool isNullable, | |
int size, int precision, int scale)> AsEnumerable( | |
IStringArray ppColumnName, | |
IStringArray ppColumnType, | |
IVariantArray ppIsNullable, | |
ILongArray ppSize, | |
ILongArray ppPrecision, | |
ILongArray ppScale) | |
{ | |
for (int i = 0, l = ppColumnName.Count; i < l; i++) | |
{ | |
yield return ( | |
ppColumnName.Element[i], | |
ppColumnType.Element[i], | |
(bool)ppIsNullable.Element[i], | |
ppSize.Element[i], | |
ppPrecision.Element[i], | |
ppScale.Element[i] | |
); | |
} | |
} | |
/// <summary> | |
/// Creates a <see cref="UID"/> from the <see cref="Type.GUID"/> from an ArcObjects type. | |
/// </summary> | |
/// <param name="type">An ArcObjects type. | |
/// </param> | |
/// <returns>A <see cref="UIDClass"/></returns> | |
/// <example> | |
/// UID arcGuid = typeof(IFeatureLayer).CreateGuidForType(); | |
/// </example> | |
public static UIDClass CreateGuidForType(this Type type) | |
{ | |
var guid = type.GUID; | |
var arcGuid = new UIDClass | |
{ | |
Value = $"{{{guid.ToString().ToUpper()}}}" | |
}; | |
return arcGuid; | |
} | |
/// <summary> | |
/// Enumerates the layers of a certain type of an object implementing <see cref="IMapLayers"/>. | |
/// </summary> | |
/// <typeparam name="T">A layer type such as <see cref="IFeatureLayer"/>.</typeparam> | |
/// <param name="mapLayers"></param> | |
/// <returns></returns> | |
/// <example> | |
/// // Note: mapDoc is assumed to be an IMapDocument in this example. | |
/// // Loop through all of the feature layers and add relationships to each table in the view. | |
/// var mapLayers = (IMapLayers2)mapDoc.ActiveView; | |
/// var featureLayers = mapLayers.EnumerateFeatureLayers<IFeatureLayer>(); | |
/// foreach (var fl in featureLayers) | |
/// { | |
/// // do something with the feature layer | |
/// Console.WriteLine($"Layer name: {fl.Name}"); | |
/// } | |
/// </example> | |
public static IEnumerable<T> EnumerateFeatureLayers<T>(this IMapLayers mapLayers) where T: ILayer | |
{ | |
var outType = typeof(T); | |
UID arcGuid = outType.CreateGuidForType(); | |
var enumLayer = mapLayers.Layers[arcGuid, false]; | |
var currentLayer = enumLayer.Next(); | |
while (currentLayer != null) | |
{ | |
if (currentLayer is T tLayer) { | |
yield return tLayer; | |
} | |
currentLayer = enumLayer.Next(); | |
} | |
} | |
/// <summary> | |
/// Enumerates sets of <see cref="ITableFields.Field(int)"/> and <see cref="ITableFields.FieldInfo(int)"/> | |
/// </summary> | |
/// <param name="tableFields"> | |
/// An object implementing <see cref="ITableFields"/>, such as <see cref="FeatureLayerClass"/> | |
/// or <see cref="StandaloneTableClass"/>. | |
/// </param> | |
/// <returns>An <see cref="IEnumerator{Tuple{IField, IFieldInfo}}"/></returns> | |
internal static IEnumerable<(IField, IFieldInfo)> AsEnumerable(this ITableFields tableFields) | |
{ | |
for (int i = 0, l = tableFields.FieldCount; i < l; i++) | |
{ | |
var field = tableFields.Field[i]; | |
var fieldInfo = tableFields.FieldInfo[i]; | |
yield return (field, fieldInfo); | |
} | |
} | |
/// <summary> | |
/// Enumerates over the <see cref="IStandaloneTable"/>s in an <see cref="IStandaloneTableCollection"/>. | |
/// </summary> | |
/// <param name="tableCollection">Can be cast from an <see cref="IActiveView"/>.</param> | |
/// <returns></returns> | |
public static IEnumerable<IStandaloneTable> AsEnumerable(this IStandaloneTableCollection tableCollection) | |
{ | |
for (int i = 0, l = tableCollection.StandaloneTableCount; i < l; i++) | |
{ | |
yield return tableCollection.StandaloneTable[i]; | |
} | |
} | |
/// <summary> | |
/// Creates an alias name by splitting detecting words in the Pascal-case | |
/// field name and separating them with a space. | |
/// </summary> | |
/// <param name="fieldName">A Pascal-case field name string</param> | |
/// <returns>Returns a string containing the space separated individual words.</returns> | |
public static string GenerateAliasName(this string fieldName) | |
{ | |
const string wordPattern = @"((SRMP)|([A-Z][a-z]+)|([A-Z]{2}?))"; | |
var wordList = new List<string>(); | |
var matches = Regex.Matches(fieldName, wordPattern, RegexOptions.ExplicitCapture); | |
foreach (Match match in matches) | |
{ | |
var word = match.Value; | |
wordList.Add(word); | |
} | |
var output = string.Join(" ", wordList); | |
output = Regex.Replace(output, @"(?i)\bId\b", "ID"); | |
output = Regex.Replace(output, @"(?i)\bDesc\b", "Description"); | |
output = Regex.Replace(output, @"(?i)\bInd\b", "Indicator"); | |
return output; | |
} | |
/// <summary> | |
/// Automatically generates field aliases for the fields in a layer or table. | |
/// </summary> | |
/// <param name="layer"> | |
/// A class implementing <see cref="ITableFields"/>, such as <see cref="FeatureLayerClass"/> | |
/// or <see cref="StandaloneTableClass"/>. | |
/// </param> | |
public static void SetFieldAliases(this ITableFields layer) | |
{ | |
foreach (var (field, fieldInfo) in layer.AsEnumerable()) | |
{ | |
var alias = field.Name.GenerateAliasName(); | |
if (string.IsNullOrWhiteSpace(alias)) | |
{ | |
continue; | |
} | |
fieldInfo.Alias = field.Name.GenerateAliasName(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment