Issues with ArcPy SpatialReference Class

9423
25
04-27-2016 01:34 AM
MattBrehm
New Contributor II

     I am attempting to write a Python script that uses a general reference map of the NAD 1983 UTM Zones to automate the selection of an appropriate map projection for a specific area. I have completed the script up until the point at which I need to create a SpatialReference object that contains the appropriate projection. I have been getting a 999999 general runtime error whenever I try to assign the SpatialReference object the value of "NAD 1983 UTM Zone 9N" or lower, but past "NAD 1983 UTM Zone 10N", it works.

     This screenshot is the result of a test script in which I import ArcPy, and then try to initialize a SpatialReference object with the respective values mentioned above. In the second run, I printed the SpatialReference object's name in order to test to make sure that the value was assigned correctly. Am I missing something here, or is this a known issue with assigning the names of projections to SpatialReference objects? I would otherwise use the WKID for the projection, but the reference map that I am using only contains a field for the name of the projection.

Edit: I am using general reference maps for both the NAD 1983 UTM Zones as well as the USA State Plane Zones NAD83 in order to find an appropriate projection for an input dataset. I first find the centroid of the dataset, and then select by location from the reference projection maps. From the responses here and my own testing, it seems as if trying to assign SpatialReference objects the projections by name does not work for certain types of projections. Namely, the NAD 1983 UTM Zone 1-9 projections. I have also yet to find a U.S. State Plane projection in which the SpatialReference object does not give an error when attempting to assign the projection by name. The solution seems to be to assign the SpatialReference object by WKID. but this could be quite cumbersome if the assignment of projection WKIDs does not follow an intuitive pattern and you're working with hundreds of reference projections.

Tags (2)
0 Kudos
25 Replies
NeilAyres
MVP Alum

Matt,

yes this sr.name vs the "Name" you're supposed to use when trying to initiate it seems to be a bit inconsistent.

The help files refers to the pdf in the documentation installation area. But those "Names" all have underscores.

Perhaps Melita or an esri guru could explain.

AdrianWelsh
MVP Honored Contributor

Matt,

From my experience of working with the SpatialReference class in Python, there are issues that have not been addressed. Certain properties that are SUPPOSED to be Read/Write are actually Read only. I had to go a complete back door approach in order to create my .prj file.

This is what I had to do:

  1. prj = open(r"C:\junk\my_new_prj_file.prj", "w")   
  2. crs_string = 'PROJCS["NAD_1983_UTM_Zone_10N",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137,298.257222101]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-123],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["Meter",1]]'   
  3. prj.write(crs_string)   
  4. prj.close()
MattBrehm
New Contributor II

Not to be insulting, but that seems like a major pain lol. It is helpful in that it shows what would go into defining the .prj file, but for just the StatePlane projections in the U.S. alone, there are 121 different features. I would not want to have to do this for all of them. I was hoping for an easy solution, but it seems as if adding a WKID field to the attribute table of the reference projection maps, adding the WKIDs for each of the projection systems, and referencing them with a SearchCursor in ArcPy is the best option for this type of workflow.

DanPatterson_Retired
MVP Emeritus

Matt... moved to Python​ and shared with Coordinate Reference Systems​ and flagging Melita Kennedy​ to see if a solution or commentary can be found

MelitaKennedy
Esri Notable Contributor

And the answer is...

there should be two spaces between Zone and 9N. That's true of most of the NAD-based UTM zones. The name look-up that arcpy is performing isn't on the object's internal name ("NAD_1983_UTM_Zone_9N"), but on the name used for the coordinate systems "folder" structure. At the time I set them up, I didn't know that we planned to add a name look-up using them.

Melita

NeilAyres
MVP Alum

Melita,

so you are saying that if the zone number has a single digit, 2 spaces should be added to form the "Name" string.

Is that true throughout the system?

Other, non UTM style names, just the .replace("_", " ") should work?

0 Kudos
NeilAyres
MVP Alum

Kept a copy of the old *.prj file structure before it disappeared.

That doesn't look like 2 spaces in that name...

0 Kudos
MelitaKennedy
Esri Notable Contributor

Neil, the internal "folder" structure information was built from the prj file names, but then I think someone (wasn't me) that the idea to improve the sort order by adding an extra space to the single digit entries.

0 Kudos
MelitaKennedy
Esri Notable Contributor

It's not 100%. The NAD83 xx UTM 2S, and some 4N and 5N zones have 1 space because I added them after we first set up the internal "folder" structure files.

1 space:

Old Hawaiian UTM 4N and 5N

HARN / PACP00 / PA11 2S, 4N, 5N

American Samoa 1962 UTM 2S

Ocean UTM zones like Pitcairn 1967 UTM 9S, RGPF UTM 5S - 8S, MOP78 UTM 1S, etc. Includes NZ.

"county" or "DOT" sets like IaCRS

Norway

Generally, GK zones do not have the extra space.

AdrianWelsh
MVP Honored Contributor

Not insulting here! It's just that this is the ONLY thing that would work for me due to me needing to creating CUSTOM projection files. If I could have used out-of-the-box projections, then utilizing the WKID would have been ideal. But, you're right, it is a major pain!

I have it more "programmatic" than just a giant string of text, though. Each of the changing variables in that string (like units, projection, scale factor, etc.) is a variable that I created earlier in the script that programmatically accesses user input so then the string looks more like this:

  1. projString = ('PROJCS["' + str(PIN) + '_' + ProjName + 
  2.             '",GEOGCS[' + GeoCS + 
  3.             '],PROJECTION["' + ProjectionName + 
  4.             '"],PARAMETER["False_Easting",' + str(FalseEasting) + 
  5.             '],PARAMETER["False_Northing",' + str(FalseNorthing) + 
  6.             '],PARAMETER["Central_Meridian",' + str(CentralMeridian) + 
  7.             '],PARAMETER["Standard_Parallel_1",' + str(StandardParallel1) + 
  8.             '],PARAMETER["Standard_Parallel_2",' + str(StandardParallel2) + 
  9.             '],PARAMETER["Scale_Factor",' + str(ScaleFactor) + 
  10.             '],PARAMETER["Latitude_Of_Origin",' + str(LatOfOrigin) + 
  11.             '],UNIT["' + LinearUnit + '",' + str(MetersPerFoot) + ']]')

But, then again, this works for me and may not be the best choice for your dataset.