forked from spencerrecneps/pfb
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdetect_utm_zone.py
executable file
·105 lines (80 loc) · 2.94 KB
/
detect_utm_zone.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
#!/usr/bin/env python
"""
Accepts a polygon shapefile and finds the SRID for the UTM zone
Based on https://github.com/jbranigan/geo-scripts-python/blob/master/latlng2utm/detect-utm-zone.py
"""
import argparse
import math
from osgeo import ogr, osr
import sys
def check_latlng(check_bbox):
""" Checks to see if the file coordinates are in lat/lng """
for i in check_bbox:
if i < -180 or i > 180:
failure('This file is already projected.')
return True
def check_width(check_bbox):
""" Checks to see if the bounding box fits in a UTM zone """
wide = check_bbox[1] - check_bbox[0]
if wide > 3:
failure('This file is too many degrees wide for UTM')
return True
def get_zone(coord):
""" Finds the UTM zone of a WGS84 coordinate """
# There are 60 longitudinal projection zones numbered 1 to 60 starting at 180W
# So that's -180 = 1, -174 = 2, -168 = 3
zone = ((coord - -180) / 6.0)
return int(math.ceil(zone))
def get_bbox(shapefile):
""" Gets the bounding box of a shapefile in EPSG 4326.
If shapefile is not in WGS84, bounds are reprojected.
"""
driver = ogr.GetDriverByName('ESRI Shapefile')
# 0 means read, 1 means write
data_source = driver.Open(shapefile, 0)
# Check to see if shapefile is found.
if data_source is None:
failure('Could not open %s' % (shapefile))
else:
layer = data_source.GetLayer()
shape_bbox = layer.GetExtent()
spatialRef = layer.GetSpatialRef()
target = osr.SpatialReference()
target.ImportFromEPSG(4326)
# this check for non-WGS84 projections gets some false positives, but that's okay
if target.ExportToProj4() != spatialRef.ExportToProj4():
transform = osr.CoordinateTransformation(spatialRef, target)
point1 = ogr.Geometry(ogr.wkbPoint)
point1.AddPoint(shape_bbox[0], shape_bbox[2])
point2 = ogr.Geometry(ogr.wkbPoint)
point2.AddPoint(shape_bbox[1], shape_bbox[3])
point1.Transform(transform)
point2.Transform(transform)
shape_bbox = [point1.GetX(), point2.GetX(), point1.GetY(), point2.GetY()]
return shape_bbox
def failure(why):
""" Quits the script with an exit message """
print(why)
sys.exit(1)
def get_srid(filename):
bbox = get_bbox(filename)
check_latlng(bbox)
check_width(bbox)
avg_longitude = ((bbox[1] - bbox[0]) / 2) + bbox[0]
utm_zone = get_zone(avg_longitude)
avg_latitude = ((bbox[3] - bbox[2]) / 2) + bbox[2]
# convert UTM zone to SRID
# SRID for a given UTM ZONE: 32[6 if N|7 if S]<zone>
srid = '32'
if avg_latitude < 0:
srid += '7'
else:
srid += '6'
srid += str(utm_zone)
print(srid)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("filename", help="the path to the input shapefile")
args = parser.parse_args()
get_srid(args.filename)
main()