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

  • 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 Feb 13 at 19:25
  • 1
    Load your records into a list and then use python's built-in sorting with a key function. – mikewatt Feb 13 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 Feb 13 at 22:49
  • @klewis thanks for your suggestion. A combination of ogr2ogr and Python was what I finally decided to use. Thanks – Luis SP Feb 14 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 Feb 14 at 17:32
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')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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