Reprojection

While reprojection is less common these days because of more advanced methods of data distribution, sometimes you do need to reproject a shapefile. The pure Python utm module works for reference system conversion, but for a full reprojection we need some help from the OGR Python API. The OGR API contained in the osgeo module has the Open Spatial Reference module, also known as osr, which we'll use for reprojection.

As an example, we'll use a point shapefile containing New York City museum and gallery locations in the Lambert conformal projection. We'll reproject it to WGS84 geographic (or unproject it rather). You can download this zipped shapefile at http://git.io/vLbT4

The following minimalist script reprojects the shapefile. The geometry is transformed and written to the new file, but the dbf file is simply copied to the new name as we aren't changing it. The standard Python shutil module, which is the shortened form for shell utilities, is used to copy dbf. The source and target shapefile names are variables at the beginning of the script. The target projection is also near the top, which is set using an European Petroleum Survey Group (EPSG) code. The script assumes there is a .prj projection file, which defines the source projection. If it's not, you could manually define it using the same syntax as the target projection. Each section is marked with comments, as you can see here:

from osgeo import ogr
from osgeo import osr
import os
import shutil
srcName = "NYC_MUSEUMS_LAMBERT.shp"
tgtName = "NYC_MUSEUMS_GEO.shp"
tgt_spatRef = osr.SpatialReference()
tgt_spatRef.ImportFromEPSG(4326)
driver = ogr.GetDriverByName("ESRI Shapefile")
src = driver.Open(srcName, 0)
srcLyr = src.GetLayer()
src_spatRef = srcLyr.GetSpatialRef()
if os.path.exists(tgtName):
    driver.DeleteDataSource(tgtName)
tgt = driver.CreateDataSource(tgtName)
lyrName = os.path.splitext(tgtName)[0]
# Use well-known binary format (WKB) to specify geometry
tgtLyr = tgt.CreateLayer(lyrName, geom_type=ogr.wkbPoint)
featDef = srcLyr.GetLayerDefn()
trans = osr.CoordinateTransformation(src_spatRef, tgt_spatRef)
srcFeat = srcLyr.GetNextFeature()
while srcFeat:
    geom = srcFeat.GetGeometryRef()
    geom.Transform(trans)
    feature = ogr.Feature(featDef)
    feature.SetGeometry(geom)
    tgtLyr.CreateFeature(feature)
    feature.Destroy()
    srcFeat.Destroy()
    srcFeat = srcLyr.GetNextFeature()
src.Destroy()
tgt.Destroy()
# Convert geometry to Esri flavor of Well-Known Text (WKT) format
# for export to the projection (prj) file.
tgt_spatRef.MorphToESRI()
prj = open(lyrName + ".prj", "w")
prj.write(tgt_spatRef.ExportToWkt())
prj.close()
srcDbf = os.path.splitext(srcName)[0] + ".dbf"
tgtDbf = lyrName + ".dbf"
shutil.copyfile(srcDbf, tgtDbf)

The following figure shows the reprojected points in QGIS with satellite imagery in the background:

Reprojection

Tip

If you are working with a set of points, you can reproject them programmatically instead of reprojecting a shapefile using PyProj as given in the following link:

http://jswhit.github.io/pyproj/

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset