from osgeo import ogr
import os
DriverName = "ESRI Shapefile" # e.g.: GeoJSON, ESRI Shapefile
FileName = 'test.shp'
driver = ogr.GetDriverByName(DriverName)
if os.path.exists(FileName):
driver.DeleteDataSource(FileName)
try:
from osgeo import ogr
print 'Import of ogr from osgeo worked. Hurray!\n'
except:
print 'Import of ogr from osgeo failed\n\n'
This code simply prints out the auto-generated help on the imported module. In this case it's OGR. This might not be the best way to scan the API's class methods. For a detailed description of the whole Python GDAL/OGR API, see the useful API docs.
import osgeo.ogr
print help(osgeo.ogr)
It's always driven me a little nuts that the command line ogr2ogr --formats returns a 'random' list of drivers. This code returns the list of OGR drivers alphabetically from A - Z. .
import ogr
cnt = ogr.GetDriverCount()
formatsList = [] # Empty List
for i in range(cnt):
driver = ogr.GetDriver(i)
driverName = driver.GetName()
if not driverName in formatsList:
formatsList.append(driverName)
formatsList.sort() # Sorting the messy list of ogr drivers
for i in formatsList:
print i
This code shows if a particular OGR driver is available. The exact names are the ones used on the OGR Vector Formats page in the "Code" column ([formats website]). This is the same names returned when you enter
ogrinfo --formats
on the command line.Code Example Source: [website]
from osgeo import ogr
## Shapefile available?
driverName = "ESRI Shapefile"
drv = ogr.GetDriverByName( driverName )
if drv is None:
print "%s driver not available.\n" % driverName
else:
print "%s driver IS available.\n" % driverName
## PostgreSQL available?
driverName = "PostgreSQL"
drv = ogr.GetDriverByName( driverName )
if drv is None:
print "%s driver not available.\n" % driverName
else:
print "%s driver IS available.\n" % driverName
## Is File GeoDatabase available?
driverName = "FileGDB"
drv = ogr.GetDriverByName( driverName )
if drv is None:
print "%s driver not available.\n" % driverName
else:
print "%s driver IS available.\n" % driverName
## SDE available?
driverName = "SDE"
drv = ogr.GetDriverByName( driverName )
if drv is None:
print "%s driver not available.\n" % driverName
else:
print "%s driver IS available.\n" % driverName
Use only the specified driver to attempt to read the data file, taking into account special nature of the CSV driver which normally requires a .csv extension.
Source, Luke Pinner on GIS Stack Exchange: [website]
import sys
from osgeo import ogr
def main(in_file, in_format, out_file, out_format):
if in_format == 'CSV' and in_file[-3:].lower() != 'csv':
in_file = 'CSV:' + in_file
in_ds = ogr.GetDriverByName(in_format).Open(in_file)
out_ds = ogr.GetDriverByName(out_format).CopyDataSource(in_ds, out_file)
if __name__ == '__main__':
main(*sys.argv[1:])
Usage:
python ogr-convert.py [in file] [format driver] [out file/dir] {out format}
python ogr-convert.py x:incomingcoolstuff.txt CSV d:shapefiles
This code example opens a shapefile and returns the number of features in it. Solution mined from: [web site]
import os
from osgeo import ogr
daShapefile = r"C:\Temp\Voting_Centers_and_Ballot_Sites.shp"
driver = ogr.GetDriverByName('ESRI Shapefile')
dataSource = driver.Open(daShapefile, 0) # 0 means read-only. 1 means writeable.
# Check to see if shapefile is found.
if dataSource is None:
print 'Could not open %s' % (daShapefile)
else:
print 'Opened %s' % (daShapefile)
layer = dataSource.GetLayer()
featureCount = layer.GetFeatureCount()
print "Number of features in %s: %d" % (os.path.basename(daShapefile),featureCount)
This returns all the layers in a database of your choosing sorted in alphabetical order (of course). Just fill in the missing information and it should work.
from osgeo import ogr
databaseServer = "<IP of database server OR Name of database server"
databaseName = "<Name of database>"
databaseUser = "<User name>"
databasePW = "<User password>"
connString = "PG: host=%s dbname=%s user=%s password=%s" %(databaseServer,databaseName,databaseUser,databasePW)
conn = ogr.Open(connString)
layerList = []
for i in conn:
daLayer = i.GetName()
if not daLayer in layerList:
layerList.append(daLayer)
layerList.sort()
for j in layerList:
print j
# Close connection
conn = None
This code example opens a postgis connection and gets the specified layer name if it exists in the database. Otherwise it throws a nice error message
from osgeo import ogr
import sys
databaseServer = "<IP of database server OR Name of database server"
databaseName = "<Name of database>"
databaseUser = "<User name>"
databasePW = "<User password>"
connString = "PG: host=%s dbname=%s user=%s password=%s" % (databaseServer,databaseName,databaseUser,databasePW)
def GetPGLayer( lyr_name ):
conn = ogr.Open(connString)
lyr = conn.GetLayer( lyr_name )
if lyr is None:
print >> sys.stderr, '[ ERROR ]: layer name = "%s" could not be found in database "%s"' % ( lyr_name, databaseName )
sys.exit( 1 )
featureCount = lyr.GetFeatureCount()
print "Number of features in %s: %d" % ( lyr_name , featureCount )
# Close connection
conn = None
if __name__ == '__main__':
if len( sys.argv ) < 2:
print >> sys.stderr, '[ ERROR ]: you must pass at least one argument -- the layer name argument'
sys.exit( 1 )
lyr_name = sys.argv[1]
GetPGLayer( lyr_name )
This returns all the layers in a Esri FileGDB in alphabetical order (of course). It needs GDAL/OGR 1.11.0 + but not any Esri dependency. That's the benefit of the OpenFileGDB driver developed by Ewen Rouault relative to the FileGDB driver.
# standard imports
import sys
# import OGR
from osgeo import ogr
# use OGR specific exceptions
ogr.UseExceptions()
# get the driver
driver = ogr.GetDriverByName("OpenFileGDB")
# opening the FileGDB
try:
gdb = driver.Open(gdb_path, 0)
except Exception, e:
print e
sys.exit()
# list to store layers'names
featsClassList = []
# parsing layers by index
for featsClass_idx in range(gdb.GetLayerCount()):
featsClass = gdb.GetLayerByIndex(featsClass_idx)
featsClassList.append(featsClass.GetName())
# sorting
featsClassList.sort()
# printing
for featsClass in featsClassList:
print featsClass
# clean close
del gdb
This illustrates how to copy a dataset to memory with write access, providing fast data access.
from osgeo import ogr
#open an input datasource
indriver=ogr.GetDriverByName('SQLite')
srcdb = indriver.Open('OUTDATA.sqlite',0)
#create an output datasource in memory
outdriver=ogr.GetDriverByName('MEMORY')
source=outdriver.CreateDataSource('memData')
#open the memory datasource with write access
tmp=outdriver.Open('memData',1)
#copy a layer to memory
pipes_mem=source.CopyLayer(srcdb.GetLayer('pipes'),'pipes',['OVERWRITE=YES'])
#the new layer can be directly accessed via the handle pipes_mem or as source.GetLayer('pipes'):
layer=source.GetLayer('pipes')
for feature in layer:
feature.SetField('SOMETHING',1)
from osgeo import ogr
import os
shapefile = "states.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
for feature in layer:
print feature.GetField("STATE_NAME")
layer.ResetReading()
You must call ResetReading if you want to start iterating over the layer again.
from osgeo import ogr
import os
shapefile = "states.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
for feature in layer:
geom = feature.GetGeometryRef()
print geom.Centroid().ExportToWkt()
from osgeo import ogr
import os
shapefile = "states.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
layer.SetAttributeFilter("SUB_REGION = 'Pacific'")
for feature in layer:
print feature.GetField("STATE_NAME")
from osgeo import ogr
import os
shapefile = "states.shp"
driver = ogr.GetDriverByName("ESRI Shapefile")
dataSource = driver.Open(shapefile, 0)
layer = dataSource.GetLayer()
wkt = "POLYGON ((-103.81402655265633 50.253951270672125,-102.94583419409656 51.535568561879401,-100.34125711841725 51.328856095555651,-100.34125711841725 51.328856095555651,-93.437060743203844 50.460663736995883,-93.767800689321859 46.450441890315041,-94.635993047881612 41.613370178339181,-100.75468205106476 41.365315218750681,-106.12920617548238 42.564247523428456,-105.96383620242338 47.277291755610058,-103.81402655265633 50.253951270672125))"
layer.SetSpatialFilter(ogr.CreateGeometryFromWkt(wkt))
for feature in layer:
print feature.GetField("STATE_NAME")
This code example returns the field names of the user defined (created) fields.
from osgeo import ogr
daShapefile = r"C:\Temp\Voting_Centers_and_Ballot_Sites.shp"
dataSource = ogr.Open(daShapefile)
daLayer = dataSource.GetLayer(0)
layerDefinition = daLayer.GetLayerDefn()
for i in range(layerDefinition.GetFieldCount()):
print layerDefinition.GetFieldDefn(i).GetName()
This code example returns the field names of the user defined (created) fields and the data types they are.
from osgeo import ogr
daShapefile = r"C:\Temp\iDay\CWI_Wetlands.shp"
dataSource = ogr.Open(daShapefile)
daLayer = dataSource.GetLayer(0)
layerDefinition = daLayer.GetLayerDefn()
print "Name - Type Width Precision"
for i in range(layerDefinition.GetFieldCount()):
fieldName = layerDefinition.GetFieldDefn(i).GetName()
fieldTypeCode = layerDefinition.GetFieldDefn(i).GetType()
fieldType = layerDefinition.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode)
fieldWidth = layerDefinition.GetFieldDefn(i).GetWidth()
GetPrecision = layerDefinition.GetFieldDefn(i).GetPrecision()
print fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)
This code example returns the field names of the user defined (created) fields.
from osgeo import ogr
import sys
databaseServer = "<IP of database server OR Name of database server"
databaseName = "<Name of database>"
databaseUser = "<User name>"
databasePW = "<User password>"
connString = "PG: host=%s dbname=%s user=%s password=%s" %(databaseServer,databaseName,databaseUser,databasePW)
def GetPGLayerFields( lyr_name ):
conn = ogr.Open(connString)
lyr = conn.GetLayer( lyr_name )
if lyr is None:
print >> sys.stderr, '[ ERROR ]: layer name = "%s" could not be found in database "%s"' % ( lyr_name, databaseName )
sys.exit( 1 )
lyrDefn = lyr.GetLayerDefn()
for i in range( lyrDefn.GetFieldCount() ):
print lyrDefn.GetFieldDefn( i ).GetName()
# Close connection
conn = None
if __name__ == '__main__':
if len( sys.argv ) < 2:
print >> sys.stderr, '[ ERROR ]: you must pass at least one argument -- the layer name argument'
sys.exit( 1 )
lyr_name = sys.argv[1]
GetPGLayerFields( lyr_name )
This code example returns the field names of the user defined (created) fields and the data types they are.
from osgeo import ogr
import sys
databaseServer = "<IP of database server OR Name of database server"
databaseName = "<Name of database>"
databaseUser = "<User name>"
databasePW = "<User password>"
connString = "PG: host=%s dbname=%s user=%s password=%s" %(databaseServer,databaseName,databaseUser,databasePW)
def GetPGLayerFieldTypes( lyr_name ):
conn = ogr.Open(connString)
lyr = conn.GetLayer( lyr_name )
if lyr is None:
print >> sys.stderr, '[ ERROR ]: layer name = "%s" could not be found in database "%s"' % ( lyr_name, databaseName )
sys.exit( 1 )
lyrDefn = lyr.GetLayerDefn()
for i in range( lyrDefn.GetFieldCount() ):
fieldName = lyrDefn.GetFieldDefn(i).GetName()
fieldTypeCode = lyrDefn.GetFieldDefn(i).GetType()
fieldType = lyrDefn.GetFieldDefn(i).GetFieldTypeName(fieldTypeCode)
fieldWidth = lyrDefn.GetFieldDefn(i).GetWidth()
GetPrecision = lyrDefn.GetFieldDefn(i).GetPrecision()
print fieldName + " - " + fieldType+ " " + str(fieldWidth) + " " + str(GetPrecision)
# Close connection
conn = None
if __name__ == '__main__':
if len( sys.argv ) < 2:
print >> sys.stderr, '[ ERROR ]: you must pass at least one argument -- the layer name argument'
sys.exit( 1 )
lyr_name = sys.argv[1]
GetPGLayerFieldTypes( lyr_name )
from osgeo import ogr
ds = ogr.Open("states.shp",0)
layer = ds.GetLayer()
capabilities = [
ogr.OLCRandomRead,
ogr.OLCSequentialWrite,
ogr.OLCRandomWrite,
ogr.OLCFastSpatialFilter,
ogr.OLCFastFeatureCount,
ogr.OLCFastGetExtent,
ogr.OLCCreateField,
ogr.OLCDeleteField,
ogr.OLCReorderFields,
ogr.OLCAlterFieldDefn,
ogr.OLCTransactions,
ogr.OLCDeleteFeature,
ogr.OLCFastSetNextByIndex,
ogr.OLCStringsAsUTF8,
ogr.OLCIgnoreFields
]
print("Layer Capabilities:")
for cap in capabilities:
print(" %s = %s" % (cap, layer.TestCapability(cap)))
This recipe queries a WFS services and fetches features from a large layer. It sets up the GDAL configuration to using WFS paging if it is supported.
import sys
try:
from osgeo import ogr, osr, gdal
except:
sys.exit('ERROR: cannot find GDAL/OGR modules')
# Set the driver (optional)
wfs_drv = ogr.GetDriverByName('WFS')
# Speeds up querying WFS capabilities for services with alot of layers
gdal.SetConfigOption('OGR_WFS_LOAD_MULTIPLE_LAYER_DEFN', 'NO')
# Set config for paging. Works on WFS 2.0 services and WFS 1.0 and 1.1 with some other services.
gdal.SetConfigOption('OGR_WFS_PAGING_ALLOWED', 'YES')
gdal.SetConfigOption('OGR_WFS_PAGE_SIZE', '10000')
# Open the webservice
url = 'http://example-service.com/wfs'
wfs_ds = wfs_drv.Open('WFS:' + url)
if not wfs_ds:
sys.exit('ERROR: can not open WFS datasource')
else:
pass
# iterate over available layers
for i in range(wfs_ds.GetLayerCount()):
layer = wfs_ds.GetLayerByIndex(i)
srs = layer.GetSpatialRef()
print 'Layer: %s, Features: %s, SR: %s...' % (layer.GetName(), layer.GetFeatureCount(), srs.ExportToWkt()[0:50])
# iterate over features
feat = layer.GetNextFeature()
while feat is not None:
feat = layer.GetNextFeature()
# do something more..
feat = None
# Get a specific layer
layer = wfs_ds.GetLayerByName("largelayer")
if not layer:
sys.exit('ERROR: can not find layer in service')
else:
pass
This recipe sets options for a HTTP proxy service that using NTLM authentication (typical for corporate environments that using Active directory for single sign-on proxy support). More information about the GDAL HTTP proxy options can be found here
import sys
try:
from osgeo import ogr, osr, gdal
except:
sys.exit('ERROR: cannot find GDAL/OGR modules')
server = 'proxy.example.com'
port = 3128
# specify proxy server
gdal.SetConfigOption('GDAL_HTTP_PROXY', server + ':' + port)
# setup proxy authentication option for NTLM with no username or password so single sign-on works
gdal.SetConfigOption('GDAL_PROXY_AUTH', 'NTLM')
gdal.SetConfigOption('GDAL_HTTP_PROXYUSERPWD', ' : ')
# now fetch a HTTP datasource and do something...
ds = ogr.Open('http://featureserver/cities/.geojson')
if not ds:
sys.exit('ERROR: can not open GeoJSON datasource')
lyr = ds.GetLayer('OGRGeoJSON')
for feat in lyr:
geom = feat.GetGeometryRef()
print geom.ExportToWkt()
GDAL/OGR has a Virtual Format spec that allows you to derive layers from flat tables such as a CSV -- it does a lot more than that too so go read about it. In the example below we are reading in a CSV with X,Y columns and values. That CSV file is wrapped by an XML file that describes it as an OGR layer. Below are all the necessary pieces and a script that reads the XML file and prints out point geometries.
Our CSV file named example.csv looks like this:
ID,X,Y
1,-127.234343,47.234325
2,-127.003243,46.234343
3,-127.345646,45.234324
4,-126.234324,44.324234
Our OGRVRTLayer XML file called example_wrapper.vrt looks like this:
<OGRVRTDataSource>
<OGRVRTLayer name="example">
<SrcDataSource>example.csv</SrcDataSource>
<SrcLayer>example</SrcLayer>
<GeometryType>wkbPoint</GeometryType>
<LayerSRS>WGS84</LayerSRS>
<GeometryField encoding="PointFromColumns" x="X" y="Y"/>
</OGRVRTLayer>
</OGRVRTDataSource>
Now let's print out the point geometries:
from osgeo import ogr
ogr.UseExceptions()
inDataSource = ogr.Open("example_wrapper.vrt")
lyr = inDataSource.GetLayer('example')
for feat in lyr:
geom = feat.GetGeometryRef()
print geom.ExportToWkt()
from osgeo import ogr
import os
# Get a Layer's Extent
inShapefile = "states.shp"
inDriver = ogr.GetDriverByName("ESRI Shapefile")
inDataSource = inDriver.Open(inShapefile, 0)
inLayer = inDataSource.GetLayer()
extent = inLayer.GetExtent()
# Create a Polygon from the extent tuple
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(extent[0],extent[2])
ring.AddPoint(extent[1], extent[2])
ring.AddPoint(extent[1], extent[3])
ring.AddPoint(extent[0], extent[3])
ring.AddPoint(extent[0],extent[2])
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)
# Save extent to a new Shapefile
outShapefile = "states_extent.shp"
outDriver = ogr.GetDriverByName("ESRI Shapefile")
# Remove output shapefile if it already exists
if os.path.exists(outShapefile):
outDriver.DeleteDataSource(outShapefile)
# Create the output shapefile
outDataSource = outDriver.CreateDataSource(outShapefile)
outLayer = outDataSource.CreateLayer("states_extent", geom_type=ogr.wkbPolygon)
# Add an ID field
idField = ogr.FieldDefn("id", ogr.OFTInteger)
outLayer.CreateField(idField)
# Create the feature and set values
featureDefn = outLayer.GetLayerDefn()
feature = ogr.Feature(featureDefn)
feature.SetGeometry(poly)
feature.SetField("id", 1)
outLayer.CreateFeature(feature)
feature = None
# Save and close DataSource
inDataSource = None
outDataSource = None
from osgeo import ogr
import os
# Get a Layer
inShapefile = "states.shp"
inDriver = ogr.GetDriverByName("ESRI Shapefile")
inDataSource = inDriver.Open(inShapefile, 0)
inLayer = inDataSource.GetLayer()
# Collect all Geometry
geomcol = ogr.Geometry(ogr.wkbGeometryCollection)
for feature in inLayer:
geomcol.AddGeometry(feature.GetGeometryRef())
# Calculate convex hull
convexhull = geomcol.ConvexHull()
# Save extent to a new Shapefile
outShapefile = "states_convexhull.shp"
outDriver = ogr.GetDriverByName("ESRI Shapefile")
# Remove output shapefile if it already exists
if os.path.exists(outShapefile):
outDriver.DeleteDataSource(outShapefile)
# Create the output shapefile
outDataSource = outDriver.CreateDataSource(outShapefile)
outLayer = outDataSource.CreateLayer("states_convexhull", geom_type=ogr.wkbPolygon)
# Add an ID field
idField = ogr.FieldDefn("id", ogr.OFTInteger)
outLayer.CreateField(idField)
# Create the feature and set values
featureDefn = outLayer.GetLayerDefn()
feature = ogr.Feature(featureDefn)
feature.SetGeometry(convexhull)
feature.SetField("id", 1)
outLayer.CreateFeature(feature)
feature = None
# Save and close DataSource
inDataSource = None
outDataSource = None
Inspired by: http://www.kralidis.ca/blog/2010/04/28/batch-centroid-calculations-with-python-and-ogr/
from osgeo import ogr
import os
# Get the input Layer
inShapefile = "states.shp"
inDriver = ogr.GetDriverByName("ESRI Shapefile")
inDataSource = inDriver.Open(inShapefile, 0)
inLayer = inDataSource.GetLayer()
# Create the output Layer
outShapefile = "states_centroids.shp"
outDriver = ogr.GetDriverByName("ESRI Shapefile")
# Remove output shapefile if it already exists
if os.path.exists(outShapefile):
outDriver.DeleteDataSource(outShapefile)
# Create the output shapefile
outDataSource = outDriver.CreateDataSource(outShapefile)
outLayer = outDataSource.CreateLayer("states_centroids", geom_type=ogr.wkbPoint)
# Add input Layer Fields to the output Layer
inLayerDefn = inLayer.GetLayerDefn()
for i in range(0, inLayerDefn.GetFieldCount()):
fieldDefn = inLayerDefn.GetFieldDefn(i)
outLayer.CreateField(fieldDefn)
# Get the output Layer's Feature Definition
outLayerDefn = outLayer.GetLayerDefn()
# Add features to the ouput Layer
for i in range(0, inLayer.GetFeatureCount()):
# Get the input Feature
inFeature = inLayer.GetFeature(i)
# Create output Feature
outFeature = ogr.Feature(outLayerDefn)
# Add field values from input Layer
for i in range(0, outLayerDefn.GetFieldCount()):
outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(), inFeature.GetField(i))
# Set geometry as centroid
geom = inFeature.GetGeometryRef()
inFeature = None
centroid = geom.Centroid()
outFeature.SetGeometry(centroid)
# Add new feature to output Layer
outLayer.CreateFeature(outFeature)
outFeature = None
# Save and close DataSources
inDataSource = None
outDataSource = None
This recipe parses a delimited text file of volcano location data and creates a shapefile.
The CSV file volcano_data.txt
contains the following fields, separated by a tab character (\t):
- Name
- Region
- Latitude
- Longitude
- Elevation
Taken from The Geospatial Desktop book.
# Parse a delimited text file of volcano data and create a shapefile
import osgeo.ogr as ogr
import osgeo.osr as osr
# use a dictionary reader so we can access by field name
reader = csv.DictReader(open("volcano_data.txt","rb"),
delimiter='\t',
quoting=csv.QUOTE_NONE)
# set up the shapefile driver
driver = ogr.GetDriverByName("ESRI Shapefile")
# create the data source
data_source = driver.CreateDataSource("volcanoes.shp")
# create the spatial reference, WGS84
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
# create the layer
layer = data_source.CreateLayer("volcanoes", srs, ogr.wkbPoint)
# Add the fields we're interested in
field_name = ogr.FieldDefn("Name", ogr.OFTString)
field_name.SetWidth(24)
layer.CreateField(field_name)
field_region = ogr.FieldDefn("Region", ogr.OFTString)
field_region.SetWidth(24)
layer.CreateField(field_region)
layer.CreateField(ogr.FieldDefn("Latitude", ogr.OFTReal))
layer.CreateField(ogr.FieldDefn("Longitude", ogr.OFTReal))
layer.CreateField(ogr.FieldDefn("Elevation", ogr.OFTInteger))
# Process the text file and add the attributes and features to the shapefile
for row in reader:
# create the feature
feature = ogr.Feature(layer.GetLayerDefn())
# Set the attributes using the values from the delimited text file
feature.SetField("Name", row['Name'])
feature.SetField("Region", row['Region'])
feature.SetField("Latitude", row['Latitude'])
feature.SetField("Longitude", row['Longitude'])
feature.SetField("Elevation", row['Elev'])
# create the WKT for the feature using Python string formatting
wkt = "POINT(%f %f)" % (float(row['Longitude']) , float(row['Latitude']))
# Create the point from the Well Known Txt
point = ogr.CreateGeometryFromWkt(wkt)
# Set the feature geometry using the point
feature.SetGeometry(point)
# Create the feature in the layer (shapefile)
layer.CreateFeature(feature)
# Dereference the feature
feature = None
# Save and close the data source
data_source = None
This recipe creates a new table in an existing PostGIS database.
import ogr, osr
database = 'test'
usr = 'postgres'
pw = ''
table = 'test'
wkt = "POINT (1120351.5712494177 741921.4223245403)"
point = ogr.CreateGeometryFromWkt(wkt)
connectionString = "PG:dbname='%s' user='%s' password='%s'" % (database,usr,pw)
ogrds = ogr.Open(connectionString)
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
layer = ogrds.CreateLayer(table, srs, ogr.wkbPoint, ['OVERWRITE=YES'] )
layerDefn = layer.GetLayerDefn()
feature = ogr.Feature(layerDefn)
feature.SetGeometry(point)
layer.StartTransaction()
layer.CreateFeature(feature)
feature = None
layer.CommitTransaction()
The ogr2ogr command line tool is an easy way to filter, reproject and trim columns in a shapefile. The workflow below shows how we can approximate the following ogr2ogr command with the OGR api using a decently large parcel shapefile from King County GIS .
#
# this command says read in "parcel_address.shp" and write out to "junkmob.shp"
# where "MINOR" column = 'HYDR' value and only output the "PIN" column
#
$ ogr2ogr -f "ESRI Shapefile" junkmob.shp -select pin -where "minor = 'HYDR'" parcel_address.shp
from osgeo import ogr
import os, sys
def main( field_name_target ):
# Get the input Layer
inShapefile = "~/DATA/SHAPES/KC_ADMIN/parcel_address/parcel_address.shp"
inDriver = ogr.GetDriverByName("ESRI Shapefile")
inDataSource = inDriver.Open(inShapefile, 0)
inLayer = inDataSource.GetLayer()
inLayer.SetAttributeFilter("minor = 'HYDR'")
# Create the output LayerS
outShapefile = os.path.join( os.path.split( inShapefile )[0], "ogr_api_filter.shp" )
outDriver = ogr.GetDriverByName("ESRI Shapefile")
# Remove output shapefile if it already exists
if os.path.exists(outShapefile):
outDriver.DeleteDataSource(outShapefile)
# Create the output shapefile
outDataSource = outDriver.CreateDataSource(outShapefile)
out_lyr_name = os.path.splitext( os.path.split( outShapefile )[1] )[0]
outLayer = outDataSource.CreateLayer( out_lyr_name, geom_type=ogr.wkbMultiPolygon )
# Add input Layer Fields to the output Layer if it is the one we want
inLayerDefn = inLayer.GetLayerDefn()
for i in range(0, inLayerDefn.GetFieldCount()):
fieldDefn = inLayerDefn.GetFieldDefn(i)
fieldName = fieldDefn.GetName()
if fieldName not in field_name_target:
continue
outLayer.CreateField(fieldDefn)
# Get the output Layer's Feature Definition
outLayerDefn = outLayer.GetLayerDefn()
# Add features to the ouput Layer
for inFeature in inLayer:
# Create output Feature
outFeature = ogr.Feature(outLayerDefn)
# Add field values from input Layer
for i in range(0, outLayerDefn.GetFieldCount()):
fieldDefn = outLayerDefn.GetFieldDefn(i)
fieldName = fieldDefn.GetName()
if fieldName not in field_name_target:
continue
outFeature.SetField(outLayerDefn.GetFieldDefn(i).GetNameRef(),
inFeature.GetField(i))
# Set geometry as centroid
geom = inFeature.GetGeometryRef()
outFeature.SetGeometry(geom.Clone())
# Add new feature to output Layer
outLayer.CreateFeature(outFeature)
outFeature = None
# Save and close DataSources
inDataSource = None
outDataSource = None
if __name__ == '__main__':
if len( sys.argv ) < 2:
print "[ ERROR ]: you need to pass at least one arg -- the field_names to include in output"
sys.exit(1)
main( sys.argv[1:] )
This recipe merges OGR Layers within a directory. Files can be specfied based on with what they start and end.
import os, ogr, osr
outputMergefn = 'merge.shp'
directory = "/Users/UserName/Downloads/"
fileStartsWith = 'test'
fileEndsWith = '.shp'
driverName = 'ESRI Shapefile'
geometryType = ogr.wkbPolygon
out_driver = ogr.GetDriverByName( driverName )
if os.path.exists(outputMergefn):
out_driver.DeleteDataSource(outputMergefn)
out_ds = out_driver.CreateDataSource(outputMergefn)
out_layer = out_ds.CreateLayer(outputMergefn, geom_type=geometryType)
fileList = os.listdir(directory)
for file in fileList:
if file.startswith(fileStartsWith) and file.endswith(fileEndsWith):
print file
ds = ogr.Open(directory+file)
lyr = ds.GetLayer()
for feat in lyr:
out_feat = ogr.Feature(out_layer.GetLayerDefn())
out_feat.SetGeometry(feat.GetGeometryRef().Clone())
out_layer.CreateFeature(out_feat)
out_feat = None
out_layer.SyncToDisk()
This recipe takes in an OSM file and prints a list of all the names of the streets in the file.
import ogr
ds = ogr.Open('map.osm')
layer = ds.GetLayer(1) # layer 1 for ways
nameList = []
for feature in layer:
if feature.GetField("highway") != None: # only streets
name = feature.GetField("name")
if name != None and name not in nameList: # only streets that have a name and are not yet in the list
nameList.append(name)
print nameList
This recipe creates a fishnet grid.
python grid.py grid.shp 992325.66 1484723.41 494849.32 781786.14 10000 10000
import os, sys
import ogr
from math import ceil
def main(outputGridfn,xmin,xmax,ymin,ymax,gridHeight,gridWidth):
# convert sys.argv to float
xmin = float(xmin)
xmax = float(xmax)
ymin = float(ymin)
ymax = float(ymax)
gridWidth = float(gridWidth)
gridHeight = float(gridHeight)
# get rows
rows = ceil((ymax-ymin)/gridHeight)
# get columns
cols = ceil((xmax-xmin)/gridWidth)
# start grid cell envelope
ringXleftOrigin = xmin
ringXrightOrigin = xmin + gridWidth
ringYtopOrigin = ymax
ringYbottomOrigin = ymax-gridHeight
# create output file
outDriver = ogr.GetDriverByName('ESRI Shapefile')
if os.path.exists(outputGridfn):
os.remove(outputGridfn)
outDataSource = outDriver.CreateDataSource(outputGridfn)
outLayer = outDataSource.CreateLayer(outputGridfn,geom_type=ogr.wkbPolygon )
featureDefn = outLayer.GetLayerDefn()
# create grid cells
countcols = 0
while countcols < cols:
countcols += 1
# reset envelope for rows
ringYtop = ringYtopOrigin
ringYbottom =ringYbottomOrigin
countrows = 0
while countrows < rows:
countrows += 1
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(ringXleftOrigin, ringYtop)
ring.AddPoint(ringXrightOrigin, ringYtop)
ring.AddPoint(ringXrightOrigin, ringYbottom)
ring.AddPoint(ringXleftOrigin, ringYbottom)
ring.AddPoint(ringXleftOrigin, ringYtop)
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)
# add new geom to layer
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(poly)
outLayer.CreateFeature(outFeature)
outFeature = None
# new envelope for next poly
ringYtop = ringYtop - gridHeight
ringYbottom = ringYbottom - gridHeight
# new envelope for next poly
ringXleftOrigin = ringXleftOrigin + gridWidth
ringXrightOrigin = ringXrightOrigin + gridWidth
# Save and close DataSources
outDataSource = None
if __name__ == "__main__":
#
# example run : $ python grid.py <full-path><output-shapefile-name>.shp xmin xmax ymin ymax gridHeight gridWidth
#
if len( sys.argv ) != 8:
print "[ ERROR ] you must supply seven arguments: output-shapefile-name.shp xmin xmax ymin ymax gridHeight gridWidth"
sys.exit( 1 )
main( sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5], sys.argv[6], sys.argv[7] )
This recipe converts a poylgon shapefile to a line shapefile
import ogr, os
def poly2line(input_poly,output_line):
source_ds = ogr.Open(input_poly)
source_layer = source_ds.GetLayer()
# polygon2geometryCollection
geomcol = ogr.Geometry(ogr.wkbGeometryCollection)
for feat in source_layer:
geom = feat.GetGeometryRef()
ring = geom.GetGeometryRef(0)
geomcol.AddGeometry(ring)
# geometryCollection2shp
shpDriver = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists(output_line):
shpDriver.DeleteDataSource(output_line)
outDataSource = shpDriver.CreateDataSource(output_line)
outLayer = outDataSource.CreateLayer(output_line, geom_type=ogr.wkbMultiLineString)
featureDefn = outLayer.GetLayerDefn()
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(geomcol)
outLayer.CreateFeature(outFeature)
outFeature = None
def main(input_poly,output_line):
poly2line(input_poly,output_line)
if __name__ == "__main__":
input_poly = 'test_polygon.shp'
output_line = 'test_line.shp'
main(input_poly,output_line)
This recipe creates a new shapefiles, adds a point to it, and adds a attribute column with a value to it.
import ogr, os
# Input data
pointCoord = -124.4577,48.0135
fieldName = 'test'
fieldType = ogr.OFTString
fieldValue = 'test'
outSHPfn = 'test.shp'
# Create the output shapefile
shpDriver = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists(outSHPfn):
shpDriver.DeleteDataSource(outSHPfn)
outDataSource = shpDriver.CreateDataSource(outSHPfn)
outLayer = outDataSource.CreateLayer(outSHPfn, geom_type=ogr.wkbPoint )
#create point geometry
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(pointCoord[0],pointCoord[1])
# create a field
idField = ogr.FieldDefn(fieldName, fieldType)
outLayer.CreateField(idField)
# Create the feature and set values
featureDefn = outLayer.GetLayerDefn()
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(point)
outFeature.SetField(fieldName, fieldValue)
outLayer.CreateFeature(outFeature)
outFeature = None
This recipe buffers features of a layer and saves them to a new Layer
import ogr, os
def createBuffer(inputfn, outputBufferfn, bufferDist):
inputds = ogr.Open(inputfn)
inputlyr = inputds.GetLayer()
shpdriver = ogr.GetDriverByName('ESRI Shapefile')
if os.path.exists(outputBufferfn):
shpdriver.DeleteDataSource(outputBufferfn)
outputBufferds = shpdriver.CreateDataSource(outputBufferfn)
bufferlyr = outputBufferds.CreateLayer(outputBufferfn, geom_type=ogr.wkbPolygon)
featureDefn = bufferlyr.GetLayerDefn()
for feature in inputlyr:
ingeom = feature.GetGeometryRef()
geomBuffer = ingeom.Buffer(bufferDist)
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(geomBuffer)
bufferlyr.CreateFeature(outFeature)
outFeature = None
def main(inputfn, outputBufferfn, bufferDist):
createBuffer(inputfn, outputBufferfn, bufferDist)
if __name__ == "__main__":
inputfn = 'test.shp'
outputBufferfn = 'testBuffer.shp'
bufferDist = 10.0
main(inputfn, outputBufferfn, bufferDist)
This recipe converts a vector layer to an array.
[[0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0]
[0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0]
[0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0]
[0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0]
[0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0]
[0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0]
[0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0]
[0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0]
[0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0]
[0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0]]
import ogr, gdal
vector_fn = 'test.shp'
# Define pixel_size and NoData value of new raster
pixel_size = 25
NoData_value = 255
# Open the data source and read in the extent
source_ds = ogr.Open(vector_fn)
source_layer = source_ds.GetLayer()
source_srs = source_layer.GetSpatialRef()
x_min, x_max, y_min, y_max = source_layer.GetExtent()
# Create the destination data source
x_res = int((x_max - x_min) / pixel_size)
y_res = int((y_max - y_min) / pixel_size)
target_ds = gdal.GetDriverByName('MEM').Create('', x_res, y_res, gdal.GDT_Byte)
target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size))
band = target_ds.GetRasterBand(1)
band.SetNoDataValue(NoData_value)
# Rasterize
gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[1])
# Read as array
array = band.ReadAsArray()
print array
This recipe converts a polygon to points.
import ogr, gdal
import numpy as np
import os
polygon_fn = 'test_polygon.shp'
# Define pixel_size which equals distance betweens points
pixel_size = 10
# Open the data source and read in the extent
source_ds = ogr.Open(polygon_fn)
source_layer = source_ds.GetLayer()
x_min, x_max, y_min, y_max = source_layer.GetExtent()
# Create the destination data source
x_res = int((x_max - x_min) / pixel_size)
y_res = int((y_max - y_min) / pixel_size)
target_ds = gdal.GetDriverByName('GTiff').Create('temp.tif', x_res, y_res, gdal.GDT_Byte)
target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size))
band = target_ds.GetRasterBand(1)
band.SetNoDataValue(255)
# Rasterize
gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[1])
# Read as array
array = band.ReadAsArray()
raster = gdal.Open('temp.tif')
geotransform = raster.GetGeoTransform()
# Convert array to point coordinates
count = 0
roadList = np.where(array == 1)
multipoint = ogr.Geometry(ogr.wkbMultiPoint)
for indexY in roadList[0]:
indexX = roadList[1][count]
geotransform = raster.GetGeoTransform()
originX = geotransform[0]
originY = geotransform[3]
pixelWidth = geotransform[1]
pixelHeight = geotransform[5]
Xcoord = originX+pixelWidth*indexX
Ycoord = originY+pixelHeight*indexY
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(Xcoord, Ycoord)
multipoint.AddGeometry(point)
count += 1
# Write point coordinates to Shapefile
shpDriver = ogr.GetDriverByName("ESRI Shapefile")
if os.path.exists('points.shp'):
shpDriver.DeleteDataSource('points.shp')
outDataSource = shpDriver.CreateDataSource('points.shp')
outLayer = outDataSource.CreateLayer('points.shp', geom_type=ogr.wkbMultiPoint)
featureDefn = outLayer.GetLayerDefn()
outFeature = ogr.Feature(featureDefn)
outFeature.SetGeometry(multipoint)
outLayer.CreateFeature(outFeature)
outFeature = None
# Remove temporary files
os.remove('temp.tif')