wiki:FAQVector

Version 14 (modified by ulysseous, 11 years ago) ( diff )

Added note about not having .shp at the end of file name so others can avoid my mistake.

FAQ - Vector

  1. How can I delete feature from Shapefile?
  2. How can I delete Shapefile?
  3. How can I merge hundreds of Shapefiles?
  4. How do I translate a mixed geometry file to shapefile format?
  5. How to quote command parameters for GDAL/OGR utilities in Microsoft Windows CLI
  6. How do I flip coordinates when they are not in the expected order

How can I delete feature from Shapefile?

This question was asked a few times on the mailing list, for instance here and here. It's recommended to look at these threads as they provide explanation on how to delete entries from Shapefile.

It is not possible to delete features from Shapefile using ogr2ogr utility.

In order to remove entries from Shapefile, you need to call OGRLayer::DeleteFeature() method, either directly from C++ program or using one of alternative interface like OGR C API or bindings to other programming languages.

How can I delete Shapefile?

Here is related thread on the mailing list.

Prior version 1.6 of GDAL/OGR it's only possible to remove Shapefile from filesystem using native API of user's operation system, for instance unlink() function from POSIX or DeleteFile() from Microsoft Windows API.

Since GDAL 1.6, it is possible to accomplish this task using OGRDataSource::DeleteLayer() method.

How can I merge hundreds of Shapefiles?

Here's a bash script to bulk load a directory of shapefiles that have the same schema to postgis. It could obviously be made smarter, but it seems to do the trick.

#!/bin/bash

# let OGR create a table from one of the files
ogr2ogr -f Postgresql PG:"host=smoke.hobu.net" -a_srs "EPSG:26915" -nln outputlayer first_input_shape.shp -overwrite -nlt POLYGON

# delete all the data in the table we just created (but don't delete the table)
ogrinfo PG:"host=smoke.hobu.net" -sql "delete  from outputlayer"

# loop through all of the shapefiles in the directory and load them
for i in $(ls *.shp); do
  ogr2ogr -f Postgresql PG:"host=smoke.hobu.net" -a_srs " EPSG:26915" -nln outputlayer $i -update -append -skipfailures
done 

*Note if you get an import error from postgis similiar to "ERROR: new row for relation "layer1" violates check constraint" you should try substituting "-nlt GEOMETRY" for your GEOMETRY TYPE (in the above example it is POLYGON). This will avoid errors if your shapefile includes both Polygon and Multipolygon geometries, for example. See this thread http://postgis.refractions.net/pipermail/postgis-users/2006-June/012495.html

These Unix shell steps illustrate how to batch merge multiple shapefiles into a single shapefile using OGR. This assumes you have downloaded a group of shapefiles in .zip format which are all the same type of data but just need to be combined. This works on a Mac but has not been test on other versions of UNIX:

#Make a new directory called "tmp" and a sub directory called "merged"
mkdir tmp
mkdir tmp/merged

#copy all zipped files to the "tmp" directory and then "cd" into it
cp *.zip tmp
cd tmp

#unzip all the .zip archives
find . -name "*.zip" -exec unzip '{}' \;

#delete all .zip archives
rm *.zip

#move a single shapefile (and the cooresponded .shx, .dbf, etc files) to the "merged" directory (exchange 'myshape*' for the name of one of your shapefiles keeping the '*' at the end of the name)
find . -name 'myshape*' -exec mv '{}' merged \;
 
#Batch merge all the remaining shapefiles from the tmp dir into the copied file in the merge dir (exchange 'myshape' for the name of the copied shapefile without the ".shp" at the end)
for i in $(ls *.shp); do ogr2ogr -f 'ESRI Shapefile' -update -append merged $i -nln myshape
done

This Windows cmd shell example merges multiple *wetlands*shapefiles in the current directory to a single merged\wetlands.shp (double % to put in a script, %f --> %%f):

mkdir merged
for %f in (*wetland*.shp) do (
  if not exist merged\wetlands.shp (
      ogr2ogr -f "esri shapefile" merged\wetlands.shp %f) else (
      ogr2ogr -f "esri shapefile" -update -append merged\wetlands.shp %f -nln Wetlands )
)

The trick is to use the first input to create a new shapefile, and thereafter only update and append. See the end of http://www.gdal.org/ogr/drv_shapefile.html

If you don't need to specify a human friendly name via -nln, using -append by itself is simpler:

 for %f in (dir1\*.shp dir2\*.shp) do (ogr2ogr -f "esri shapefile" -append merged %f)

How do I include the source filename in a field when merging hundreds of shapefiles (Windows)?

 for %f in (*.shp) do ogr2ogr -sql "select *, '%~nf' as s_file from %~nf" -update -append merged\output.shp %f -nln output

How do I translate a mixed geometry file to shapefile format?

Some formats (such as ESRI Shapefiles) only allow one type of geometry in a layer, while other formats (such as DGN, MapInfo, GML) allow a mixture of geometry types within a single layer. Direct attempts to translate result in errors like this:

% ogr2ogr out.shp mixed.dgn 
ERROR 1: Attempt to write non-linestring (POLYGON) geometry to ARC type shapefile.
ERROR 1: Terminating translation prematurely after failed
translation of layer elements

The first step in dealing with such a problem is to discover what geometry types exist in the source file. For a DGN file called mixed.dgn, with a layer called elements this can be accomplished using the following OGR SQL command (see OGR SQL tutorial for details):

% ogrinfo -ro mixed.dgn -sql 'select distinct ogr_geometry from elements'
INFO: Open of `mixed.dgn'
      using driver `DGN' successful.

Layer name: elements
Geometry: Unknown (any)
Feature Count: 1
Layer SRS WKT:
(unknown)
ogr_geometry: String (0.0)
OGRFeature(elements):0
  ogr_geometry (String) = LINESTRING

OGRFeature(elements):1
  ogr_geometry (String) = POLYGON

OGRFeature(elements):2
  ogr_geometry (String) = POINT

This file has point, line and polygon geometries. Each will need to be translated to a separate output file.

% ogr2ogr out_point.shp mixed.dgn -where 'ogr_geometry = "POINT"'
% ogr2ogr out_line.shp mixed.dgn -where 'ogr_geometry = "LINESTRING"'
% ogr2ogr out_poly.shp mixed.dgn -where 'ogr_geometry = "POLYGON"'

How to quote command parameters for GDAL/OGR utilities in Microsoft Windows CLI

When working with Windows CLI, it's helpful to remember that quoting rules are different to those used on Unix. Here is example of properly quoted SQL statement passed to ogrinfo (or ogr2ogr) with -sql option:

ogrinfo . -sql "SELECT * FROM 'B_Major Cities 1' WHERE FID = 49"

The whole SQL statement is wrapped with double quotes, but not single quotes. The name of table (here it works against ESRI Shapefile in current directory, note the dot) includes spaces, so it must be wrapped with single quotes.

For contrast, these two variants present incorrect command:

ogrinfo . -sql 'SELECT * FROM 'B_Major Cities 1' WHERE FID = 49'
ogrinfo . -sql 'SELECT * FROM "B_Major Cities 1" WHERE FID = 49'

How do I flip coordinates when they are not in the expected order

The EPSG has a recommanded order for geographic SRS where the coordinates tuples of a geometry must appear in the (latitude, longitude) order, whereas most GIS will properly display such geometries if they appear in the (longitude, latitude) order. This issue can be often encountered in situation with GML3 files, WFS 1.1 data, etc... that adhere to the (latitude, longitude) order.

When, for some reason, the coordinate order isn't the one that is wished, the following trick can be used to flip them :

ogr2ogr -s_srs "+proj=latlong +datum=WGS84 +axis=neu +wktext"
        -t_srs "+proj=latlong +datum=WGS84 +axis=enu +wktext" dest.shp source.shp

Note: this will work even if the SRS of your input data isn't using the WGS84 datum. The reason for the above magic incantation to work is that the values of -s_srs and -t_srs only differ by the value of the +axis parameter.

This trick might also be used for some projected SRS that have unusual axis order.

An alternative way of achieving the same result, providing using GDAL 2.0 compiled with Spatialite support to benefit from SQLite SQL dialect, is :

ogr2ogr -dialect SQLite -sql "SELECT SwapCoordinates(geometry) AS geometry, * FROM source" dest.shp source.shp
Note: See TracWiki for help on using the wiki.