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.
| 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.
| 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.
| 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.
| 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.
| 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.
| 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:
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.
| 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.")