Select to view content in your preferred language

Expose Georeferencing Control Points to ArcPy

286
1
01-13-2026 02:04 PM
Status: Open
Labels (1)
JasperRomero
Regular Contributor

It would be very helpful to have access georeferencing Control Points through ArcPy or some other programmatic accessor - for example, batch exporting or loading GCPs via strings extracted from the respective raster file names. I have spent some time looking into this and have not come across any way to access control points other than individually, manually, through the GUI with the Georeferencing tool for a specific file.

 

1 Comment
StephenKCA

I came upon this post looking for a way to use WarpFromFile_management on a set of images I had georeferenced, then saved the control points using Save (not Export Control Points). This after I discovered that CopyImage does not warp the original raster.

I wrote the attached code to iterate through a workspace containing images and write out the control points saved in the associated aux.xml files to the straight, tab-delimited text files that can be used with WarpFromFile_management. You could also adapt it for other purposes.

EDIT: Changed code to use tree.find('.//SourceGCPs') after colleague found that some georeferenced JPEGs omit <PolynomialXform>.

import arcpy
from arcpy import env
from arcpy.sa import *

import xml.etree.ElementTree as ET
import itertools

# Python naming conventions make me crazy. I use camelCase for variables,
# StudlyCase for functions, and screaming snake case for constants. 
# Call me a fossil or incorrigible.
def script_tool(param0):
    # Script arguments
    inputWorkspace = param0
    outputWorkspace = param0

    env.workspace = inputWorkspace 
    for inRaster in arcpy.ListRasters():
        arcpy.AddMessage('Processing: ' + arcpy.Describe(inRaster).Name)
        auxxmlfile = inputWorkspace + "\\" + arcpy.Describe(inRaster).Name + ".aux.xml"
        regPtsFile = inputWorkspace + "\\" + arcpy.Describe(inRaster).baseName + ".txt"

        arcpy.AddMessage(auxxmlfile)
        tree = ET.parse(auxxmlfile)
        
        fromCoordX = []
        fromCoordY = []
        toCoordX = []
        toCoordY = []
        
        ecount = 0
        for elem in tree.find('.//SourceGCPs'):
            # Contents will all be an element Double, but treat as text.
            if ecount % 2 == 0:
                fromCoordX.append(elem.text)
            else:
                fromCoordY.append(elem.text)
            ecount += 1

        ecount = 0
        for elem in tree.find('.//TargetGCPs'):
            # Contents will all be an element Double, but treat as text.
            if ecount % 2 == 0:
                toCoordX.append(elem.text)
            else:
                toCoordY.append(elem.text)
            ecount += 1

        # File written by Export Control Points uses single precision. Retain double.
        # Double seems to work fine for WarpFromFile_management.
        with open(regPtsFile, 'w') as ptsTextFile:
            for fromX, fromY, toX, toY in zip(fromCoordX, fromCoordY, toCoordX, toCoordY):
                #arcpy.AddMessage("From: "+ fromX + ", " + fromY + " ; To: " + toX + ", " + toY)
                ptsTextFile.write(fromX + "\t" + fromY + "\t" + toX + "\t" + toY + "\n")

        ptsTextFile.close()

    return


if __name__ == "__main__":

    param0 = arcpy.GetParameterAsText(0)

    script_tool(param0)
    arcpy.SetParameterAsText(2, "Result")