Wednesday, March 8, 2017

Voting Districts Day 8 Changing Projections

Well, I can't map my json file because the coordinates are not the traditional latitude/longitude values, but numbers in the 800Ks.  Here's an example of a coordinate:  [1884558.6496061385, 851226.325625971]

Why's this?  The shapefile I downloaded is using a different, less popular, projection to describe where the shapes go in relation to the earth.  So, I need to change the projection of the voting district shapefile to have traditional latitude longitude coordinates.

There's a python package called pyproj that'll hopefully help me.  I was able to install the binary version with pip.  

What projection do I use?  Well, to figure this out, I looked at the prj file that came with the voting district's shapefile and it said:  NAD_1983_StatePlane_North_Carolina_FIPS_3200_Feet.

Thanks to spatialreference.org, I was able to get the projection the pyproj needed here (clicked the Proj4 link).  I plugged the value in the Proj4 link into the right parameter using pyproj's Proj class:

from pyproj import Proj
myProj = Proj("+proj=lcc +lat_1=34.33333333333334 +lat_2=36.16666666666666 +lat_0=33.75 +lon_0=-79 +x_0=609601.2199999999 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs")

and then test it out using a coordinate from the voting district shapefile using the corresponding method for Proj and the myProj object I created.

 lat = my_json['features'][1000]['geometry']['coordinates'][0][0][1]
 lon = my_json['features'][1000]['geometry']['coordinates'][0][0][0]
 longi, latti = myProj(lon, lat, inverse=True)

From that, the long and lat values looked to be in the right ballpark (NOT!).  

It turns out that the projection requires another parameter according to this forum post due to the measurements being different (feet vs meters).  I need to set preserve_units to True.    

nc = Proj("+proj=lcc +lat_1=34.33333333333334 +lat_2=36.16666666666666 +lat_0=33.75 +lon_0=-79 +x_0=609601.2192024384 +y_0=0 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs ", preserve_units=True)

Now when I use Proj with the new parameters, I get something much more realistic:  (-81.23183299105735, 36.13090600029268).

So, now I've got to plug the use of pyproj into my overall script, figure out how to convert all of my shapes' coordinates so I can finally create a map!