Using Corpscon6.dll with python to convert State Plane to Lat/Long

940
2
10-22-2013 01:11 PM
BillyBarrows
New Contributor
Hi. first post here. (running Windows 7)
I am a beginner in python, but I have a working version of this function in visual basic that I want to use in python.

I use the corpscon6.dll library to convert coordinates from state plane to Latitude/Longitude. My next step will be to write a shapefile using the shapefile.py

The corpscon.dll, Nadcon,Vertcon and Geoid data are a free download from http://www.agc.army.mil/Missions/Corpscon.aspx. I put these downloaded files in "C:\Program Files\Corpscon6" as suggested.


The following setup code seems to work (all the test variables return 1, a negative value means error)
Note: you can paste it into your IDLE and run as one line...
exec('''
from ctypes import* 
corpslib = windll.LoadLibrary("c:\program files\corpscon6\corpscon_v6.dll")
test00=corpslib.corpscon_default_config()
test1=corpslib.SetNadconPath("C:\Program Files\Corpscon6\Nadcon")
test2=corpslib.SetVertconPath("C:\Program Files\Corpscon6\Vertcon")
test3=corpslib.SetGeoidPath("C:\Program Files\Corpscon6\Geoid")
x10=2
test10 =  corpslib.SetInSystem(x10)
x11=1927
test11 =  corpslib.SetInDatum(x11)
x12=3
test12= corpslib.SetOutSystem(x12)
x14=x27=1602
test27 =  corpslib.SetInZone(x27)     #NAD83 or NAD27 zone (1602 is Ky South)
test14 =  corpslib.SetOutZone(x14)     #' NAD83 or NAD27 zone (1602 is Ky South)
x15=x28=1
test28 =  corpslib.SetInUnits(x28)        # 1=USFT, 2=IFT, 3=Meter
test15 =  corpslib.SetOutUnits(x15)      # 1=USFT, 2=IFT, 3=Meter
x22=x23=1929
test22 = corpslib.SetInVDatum(x22)   # Vdatum 1929, 1988, 1980
test23 =  corpslib.SetOutVDatum(x23)  # Vdatum 1929, 1988, 1980
x24=x25=1
test24 =  corpslib.SetInVUnits(x24)     #  1=USFT, 2=IFT, 3=Meter
test25 =  corpslib.SetOutVUnits(x25)    # 1=USFT, 2=IFT, 3=Meter
x26=2003
test26 =  corpslib.SetGeoidCodeBase(x26)
''')


Next I initilize the conversion

test16=corpslib.corpscon_initialize_convert()



Then entering the coordinates should go like this...

exec('''
xVal=2790955
yVal=503380
zVal=1000
test17 =  corpslib.SetXIn(xVal)
test18 =  corpslib.SetYIn(yVal)
test18 =  corpslib.SetZIn(zVal)
test19 = corpslib.corpscon_convert()
longOut = corpslib.GetXOut()
latOut = corpslib.GetYOut()
zOut = corpslib.GetZOut()
''')


however the line
corpslib.SetXin(xVal)
seems to be a problem... I get this error...

Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    corpslib.SetXIn(xVal)
ValueError: Procedure probably called with not enough arguments (4 bytes missing)

My VBA application runs this code ok. Does anyone know what I might be missing??
Thanks
Billy
Tags (2)
0 Kudos
2 Replies
JasonScheirer
Occasional Contributor III
You haven't cast your x/y values into floats like the DLL documentation asks.

I very, very, very strongly recommend you read the ctypes documentation's section on specifying the input/return types in an imported function. This way the arguments will be sanity-checked before calling the functions in the DLL.

For example,

SetXIn = corpslib.SetXIn
SetXIn.argtypes = [ctypes.c_double]
SetXIn.retval = ctypes.c_int

SetXIn(2790955)
0 Kudos
BillyBarrows
New Contributor
Thanks for the info jscheirer. I read the ctypes documentation and changed my code.

Not sure I understand the ctypes correctly, but I am not getting errors and (now that I changed the SetOutSystem to 1) I am getting the right return values!!!




# -*- coding: cp1252 -*-
#define objects from corpscon.dll
from ctypes import* 
corpslib = windll.LoadLibrary("c:\program files\corpscon6\corpscon_v6.dll")
#
test00=corpslib.corpscon_default_config()
# define objects
SetNadconPath=corpslib.SetNadconPath   #1
SetVertconPath=corpslib.SetVertconPath #2
SetGeoidPath=corpslib.SetGeoidPath         #3
SetInSystem=  corpslib.SetInSystem           #10
SetInDatum=  corpslib.SetInDatum              #11
SetOutSystem= corpslib.SetOutSystem      #12
SetInZone    =  corpslib.SetInZone    #27
SetOutZone  =  corpslib.SetOutZone  #14
SetInUnits    =  corpslib.SetInUnits    #28
SetOutUnits  =  corpslib.SetOutUnits  #15
SetInVDatum   = corpslib.SetInVDatum   #22
SetOutVDatum  =  corpslib.SetOutVDatum  #23
SetInVUnits =  corpslib.SetInVUnits #24
SetOutVUnits  =  corpslib.SetOutVUnits  #25
SetGeoidCodeBase  =  corpslib.SetGeoidCodeBase  #26
SetXIn=corpslib.SetXIn
SetYIn=corpslib.SetYIn
SetZIn=corpslib.SetZIn
GetXOut= corpslib.GetXOut
GetYOut= corpslib.GetYOut
GetZOut= corpslib.GetZOut
#
# set ctypes data type
import ctypes
SetNadconPath.argtypes = [ctypes.c_char_p]
SetNadconPath.retval =[ctypes.c_int]
SetVertconPath.argtypes = [ctypes.c_char_p]
SetVertconPath.retval = [ctypes.c_int]
SetGeoidPath.argtypes = [ctypes.c_char_p]
SetGeoidPath.retval =[ctypes.c_int]
SetInSystem.argtypes = [ctypes.c_int]
SetInSystem.retval = [ctypes.c_int]
SetInDatum.argtypes = [ctypes.c_int]
SetInDatum.retval =[ctypes.c_int]
SetOutSystem.argtypes = [ctypes.c_int]
SetOutSystem.retval = [ctypes.c_int]
SetInZone.argtypes = [ctypes.c_int]    
SetInZone .retval = [ctypes.c_int]
SetOutZone.argtypes = [ctypes.c_int]  
SetOutZone .retval = [ctypes.c_int] 
SetInUnits.argtypes = [ctypes.c_int]
SetInUnits .retval =[ctypes.c_int] 
SetInVDatum.argtypes = [ctypes.c_int]   
SetInVDatum .retval = [ctypes.c_int]   
SetOutVDatum.argtypes = [ctypes.c_int]  
SetOutVDatum .retval =[ctypes.c_int]  
SetInVUnits.argtypes = [ctypes.c_int] 
SetInVUnits .retval =[ ctypes.c_int] 
SetOutVUnits.argtypes = [ctypes.c_int]  
SetOutVUnits .retval =[ ctypes.c_int]
SetGeoidCodeBase.argtypes = [ctypes.c_int]  
SetGeoidCodeBase  .retval =[ ctypes.c_int]
SetXIn.argtypes = [ctypes.c_double]
SetXIn.retval =[ ctypes.c_int]
SetYIn.argtypes = [ctypes.c_double]
SetYIn.retval = [ctypes.c_int]
SetZIn.argtypes = [ctypes.c_double]
SetZIn.retval =[ ctypes.c_int]
GetXOut.retval =[ ctypes.c_double]
GetYOut.retval =[ ctypes.c_double]
GetZOut.retval = [ctypes.c_double]
#
# set up dll data
test1=SetNadconPath("C:\Program Files\Corpscon6\Nadcon")
test2=SetVertconPath("C:\Program Files\Corpscon6\Vertcon")
test3=SetGeoidPath("C:\Program Files\Corpscon6\Geoid")
x10=2
test10 =  SetInSystem(x10)
x11=1927
test11 =  SetInDatum(x11)
x12=1
test12= SetOutSystem(x12)
x14=x27=1602
test27 =  SetInZone(x27)     #NAD83 or NAD27 zone (1602 is Ky South)
test14 =  SetOutZone(x14)     #' NAD83 or NAD27 zone (1602 is Ky South)
x15=x28=1
test28 =  SetInUnits(x28)        # 1=USFT, 2=IFT, 3=Meter
test15 =  SetOutUnits(x15)      # 1=USFT, 2=IFT, 3=Meter
x22=x23=1929
test22 = SetInVDatum(x22)   # Vdatum 1929, 1988, 1980
test23 =  SetOutVDatum(x23)  # Vdatum 1929, 1988, 1980
x24=x25=1
test24 =  SetInVUnits(x24)     #  1=USFT, 2=IFT, 3=Meter
test25 =  SetOutVUnits(x25)    # 1=USFT, 2=IFT, 3=Meter
x26=2003
test26 =  SetGeoidCodeBase(x26)
test16=corpslib.corpscon_initialize_convert()
#
#Enter points and convert
StartX=2790955
StartY=503380
inx = c_double(StartX)
iny = c_double(StartY)
inz = c_double(0.00)
outx = c_double()
outy = c_double()
outz = c_double()
SetXIn(inx)
SetYIn(iny)
SetZIn(inz)
corpslib.corpscon_convert()
corpslib.GetXOut.restype = c_double
corpslib.GetYOut.restype = c_double
corpslib.GetZOut.restype = c_double
PtX = corpslib.GetXOut()
PtY = corpslib.GetYOut()
print PtX, PtY
0 Kudos