-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStatePlanetoLatLongConverter.py
147 lines (126 loc) · 6.15 KB
/
StatePlanetoLatLongConverter.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
from pyproj import Transformer
import tkinter
from tkinter import filedialog
from tablib import Dataset
from difflib import SequenceMatcher
import os
def mainMenu():
print("State Plane to Latitude/Longitude Converter".center(80))
print("===============\n".center(80))
print("[L] - State Plane to Latitude/Longitude Conversion")
print("[S] - Latitude/Longitude to State Plane Conversion")
print("[B] - State Plane to State Plane Conversion")
print("[X] - Exit")
userInput = input("\nSelection: ")
if userInput == "X" or userInput == "x":
exitProgram()
elif userInput == "":
print("This is not a valid input. Please try again")
mainMenu()
file = getFile()
data = importData(file)
if userInput == "L" or userInput == "l":
print("This conversion format will accept any EPSG code as a source.")
print("Some useful codes: \n1. [26916] - NAD83 / UTM zone 16N\n2. [4326] - WGS 84 Latitude/Longitude\n3. [2240] - NAD83 State Plane West Georgia (US Survey ft.)")
continueInput = input("Press `Enter` to continue...")
EPSGZone = getEPSG(True)
convertedCoordinates = convertCoordinates(data, EPSGZone, 4326, True)
newData = writeData(data, convertedCoordinates, False)
elif userInput == "S" or userInput == "s":
print("This conversion format will accept any EPSG code as a target.")
print("Some useful codes: \n1. [26916] - NAD83 / UTM zone 16N\n2. [4326] - WGS 84 Latitude/Longitude\n3. [2240] - NAD83 State Plane West Georgia (US Survey ft.)")
continueInput = input("Press `Enter` to continue...")
EPSGZone = getEPSG(False)
convertedCoordinates = convertCoordinates(data, 4326, EPSGZone, False)
newData = writeData(data, convertedCoordinates, True)
elif userInput == "B" or userInput == "b":
print("This conversion format will accept any EPSG code as a source and target.")
print("Some useful codes: \n1. [26916] - NAD83 / UTM zone 16N\n2. [4326] - WGS 84 Latitude/Longitude\n3. [2240] - NAD83 State Plane West Georgia (US Survey ft.)")
continueInput = input("Press `Enter` to continue...")
EPSGFrom = getEPSG(True)
EPSGTo = getEPSG(False)
convertedCoordinates = convertCoordinates(data, EPSGFrom, EPSGTo, True)
newData = writeData(data, convertedCoordinates, True)
exportData(file, newData)
def getEPSG(gettingFrom):
if gettingFrom:
print("Please input the EPSG Zone that the coordinates are in.")
else:
print("Please input the EPSG Zone that you are converting to.")
try:
EPSGZone = int(input("EPSG Zone: "))
except:
print ("Please enter only digits for the EPSG Zone.")
getEPSG(gettingFrom)
return EPSGZone
def getFile(): #responsible for displaying the UI and collecting desired selections
while True:
try:
window = tkinter.Tk()
window.wm_attributes("-topmost", 1)
window.withdraw()
workingFile = filedialog.askopenfilename(parent = window, filetypes = [("CSV Files", "*.csv")], initialdir = "/", title = "Select the directory which contains your coordinates.") #Tkinter allows for the creation of pop-up file directories
except:
workingFile = input("Enter the directory which contains your coordinates.")
if os.path.exists(workingFile): #pathlib is incompatible with pyinstaller, so I'm using os.path
return workingFile
elif workingFile == "":
exitProgram()
else:
print("This is not a valid .csv file! Please try again.")
getFile()
def importData(workingFile):
try:
with open(workingFile, 'r') as file:
importedData = Dataset().load(file)
return importedData
except:
print("There was an error importing the data.\n Please ensure the file exists where specified and is in the correct format.")
exitProgram()
def getHeader(data, toFind):
headers = data.headers
for header in headers:
if SequenceMatcher(None, toFind, header.lower()).ratio() > 0.75:
return str(header)
print ("Please make sure that you have columns in your .csv file which contain Easting/Northing or Latitude/Longitude!")
exitProgram()
def convertCoordinates(importedData, EPSGFrom, EPSGTo, statePlane):
transformer = Transformer.from_crs(f'EPSG:{EPSGFrom}', f'EPSG:{EPSGTo}', always_xy=True)
if statePlane:
x = importedData[getHeader(importedData, "easting")]
y = importedData[getHeader(importedData, "northing")]
else:
y = importedData[getHeader(importedData, "latitude")]
x = importedData[getHeader(importedData, "longitude")]
convertedX = []
convertedY = []
for currentX, currentY in zip(x, y):
coordinate = transformer.transform(currentX, currentY)
convertedX.append(coordinate[0])
convertedY.append(coordinate[1])
convertedCoordinates = [convertedX, convertedY]
return convertedCoordinates
def writeData(data, convertedCoordinates, statePlane):
if statePlane:
data.append_col(convertedCoordinates[1], header="NORTHING")
data.append_col(convertedCoordinates[0], header="EASTING")
else:
data.append_col(convertedCoordinates[1], header="LATITUDE")
data.append_col(convertedCoordinates[0], header = "LONGITUDE")
return data
def exportData(file, data):
try:
outputPath = os.path.join(os.path.dirname(os.path.realpath(file)), "output.csv")
with open(outputPath, 'w', newline='') as outputFile:
outputFile.write(data.csv)
except:
print("The program has insufficient permissions to write to this location. Please make sure the file is not currently open.\nPlease try selecting a new filename below. Please include .csv at the end.")
filename = input("Filename (`example.csv`): ")
outputPath = os.path.join(os.path.dirname(os.path.realpath(file)), filename)
with open(outputPath, 'w', newline='') as outputFile:
outputFile.write(data.csv)
def exitProgram():
while True:
exitInput = input("Press `Enter` to exit...")
quit()
mainMenu()