I'm writing a Python script where I have to read a Shapefile, sort its rows/records by a specific field, and then write a new shapefile with that new order.
Does anyone how can I do it?
I'm using Fiona to open the file but I can't find out how I can do an so easy and common operation as an ORDER BY.
EDIT
The solution proposed by @Jose works perfectly right. But geopandas doesn't create the .prj file that contains the projection description and this is a problem if you need it. A possible solution could be just copy the original file with the new name:
import os
import geopandas as gpd
def main(file, field):
output_file_name = os.path.splitext(file)[0] + '_sorted_by_' + field + os.path.splitext(file)[1]
shape = gpd.read_file(file)
shape_sorted = shape.iloc[shape[field].sort_values().index.values]
shape_sorted.to_file(driver='ESRI Shapefile', filename=output_file_name)
# Copy prj file
prj_file = os.path.splitext(file)[0] + '.prj'
if os.path.isfile(prj_file):
from shutil import copyfile
output_prj_file_name = os.path.splitext(file)[0] + '_sorted_by_' + field + '.prj'
copyfile(prj_file, output_prj_file_name)
Finally I decided to use a ogr2ogr command with -sql
argument and execute it in Python using os.system(command)
utility.
import os
def main(file, field):
output_file_name = os.path.splitext(file)[0] + '_sorted_by_' + field + os.path.splitext(file)[1]
file_object = os.path.splitext(os.path.basename(file))[0]
command = 'ogr2ogr -sql "SELECT * FROM ' + file_object + ' ORDER BY ' + field + '" ' + output_file_name + ' ' + file
os.system(command)
if __name__ == '__main__':
main()
shape.crs = {'init': 'epsg:4326'}
orshape.to_file(crs={'init': 'epsg:4326'})