12
#import shapely.geometry
18
class TimeRange(object):
20
def __init__(self, endTime, deltaTime=datetime.timedelta(hours=2)):
21
self.endTime = endTime
22
self.startTime = endTime - deltaTime
25
return "['" + str(self.startTime) + "':'" + str(self.endTime) + "']"
27
def getStartTime(self):
33
def getEndMinute(self):
34
return self.getEndTime() - datetime.timedelta(minutes=1)
36
def contains(self, time):
37
return time >= self.getStartTime() and time <= self.getEndTime()
39
class TimeInterval(TimeRange):
41
def __init__(self, endTime, deltaTime=datetime.timedelta(hours=1)):
42
self.deltaTime = deltaTime
43
TimeRange.__init__(self, self.roundTime(endTime), deltaTime)
46
return "['" + str(self.startTime) + "':'" + str(self.endTime) + "'," + str(self.deltaTime) + "]"
48
def totalSeconds(self, time):
49
' return the total seconds of the given time or datetime (relative to midnight) '
51
if isinstance(time, datetime.datetime):
52
return time.hour * 3600 + time.minute * 60 + time.second
53
elif isinstance(time, datetime.timedelta):
54
return time.seconds + time.days * 24 * 3600
56
raise Exception("unhandled type"+type(time))
58
def roundTime(self, time):
59
deltaSeconds = self.totalSeconds(self.deltaTime)
61
seconds = self.totalSeconds(time)
62
seconds /= deltaSeconds
63
seconds *= deltaSeconds
65
if isinstance(time, datetime.datetime):
66
return time.replace(hour = seconds/3600, minute= seconds / 60 % 60, second= seconds % 60, microsecond=0)
68
return datetime.timedelta(seconds=seconds)
74
raise Exception(' no next interval ')
76
def getCenterTime(self):
77
return self.startTime + self.deltaTime / 2
79
class TimeIntervals(TimeInterval):
81
def __init__(self, endTime, deltaTime=datetime.timedelta(minutes=15), totalDuration=datetime.timedelta(days=1)):
82
TimeInterval.__init__(self, endTime, deltaTime)
84
self.totalDuration = self.roundTime(totalDuration)
86
self.startTime = self.endTime - self.totalDuration
89
return self.startTime + self.deltaTime < self.endTime
93
self.startTime += self.deltaTime
96
raise Exception('no more time intervals')
99
return self.startTime + self.deltaTime
103
__geod = pyproj.Geod(ellps='WGS84', units='m')
105
def __init__(self, x, y):
109
def __invgeod(self, other):
110
return Point.__geod.inv(self.x, self.y, other.x, other.y)
112
def distance(self, other):
113
return self.__invgeod(other)[2]
115
def azimuth(self, other):
116
return self.__invgeod(other)[0]
120
timeformat = '%Y-%m-%d %H:%M:%S.%f'
122
def __init__(self, x, y, time):
123
Point.__init__(self, x, y)
124
if isinstance(time, datetime.datetime):
127
elif isinstance(time, str):
128
self.set_time_from_string(time)
130
def set_time_from_string(self, time):
131
self.nanoseconds = int(time[-3:])
132
time = datetime.datetime.strptime(time[:-3], Event.timeformat)
133
self.time = time.replace(tzinfo=pytz.UTC)
135
def set_time(self, time):
141
def set_nanoseconds(self, nanoseconds):
142
self.nanoseconds = nanoseconds
144
def get_nanoseconds(self):
145
return self.nanoseconds
147
def difference(self, other):
148
return self.time - other.time
150
def nanoseconds_difference(self, other):
151
return self.nanoseconds - other.nanoseconds
153
class RawEvent(Event):
154
#2011-02-20 15:16:26.723987041 11.5436 48.1355 521 8 3125 -0.12 0.20 14
155
def __init__(self, data = None):
157
fields = data.split(' ')
158
Event.__init__(self, float(fields[2]), float(fields[3]), ' '.join(fields[0:2]))
159
self.time = self.time + datetime.timedelta(seconds=1)
161
self.height = int(fields[4])
162
self.numberOfSatellites = int(fields[5])
163
self.samplePeriod = int(fields[6])
164
self.amplitudeX = float(fields[7])
165
self.amplitudeY = float(fields[8])
167
raise Error("not enough data fields for raw event data '%s'" %(data))
170
return "%s%03d %.4f %.4f %d %d %d %.2f %.2f" %(self.time.strftime(Event.timeformat), self.get_nanoseconds(), self.x, self.y, self.height, self.numberOfSatellites, self.samplePeriod, self.amplitudeX, self.amplitudeY)
172
def getXAmplitude(self):
173
return self.amplitudeX
175
def getYAmplitude(self):
176
return self.amplitudeY
183
def __init__(self, data = None):
185
' Construct stroke from blitzortung text format data line '
186
fields = data.split(' ')
187
Event.__init__(self, float(fields[3]), float(fields[2]), ' '.join(fields[0:2]))
189
self.amplitude = float(fields[4][:-2])
190
self.typeVal = int(fields[5])
191
self.error2d = int(fields[6][:-1])
194
self.stationcount = int(fields[7])
195
self.participants = []
196
if (len(fields) >=9):
197
for index in range(8,len(fields)):
198
self.participants.append(fields[index])
200
raise Error("not enough data fields from stroke data line '%s'" %(data))
203
def set_location(self, location):
204
Point.__init__(self, location.x, location.y)
206
def get_location(self):
209
def get_height(self):
212
def set_height(self, height):
215
def get_amplitude(self):
216
return self.amplitude
218
def set_amplitude(self, amplitude):
219
self.amplitude = amplitude
224
def set_type(self, typeVal):
225
self.typeVal = typeVal
227
def get_lateral_error(self):
230
def set_lateral_error(self, error2d):
231
self.error2d = error2d
233
def get_station_count(self):
234
return self.stationcount
236
def set_station_count(self, stationcount):
237
self.stationcount = stationcount
239
def has_participant(self, participant):
240
return self.participants.count(participant) > 0
242
def is_detected_by_user(self):
246
return "%s%03d%s %.4f %.4f %d %.1f %d %.1f %d" %(self.time.strftime(Event.timeformat), self.get_nanoseconds(), self.time.strftime('%z'), self.x, self.y, self.height, self.amplitude, self.typeVal, self.error2d, self.stationcount)
248
class Histogram(object):
250
def __init__(self, fileNames, time):
251
data = files.StatisticsData(fileNames, time)
257
print time.getCenterTime(), data.getCount(), data.getMean(), data.getVariance()
259
if not time.hasNext():
264
class AmplitudeHistogram(object):
266
def __init__(self, fileNames, time):
267
data = files.HistogramData(fileNames, time)
273
def __init__(self, baseurl):
276
def add(self, name, value):
277
self.url += '&' + str(name).strip() + '=' + str(value).strip()
280
urlconnection = urllib.urlopen(self.url)
281
data = urlconnection.read().strip()
282
urlconnection.close()
285
def get(self, timeInterval=None):
287
for line in self.readData().split('\n'):
288
stroke = Stroke(line)
289
if timeInterval==None or timeInterval.contains(stroke.get_time()):
290
strokes.append(stroke)
293
class Strokes(StrokesUrl):
295
def __init__(self, config):
296
StrokesUrl.__init__(self, 'http://'+config.get('username')+':'+config.get('password')+'@blitzortung.tmt.de/Data/Protected/strikes.txt')
298
class ParticipantStrokes(StrokesUrl):
300
def __init__(self, config):
301
StrokesUrl.__init__(self, 'http://'+config.get('username')+':'+config.get('password')+'@blitzortung.tmt.de/Data/Protected/participants.txt')