What you are trying to do can indeed be done with Fiona and Shapely.
for this error:
SyntaxError: positional argument follows keyword argument
The problem is in your fiona.open
call here:
with fiona.open(r'C:\\Users\\Desktop\\GEM\20test\\counties\\counties2.shp' , 'w', 'ESRI Shapefile',output_schema, crs=input.epsg, 4326) as output:
You have 4326
in the function call after specifying crs=input.epsg
. Since you're specifying the CRS as the same as the input file, you don't need the 4326
there. This isn't an error with fiona necessarily but something that's not allowed in Python:
def my_func(thing1, thing2):
print(thing1, thing2)
my_func(thing1='hello', 'world')
SyntaxError: positional argument follows keyword argument
Alright, now to the meat of the issue. You want to "select" certain rows from your input shapefile. You can do that easily, you just need to look at the values of the columns you want to "select" using in each row of the shapefile. In fiona
, the records are converted to GeoJSON structure, so you can access attributes in the properties
member of the record. Imagine we have a shapefile of counties with three columns, the name, the fips, and the population, and we want to "select" the counties where population is greater than 100,000 people. We only want to write out the name and the population.
# open our input file
src = fiona.open('counties.shp')
# define the columns - by name - which we want to
# keep from the original file
keep_columns = ['name', 'population']
# create the output schema from the input
output_schema = src.schema.copy()
# create new properties schema without the columns we don't want
output_schema['properties'] = {column_name: typ for column_name, typ in output_schema['properties'].items() if column_name in keep_columns}
# Open output file
sink = fiona.open('counties_over_100k.shp', 'w', driver='Esri Shapefile', schema=output_schema, crs=src.crs)
for feature in src:
# check to see if this is a row we care about based
# on the value of a column
if feature['properties']['population'] > 100000:
# remove columns we don't need from the feature
feature['properties'] = {column_name: value for column_name, value in feature['properties'].items() if column_name in keep_columns}
sink.write(feature)
try
block is a great way to hide useful error messages. I suggest you remove thetry...except
and report the actual error encountered.