-
Notifications
You must be signed in to change notification settings - Fork 3
/
profile_server.py
executable file
·141 lines (111 loc) · 5.4 KB
/
profile_server.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
#!/usr/bin/env python
"""
Program that run a web server providing elevation profile and profile graph in a RESTful webservice fashion.
See profiler.py and profile_output.py for generation details.
"""
import argparse
import ConfigParser
import logging
import os
import cherrypy
from osgeo import gdal
from gdalconst import GA_ReadOnly
import profiler
from profile_format import JSON, PNG
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
LOGGER = logging.getLogger(os.path.basename(__file__))
class Profile(object):
"""Profile service"""
def __init__(self, data_source):
self.data_source = data_source
def serve_profile(self, lat1, long1, lat2, long2, content_type='application/json', profile_format=JSON,
og1=None, os1=None, og2=None, os2=None):
"""
Generate and format a profile for the given parameters.
:param lat1: latitude of the first point
:param long1: longitude of the first point
:param lat2: latitude of the second point
:param long2: longitude of the second point
:param content_type: response content-type to send, defaults to 'application/json'
:param profile_format: profile format to use, defaults to profile_format.JSON
:param og1: line of sight offset from the ground level of the first point
:param os1: line of sight offset from the sea level of the first point
:param og2: line of sight offset from the ground level of the second point
:param os2: line of sight offset from the sea level of the second point
:return: the formatted elevation profile between the two points
"""
if og1 is not None and os1 is not None:
raise cherrypy.HTTPError(400, "Incompatible parameters 'og1' and 'os1'")
if og2 is not None and os2 is not None:
raise cherrypy.HTTPError(400, "Incompatible parameters 'og2' and 'os2'")
kwargs = {}
if os1 is not None:
kwargs['height1'] = os1
kwargs['above_ground1'] = False
elif og1 is not None:
kwargs['height1'] = og1
kwargs['above_ground1'] = True
if os2 is not None:
kwargs['height2'] = os2
kwargs['above_ground2'] = False
elif og2 is not None:
kwargs['height2'] = og2
kwargs['above_ground2'] = True
elevations = profiler.profile(self.data_source, float(lat1), float(long1), float(lat2), float(long2), **kwargs)
cherrypy.response.headers['Content-Type'] = content_type
return profile_format.get_data(elevations)
@cherrypy.expose
def index(self): # pylint: disable=no-self-use
"""
Index mapping that redirects to /profile/json.
:return: nothing, raises an exception to redirect
"""
raise cherrypy.HTTPRedirect("/profile/json", 301)
@cherrypy.expose
def json(self, lat1, long1, lat2, long2, og1=None, os1=None, og2=None, os2=None):
"""
JSON mapping that outputs the elevations.
:param lat1: latitude of the first point
:param long1: longitude of the first point
:param lat2: latitude of the second point
:param long2: longitude of the second point
:param og1: line of sight offset from the ground level of the first point
:param os1: line of sight offset from the sea level of the first point
:param og2: line of sight offset from the ground level of the second point
:param os2: line of sight offset from the sea level of the second point
:return: the list of elevations between the two points
"""
return self.serve_profile(lat1, long1, lat2, long2, og1=og1, os1=os1, og2=og2, os2=os2)
@cherrypy.expose
def png(self, lat1, long1, lat2, long2, og1=None, os1=None, og2=None, os2=None):
"""
PNG mapping that outputs a png image of the profile
:param lat1: latitude of the first point
:param long1: longitude of the first point
:param lat2: latitude of the second point
:param long2: longitude of the second point
:param og1: line of sight offset from the ground level of the first point
:param os1: line of sight offset from the sea level of the first point
:param og2: line of sight offset from the ground level of the second point
:param os2: line of sight offset from the sea level of the second point
:return: the picture of the requested profile
"""
return self.serve_profile(lat1, long1, lat2, long2, content_type='image/png', profile_format=PNG,
og1=og1, os1=os1, og2=og2, os2=os2)
def main():
"""Main entrypoint"""
config = ConfigParser.ConfigParser()
config.read('config.ini')
config_dem_location = config.get('dem', 'location')
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-d', '--dem', help="DEM file location, ex: '/path/to/file/EUD_CP-DEMS_3500025000-AA.tif'")
args = parser.parse_args()
LOGGER.debug("using the following DEM: %s", args.dem)
# register all of the drivers
gdal.AllRegister()
# open the image
dem_location = args.dem or config_dem_location
data_source = gdal.Open(dem_location, GA_ReadOnly)
cherrypy.quickstart(Profile(data_source), '/profile')
if __name__ == '__main__':
main()