Blame view

tr_position.py 8.8 KB
e82385a1   Paul Nicot   Ajout des fichier...
1
2
3
#!/usr/bin/env python
#! python

184f68e6   Paul Nicot   nettoyage et ajou...
4
5
6
7
8
9
"""
	SPOT position recovery from internet.
	Positions are also flagged if they are in water/land or onboard

"""

e82385a1   Paul Nicot   Ajout des fichier...
10
11
12
13
14
15
import sys
import xml.dom.minidom as minidom
import urllib
import math
import csv
import fiona
184f68e6   Paul Nicot   nettoyage et ajou...
16
import pandas as pd
e82385a1   Paul Nicot   Ajout des fichier...
17
18
19
import shapely.geometry
from time import localtime, strftime, ctime

184f68e6   Paul Nicot   nettoyage et ajou...
20
21
22
23
24
25
26
27
28
29
30
31
32
# debug pour le protocole ssl
import ssl
from functools import wraps
def sslwrap(func):
	@wraps(func)
	def bar(*args, **kw):
		kw['ssl_version'] = ssl.PROTOCOL_TLSv1
		return func(*args, **kw)
	return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)

#==================================================
e82385a1   Paul Nicot   Ajout des fichier...
33
34
#Liste globale contenant tous les objets 
#instancies a partir de la classe Spot
184f68e6   Paul Nicot   nettoyage et ajou...
35
#==================================================
e82385a1   Paul Nicot   Ajout des fichier...
36

509db604   Paul Nicot   maj tr_position.p...
37
spots = []
e82385a1   Paul Nicot   Ajout des fichier...
38
39

class Spot:
184f68e6   Paul Nicot   nettoyage et ajou...
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
	"""
	Classe pour les GPS SPOT 
	"""
	spotCount=0
	rayonTerre = 6371.0 # Rayon moyen  de la terre

	distancePlusPres = 100000000.0 # Init a 1 million de km !
	capPlusPres = 0.0
	identPlusPres = 0
	parentPlusPres = 0
	ecartDistance = 0
	
	spotPlusPres = None
	dejaTraite  = False

	def __init__(self,esnName):
		self.esnName = esnName
		Spot.spotCount += 1

	def setEsn(self,esn):
		self.esn = esn
	
	def setTimestamp(self, timestamp):
		self.timestamp = timestamp

	def setTimeGMT(self, timeGMT):
		self.timeGMT = int(timeGMT)

	def setTimeStampEST(self, timeGMT):
		self.timeStampEST = ctime(int(timeGMT))

	def setLatitude(self,latitude):
		self.latitude = float(latitude)
		
	def setLongitude(self, longitude):
		self.longitude = float(longitude)

	def setMessageType(self, messagetype):
		self.messagetype = messagetype
		
	def setFlag(self, flag):
e82385a1   Paul Nicot   Ajout des fichier...
81
		self.flag = flag
184f68e6   Paul Nicot   nettoyage et ajou...
82
83
		
		
e82385a1   Paul Nicot   Ajout des fichier...
84

e82385a1   Paul Nicot   Ajout des fichier...
85
86
87
88
89
#############################################################
#
#Lecture du fichier XML contenant les information des spots et
#Instanciation de tous les objets Spot a partir de ces info.
#
184f68e6   Paul Nicot   nettoyage et ajou...
90
#A la sortie de cette fonction, la liste globale spots[] contient
e82385a1   Paul Nicot   Ajout des fichier...
91
92
93
94
95
#tous les spots necessaires au traitement
#
#############################################################

def getTags(url):
184f68e6   Paul Nicot   nettoyage et ajou...
96
97
98
	"""
	Initialiser tous les spots a partir du fichier XML
	"""
e82385a1   Paul Nicot   Ajout des fichier...
99

184f68e6   Paul Nicot   nettoyage et ajou...
100
101
102
	doc = minidom.parse(urllib.urlopen(url))
	node = doc.documentElement
	messages = doc.getElementsByTagName("message")
e82385a1   Paul Nicot   Ajout des fichier...
103
104
105

# Initialisation des listes de donnes

184f68e6   Paul Nicot   nettoyage et ajou...
106
107
108
109
110
111
112
113
	esns = []
	esnNames = []
	timestamps = []
	timeInGMTSeconds = []
	latitudes = []
	longitudes = []
	messagetype = []
	spottemp = []
e82385a1   Paul Nicot   Ajout des fichier...
114
115
116
117

# On boucle sur tous les tags messages du fichier XML
# et on extrait les informations

184f68e6   Paul Nicot   nettoyage et ajou...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
	if len(messages) == 0:
		sys.exit(1)

	for message in messages:
		esnObj = message.getElementsByTagName("messengerId")[0]
		esns.append(esnObj)
		esnNameObj = message.getElementsByTagName("messengerName")[0]
		esnNames.append(esnNameObj)
		timestampObj = message.getElementsByTagName("dateTime")[0]
		timestamps.append(timestampObj)
		timeGMTObj = message.getElementsByTagName("unixTime")[0]
		timeInGMTSeconds.append(timeGMTObj)
		latObj = message.getElementsByTagName("latitude")[0]
		latitudes.append(latObj)
		lonObj = message.getElementsByTagName("longitude")[0]
		longitudes.append(lonObj)
		msgtypeObj = message.getElementsByTagName("messageType")[0]
		messagetype.append(msgtypeObj)
e82385a1   Paul Nicot   Ajout des fichier...
136
137
138
139


#On instancie une liste temporaire d'objets de classe Spot
#qui contient l'information de tous les spots 
184f68e6   Paul Nicot   nettoyage et ajou...
140
141
142
143
	for esnName in esnNames:
		nodes = esnName.childNodes
		for node in nodes:
			spottemp.append(Spot(node.data))
e82385a1   Paul Nicot   Ajout des fichier...
144
145
146

#On conserve l'info dans chaque objet

184f68e6   Paul Nicot   nettoyage et ajou...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	for i,s  in enumerate(spottemp):
		nodes = esns[i].childNodes
		for node in nodes:
			s.setEsn(node.data)
		nodes = timestamps[i].childNodes
		for node in nodes:
			s.setTimestamp(node.data)
		nodes = timeInGMTSeconds[i].childNodes
		for node in nodes:
			s.setTimeGMT(node.data)
			s.setTimeStampEST(node.data)
		nodes = latitudes[i].childNodes
		for node in nodes:
			s.setLatitude(node.data)
		nodes = longitudes[i].childNodes
		for node in nodes:
			s.setLongitude(node.data)
		nodes = messagetype[i].childNodes
		for node in nodes:
			s.setMessageType(node.data)
e82385a1   Paul Nicot   Ajout des fichier...
167
168
169
170

#
#On produit une liste unique des identifiants des spots 
#
184f68e6   Paul Nicot   nettoyage et ajou...
171
	spotlist = sorted(set([s.esnName for s in spottemp ]))
e82385a1   Paul Nicot   Ajout des fichier...
172
173
174
175
176
177

#
#On boucle sur la liste des identifiants uniques
#et pour chaque spot on conserve la donnee la plus recente
#(max timestamp)
#
184f68e6   Paul Nicot   nettoyage et ajou...
178
179
180
181
182
183
184
185
	for i in spotlist :
		spotmax = None
		for s in spottemp :
			if s.esnName == i:
				if spotmax == None:
					spotmax = s
				if int(s.timeGMT) > int(spotmax.timeGMT) :
					spotmax = s
e82385a1   Paul Nicot   Ajout des fichier...
186

184f68e6   Paul Nicot   nettoyage et ajou...
187
		spots.append(spotmax)
e82385a1   Paul Nicot   Ajout des fichier...
188
189
190
191
192
193
194
195
196

#
#Rendu ici, la liste spots contient une entree par spot
#et cette entree est la plus recente (plus grand timestamp)
# Fin de la fonction
#

############################################################
#
184f68e6   Paul Nicot   nettoyage et ajou...
197
#	implemente les positions des spots dans le csv
e82385a1   Paul Nicot   Ajout des fichier...
198
199
200
201
#
############################################################

def ecrirecsv(fichier) :
184f68e6   Paul Nicot   nettoyage et ajou...
202
203
204
205
206
207
	""" 
	Creation of a temporary csv file from SPOT class 
	"""

	# cree un fichier temporaire de spots_pos
	f = open(fichier, "w")
e82385a1   Paul Nicot   Ajout des fichier...
208
	writer = csv.writer(f,delimiter=';')
184f68e6   Paul Nicot   nettoyage et ajou...
209
	writer.writerow(['SPOT','LAT','LON','TIME','STATUS','FLAG'])
e82385a1   Paul Nicot   Ajout des fichier...
210
	
e82385a1   Paul Nicot   Ajout des fichier...
211
	for k in spots:
e82385a1   Paul Nicot   Ajout des fichier...
212
		
184f68e6   Paul Nicot   nettoyage et ajou...
213
214
215
216
		k.flag = "FLG"
		data = [ str(k.esnName), float(k.latitude), float(k.longitude),\
				 int(k.timeGMT), str(k.messagetype), str(k.flag)]
		writer.writerow(data)   
e82385a1   Paul Nicot   Ajout des fichier...
217
218
	f.close
	
509db604   Paul Nicot   maj tr_position.p...
219
def cleancsv(fichier_clean) :
184f68e6   Paul Nicot   nettoyage et ajou...
220
221
222
223
	"""
	Nettoyage du csv (suppression des doublons)
	"""

509db604   Paul Nicot   maj tr_position.p...
224
	# nettoyage des doublons 
184f68e6   Paul Nicot   nettoyage et ajou...
225
	with open('/share/archives/partage_lasso/spot/spots_pos_flag.csv','r') as in_file,\
509db604   Paul Nicot   maj tr_position.p...
226
227
228
229
230
231
232
	 open(fichier_clean,'w') as out_file:
		 seen = set() 
		 for line in in_file:
			 if line in seen: continue # skip duplicate
			 seen.add(line)
			 out_file.write(line)

184f68e6   Paul Nicot   nettoyage et ajou...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
def flagcsv(fichier_flag) :
	"""
	marquage des positions
	"""

	# lit le fichier des positions flaguees
	df = pd.read_csv(fichier_flag,delimiter=';')
	df = df.drop_duplicates(take_last=True)	
	
	# lit le fichier des dernieres positions crees dans 'ecrirecsv'
	tmp = pd.read_csv('/share/archives/partage_lasso/spot/tmp.csv',delimiter=';')
	
	# charge le shapefile du trait de cote du GSL
	s = fiona.open("/share/archives/nicp0003/spot/shp/GSL_GSHHS_f.shp")
	shapefile_record = s.next()
	shape = shapely.geometry.asShape(shapefile_record['geometry'])
	x_min, y_min, x_max, y_max = shape.bounds
	rayonTerre = 6371.0
	
	# 
	for index,val in tmp.iterrows():
		LON = val['LON']
		LAT = val['LAT']
		T   = val['TIME']
		SPT = val['SPOT']
		STA = val['STATUS']
		
		# avant-dernieres positions des spots
		T1   = df.loc[(df['SPOT'] == SPT)\
				  & (df['TIME'] < T), 'TIME'][-1:].values
		
		LAT1 = df.loc[(df['SPOT'] == SPT)\
				  & ((df['TIME'] < T)), 'LAT'][-1:].values
				  
		LON1 = df.loc[(df['SPOT'] == SPT)\
				  & ((df['TIME'] < T)), 'LON'][-1:].values
		
		
		if not LAT1:
			LAT1 = LAT	
		if not LON1:
			LON1 = LON	
		if not T1:
			T1 = T	
			
		lat1 = math.radians(LAT)
		lon1 = math.radians(LON)
		tim1 = T
		lat2 = math.radians(LAT1)
		lon2 = math.radians(LON1)
		tim2 = T1
		dlat = math.radians(LAT1 - LAT)
		dlon = math.fabs(math.radians(LON1 - LON))
		
		dPhi = math.log(math.tan(lat2/2+math.pi/4)/math.tan(lat1/2+math.pi/4))
	
		if dPhi <> 0 :
			q = dlat/dPhi
		else :
			q = math.cos(lat1)
	
		#if dLon > 180 degres take shorter rhumb across anti-meridian:
		if math.fabs(dlon) > math.pi :
			if dlon > 0 :
				dlon= -(2*math.pi - dlon) 
			else: 
				dlon = (2*math.pi + dlon)
	
		dist = math.sqrt(dlat*dlat + q*q*dlon*dlon) * rayonTerre
		
		# si distance non nulle (s'il y a une position anterieur du spot)
		# calcul de la vitesse par rapport a la derniere position connue
		if not dist == 0:
			vitesse = (dist * 1000) / abs((tim2 - tim1))  # m.s-1
			# si vitesse > 1.1 m.s (sur bateau par exemple)
			if vitesse > 1.1:
				val.FLAG = "SPD"
			else:
				val.FLAG = "OCN"
		
		# si distance nulle =  marque "NEW"
		if dist == 0:
			val.FLAG = "NEW"
		
		# si position a l'interieur du trait de cote = marque "LND"
		point = shapely.geometry.Point(LON,LAT)
		if shape.contains(point):
				val.FLAG = "LND"

		# si LON / LAT incoherent = marque "OUT"
		if (LON < x_min) or (LON > x_max) \
		or (LAT < y_min) or (LAT > y_max):
				val.FLAG = "OUT"
		
		# rajoute les positions flaguees au fichier final
		f = open(fichier_flag, "ab")
		writer = csv.writer(f,delimiter=';',lineterminator="\n")
		data = [ str(SPT), float(round(LAT,6)), float(round(LON,6)), int(T), str(STA), str(val.FLAG)]
		writer.writerow(data)
		f.close
	
e82385a1   Paul Nicot   Ajout des fichier...
334
335
336

#############################################################
#
184f68e6   Paul Nicot   nettoyage et ajou...
337
#	Debut du programme principal
e82385a1   Paul Nicot   Ajout des fichier...
338
339
340
341
#
#############################################################

if __name__ == "__main__":
184f68e6   Paul Nicot   nettoyage et ajou...
342
343
344
#	url = ' http://share.findmespot.com/messageService/guestlinkservlet?glId=03kp21oFnOj8bRHaPQPPAjf2TuO19VRa3'
	url = ' https://api.findmespot.com/spot-main-web/consumer/rest-api/2.0/public/feed/0zgtS2Yrxgzl8in5LvVoAg0ae76LfQcdO/message.xml'
	getTags(url)
509db604   Paul Nicot   maj tr_position.p...
345

184f68e6   Paul Nicot   nettoyage et ajou...
346
347
348
ecrirecsv("/share/archives/partage_lasso/spot/tmp.csv")
flagcsv("/share/archives/partage_lasso/spot/spots_pos_flag.csv")
cleancsv("/share/archives/partage_lasso/spot/spots_pos_flag_clean.csv")
e82385a1   Paul Nicot   Ajout des fichier...
349
350

sys.exit(0)