Skip to content

arcsmith.fc

arcsmith.fc

Feature Class

Helpers for building SQL WHERE clauses and exporting filtered subsets of feature classes inside 'Tool.execute'.

  • Build SQL WHERE clauses with automatic field delimiting and value quoting, including multi-value IN filters
  • Export subsets of a feature class by attribute filter in a single call
  • Copy feature classes with field and row filtering in a single call
  • Ingest external feature classes into a working geodatabase
  • Validate geometry types and compute polygon area with optional unit conversion

Functions of the fc module

build_where

Builds a SQL WHERE clause for a single field comparison, handling field delimiting and value quoting automatically based on the field's type.

build_where(input_fc, field, value, operator="=")
Parameter Type Default Description
input_fc str or Path required Path to the feature class. Used to resolve the correct field delimiter for the data source.
field str required Name of the field to filter on.
value str, int, float, or None required Value to compare against. Automatically quoted for string-like field types (String, Guid, Date). Pass None to produce an IS NULL or IS NOT NULL clause.
operator str '=' SQL comparison operator. Any valid SQL operator is accepted ('<>', '>', '<=', etc.). When value is None, '<>' and '!=' produce IS NOT NULL; all other operators produce IS NULL. Default '='.

Returns

str: a SQL WHERE clause ready to pass to export_where or any arcpy function that accepts a where clause.

Raises

ValueError if field is not found in input_fc.

Note

Field delimiters vary by data source (e.g. double-quotes for file geodatabases, square brackets for personal geodatabases). build_where calls arcpy.AddFieldDelimiters internally to process delimiters accordingly.

Examples

# String field: value is quoted automatically
clause = arcsmith.fc.build_where(input_fc, "STATUS", "Active")
# "STATUS" = 'Active'

# Exclude a value
clause = arcsmith.fc.build_where(input_fc, "STATUS", "Inactive", operator="<>")
# "STATUS" <> 'Inactive'

# Numeric field: no quoting applied
clause = arcsmith.fc.build_where(input_fc, "ZONE_ID", 4, operator=">=")
# "ZONE_ID" >= 4

# Null check — produces IS NULL
clause = arcsmith.fc.build_where(input_fc, "NOTES", None)
# "NOTES" IS NULL

# Null exclusion — produces IS NOT NULL
clause = arcsmith.fc.build_where(input_fc, "NOTES", None, operator="<>")
# "NOTES" IS NOT NULL

build_where_in

Builds a SQL WHERE clause for a multi-value IN (or NOT IN) filter, handling field delimiting and value quoting automatically based on the field's type.

build_where_in(input_fc, field, values, exclude=False)
Parameter Type Default Description
input_fc str or Path required Path to the feature class. Used to resolve the correct field delimiter and field type for the data source.
field str required Name of the field to filter on.
values list of str, int, or float required Values to match against. Must contain at least one entry. Automatically quoted for string-like field types (String, Guid, Date); left unquoted for numeric types.
exclude bool False If False (default), generates an IN clause (keep matching rows). If True, generates a NOT IN clause (drop matching rows).

Returns

str: a SQL WHERE clause ready to pass to export_where, copy_w_fields, or any arcpy function that accepts a where clause.

Raises

ValueError if field is not found in input_fc.

Raises

ValueError if values is empty.

Note

Use build_where_in when filtering on a list of values — for example, the selections from a multi-value toolbox parameter. For a single value use build_where instead.

Examples

# Keep only selected states (string field — values quoted automatically)
clause = arcsmith.fc.build_where_in(fc, "ST_STUSPS", ["FL", "GA", "AL"])
# "ST_STUSPS" IN ('FL', 'GA', 'AL')

# Exclude a list of zone IDs (numeric field — no quoting applied)
clause = arcsmith.fc.build_where_in(fc, "ZONE_ID", [3, 7, 12], exclude=True)
# "ZONE_ID" NOT IN (3, 7, 12)

# Combine with copy_w_fields to filter rows and fields in one call
clause = arcsmith.fc.build_where_in(fc, "STATE", states_list)
out = arcsmith.fc.copy_w_fields(fc, output_fc, ["NAME", "STATE"], where_clause=clause)

# Unpack a multi-value toolbox parameter directly
states_list = ['CA', 'AZ', 'NV']
clause = arcsmith.fc.build_where_in(fc_path, state_field, states_list)

export_where

Exports a subset of a feature class to a new feature class using a SQL WHERE clause.

export_where(input_fc, output_fc, where_clause)
Parameter Type Default Description
input_fc str or Path required Path to the input feature class.
output_fc str or Path required Path for the output feature class.
where_clause str required SQL WHERE clause used to filter features.

Returns

str: path to the output feature class.

Note

Internally creates a temporary feature layer, selects by attribute, and copies features. The temporary layer is always cleaned up, even if an error occurs.

Examples

# Build a clause with build_where, then export
clause = arcsmith.fc.build_where(input_fc, "STATUS", "Active")
out = arcsmith.fc.export_where(input_fc, output_fc, clause)
arcsmith.layer.add(out, target_map)

# Write a clause directly for more complex expressions
out = arcsmith.fc.export_where(
    input_fc, output_fc,
    where_clause="POP_2020 > 10000 AND STATE = 'TX'",
)

get_area

Returns the area of a polygon feature class and the unit name. Optionally converts the area to a different unit system before returning.

get_area(polygon_fc, output_units=None)
Parameter Type Default Description
polygon_fc str or Path required Path to the polygon feature class.
output_units str None Linear unit name to convert the area into. Must be one of: 'Meter', 'Kilometer', 'Foot_US', 'Foot', 'Mile_US', 'Nautical_Mile', 'Yard'. Case-sensitive. Default None (returns area in the native spatial reference units).

Returns

tuple of (float, str): the area value and the name of the units it is expressed in.

Raises

ValueError if output_units is not a recognised unit name.

Area units

SHAPE@AREA is always in the spatial reference's native linear units squared. get_area reads the native value and converts if output_units is provided. The returned unit string is the linear unit name; the area itself is in those units squared.

Linear unit conversion factors (area factor = linear² )

Unit Factor to Meters
Meter 1.0
Kilometer 1,000.0
Foot_US 0.304800609601
Foot 0.3048
Mile_US 1,609.347219
Nautical_Mile 1,852.0
Yard 0.9144

Examples

# Native units — no conversion
area, units = arcsmith.fc.get_area("path/to/polygon.shp")
arcpy.AddMessage(f"Area: {area} {units}^2")

# Convert to kilometres before returning
area, units = arcsmith.fc.get_area("path/to/polygon.shp", output_units="Kilometer")

# Feed directly into AverageNearestNeighbor (requires area in square metres)
area, _ = arcsmith.fc.get_area(study_poly, output_units="Meter")
arcpy.stats.AverageNearestNeighbor(points, "EUCLIDEAN_DISTANCE", Area=area)

to_gdb

Copies a feature class into a geodatabase. A convenience wrapper for the common pattern of pulling an external feature class into the working geodatabase at the start of a script.

to_gdb(input_fc, gdb, name=None)
Parameter Type Default Description
input_fc str or Path required Path to the source feature class. Accepts any path arcpy can read, including SDE paths and memory/ paths.
gdb str or Path required Path to the destination file geodatabase (.gdb).
name str None Name for the feature class inside gdb. Defaults to the stem of input_fc (the last path component without extension). For GDB sources such as C:/data.gdb/parcels the stem is "parcels"; for shapefiles such as path/parcels.shp it is also "parcels".

Returns

str: absolute path to the newly created feature class inside gdb.

Note

The source feature class is left unchanged. Use this at the top of execute to ingest inputs into the working geodatabase before further processing.

Examples

# Ingest under the original name
path = arcsmith.fc.to_gdb("C:/source/parcels.shp", gdb)
# "<gdb>/parcels"

# Ingest with a custom name
path = arcsmith.fc.to_gdb(input_fc, gdb, name="study_parcels")
arcsmith.layer.add(path, target_map)

# Resolve a toolbox parameter first, then ingest
src = arcsmith.param.to_path(parameters[0])
path = arcsmith.fc.to_gdb(src, gdb)

copy_w_fields

Copies a feature class to a new feature class, optionally filtering fields and rows in a single call.

copy_w_fields(input_fc, output_fc, fields=None, keep=True, where_clause=None)
Parameter Type Default Description
input_fc str or Path required Path to the source feature class.
output_fc str or Path required Full path for the output feature class, including workspace and name (e.g. "C:/data/results.gdb/clipped_parcels").
fields list of str None Field names to act on. When keep=True these are the fields to retain; all others are removed. When keep=False these are the fields to remove; all others are kept. Pass [] to copy geometry only. Default None (all fields copied).
keep bool True If True, fields specifies what to keep. If False, fields specifies what to drop. Ignored when fields is None.
where_clause str None SQL expression to filter rows. Use arcsmith.fc.build_where to construct a clause for a single field, or write one directly. Default None (all rows copied).

Returns

str: absolute path to the output feature class.

Raises

ValueError if any field name in fields does not exist in input_fc.

Note

Combines arcsmith.flds.build_field_map with arcpy.conversion.FeatureClassToFeatureClass. Use where_clause to filter rows at the same time as filtering fields, no intermediate feature class needed.

Multivalue field parameters

arcpy.Parameter.values on a multivalue Field parameter returns a list of ValueObjects, not strings. Extract string values before passing to arcsmith functions:

    fields = [str(f) for f in parameters[1].values] if parameters[1].values else None

Examples

# Copy all fields
out = arcsmith.fc.copy_w_fields(input_fc, "C:/data/results.gdb/parcels_full")

# Copy geometry only. No attribute fields
out = arcsmith.fc.copy_w_fields(input_fc, "C:/data/results.gdb/parcels_geom", fields=[])

# Keep only specific fields
out = arcsmith.fc.copy_w_fields(
    input_fc, "C:/data/results.gdb/parcels_slim",
    ["PARCEL_ID", "OWNER", "AREA_SQFT"],
)

# Drop a few fields and keep everything else
out = arcsmith.fc.copy_w_fields(
    input_fc, "C:/data/results.gdb/parcels_clean",
    ["TEMP_FLAG", "LEGACY_CODE"], keep=False,
)

# Filter fields and rows together
clause = arcsmith.fc.build_where(input_fc, "STATUS", "Active")
out = arcsmith.fc.copy_w_fields(
    input_fc, "C:/data/results.gdb/active_parcels",
    ["PARCEL_ID", "OWNER", "STATUS"],
    where_clause=clause,
)
arcsmith.layer.add(out, target_map)

validate_geom_type

Checks whether a feature class has the expected geometry type. Returns True if the geometry matches, False otherwise.

validate_geom_type(input_fc, expected_shape)
Parameter Type Default Description
input_fc str or Path required Path to the feature class to inspect.
expected_shape str or list of str required Geometry type(s) to accept. Case-insensitive. Common values: 'Point', 'Polyline', 'Polygon', 'Multipoint'. Pass a list to accept more than one type.

Returns

bool: True if the feature class geometry matches any entry in expected_shape, False otherwise.

Where to call this

Call validate_geom_type inside updateMessages to surface a clear error while the user is still configuring the tool, rather than letting an unexpected geometry type cause a cryptic failure partway through execute.

Examples

# Single accepted type
if not arcsmith.fc.validate_geom_type(input_fc, "Point"):
    arcpy.AddError("Input must be a point layer.")

# Multiple accepted types
if not arcsmith.fc.validate_geom_type(input_fc, ["Point", "Multipoint"]):
    arcpy.AddError("Input must be a point or multipoint layer.")


# Use inside updateMessages to set a parameter error message
def updateMessages(self, parameters):
    input_points = parameters[0]
    if input_points.value:
        fc_path = arcsmith.param.to_path(input_points)
        if not arcsmith.fc.validate_geom_type(fc_path, "Point"):
            input_points.setErrorMessage("Input must be a point layer.")