Commit 184f68e6fa8b0bd862618b3d6a2d173f1ba32e36

Authored by Paul Nicot
1 parent 0a12a48d
Exists in master and in 1 other branch simon

nettoyage et ajout de commentaires

Showing 1 changed file with 256 additions and 143 deletions   Show diff stats
tr_position.py
1 1 #!/usr/bin/env python
2 2 #! python
3 3  
  4 +"""
  5 + SPOT position recovery from internet.
  6 + Positions are also flagged if they are in water/land or onboard
  7 +
  8 +"""
  9 +
4 10 import sys
5 11 import xml.dom.minidom as minidom
6 12 import urllib
7 13 import math
8 14 import csv
9 15 import fiona
  16 +import pandas as pd
10 17 import shapely.geometry
11 18 from time import localtime, strftime, ctime
12 19  
13   -#
  20 +# debug pour le protocole ssl
  21 +import ssl
  22 +from functools import wraps
  23 +def sslwrap(func):
  24 + @wraps(func)
  25 + def bar(*args, **kw):
  26 + kw['ssl_version'] = ssl.PROTOCOL_TLSv1
  27 + return func(*args, **kw)
  28 + return bar
  29 +
  30 +ssl.wrap_socket = sslwrap(ssl.wrap_socket)
  31 +
  32 +#==================================================
14 33 #Liste globale contenant tous les objets
15 34 #instancies a partir de la classe Spot
16   -#
  35 +#==================================================
17 36  
18 37 spots = []
19 38  
20 39 class Spot:
21   - '''Classe pour les GPS SPOT'''
22   - spotCount=0
23   - rayonTerre = 6371.0 # Rayon moyen de la terre
24   -
25   - distancePlusPres = 100000000.0 # Init a 1 million de km !
26   - capPlusPres = 0.0
27   - identPlusPres = 0
28   - parentPlusPres = 0
29   - ecartDistance = 0
30   -
31   - spotPlusPres = None
32   - dejaTraite = False
33   -
34   - def __init__(self,esnName):
35   - self.esnName = esnName
36   - Spot.spotCount += 1
37   -
38   - def setEsn(self,esn):
39   - self.esn = esn
40   -
41   - def setTimestamp(self, timestamp):
42   - self.timestamp = timestamp
43   -
44   - def setTimeGMT(self, timeGMT):
45   - self.timeGMT = int(timeGMT)
46   -
47   - def setTimeStampEST(self, timeGMT):
48   - self.timeStampEST = ctime(int(timeGMT))
49   -
50   - def setLatitude(self,latitude):
51   - self.latitude = float(latitude)
52   -
53   - def setLongitude(self, longitude):
54   - self.longitude = float(longitude)
55   -
56   - def setMessageType(self, messagetype):
57   - self.messagetype = messagetype
58   -
59   - def setFlag(self, flag):
  40 + """
  41 + Classe pour les GPS SPOT
  42 + """
  43 + spotCount=0
  44 + rayonTerre = 6371.0 # Rayon moyen de la terre
  45 +
  46 + distancePlusPres = 100000000.0 # Init a 1 million de km !
  47 + capPlusPres = 0.0
  48 + identPlusPres = 0
  49 + parentPlusPres = 0
  50 + ecartDistance = 0
  51 +
  52 + spotPlusPres = None
  53 + dejaTraite = False
  54 +
  55 + def __init__(self,esnName):
  56 + self.esnName = esnName
  57 + Spot.spotCount += 1
  58 +
  59 + def setEsn(self,esn):
  60 + self.esn = esn
  61 +
  62 + def setTimestamp(self, timestamp):
  63 + self.timestamp = timestamp
  64 +
  65 + def setTimeGMT(self, timeGMT):
  66 + self.timeGMT = int(timeGMT)
  67 +
  68 + def setTimeStampEST(self, timeGMT):
  69 + self.timeStampEST = ctime(int(timeGMT))
  70 +
  71 + def setLatitude(self,latitude):
  72 + self.latitude = float(latitude)
  73 +
  74 + def setLongitude(self, longitude):
  75 + self.longitude = float(longitude)
  76 +
  77 + def setMessageType(self, messagetype):
  78 + self.messagetype = messagetype
  79 +
  80 + def setFlag(self, flag):
60 81 self.flag = flag
61   -
62   -
  82 +
  83 +
63 84  
64 85 #############################################################
65 86 #
66 87 #Lecture du fichier XML contenant les information des spots et
67 88 #Instanciation de tous les objets Spot a partir de ces info.
68 89 #
69   -#A la sortie de cette fonction, la liste globale spots[] contient tous
  90 +#A la sortie de cette fonction, la liste globale spots[] contient
70 91 #tous les spots necessaires au traitement
71 92 #
72 93 #############################################################
73 94  
74 95 def getTags(url):
75   - """
76   - Initialiser tous les spots a partir du fichier XML
77   - """
  96 + """
  97 + Initialiser tous les spots a partir du fichier XML
  98 + """
78 99  
79   - doc = minidom.parse(urllib.urlopen(url))
80   - node = doc.documentElement
81   - messages = doc.getElementsByTagName("message")
  100 + doc = minidom.parse(urllib.urlopen(url))
  101 + node = doc.documentElement
  102 + messages = doc.getElementsByTagName("message")
82 103  
83 104 # Initialisation des listes de donnes
84 105  
85   - esns = []
86   - esnNames = []
87   - timestamps = []
88   - timeInGMTSeconds = []
89   - latitudes = []
90   - longitudes = []
91   - messagetype = []
92   - spottemp = []
  106 + esns = []
  107 + esnNames = []
  108 + timestamps = []
  109 + timeInGMTSeconds = []
  110 + latitudes = []
  111 + longitudes = []
  112 + messagetype = []
  113 + spottemp = []
93 114  
94 115 # On boucle sur tous les tags messages du fichier XML
95 116 # et on extrait les informations
96 117  
97   - if len(messages) == 0:
98   - sys.exit(1)
99   -
100   - for message in messages:
101   - esnObj = message.getElementsByTagName("messengerId")[0]
102   - esns.append(esnObj)
103   - esnNameObj = message.getElementsByTagName("messengerName")[0]
104   - esnNames.append(esnNameObj)
105   - timestampObj = message.getElementsByTagName("dateTime")[0]
106   - timestamps.append(timestampObj)
107   - timeGMTObj = message.getElementsByTagName("unixTime")[0]
108   - timeInGMTSeconds.append(timeGMTObj)
109   - latObj = message.getElementsByTagName("latitude")[0]
110   - latitudes.append(latObj)
111   - lonObj = message.getElementsByTagName("longitude")[0]
112   - longitudes.append(lonObj)
113   - msgtypeObj = message.getElementsByTagName("messageType")[0]
114   - messagetype.append(msgtypeObj)
  118 + if len(messages) == 0:
  119 + sys.exit(1)
  120 +
  121 + for message in messages:
  122 + esnObj = message.getElementsByTagName("messengerId")[0]
  123 + esns.append(esnObj)
  124 + esnNameObj = message.getElementsByTagName("messengerName")[0]
  125 + esnNames.append(esnNameObj)
  126 + timestampObj = message.getElementsByTagName("dateTime")[0]
  127 + timestamps.append(timestampObj)
  128 + timeGMTObj = message.getElementsByTagName("unixTime")[0]
  129 + timeInGMTSeconds.append(timeGMTObj)
  130 + latObj = message.getElementsByTagName("latitude")[0]
  131 + latitudes.append(latObj)
  132 + lonObj = message.getElementsByTagName("longitude")[0]
  133 + longitudes.append(lonObj)
  134 + msgtypeObj = message.getElementsByTagName("messageType")[0]
  135 + messagetype.append(msgtypeObj)
115 136  
116 137  
117 138 #On instancie une liste temporaire d'objets de classe Spot
118 139 #qui contient l'information de tous les spots
119   - for esnName in esnNames:
120   - nodes = esnName.childNodes
121   - for node in nodes:
122   - spottemp.append(Spot(node.data))
  140 + for esnName in esnNames:
  141 + nodes = esnName.childNodes
  142 + for node in nodes:
  143 + spottemp.append(Spot(node.data))
123 144  
124 145 #On conserve l'info dans chaque objet
125 146  
126   - for i,s in enumerate(spottemp):
127   - nodes = esns[i].childNodes
128   - for node in nodes:
129   - s.setEsn(node.data)
130   - nodes = timestamps[i].childNodes
131   - for node in nodes:
132   - s.setTimestamp(node.data)
133   - nodes = timeInGMTSeconds[i].childNodes
134   - for node in nodes:
135   - s.setTimeGMT(node.data)
136   - s.setTimeStampEST(node.data)
137   - nodes = latitudes[i].childNodes
138   - for node in nodes:
139   - s.setLatitude(node.data)
140   - nodes = longitudes[i].childNodes
141   - for node in nodes:
142   - s.setLongitude(node.data)
143   - nodes = messagetype[i].childNodes
144   - for node in nodes:
145   - s.setMessageType(node.data)
  147 + for i,s in enumerate(spottemp):
  148 + nodes = esns[i].childNodes
  149 + for node in nodes:
  150 + s.setEsn(node.data)
  151 + nodes = timestamps[i].childNodes
  152 + for node in nodes:
  153 + s.setTimestamp(node.data)
  154 + nodes = timeInGMTSeconds[i].childNodes
  155 + for node in nodes:
  156 + s.setTimeGMT(node.data)
  157 + s.setTimeStampEST(node.data)
  158 + nodes = latitudes[i].childNodes
  159 + for node in nodes:
  160 + s.setLatitude(node.data)
  161 + nodes = longitudes[i].childNodes
  162 + for node in nodes:
  163 + s.setLongitude(node.data)
  164 + nodes = messagetype[i].childNodes
  165 + for node in nodes:
  166 + s.setMessageType(node.data)
146 167  
147 168 #
148 169 #On produit une liste unique des identifiants des spots
149 170 #
150   - spotlist = sorted(set([s.esnName for s in spottemp ]))
  171 + spotlist = sorted(set([s.esnName for s in spottemp ]))
151 172  
152 173 #
153 174 #On boucle sur la liste des identifiants uniques
154 175 #et pour chaque spot on conserve la donnee la plus recente
155 176 #(max timestamp)
156 177 #
157   - for i in spotlist :
158   - spotmax = None
159   - for s in spottemp :
160   - if s.esnName == i:
161   - if spotmax == None:
162   - spotmax = s
163   - if int(s.timeGMT) > int(spotmax.timeGMT) :
164   - spotmax = s
  178 + for i in spotlist :
  179 + spotmax = None
  180 + for s in spottemp :
  181 + if s.esnName == i:
  182 + if spotmax == None:
  183 + spotmax = s
  184 + if int(s.timeGMT) > int(spotmax.timeGMT) :
  185 + spotmax = s
165 186  
166   - spots.append(spotmax)
  187 + spots.append(spotmax)
167 188  
168 189 #
169 190 #Rendu ici, la liste spots contient une entree par spot
... ... @@ -173,42 +194,35 @@ def getTags(url):
173 194  
174 195 ############################################################
175 196 #
176   -# implemente les positions des spots dans le csv
  197 +# implemente les positions des spots dans le csv
177 198 #
178 199 ############################################################
179 200  
180 201 def ecrirecsv(fichier) :
181   -
182   - f = open(fichier, "ab")
  202 + """
  203 + Creation of a temporary csv file from SPOT class
  204 + """
  205 +
  206 + # cree un fichier temporaire de spots_pos
  207 + f = open(fichier, "w")
183 208 writer = csv.writer(f,delimiter=';')
  209 + writer.writerow(['SPOT','LAT','LON','TIME','STATUS','FLAG'])
184 210  
185   - # charge le shapefile du trait de cote du GSL
186   - s = fiona.open("/home/nicopa01/data/spot/shp/GSL_GSHHS_f.shp")
187   - shapefile_record = s.next()
188   - shape = shapely.geometry.asShape(shapefile_record['geometry'])
189   - x_min, y_min, x_max, y_max = shape.bounds
190   -
191 211 for k in spots:
192   - point = shapely.geometry.Point(k.longitude,k.latitude)
193   -
194   - if shape.contains(point):
195   - k.flag = "LND"
196   - else:
197   - k.flag = "OCN"
198   -
199   - if (k.longitude < x_min) or (k.longitude > x_max) \
200   - or (k.latitude < y_min) or (k.latitude > y_max):
201   - k.flag = "OUT"
202   -
203   - data = [ str(k.esnName), float(k.latitude), float(k.longitude), int(k.timeGMT), str(k.messagetype), str(k.flag)]
204   -
205   - writer.writerow(data)
206 212  
  213 + k.flag = "FLG"
  214 + data = [ str(k.esnName), float(k.latitude), float(k.longitude),\
  215 + int(k.timeGMT), str(k.messagetype), str(k.flag)]
  216 + writer.writerow(data)
207 217 f.close
208 218  
209 219 def cleancsv(fichier_clean) :
  220 + """
  221 + Nettoyage du csv (suppression des doublons)
  222 + """
  223 +
210 224 # nettoyage des doublons
211   - with open('/home/nicopa01/data/spot/spots_pos.csv','r') as in_file,\
  225 + with open('/share/archives/partage_lasso/spot/spots_pos_flag.csv','r') as in_file,\
212 226 open(fichier_clean,'w') as out_file:
213 227 seen = set()
214 228 for line in in_file:
... ... @@ -216,22 +230,121 @@ def cleancsv(fichier_clean) :
216 230 seen.add(line)
217 231 out_file.write(line)
218 232  
  233 +def flagcsv(fichier_flag) :
  234 + """
  235 + marquage des positions
  236 + """
  237 +
  238 + # lit le fichier des positions flaguees
  239 + df = pd.read_csv(fichier_flag,delimiter=';')
  240 + df = df.drop_duplicates(take_last=True)
  241 +
  242 + # lit le fichier des dernieres positions crees dans 'ecrirecsv'
  243 + tmp = pd.read_csv('/share/archives/partage_lasso/spot/tmp.csv',delimiter=';')
  244 +
  245 + # charge le shapefile du trait de cote du GSL
  246 + s = fiona.open("/share/archives/nicp0003/spot/shp/GSL_GSHHS_f.shp")
  247 + shapefile_record = s.next()
  248 + shape = shapely.geometry.asShape(shapefile_record['geometry'])
  249 + x_min, y_min, x_max, y_max = shape.bounds
  250 + rayonTerre = 6371.0
  251 +
  252 + #
  253 + for index,val in tmp.iterrows():
  254 + LON = val['LON']
  255 + LAT = val['LAT']
  256 + T = val['TIME']
  257 + SPT = val['SPOT']
  258 + STA = val['STATUS']
  259 +
  260 + # avant-dernieres positions des spots
  261 + T1 = df.loc[(df['SPOT'] == SPT)\
  262 + & (df['TIME'] < T), 'TIME'][-1:].values
  263 +
  264 + LAT1 = df.loc[(df['SPOT'] == SPT)\
  265 + & ((df['TIME'] < T)), 'LAT'][-1:].values
  266 +
  267 + LON1 = df.loc[(df['SPOT'] == SPT)\
  268 + & ((df['TIME'] < T)), 'LON'][-1:].values
  269 +
  270 +
  271 + if not LAT1:
  272 + LAT1 = LAT
  273 + if not LON1:
  274 + LON1 = LON
  275 + if not T1:
  276 + T1 = T
  277 +
  278 + lat1 = math.radians(LAT)
  279 + lon1 = math.radians(LON)
  280 + tim1 = T
  281 + lat2 = math.radians(LAT1)
  282 + lon2 = math.radians(LON1)
  283 + tim2 = T1
  284 + dlat = math.radians(LAT1 - LAT)
  285 + dlon = math.fabs(math.radians(LON1 - LON))
  286 +
  287 + dPhi = math.log(math.tan(lat2/2+math.pi/4)/math.tan(lat1/2+math.pi/4))
  288 +
  289 + if dPhi <> 0 :
  290 + q = dlat/dPhi
  291 + else :
  292 + q = math.cos(lat1)
  293 +
  294 + #if dLon > 180 degres take shorter rhumb across anti-meridian:
  295 + if math.fabs(dlon) > math.pi :
  296 + if dlon > 0 :
  297 + dlon= -(2*math.pi - dlon)
  298 + else:
  299 + dlon = (2*math.pi + dlon)
  300 +
  301 + dist = math.sqrt(dlat*dlat + q*q*dlon*dlon) * rayonTerre
  302 +
  303 + # si distance non nulle (s'il y a une position anterieur du spot)
  304 + # calcul de la vitesse par rapport a la derniere position connue
  305 + if not dist == 0:
  306 + vitesse = (dist * 1000) / abs((tim2 - tim1)) # m.s-1
  307 + # si vitesse > 1.1 m.s (sur bateau par exemple)
  308 + if vitesse > 1.1:
  309 + val.FLAG = "SPD"
  310 + else:
  311 + val.FLAG = "OCN"
  312 +
  313 + # si distance nulle = marque "NEW"
  314 + if dist == 0:
  315 + val.FLAG = "NEW"
  316 +
  317 + # si position a l'interieur du trait de cote = marque "LND"
  318 + point = shapely.geometry.Point(LON,LAT)
  319 + if shape.contains(point):
  320 + val.FLAG = "LND"
  321 +
  322 + # si LON / LAT incoherent = marque "OUT"
  323 + if (LON < x_min) or (LON > x_max) \
  324 + or (LAT < y_min) or (LAT > y_max):
  325 + val.FLAG = "OUT"
  326 +
  327 + # rajoute les positions flaguees au fichier final
  328 + f = open(fichier_flag, "ab")
  329 + writer = csv.writer(f,delimiter=';',lineterminator="\n")
  330 + data = [ str(SPT), float(round(LAT,6)), float(round(LON,6)), int(T), str(STA), str(val.FLAG)]
  331 + writer.writerow(data)
  332 + f.close
  333 +
219 334  
220 335 #############################################################
221 336 #
222   -# Debut du programme principal
  337 +# Debut du programme principal
223 338 #
224 339 #############################################################
225 340  
226 341 if __name__ == "__main__":
227   -# url = ' http://share.findmespot.com/messageService/guestlinkservlet?glId=03kp21oFnOj8bRHaPQPPAjf2TuO19VRa3'
228   - url = ' https://api.findmespot.com/spot-main-web/consumer/rest-api/2.0/public/feed/0zgtS2Yrxgzl8in5LvVoAg0ae76LfQcdO/message.xml'
229   -# positions = 'positions_mai_2013.xml'
230   - getTags(url)
231   -
232   -ecrirecsv("/home/nicopa01/data/spot/spots_pos.csv")
233   -cleancsv("/home/nicopa01/data/spot/spots_pos_clean.csv")
  342 +# url = ' http://share.findmespot.com/messageService/guestlinkservlet?glId=03kp21oFnOj8bRHaPQPPAjf2TuO19VRa3'
  343 + url = ' https://api.findmespot.com/spot-main-web/consumer/rest-api/2.0/public/feed/0zgtS2Yrxgzl8in5LvVoAg0ae76LfQcdO/message.xml'
  344 + getTags(url)
234 345  
  346 +ecrirecsv("/share/archives/partage_lasso/spot/tmp.csv")
  347 +flagcsv("/share/archives/partage_lasso/spot/spots_pos_flag.csv")
  348 +cleancsv("/share/archives/partage_lasso/spot/spots_pos_flag_clean.csv")
235 349  
236 350 sys.exit(0)
237   -
... ...