-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRoute.jl
233 lines (217 loc) · 11.7 KB
/
Route.jl
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# Functions load route to all programs
# Aut: Adriano Bassignana
# Licence: GPL 2
# Date start production: September 2021
module Route
import Unicode: graphemes # To solve the problem of an error in extracting unicode characters from a string.
using Unicode
using LightXML
using Geodesy
using Printf
using CSV
using DataFrames
using Serialization
include("./Commons.jl")
include("./ScanDir.jl")
export loadRoute
function findFileOfRoute(fileName::String,idTypeOfFile::Int=0)
typeOfFile = [("FGFS","route"),("GPX","rte")]
date = 0.0
fileId = 0
route = nothing
files = Commons.findFile(fileName)
typeOfFileSelected = Nothing
for file in files
if file[3] >= date
# Test the file
try
if idTypeOfFile > 0
route = get_elements_by_tagname(LightXML.root(parse_file(file[2])),typeOfFile[idTypeOfFile][2])
typeOfFileSelected = typeOfFile[idTypeOfFile][1]
else
for (nameFormat,selector) in typeOfFile
route = get_elements_by_tagname(LightXML.root(parse_file(file[2])),selector)
typeOfFileSelected = nameFormat
if size(route)[1] > 0 break end
end
end
fileId = file[1]
date = file[3]
catch
end
end
end
if fileId > 0
return route,files[fileId][2],typeOfFileSelected
else
return nothing
end
end
# Select lat lon by ICAO airport id or name or municipality
function selectIcao(icaoToSelect, centralPointRadiusDistance)
centralPointLat = nothing
centralPointLon = nothing
errorCode = 0
retrayNumber = 0
# Test the DB csv or jdb
while retrayNumber <= 1
if stat("airports.csv").mtime > stat("airports.jls").mtime
println("\nThe airports database 'airports.csv' is loading for conversion to airports.jls file")
serialize("airports.jls",DataFrame(CSV.File("airports.csv")))
println("The airports database 'airports.jls' is converted")
elseif stat("airports.jls").mtime == 0.0
println("\nError: The airports.jls file and airports.csv file is unreachable!\nPlease, make sure it is present in the photoscenary.jl program directory")
errorCode = 403
retrayNumber = 9
end
if errorCode == 0
try
db = deserialize("airports.jls")
# println("\nThe airports database 'airports.csv' is loading")
searchString = Unicode.normalize(uppercase(icaoToSelect),stripmark=true)
# Frist step try with ICAO ident
foundDatas = filter(i -> (i.ident == searchString),db)
if size(foundDatas)[1] == 0
foundDatas = filter(i -> occursin(searchString,Unicode.normalize(uppercase(i.municipality),stripmark=true)),dropmissing(df,:municipality))
end
if size(foundDatas)[1] == 0
foundDatas = filter(i -> occursin(searchString,Unicode.normalize(uppercase(i.name),stripmark=true)),dropmissing(df,:name))
end
if size(foundDatas)[1] == 1
if centralPointRadiusDistance == nothing || centralPointRadiusDistance <= 1.0 centralPointRadiusDistance = 10.0 end
centralPointLat = foundDatas[1,:latitude_deg]
centralPointLon = foundDatas[1,:longitude_deg]
# Some airports have the location data multiplied by a thousand, in this case we proceed to the reduction
if !(Commons.inValue(centralPointLat,90) && Commons.inValue(centralPointLon,180))
if abs(centralPointLat) > 1000.0 centralPointLat /= 1000.0 end
if abs(centralPointLon) > 1000.0 centralPointLon /= 1000.0 end
end
println("\nThe ICAO term $(icaoToSelect) is found in the database\n\tIdent: $(foundDatas[1,:ident])\n\tName: $(foundDatas[1,:name])\n\tCity: $(foundDatas[1,:municipality])\n\tCentral point lat: $(round(centralPointLat,digits=4)) lon: $(round(centralPointLon,digits=4)) radius: $centralPointRadiusDistance nm")
else
if size(foundDatas)[1] == 0 > 1
errorCode = 401
println("\nError: The ICAO search term $(icaoToSelect) is ambiguous, there are $(size(foundDatas)[1]) airports with a similar term")
for i in 1:min(size(foundDatas)[1],30)
println("\tId: $(foundDatas[i,:ident])\tname: $(foundDatas[i,:name]) ($(foundDatas[i,:municipality]))")
end
else
errorCode = 400
println("\nError: The ICAO search term $(icaoToSelect) is not found in the airports.csv database")
end
end
retrayNumber = 9
catch err
if retrayNumber == 0
retrayNumber = 1
println("\nError: The airports.csv file is corrupt or not exist")
errorCode = 403
else
println("\nError: The airports.csv file is corrupt\n\tPlease, make sure if airports.csv file is present in the program directory\n\tand restart the program\nError code is $err")
errorCode = 404
retrayNumber = 9
end
end
end
if retrayNumber == 0 retrayNumber = 9 end
end
return centralPointLat, centralPointLon, errorCode
end
function getRouteListFormatFGFS!(routeList,route,minDistance)
wps = LightXML.get_elements_by_tagname(route[1][1], "wp")
centralPointLatPrec = nothing
centralPointLonPrec = nothing
for wp in wps
foundData = false
if wp != nothing
if find_element(wp,"icao") != nothing
icao = strip(content(find_element(wp,"icao")))
(centralPointLat, centralPointLon, errorCode) = selectIcao(icao,minDistance)
if errorCode == 0 foundData = true end
elseif find_element(wp,"lon") != nothing
centralPointLat = Base.parse(Float64, strip(content(find_element(wp,"lat"))))
centralPointLon = Base.parse(Float64, strip(content(find_element(wp,"lon"))))
foundData = true
end
if foundData
# Get the distance
if centralPointLatPrec != nothing && centralPointLonPrec != nothing
posPrec = Geodesy.LLA(centralPointLatPrec,centralPointLonPrec, 0.0)
pos = Geodesy.LLA(centralPointLat,centralPointLon, 0.0)
distanceNm = euclidean_distance(pos,posPrec) / 1852.0
else
distanceNm = 0.0
end
if minDistance < distanceNm
numberTrunk = Int32(round(distanceNm / minDistance))
for i in 1:(numberTrunk - 1)
degLat = centralPointLatPrec + i * (centralPointLat - centralPointLatPrec) / numberTrunk
deglon = centralPointLonPrec + i * (centralPointLon - centralPointLonPrec) / numberTrunk
dist = euclidean_distance(Geodesy.LLA(degLat,deglon, 0.0),posPrec) / 1852.0
push!(routeList,(degLat, deglon, dist))
println("Load Route step $(size(routeList)[1]).$i coordinates lat: $(round(routeList[end][1],digits=4)) lon: $(round(routeList[end][2],digits=4)) distance: $(round(dist,digits=1))")
end
end
push!(routeList,(centralPointLat, centralPointLon, distanceNm))
println("Load Route step $(size(routeList)[1]).0 coordinates lat: $(round(routeList[end][1],digits=4)) lon: $(round(routeList[end][2],digits=4)) distance: $(round(distanceNm,digits=1))")
centralPointLatPrec = centralPointLat
centralPointLonPrec = centralPointLon
end
end
end
return routeList
end
function getRouteListFormatGPX!(routeList,route,minDistance)
wps = LightXML.get_elements_by_tagname(route[1][1], "rtept")
centralPointLatPrec = nothing
centralPointLonPrec = nothing
for wp in wps
if wp != nothing
if attribute(wp,"lon") != nothing && attribute(wp,"lat") != nothing
centralPointLat = Base.parse(Float64, strip(attribute(wp,"lat")))
centralPointLon = Base.parse(Float64, strip(attribute(wp,"lon")))
# Get the distance
if centralPointLatPrec != nothing && centralPointLonPrec != nothing
posPrec = Geodesy.LLA(centralPointLatPrec,centralPointLonPrec, 0.0)
pos = Geodesy.LLA(centralPointLat,centralPointLon, 0.0)
distanceNm = euclidean_distance(pos,posPrec) / 1852.0
else
distanceNm = 0.0
end
if minDistance < distanceNm
numberTrunk = Int32(round(distanceNm / minDistance))
for i in 1:(numberTrunk - 1)
degLat = centralPointLatPrec + i * (centralPointLat - centralPointLatPrec) / numberTrunk
deglon = centralPointLonPrec + i * (centralPointLon - centralPointLonPrec) / numberTrunk
dist = euclidean_distance(Geodesy.LLA(degLat,deglon, 0.0),posPrec) / 1852.0
push!(routeList,(degLat, deglon, dist))
println("Load Route step $(size(routeList)[1]).$i coordinates lat: $(round(routeList[end][1],digits=4)) lon: $(round(routeList[end][2],digits=4)) distance: $(round(dist,digits=1))")
end
end
push!(routeList,(centralPointLat, centralPointLon, distanceNm))
println("Load Route step $(size(routeList)[1]).0 coordinates lat: $(round(routeList[end][1],digits=4)) lon: $(round(routeList[end][2],digits=4)) distance: $(round(distanceNm,digits=1))")
centralPointLatPrec = centralPointLat
centralPointLonPrec = centralPointLon
end
end
end
return routeList
end
function loadRoute(fileOfRoute,centralPointRadiusDistance)
centralPointRadiusDistanceFactor = 0.5
minDistance = centralPointRadiusDistance * centralPointRadiusDistanceFactor
route = findFileOfRoute(fileOfRoute)
routeList = Any[]
if route != nothing
if route[3] == "FGFS"
getRouteListFormatFGFS!(routeList,route,minDistance)
elseif route[3] == "GPX"
getRouteListFormatGPX!(routeList,route,minDistance)
else
end
else
println("\nError: loadRoute in the route file: $fileOfRoute")
end
#ccall(:jl_exit, Cvoid, (Int32,), 405)
return routeList, size(routeList)[1]
end
end