2

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()

7
  • 1
    If you just need to sort the file and it does not need to be with Python you could use this MapServer utility mapserver.org/utilities/sortshp.html.
    – user30184
    Commented Feb 13, 2019 at 19:25
  • 1
    Load your records into a list and then use python's built-in sorting with a key function.
    – mikewatt
    Commented Feb 13, 2019 at 20:12
  • ogr2ogr can read/write shapefiles, it has a sql option you can issue an Order By to sort a shapefile. Not Python specific.
    – klewis
    Commented Feb 13, 2019 at 22:49
  • @klewis thanks for your suggestion. A combination of ogr2ogr and Python was what I finally decided to use. Thanks Commented Feb 14, 2019 at 11:33
  • I don't have that issue with the prj file, @LuisSP, maybe if you set the crs with shape.crs = {'init': 'epsg:4326'} or shape.to_file(crs={'init': 'epsg:4326'})
    – Jose
    Commented Feb 14, 2019 at 17:32

1 Answer 1

2

You can use geopandas, if you use pandas you will be familiar with this library:

import geopandas as gpd

shapefile_path = 'path_to_your_file/your_file.shp'
shape = gpd.read_file(shapefile_path)
shape_sorted = shape.iloc[shape['YOUR FIELD'].sort_values().index.values]
shape_sorted.to_file(driver='ESRI Shapefile', filename='output_file.shp')
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.