Showing 3 changed files with 1049 additions and 113 deletions
+629
Models/MapIcons.svg
... ...
@@ -0,0 +1,629 @@
1
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
3
+
4
+<svg
5
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
6
+   xmlns:cc="http://creativecommons.org/ns#"
7
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
+   xmlns:svg="http://www.w3.org/2000/svg"
9
+   xmlns="http://www.w3.org/2000/svg"
10
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
+   width="546.13336"
13
+   height="546.13336"
14
+   id="svg2"
15
+   version="1.1"
16
+   inkscape:version="0.92.1 r15371"
17
+   sodipodi:docname="MapIcons.svg">
18
+  <defs
19
+     id="defs4">
20
+    <inkscape:perspective
21
+       sodipodi:type="inkscape:persp3d"
22
+       inkscape:vp_x="0 : 0.53333333 : 1"
23
+       inkscape:vp_y="0 : 1066.6667 : 0"
24
+       inkscape:vp_z="1.0666667 : 0.53333333 : 1"
25
+       inkscape:persp3d-origin="0.53333333 : 0.35555555 : 1"
26
+       id="perspective4043" />
27
+    <inkscape:perspective
28
+       sodipodi:type="inkscape:persp3d"
29
+       inkscape:vp_x="0 : 0.53333333 : 1"
30
+       inkscape:vp_y="0 : 1066.6667 : 0"
31
+       inkscape:vp_z="1.0666667 : 0.53333333 : 1"
32
+       inkscape:persp3d-origin="0.53333333 : 0.35555555 : 1"
33
+       id="perspective4001" />
34
+    <inkscape:perspective
35
+       sodipodi:type="inkscape:persp3d"
36
+       inkscape:vp_x="0 : 0.53333333 : 1"
37
+       inkscape:vp_y="0 : 1066.6667 : 0"
38
+       inkscape:vp_z="1.0666667 : 0.53333333 : 1"
39
+       inkscape:persp3d-origin="0.53333333 : 0.35555555 : 1"
40
+       id="perspective3970" />
41
+    <inkscape:perspective
42
+       sodipodi:type="inkscape:persp3d"
43
+       inkscape:vp_x="0 : 0.53333333 : 1"
44
+       inkscape:vp_y="0 : 1066.6667 : 0"
45
+       inkscape:vp_z="1.0666667 : 0.53333333 : 1"
46
+       inkscape:persp3d-origin="0.53333333 : 0.35555555 : 1"
47
+       id="perspective3942" />
48
+    <inkscape:perspective
49
+       sodipodi:type="inkscape:persp3d"
50
+       inkscape:vp_x="0 : 0.53333333 : 1"
51
+       inkscape:vp_y="0 : 1066.6667 : 0"
52
+       inkscape:vp_z="1.0666667 : 0.53333333 : 1"
53
+       inkscape:persp3d-origin="0.53333333 : 0.35555555 : 1"
54
+       id="perspective3893" />
55
+    <inkscape:perspective
56
+       id="perspective3883"
57
+       inkscape:persp3d-origin="396.85039 : 374.17322 : 1"
58
+       inkscape:vp_z="793.70078 : 561.25983 : 1"
59
+       inkscape:vp_y="0 : 1066.6667 : 0"
60
+       inkscape:vp_x="0 : 561.25983 : 1"
61
+       sodipodi:type="inkscape:persp3d" />
62
+  </defs>
63
+  <sodipodi:namedview
64
+     id="base"
65
+     pagecolor="#ffffff"
66
+     bordercolor="#666666"
67
+     borderopacity="1.0"
68
+     inkscape:pageopacity="0.0"
69
+     inkscape:pageshadow="2"
70
+     inkscape:zoom="2.0000001"
71
+     inkscape:cx="329.97268"
72
+     inkscape:cy="350.78415"
73
+     inkscape:document-units="px"
74
+     inkscape:current-layer="svg2"
75
+     showgrid="true"
76
+     inkscape:snap-object-midpoints="false"
77
+     inkscape:window-width="1600"
78
+     inkscape:window-height="836"
79
+     inkscape:window-x="0"
80
+     inkscape:window-y="27"
81
+     inkscape:window-maximized="1"
82
+     inkscape:snap-page="true"
83
+     inkscape:snap-bbox="true"
84
+     showguides="true"
85
+     inkscape:guide-bbox="true"
86
+     inkscape:bbox-nodes="true">
87
+    <sodipodi:guide
88
+       orientation="1,0"
89
+       position="91.733333,473.66726"
90
+       id="guide4221"
91
+       inkscape:locked="false" />
92
+    <inkscape:grid
93
+       type="xygrid"
94
+       id="grid4225"
95
+       empspacing="5"
96
+       visible="true"
97
+       enabled="true"
98
+       snapvisiblegridlinesonly="true"
99
+       originx="0"
100
+       originy="0"
101
+       spacingx="1.0666667"
102
+       spacingy="1.0666667" />
103
+    <sodipodi:guide
104
+       orientation="0,1"
105
+       position="56.533333,473.6"
106
+       id="guide3103"
107
+       inkscape:locked="false" />
108
+  </sodipodi:namedview>
109
+  <metadata
110
+     id="metadata7">
111
+    <rdf:RDF>
112
+      <cc:Work
113
+         rdf:about="">
114
+        <dc:format>image/svg+xml</dc:format>
115
+        <dc:type
116
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
117
+        <dc:title />
118
+      </cc:Work>
119
+    </rdf:RDF>
120
+  </metadata>
121
+  <g
122
+     id="Airplane"
123
+     inkscape:label="Airplane">
124
+    <path
125
+       inkscape:label="airplane"
126
+       sodipodi:nodetypes="zccccccccccccccccz"
127
+       inkscape:connector-curvature="0"
128
+       id="airplane"
129
+       d="m 271.66668,193.46668 c -2.79029,0 -5,3 -5,3 v 8.5 l -13.5,5.5 v 5 h 13.5 v 9 l -3.5,4 v 4 h 17 v -4 l -3.5,-4 v -9 h 13.5 v -5 l -13.5,-5.5 v -8.5 c 0,0 -2.20971,-3 -5,-3 z"
130
+       style="display:inline;fill:#ff0005;fill-opacity:1;fill-rule:evenodd;stroke:none" />
131
+  </g>
132
+  <g
133
+     inkscape:label="NavAids"
134
+     id="layer1">
135
+    <path
136
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:5.33333349;marker:none;enable-background:accumulate"
137
+       d="m 38.007292,439.46667 -12,21.33333 12,21.33333 h 24 l 12,-21.33333 -12,-21.33333 z m 3.016394,5.3838 H 58.990897 L 67.974502,460.8 58.990897,476.74953 H 41.023686 L 32.040081,460.8 Z"
138
+       id="Navaid_VOR"
139
+       inkscape:connector-curvature="0"
140
+       sodipodi:nodetypes="cccccccccccccc" />
141
+    <path
142
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#0000ff;fill-opacity:1;stroke:none;stroke-width:3.20000005;marker:none;enable-background:accumulate"
143
+       d="m 106.66667,434.13333 v 53.33334 H 160 v -53.33334 z m 3.2,3.2 H 156.8 v 46.93334 h -46.93333 z"
144
+       id="Navaid_DME"
145
+       inkscape:connector-curvature="0"
146
+       sodipodi:nodetypes="cccccccccc" />
147
+    <path
148
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;fill-rule:nonzero;stroke:#00ffff;stroke-width:3.20000005;marker:none;enable-background:accumulate"
149
+       d="m 31.307291,535.43289 18.7,-32.375 18.7,32.375 3.125002,0.6 -20.774997,-36 c -0.222955,-0.38866 -0.678059,-0.63136 -1.125003,-0.6 -0.397205,0.0217 -0.776672,0.25516 -0.974997,0.6 l -20.775006,36 z"
150
+       id="Navaid_Height"
151
+       inkscape:connector-curvature="0"
152
+       sodipodi:nodetypes="ccccccccc" />
153
+    <path
154
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;fill-rule:nonzero;stroke:#00ffff;stroke-width:3.20000005;marker:none;enable-background:accumulate"
155
+       d="m 122.6,499.4 c -0.39721,0.0217 -0.76834,0.25517 -0.96667,0.6 l -20.8,36 3.13334,-0.6 18.7,-32.36667 9.26666,16.06667 -9.76666,16.9 3.13333,-0.6 8.03333,-13.9 8.03334,13.9 L 144.5,536 134.73333,519.06667 144,503.03333 162.7,535.4 l 3.13333,0.6 -20.76666,-36 c -0.22296,-0.38865 -0.68639,-0.63136 -1.13334,-0.6 -0.3972,0.0217 -0.76834,0.25517 -0.96666,0.6 l -9.63334,16.66667 -9.6,-16.66667 c -0.22295,-0.38865 -0.68639,-0.63136 -1.13333,-0.6 z"
156
+       id="Navaid_Height2"
157
+       inkscape:connector-curvature="0" />
158
+    <g
159
+       id="Navaid_NDB"
160
+       transform="translate(-92.533343,-1.8666667)"
161
+       inkscape:label="Navaid_NDB">
162
+      <circle
163
+         id="path3586"
164
+         style="fill:none;stroke:#c87137;stroke-width:1.06666672;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
165
+         cx="296.93335"
166
+         cy="459.06668"
167
+         r="6.4533334" />
168
+      <circle
169
+         id="path3588"
170
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
171
+         cx="296.93335"
172
+         cy="459.06668"
173
+         r="0.66666669" />
174
+      <circle
175
+         id="path3648"
176
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
177
+         cx="296.93335"
178
+         cy="448.39999"
179
+         r="0.66666669" />
180
+      <circle
181
+         id="path3650"
182
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
183
+         cx="296.93335"
184
+         cy="469.73334"
185
+         r="0.66666669" />
186
+      <circle
187
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
188
+         id="path3658"
189
+         transform="rotate(-30)"
190
+         cx="27.618488"
191
+         cy="535.3634"
192
+         r="0.66666669" />
193
+      <circle
194
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
195
+         id="path3660"
196
+         transform="rotate(-30)"
197
+         cx="27.618486"
198
+         cy="556.69672"
199
+         r="0.66666669" />
200
+      <circle
201
+         transform="rotate(-60)"
202
+         id="path3664"
203
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
204
+         cx="-249.09673"
205
+         cy="476.01849"
206
+         r="0.66666669" />
207
+      <circle
208
+         transform="rotate(-60)"
209
+         id="path3666"
210
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
211
+         cx="-249.09673"
212
+         cy="497.35184"
213
+         r="0.66666669" />
214
+      <circle
215
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
216
+         id="path3670"
217
+         transform="rotate(-90)"
218
+         cx="-459.06668"
219
+         cy="286.26669"
220
+         r="0.66666669" />
221
+      <circle
222
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
223
+         id="path3672"
224
+         transform="rotate(-90)"
225
+         cx="-459.06668"
226
+         cy="307.60001"
227
+         r="0.66666669" />
228
+      <circle
229
+         transform="rotate(-120)"
230
+         id="path3676"
231
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
232
+         cx="-546.03009"
233
+         cy="16.95182"
234
+         r="0.66666669" />
235
+      <circle
236
+         transform="rotate(-120)"
237
+         id="path3678"
238
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
239
+         cx="-546.03009"
240
+         cy="38.285156"
241
+         r="0.66666669" />
242
+      <circle
243
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
244
+         id="path3682"
245
+         transform="rotate(-150)"
246
+         cx="-486.68518"
247
+         cy="-259.7634"
248
+         r="0.66666669" />
249
+      <circle
250
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
251
+         id="path3684"
252
+         transform="rotate(-150)"
253
+         cx="-486.68518"
254
+         cy="-238.43005"
255
+         r="0.66666669" />
256
+      <circle
257
+         transform="rotate(-24.999996)"
258
+         id="path3686"
259
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
260
+         cx="75.103081"
261
+         cy="525.54517"
262
+         r="0.66666669" />
263
+      <circle
264
+         transform="rotate(-24.999996)"
265
+         id="path3688"
266
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
267
+         cx="75.103065"
268
+         cy="557.54517"
269
+         r="0.66666669" />
270
+      <circle
271
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
272
+         id="path3696"
273
+         transform="rotate(-45.000005)"
274
+         cx="-114.64561"
275
+         cy="518.57269"
276
+         r="0.66666663" />
277
+      <circle
278
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
279
+         id="path3698"
280
+         transform="rotate(-45.000005)"
281
+         cx="-114.64561"
282
+         cy="550.57269"
283
+         r="0.66666663" />
284
+      <circle
285
+         transform="rotate(-64.999999)"
286
+         id="path3702"
287
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
288
+         cx="-290.56622"
289
+         cy="447.12299"
290
+         r="0.66666669" />
291
+      <circle
292
+         transform="rotate(-64.999999)"
293
+         id="path3704"
294
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
295
+         cx="-290.56622"
296
+         cy="479.12299"
297
+         r="0.66666669" />
298
+      <circle
299
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
300
+         id="path3708"
301
+         transform="rotate(-84.999999)"
302
+         cx="-431.44031"
303
+         cy="319.81372"
304
+         r="0.66666663" />
305
+      <circle
306
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
307
+         id="path3710"
308
+         transform="rotate(-84.999999)"
309
+         cx="-431.44031"
310
+         cy="351.81372"
311
+         r="0.66666663" />
312
+      <circle
313
+         transform="rotate(-105)"
314
+         id="path3714"
315
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
316
+         cx="-520.27631"
317
+         cy="152.00043"
318
+         r="0.66666663" />
319
+      <circle
320
+         transform="rotate(-105)"
321
+         id="path3716"
322
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
323
+         cx="-520.27631"
324
+         cy="184.00043"
325
+         r="0.66666663" />
326
+      <circle
327
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
328
+         id="path3720"
329
+         transform="rotate(-125)"
330
+         cx="-546.35938"
331
+         cy="-36.076218"
332
+         r="0.66666663" />
333
+      <circle
334
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
335
+         id="path3722"
336
+         transform="rotate(-125)"
337
+         cx="-546.35938"
338
+         cy="-4.0762215"
339
+         r="0.66666663" />
340
+      <circle
341
+         transform="rotate(-145)"
342
+         id="path3726"
343
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
344
+         cx="-506.5434"
345
+         cy="-221.73141"
346
+         r="0.66666657" />
347
+      <circle
348
+         transform="rotate(-145)"
349
+         id="path3728"
350
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
351
+         cx="-506.5434"
352
+         cy="-189.7314"
353
+         r="0.66666657" />
354
+      <circle
355
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
356
+         id="path3732"
357
+         transform="rotate(-164.99999)"
358
+         cx="-405.63083"
359
+         cy="-382.5723"
360
+         r="0.66666657" />
361
+      <circle
362
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
363
+         id="path3734"
364
+         transform="rotate(-164.99999)"
365
+         cx="-405.63083"
366
+         cy="-350.5723"
367
+         r="0.66666657" />
368
+      <circle
369
+         transform="rotate(175.00001)"
370
+         id="path3738"
371
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
372
+         cx="-255.79318"
373
+         cy="-499.19922"
374
+         r="0.66666657" />
375
+      <circle
376
+         transform="rotate(175.00001)"
377
+         id="path3740"
378
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
379
+         cx="-255.79318"
380
+         cy="-467.19922"
381
+         r="0.66666657" />
382
+      <circle
383
+         id="path3742"
384
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
385
+         cx="296.93335"
386
+         cy="480.39999"
387
+         r="0.66666669" />
388
+      <circle
389
+         id="path3744"
390
+         style="fill:none;stroke:#c87137;stroke-width:2.13333344;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
391
+         cx="296.93335"
392
+         cy="437.73334"
393
+         r="0.66666669" />
394
+      <circle
395
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
396
+         id="path3752"
397
+         transform="rotate(-14.999998)"
398
+         cx="168.00041"
399
+         cy="541.60968"
400
+         r="0.66666663" />
401
+      <circle
402
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
403
+         id="path3754"
404
+         transform="rotate(-14.999998)"
405
+         cx="168.00041"
406
+         cy="498.94302"
407
+         r="0.66666663" />
408
+      <circle
409
+         transform="rotate(-29.999994)"
410
+         id="path3758"
411
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
412
+         cx="27.61853"
413
+         cy="567.3634"
414
+         r="0.66666663" />
415
+      <circle
416
+         transform="rotate(-29.999994)"
417
+         id="path3760"
418
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
419
+         cx="27.618536"
420
+         cy="524.69672"
421
+         r="0.66666663" />
422
+      <circle
423
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
424
+         id="path3764"
425
+         transform="rotate(-44.999995)"
426
+         cx="-114.64552"
427
+         cy="555.90607"
428
+         r="0.66666663" />
429
+      <circle
430
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
431
+         id="path3766"
432
+         transform="rotate(-44.999995)"
433
+         cx="-114.64553"
434
+         cy="513.23944"
435
+         r="0.66666663" />
436
+      <circle
437
+         transform="rotate(-59.999996)"
438
+         id="path3770"
439
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
440
+         cx="-249.09669"
441
+         cy="508.01849"
442
+         r="0.66666657" />
443
+      <circle
444
+         transform="rotate(-59.999996)"
445
+         id="path3772"
446
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
447
+         cx="-249.09669"
448
+         cy="465.35184"
449
+         r="0.66666657" />
450
+      <circle
451
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
452
+         id="path3776"
453
+         transform="rotate(-74.999994)"
454
+         cx="-366.57233"
455
+         cy="426.96414"
456
+         r="0.66666657" />
457
+      <circle
458
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
459
+         id="path3778"
460
+         transform="rotate(-74.999994)"
461
+         cx="-366.57233"
462
+         cy="384.29749"
463
+         r="0.66666657" />
464
+      <circle
465
+         transform="rotate(-89.999995)"
466
+         id="path3782"
467
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
468
+         cx="-459.06665"
469
+         cy="318.26669"
470
+         r="0.66666663" />
471
+      <circle
472
+         transform="rotate(-89.999995)"
473
+         id="path3784"
474
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
475
+         cx="-459.06665"
476
+         cy="275.60004"
477
+         r="0.66666663" />
478
+      <circle
479
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
480
+         id="path3788"
481
+         transform="rotate(-104.99999)"
482
+         cx="-520.27637"
483
+         cy="189.33377"
484
+         r="0.66666663" />
485
+      <circle
486
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
487
+         id="path3790"
488
+         transform="rotate(-104.99999)"
489
+         cx="-520.27637"
490
+         cy="146.66711"
491
+         r="0.66666663" />
492
+      <circle
493
+         transform="rotate(-119.99999)"
494
+         id="path3794"
495
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
496
+         cx="-546.03009"
497
+         cy="48.951866"
498
+         r="0.66666663" />
499
+      <circle
500
+         transform="rotate(-119.99999)"
501
+         id="path3796"
502
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
503
+         cx="-546.03009"
504
+         cy="6.2852001"
505
+         r="0.66666663" />
506
+      <circle
507
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
508
+         id="path3800"
509
+         transform="rotate(-135)"
510
+         cx="-534.57275"
511
+         cy="-93.312202"
512
+         r="0.66666663" />
513
+      <circle
514
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
515
+         id="path3802"
516
+         transform="rotate(-135)"
517
+         cx="-534.57275"
518
+         cy="-135.97887"
519
+         r="0.66666663" />
520
+      <circle
521
+         transform="rotate(-150)"
522
+         id="path3806"
523
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
524
+         cx="-486.68515"
525
+         cy="-227.76337"
526
+         r="0.66666657" />
527
+      <circle
528
+         transform="rotate(-150)"
529
+         id="path3808"
530
+         style="fill:none;stroke:#c87137;stroke-width:2.13333321;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
531
+         cx="-486.68515"
532
+         cy="-270.43002"
533
+         r="0.66666657" />
534
+      <circle
535
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
536
+         id="path3812"
537
+         transform="rotate(-164.99999)"
538
+         cx="-405.63083"
539
+         cy="-345.23898"
540
+         r="0.66666657" />
541
+      <circle
542
+         style="fill:none;stroke:#c87137;stroke-width:2.13333297;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
543
+         id="path3814"
544
+         transform="rotate(-164.99999)"
545
+         cx="-405.6308"
546
+         cy="-387.90564"
547
+         r="0.66666657" />
548
+    </g>
549
+    <path
550
+       sodipodi:nodetypes="ccccccccccccc"
551
+       d="m 292.35213,454.9857 10.31454,-5.95477 -7.83102,-13.56371 -10.31453,5.95964 -15.65357,-2.8e-4 -10.31405,-5.95991 -7.831,13.56371 10.31404,5.95504 7.82654,13.55161 v 11.91481 h 15.66202 v -11.91481 z"
552
+       style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#0000ff;stroke-width:2.66666675;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
553
+       id="Navaid_TACAN"
554
+       inkscape:connector-curvature="0"
555
+       inkscape:label="Navaid_TACAN" />
556
+  </g>
557
+  <g
558
+     id="Aiports"
559
+     inkscape:label="Airports">
560
+    <path
561
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;stroke:none;stroke-width:1.06666672;marker:none;enable-background:accumulate"
562
+       d="m 52.225958,302.4 v 3.92533 c -5.672973,0.88849 -10.226389,5.383 -11.114666,11.09334 h -3.904 v 4.096 h 3.904 c 0.888277,5.71032 5.441693,10.20484 11.114666,11.09333 v 3.92533 h 4.096 V 332.608 c 5.672974,-0.88849 10.22639,-5.38301 11.114667,-11.09333 h 3.904 v -4.096 h -3.904 C 66.548348,311.70833 61.994932,307.21382 56.321958,306.32533 V 302.4 Z m 2.048,7.808 c 5.232883,0 9.365334,4.15463 9.365334,9.25867 0,5.10403 -4.132451,9.25866 -9.365334,9.25866 -5.232867,0 -9.386666,-4.15463 -9.386666,-9.25866 0,-5.10404 4.153799,-9.25867 9.386666,-9.25867 z"
563
+       id="Airport_0011"
564
+       inkscape:connector-curvature="0" />
565
+    <path
566
+       inkscape:connector-curvature="0"
567
+       id="Airport_1011"
568
+       d="M 117.2073,297.06667 V 303.2 c -8.86401,1.38826 -15.97874,8.41093 -17.366673,17.33333 h -6.1 v 6.4 h 6.1 c 1.387933,8.92238 8.502663,15.94507 17.366673,17.33334 V 350.4 h 6.4 v -6.13333 c 8.86402,-1.38827 15.97873,-8.41096 17.36666,-17.33334 h 6.1 v -6.4 h -6.1 C 139.58603,311.61093 132.47132,304.58826 123.6073,303.2 v -6.13333 z m 3.2,12.2 c 8.17638,0 14.63333,6.49161 14.63333,14.46666 0,7.97504 -6.45695,14.46667 -14.63333,14.46667 -8.17637,0 -14.66667,-6.49163 -14.66667,-14.46667 0,-7.97505 6.4903,-14.46666 14.66667,-14.46666 z"
569
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" />
570
+    <path
571
+       inkscape:connector-curvature="0"
572
+       id="Airport_0111"
573
+       d="m 51.756626,373.86669 v 3.80266 c -5.495686,0.86073 -9.906813,5.21478 -10.767333,10.74667 h -3.782 v 3.968 h 3.782 c 0.86052,5.53187 5.271647,9.88594 10.767333,10.74667 v 3.80266 h 3.968 v -3.80266 c 5.495694,-0.86073 9.906814,-5.2148 10.767335,-10.74667 h 3.782 v -3.968 h -3.782 C 65.63144,382.88413 61.22032,378.53008 55.724626,377.66935 v -3.80266 z"
574
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;stroke:none;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
575
+       sodipodi:nodetypes="ccccccccccccccccc" />
576
+    <path
577
+       sodipodi:nodetypes="ccccccccccccccccc"
578
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1.06666672;marker:none;enable-background:accumulate"
579
+       d="m 52.225958,232 v 3.92533 c -5.672967,0.88849 -10.226388,5.383 -11.114666,11.09334 h -3.904 v 4.096 h 3.904 c 0.888278,5.71032 5.441699,10.20484 11.114666,11.09333 v 3.92533 h 4.096 V 262.208 c 5.672974,-0.88849 10.226389,-5.38301 11.114667,-11.09333 h 3.904 v -4.096 h -3.904 C 66.548347,241.30833 61.994932,236.81382 56.321958,235.92533 V 232 Z"
580
+       id="Airport_0110"
581
+       inkscape:connector-curvature="0" />
582
+    <path
583
+       inkscape:connector-curvature="0"
584
+       id="Airport_0010"
585
+       d="m 50.218667,165.33333 v 3.92534 C 44.5457,170.14716 39.992279,174.64166 39.104,180.352 H 35.2 v 4.096 h 3.904 c 0.888279,5.71031 5.4417,10.20484 11.114667,11.09333 v 3.92534 h 4.096 v -3.92534 c 5.672974,-0.88849 10.226387,-5.38302 11.114666,-11.09333 h 3.904 v -4.096 h -3.904 c -0.888279,-5.71034 -5.441692,-10.20484 -11.114666,-11.09333 v -3.92534 z m 2.048,7.808 c 5.232885,0 9.365333,4.15465 9.365333,9.25867 0,5.10402 -4.132448,9.25867 -9.365333,9.25867 -5.232873,0 -9.386667,-4.15465 -9.386667,-9.25867 0,-5.10402 4.153794,-9.25867 9.386667,-9.25867 z"
586
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:1.06666672;marker:none;enable-background:accumulate" />
587
+    <path
588
+       inkscape:connector-curvature="0"
589
+       id="Airport_0000"
590
+       d="m 50.017249,28.8 c -7.280957,0 -13.343291,5.954941 -13.343291,13.333333 0,7.378413 6.062334,13.333334 13.343291,13.333334 7.280963,0 13.323376,-5.954921 13.323376,-13.333334 C 63.340625,34.754941 57.298212,28.8 50.017249,28.8 Z m 0,6.238524 c 4.096313,0 7.249192,3.190264 7.249192,7.094809 0,3.904545 -3.152879,7.09481 -7.249192,7.09481 -4.096311,0 -7.269105,-3.190265 -7.269105,-7.09481 0,-3.904545 3.172794,-7.094809 7.269105,-7.094809 z"
591
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:none;stroke-width:10.18105507;marker:none;enable-background:accumulate" />
592
+    <path
593
+       sodipodi:nodetypes="sssss"
594
+       inkscape:connector-curvature="0"
595
+       id="Airport_0100"
596
+       d="m 50.017249,99.2 c -7.280958,0 -13.343291,5.95494 -13.343291,13.33333 0,7.37841 6.062333,13.33334 13.343291,13.33334 7.280963,0 13.323376,-5.95493 13.323376,-13.33334 0,-7.37839 -6.042413,-13.33333 -13.323374,-13.33333 z"
597
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.18105507;marker:none;enable-background:accumulate" />
598
+    <path
599
+       inkscape:connector-curvature="0"
600
+       id="Airport_1000"
601
+       d="m 120.4073,21.333333 c -11.39967,0 -20.800006,9.297357 -20.800006,20.800011 0,11.502633 9.400336,20.799989 20.800006,20.799989 11.39965,0 20.8,-9.297356 20.8,-20.799989 0,-11.502654 -9.40035,-20.800011 -20.8,-20.800011 z m 0,6.335035 c 8.17637,0 14.63196,6.489921 14.63196,14.464976 0,7.975055 -6.45559,14.464955 -14.63196,14.464955 -8.17638,0 -14.66624,-6.4899 -14.66624,-14.464955 0,-7.975055 6.48986,-14.464976 14.66624,-14.464976 z"
602
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate" />
603
+    <path
604
+       sodipodi:nodetypes="ccccccccccccccccc"
605
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#00ffff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
606
+       d="M 117.2073,367.46667 V 373.6 c -8.86401,1.38826 -15.97874,8.41093 -17.366673,17.33333 h -6.1 v 6.4 h 6.1 c 1.387933,8.92238 8.502663,15.94508 17.366673,17.33334 V 420.8 h 6.4 v -6.13333 c 8.86402,-1.38826 15.97873,-8.41096 17.36666,-17.33334 h 6.1 v -6.4 h -6.1 C 139.58603,382.01093 132.47132,374.98826 123.6073,373.6 v -6.13333 z"
607
+       id="Airport_1111"
608
+       inkscape:connector-curvature="0" />
609
+    <path
610
+       inkscape:connector-curvature="0"
611
+       id="Airport_1110"
612
+       d="M 117.2073,226.66667 V 232.8 c -8.86401,1.38826 -15.97874,8.41093 -17.366673,17.33333 h -6.1 v 6.4 h 6.1 c 1.387933,8.92238 8.502663,15.94507 17.366673,17.33334 V 280 h 6.4 v -6.13333 c 8.86402,-1.38827 15.97873,-8.41096 17.36666,-17.33334 h 6.1 v -6.4 h -6.1 C 139.58603,241.21093 132.47132,234.18826 123.6073,232.8 v -6.13333 z"
613
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
614
+       sodipodi:nodetypes="ccccccccccccccccc" />
615
+    <path
616
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
617
+       d="M 117.2073,156.26667 V 162.4 c -8.86401,1.38826 -15.97874,8.41093 -17.366673,17.33333 h -6.1 v 6.4 h 6.1 c 1.387933,8.92238 8.502663,15.94507 17.366673,17.33334 V 209.6 h 6.4 v -6.13333 c 8.86402,-1.38827 15.97873,-8.41096 17.36666,-17.33334 h 6.1 v -6.4 h -6.1 C 139.58603,170.81093 132.47132,163.78826 123.6073,162.4 v -6.13333 z m 3.2,12.2 c 8.17638,0 14.63333,6.49161 14.63333,14.46666 0,7.97504 -6.45695,14.46667 -14.63333,14.46667 -8.17637,0 -14.66667,-6.49163 -14.66667,-14.46667 0,-7.97505 6.4903,-14.46666 14.66667,-14.46666 z"
618
+       id="Airport_1010"
619
+       inkscape:connector-curvature="0"
620
+       inkscape:label="Airport_1010" />
621
+    <path
622
+       sodipodi:nodetypes="sssss"
623
+       style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ff00ff;fill-opacity:1;stroke:#000000;stroke-width:1.06666672;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
624
+       d="m 120.4073,91.733333 c -11.39966,0 -20.800006,9.297367 -20.800006,20.799997 0,11.50264 9.400346,20.8 20.800006,20.8 11.39965,0 20.8,-9.29736 20.8,-20.8 0,-11.50263 -9.40035,-20.799997 -20.8,-20.799997 z"
625
+       id="Airport_1100"
626
+       inkscape:connector-curvature="0"
627
+       inkscape:label="Airport_1100" />
628
+  </g>
629
+</svg>
+3 -2
Nasal/display.nas
... ...
@@ -25,7 +25,7 @@ var displayClass = {
25 25
 
26 26
         if (device.role == 'MFD') {
27 27
             m.MFDMapTiles = MapTiles.new(m.display);
28
-            m.MFDMapNavDisplay = MapNavDisplay.new(m.display);
28
+            m.MFDMapNavaids = PositionedLayer.new(m.display);
29 29
             var eis_dir = data.zkv1000_dir ~ 'Nasal/EIS/';
30 30
             var eis_type = getprop('/instrumentation/zkv1000/eis/type');
31 31
             if (eis_type == nil or
... ...
@@ -214,7 +214,8 @@ var displayClass = {
214 214
             }
215 215
             else {
216 216
                 me.updateEIS();
217
-                me.MFDMapNavDisplay.showMap();
217
+                me.MFDMapNavaids.setVisible(1);
218
+                me.MFDMapNavaids.update();
218 219
                 me.MFDMapTiles.initialize_grid();
219 220
                 me.MFDMapTiles.update_timer.start();
220 221
                 me['page selected'] = 0;
+417 -111
Nasal/map.nas
... ...
@@ -1,5 +1,6 @@
1 1
 # vim: set foldmethod=marker foldmarker={{{,}}} :
2 2
 var MapTiles = {
3
+# displays maps background from web tiles {{{
3 4
 # code from http://wiki.flightgear.org/Canvas_Snippets#A_simple_tile_map
4 5
     new : func (display) {
5 6
         var m = { parents: [MapTiles] };
... ...
@@ -10,7 +11,7 @@ var MapTiles = {
10 11
         m.makeUrl = string.compileTemplate('https://{server}/{type}/{z}/{x}/{y}.png{apikey}');
11 12
         m.makePath = string.compileTemplate(m.maps_base ~ '/{server}/{type}/{z}/{x}/{y}.png');
12 13
         m.num_tiles = [
13
-            math.ceil( m.display.get('view[0]') / m.tile_size ) + 1, 
14
+            math.ceil( m.display.get('view[0]') / m.tile_size ) + 1,
14 15
             math.ceil( m.display.get('view[1]') / m.tile_size ) + 1
15 16
         ];
16 17
         m.center_tile_offset = [
... ...
@@ -30,22 +31,22 @@ var MapTiles = {
30 31
     },
31 32
 
32 33
 # Simple user interface (Buttons for zoom and label for displaying it)
33
-    changeZoom : func(d) {
34
+    changeZoom : func (d) {
34 35
         me.zoom = math.max(2, math.min(19, me.zoom + d));
35 36
         call(me.updateTiles, [], me);
36 37
     },
37 38
 
38
-# initialize the map by setting up a grid of raster images  
39
+# initialize the map by setting up a grid of raster images
39 40
     initialize_grid : func {
40 41
         for(var x = 0; x < me.num_tiles[0]; x += 1) {
41 42
             me.tiles[x] = setsize([], me.num_tiles[1]);
42 43
             for(var y = 0; y < me.num_tiles[1]; y += 1)
43
-                me.tiles[x][y] = me.group.createChild("image", "map-tile");
44
+                me.tiles[x][y] = me.group.createChild('image', 'tile ' ~ x ~ ',' ~ y);
44 45
         }
45 46
     },
46 47
 
47 48
 # this is the callback that will be regularly called by the timer to update the map
48
-    updateTiles : func() {
49
+    updateTiles : func {
49 50
 #        me.group.setRotation(-data.hdg * D2R);
50 51
 
51 52
         var n = math.pow(2, me.zoom);
... ...
@@ -100,141 +101,446 @@ var MapTiles = {
100 101
         }
101 102
     },
102 103
 
103
-    del : func() {
104
+    del : func {
104 105
         me.update_timer.stop();
105 106
         call(canvas.Window.del, [], me);
106 107
     },
107 108
 };
109
+# }}}
108 110
 
109
-var MapNavDisplay = {
110
-    new : func (display) {
111
-        var m = { parents: [MapNavDisplay] };
112
-        m.display = display;
113
-        m.map = m.display.createGroup().createChild('map');
114
-        m.ctrl_ns = canvas.Map.Controller.get("Aircraft position");
115
-        m.ctrl_ns.SOURCES["map-dialog"] = {
116
-            getPosition: func subvec(geo.aircraft_position().latlon(), 0, 2),
117
-            getAltitude: func getprop('/position/altitude-ft'),
118
-            getHeading:  func {
119
-                if (me.aircraft_heading)
120
-                    getprop('/orientation/heading-deg')
121
-                else 0
122
-            },
123
-            aircraft_heading: 0,
124
-        };
111
+# The following is largely inspired from the Extra500 Avidyne Entegra 9 
112
+# https://gitlab.com/extra500/extra500.git
113
+# Many thanks to authors: Dirk Dittmann and Eric van den Berg
125 114
 
126
-        m.Styles = {
127
-            get : func(type) return m.Styles[type],
128
-        };
115
+var MapIconCache = {
116
+# creates at init an icons cache for navaids, airports and airplane {{{
117
+    new : func (svgFile) {
118
+        var m = { parents:[MapIconCache] };
129 119
 
130
-        m.Options = {
131
-            get : func(type) return m.Options[type],
132
-        };
120
+        m._canvas = canvas.new( {
121
+            'name': 'MapIconCache',
122
+            'size': [512, 512],
123
+            'view': [512, 512],
124
+            'mipmapping': 1
125
+        });
126
+        m._canvas.addPlacement( {'type': 'ref'} );
127
+        m._canvas.setColorBackground(1,1,1,0);
128
+        m._group = m._canvas.createGroup('MapIcons');
129
+
130
+        canvas.parsesvg(m._group, data.zkv1000_reldir ~ svgFile);
131
+
132
+        m._sourceRectMap = {};
133
+
134
+        var icons = [ 'airplane' ];
133 135
 
134
-        m.listeners = [];
136
+        foreach (var near; [0, 1])
137
+            foreach (var surface; [0, 1])
138
+                foreach (var tower; [0, 1])
139
+                    foreach (var center; tower ? [0, 1] : [ 0 ])
140
+                        append(icons, 'Airport_' ~ near ~ surface ~ tower ~ center);
141
+
142
+        foreach (var type; ['VOR', 'DME', 'TACAN', 'NDB'])
143
+            append(icons, 'Navaid_' ~ type);
144
+
145
+        foreach (var i; icons)
146
+            m.registerIcon(i);
135 147
 
136 148
         return m;
137 149
     },
138
-
139
-    showMap : func {
140
-        me.setMap();
141
-        me.setStyles();
142
-        me.setOptions();
143
-        me.refresh();
150
+    registerIcon : func (id) {
151
+        me._sourceRectMap[id] = {
152
+            'bound' : [],
153
+            'size'  : [],
154
+        };
155
+        var element = me._group.getElementById(id);
156
+        if (element != nil) {
157
+            me._sourceRectMap[id].bound = element.getTransformedBounds();
158
+            # TODO ugly hack ? check for reason!
159
+            var top     = 512 - me._sourceRectMap[id].bound[3];
160
+            var bottom  = 512 - me._sourceRectMap[id].bound[1];
161
+            me._sourceRectMap[id].bound[1] = top;
162
+            me._sourceRectMap[id].bound[3] = bottom;
163
+
164
+            me._sourceRectMap[id].size = [
165
+                me._sourceRectMap[id].bound[2] - me._sourceRectMap[id].bound[0],
166
+                me._sourceRectMap[id].bound[3] - me._sourceRectMap[id].bound[1]
167
+            ];
168
+        }
169
+        else {
170
+            print('MapIconCache.registerIcon(' ~ id ~ ') fail');
171
+        }
144 172
     },
145
-
146
-    setMap : func {
147
-        var source = me.ctrl_ns.SOURCES["map-dialog"];
148
-        me.map.setController("Aircraft position", "map-dialog");
149
-        me.map.setRange(40);
150
-        me.map.setTranslation(
151
-            me.display.get("view[0]")/2,
152
-            me.display.get("view[1]")/2
153
-        );
173
+    getBounds : func (id) {
174
+        return me._sourceRectMap[id].bound;
154 175
     },
176
+    getSize : func (id) {
177
+        return me._sourceRectMap[id].size;
178
+    },
179
+    boundIconToImage : func (id, image, center=1) {
180
+        if (!contains(me._sourceRectMap, id)) {
181
+            print('MapIconCache.boundIconToImage('~id~') ... no available.');
182
+            id = 'Airport_0001';
183
+        }
184
+        image.setSourceRect(
185
+                me._sourceRectMap[id].bound[0],
186
+                me._sourceRectMap[id].bound[1],
187
+                me._sourceRectMap[id].bound[2],
188
+                me._sourceRectMap[id].bound[3],
189
+                0);
190
+        image.setSize(
191
+                me._sourceRectMap[id].size[0],
192
+                me._sourceRectMap[id].size[1]);
193
+        if (center) {
194
+            image.setTranslation(
195
+                    -me._sourceRectMap[id].size[0]/2,
196
+                    -me._sourceRectMap[id].size[1]/2);
197
+        }
198
+    },
199
+};
155 200
 
156
-    setStyles : func {
157
-## set up a few keys supported by the DME.symbol file to customize appearance: {{{
158
-        me.Styles.DME = {};
159
-        me.Styles.DME.debug = 1; # HACK for benchmarking/debugging purposes
160
-        me.Styles.DME.animation_test = 0; # for prototyping animated symbols
161
-
162
-        me.Styles.DME.scale_factor = 0.4; # 40% (applied to whole group)
163
-        me.Styles.DME.line_width = 3.0;
164
-        me.Styles.DME.color_tuned = [0,1,0]; #rgb
165
-        me.Styles.DME.color_default = [1,1,0];  #rgb
201
+var mapIconCache = MapIconCache.new('Models/MapIcons.svg');
202
+# }}}
203
+
204
+var MapAirportItem = {
205
+# manage airports items by adding the ID and runways on associated icon {{{
206
+    new : func (id) {
207
+        var m = {parents:[MapAirportItem]};
208
+        m._id = id;
209
+        m._can = {
210
+            'group' : nil,
211
+            'label' : nil,
212
+            'image' : nil,
213
+            'layout': nil,
214
+            'runway': [],
215
+        };
216
+        m._mapAirportIcon = {
217
+            'near'      : 0,
218
+            'surface'   : 0,
219
+            'tower'     : 0,
220
+            'center'    : 0,
221
+            'displayed' : 0,
222
+            'icon'      : '',
223
+        };
224
+        return m;
225
+    },
226
+    create : func (group) {
227
+        me._can.group = group.createChild('group', 'airport_' ~ me._id);
228
+        me._can.image = me._can.group.createChild('image', 'airport-image_' ~ me._id)
229
+            .setFile(mapIconCache._canvas.getPath())
230
+            .setSourceRect(0,0,0,0,0);
231
+        me._can.label = me._can.group.createChild('text', 'airport-label_' ~ me._id)
232
+            .setDrawMode( canvas.Text.TEXT )
233
+            .setTranslation(0, 37)
234
+            .setAlignment('center-bottom-baseline')
235
+            .setFont('LiberationFonts/LiberationSans-Regular.ttf')
236
+            .setFontSize(32);
237
+
238
+        me._can.layout = group.createChild('group','airport_layout' ~ me._id);
239
+        me._can.layoutIcon = group.createChild('group','airport_layout_Icon' ~ me._id);
240
+        return me._can.group;
241
+    },
242
+    draw : func (apt, mapOptions) {
243
+        me._mapAirportIcon.near = mapOptions.range > 30 ? 0 : 1;
244
+        me._mapAirportIcon.surface  = 0;
245
+        me._mapAirportIcon.tower    = 0;
246
+        me._mapAirportIcon.center   = 0;
247
+        me._mapAirportIcon.displayed    = 0;
248
+
249
+        # TODO make departure and destination airports specific
250
+        var aptInfo = airportinfo(apt.id);
251
+
252
+        me._can.layout.removeAllChildren();
253
+        me._can.layoutIcon.removeAllChildren();
254
+
255
+        me._mapAirportIcon.tower = (size(aptInfo.comms('tower')) > 0);
256
+        me._mapAirportIcon.center = me._mapAirportIcon.tower and (size(aptInfo.comms('approach')) > 0);
257
+
258
+        foreach (var rwy; keys(aptInfo.runways)) {
259
+            var runway = aptInfo.runways[rwy];
260
+            me._mapAirportIcon.surface = MAP_RUNWAY_SURFACE[runway.surface] ? 1 : me._mapAirportIcon.surface;
261
+            me._mapAirportIcon.displayed = runway.length > mapOptions.runwayLength ? 1 : me._mapAirportIcon.displayed;
262
+
263
+            if (mapOptions.range <= 10) {    # drawing real runways
264
+                me._can.layout.createChild('path', 'airport-runway-' ~ me._id ~ '-' ~ runway.id)
265
+                    .setStrokeLineWidth(7)
266
+                    .setColor(1,1,1)
267
+                    .setColorFill(1,1,1)
268
+                    .setDataGeo([
269
+                        canvas.Path.VG_MOVE_TO,
270
+                        canvas.Path.VG_LINE_TO,
271
+                        canvas.Path.VG_CLOSE_PATH
272
+                    ],[
273
+                        'N' ~ runway.lat, 'E' ~ runway.lon,
274
+                        'N' ~ runway.reciprocal.lat, 'E' ~ runway.reciprocal.lon,
275
+                    ]);
276
+            }
277
+            elsif (mapOptions.range <= 30) {     #draw icon runways
278
+                me._can.layoutIcon.setGeoPosition(apt.lat, apt.lon);
279
+                me._can.layoutIcon.createChild('path', 'airport-runway-' ~ me._id ~ '-' ~ runway.id)
280
+                    .setStrokeLineWidth(7)
281
+                    .setColor(1,1,1)
282
+                    .setColorFill(1,1,1)
283
+                    .setData([
284
+                        canvas.Path.VG_MOVE_TO,
285
+                        canvas.Path.VG_LINE_TO,
286
+                        canvas.Path.VG_CLOSE_PATH
287
+                    ],[
288
+                        0, -20,
289
+                        0, 20,
290
+                    ])
291
+                    .setRotation((runway.heading)* D2R);
292
+            }
293
+        }
294
+        me._mapAirportIcon.icon = 'Airport_'
295
+            ~ me._mapAirportIcon.near
296
+            ~ me._mapAirportIcon.surface
297
+            ~ me._mapAirportIcon.tower
298
+            ~ me._mapAirportIcon.center;
299
+
300
+        if (me._mapAirportIcon.displayed) {
301
+            me._can.label.setText(apt.id);
302
+            me._can.group.setGeoPosition(apt.lat, apt.lon);
303
+            if (mapOptions.range <= 10) {
304
+                me._can.image.setVisible(0);
305
+                me._can.layout.setVisible(1);
306
+            }
307
+            elsif (mapOptions.range <= 30) {
308
+                mapIconCache.boundIconToImage(me._mapAirportIcon.icon, me._can.image);
309
+                me._can.image.setVisible(1);
310
+                me._can.layout.setVisible(1);
311
+            }
312
+            else {
313
+                mapIconCache.boundIconToImage(me._mapAirportIcon.icon, me._can.image);
314
+                me._can.layout.setVisible(0);
315
+                me._can.image.setVisible(1);
316
+            }
317
+            me._can.group.setVisible(1);
318
+        }
319
+        return me._mapAirportIcon.displayed;
320
+    },
321
+    update : func (mapOptions) {
322
+        if (mapOptions.range <= 10) { }
323
+        elsif (mapOptions.range <= 30)
324
+            me._can.layoutIcon.setRotation(-mapOptions.orientation * D2R);
325
+        else { }
326
+    },
327
+    setVisible : func (visibility) {
328
+        me._can.group.setVisible(visibility);
329
+        me._can.layout.setVisible(visibility);
330
+        me._can.image.setVisible(visibility);
331
+        me._can.layoutIcon.setVisible(visibility);
332
+    },
333
+};
334
+# }}}
335
+
336
+var MapNavaidItem = {
337
+# manage navaids items by adding ID in the icon {{{
338
+    new : func (id, type) {
339
+        var m = {parents:[MapNavaidItem]};
340
+        m._id = id;
341
+        m._type = type;
342
+        m._can = {
343
+            'group' : nil,
344
+            'label' : nil,
345
+            'image' : nil,
346
+        };
347
+        return m;
348
+    },
349
+    create : func (group) {
350
+        me._can.group = group.createChild('group', me._type ~ '_' ~ me._id);
166 351
 
167
-        me.Styles.APT = {};
168
-        me.Styles.APT.scale_factor = 0.4; # 40% (applied to whole group)
169
-        me.Styles.APT.line_width = 3.0;
170
-        me.Styles.APT.color_default = [0,0.6,0.85];  #rgb
171
-        me.Styles.APT.label_font_color = me.Styles.APT.color_default;
172
-        me.Styles.APT.label_font_size=16;
352
+        me._can.image = me._can.group.createChild('image', me._type ~ '-image_' ~ me._id)
353
+            .setFile(mapIconCache._canvas.getPath())
354
+            .setSourceRect(0,0,0,0,0);
173 355
 
174
-        me.Styles.TFC = {};
175
-        me.Styles.TFC.scale_factor = 0.4; # 40% (applied to whole group)
356
+        me._can.label = me._can.group.createChild('text', me._type ~ '-label_' ~ me._id)
357
+            .setDrawMode( canvas.Text.TEXT )
358
+            .setTranslation(0,42)
359
+            .setAlignment('center-bottom-baseline')
360
+            .setFont('LiberationFonts/LiberationSans-Regular.ttf')
361
+            .setFontSize(32);
176 362
 
177
-        me.Styles.WPT = {};
178
-        me.Styles.WPT.scale_factor = 0.5; # 50% (applied to whole group)
363
+        me._can.label.set('fill','#BACBFB');
364
+        me._can.label.set('stroke','#000000');
179 365
 
180
-        me.Styles.RTE = {};
181
-        me.Styles.RTE.line_width = 2;
366
+        return me._can.group;
367
+    },
368
+    setData : func (navaid, type) {
369
+        mapIconCache.boundIconToImage('Navaid_' ~ type, me._can.image);
370
+        me._can.label.setText(navaid.id);
371
+        me._can.group.setGeoPosition(navaid.lat, navaid.lon);
372
+    },
373
+    setVisible : func (visibility) {
374
+        me._can.group.setVisible(visibility);
375
+    },
376
+};
377
+# }}}
378
+
379
+var MAP_RUNWAY_SURFACE =  {0:0, 1:1, 2:1, 3:0, 4:0, 5:0, 6:1, 7:1, 8:0, 9:0, 10:0, 11:0, 12:0};
380
+var MAP_RUNWAY_AT_RANGE = {2:0, 4:0, 10:0, 20:0, 30:0, 40:250, 50:500, 80:1000, 160:2000, 240:3000}; # TODO: make it compatible with tiles zoom level
381
+var MAP_TXRANGE_VOR     = {2:0, 4:0, 10:0, 20:0, 30:0, 40:20,  50:25,  80:30,   160:50,   240:100}; # TODO: make it compatible with tiles zoom level
382
+####
383
+# Declutter
384
+#   land
385
+#       0 : 'Terrain'
386
+#       1 : 'Political boundaries'
387
+#       2 : 'River/Lakes/Oceans'
388
+#       3 : 'Roads'
389
+#   Nav
390
+#       0 : 'Airspace'
391
+#       1 : 'Victor/Jet airways'
392
+#       2 : 'Obstacles'
393
+#       3 : 'Navaids'
394
+
395
+var PositionedLayer = {
396
+# the layer to show navaids, airports and airplane symbol {{{
397
+    new : func (display) {
398
+        var m = {parents : [PositionedLayer]};
399
+
400
+        m._model = nil;
401
+        m._group = display.createGroup().createChild('map', 'MFD map');
402
+
403
+        m._can = {};
404
+        m._cache = {};
405
+        foreach (var n; ['airport', 'VOR', 'TACAN', 'NDB', 'DME']) {
406
+            m._can[n] = m._group.createChild('group', n);
407
+            m._cache[n] = {
408
+                'data' : [],
409
+                'index' : 0,
410
+                'max' : 100,
411
+            };
412
+        }
182 413
 
183
-        me.Styles.FLT = {};
184
-        me.Styles.FLT.line_width = 3;
414
+        m._mapOptions = {
415
+            declutterLand : 3,
416
+            declutterNAV  : 3,
417
+            lightning     : 0,
418
+            reports       : 0,
419
+            overlay       : 0,
420
+            range         : 30,
421
+            rangeLow      : 15,
422
+            runwayLength  : -1,
423
+            orientation   : 0,
424
+        };
185 425
 
186
-        me.Styles.FIX = {};
187
-        me.Styles.FIX.color = [1,0,0];
188
-        me.Styles.FIX.scale_factor = 0.4; # 40%
426
+        m._results = nil;
427
+        m._timer = maketimer(600, m, PositionedLayer.update);
189 428
 
190
-        me.Styles.VOR = {};
191
-        me.Styles.VOR.range_line_width = 2;
192
-        me.Styles.VOR.radial_line_width = 1;
193
-        me.Styles.VOR.scale_factor = 0.6; # 60%
429
+        m._visibility = 0;
194 430
 
195
-        me.Styles.APS = {};
196
-        me.Styles.APS.scale_factor = 0.5;
431
+        return m;
197 432
     },
198
-#}}}
199
-
200
-    setOptions : func {
201
-        me.Options.FLT = {};
433
+    update : func {
434
+        if (me._visibility == 1) {
435
+            me.loadAirport();
436
+            foreach (var n; ['VOR', 'TACAN', 'NDB', 'DME'])
437
+                me.loadNavaid(n);
438
+        }
439
+        #TODO compute from actual speed (220 = Vne extra500)
440
+        me._timer.restart(me._mapOptions.range/(220/3600));
202 441
     },
203
-
204
-    make_update_wrapper : func(name) {
205
-        if (!contains(me.Options, name)) me.Options[name] = {};
206
-        me.Options[name].update_wrapper = func(layer, fn) {
207
-            fn();
442
+    _onVisibilityChange : func {
443
+        me._group.setVisible(me._visibility);
444
+    },
445
+    setMapOptions : func (mapOptions) {
446
+        me._mapOptions = mapOptions;
447
+        me.update();
448
+    },
449
+    updateOrientation : func (value) {
450
+        me._mapOptions.orientation = value;
451
+        for (var i = 0 ; i < me._cache.airport.index ; i +=1) {
452
+            item = me._cache.airport.data[i];
453
+            item.update(me._mapOptions);
208 454
         }
209 455
     },
210
-
211
-    ToggleLayerVisible : func(name) {
212
-        (var l = me.map.getLayer(name)).setVisible(l.getVisible());
456
+    setRange : func (range=100) {
457
+        me._mapOptions.range = range;
458
+        me._mapOptions.rangeLow = range/2;
459
+        me.update();
213 460
     },
214
-
215
-    SetLayerVisible : func(name,n=1) {
216
-        me.map.getLayer(name).setVisible(n);
461
+    setRotation : func (deg) {
462
+        me._group.setRotation(deg * D2R);
463
+    },
464
+    setVisible : func (v) {
465
+        if (me._visibility != v) {
466
+            me._visibility = v;
467
+            me._onVisibilityChange();
468
+        }
469
+    },
470
+    _onVisibilityChange : func {
471
+        me._group.setVisible(me._visibility);
217 472
     },
473
+    # positioned.findWithinRange : any, fix, vor, ndb, ils, dme, tacan
474
+
475
+    loadAirport : func {
476
+        me._cache.airport.index = 0;
477
+        var results = positioned.findWithinRange(me._mapOptions.range * 2.5, 'airport');
478
+        var item = nil;
479
+
480
+        if (me._mapOptions.declutterNAV >= 2)
481
+            me._mapOptions.runwayLength = MAP_RUNWAY_AT_RANGE[me._mapOptions.range];
482
+        elsif (me._mapOptions.declutterNAV >= 1)
483
+            me._mapOptions.runwayLength = 2000;
484
+        else
485
+            me._mapOptions.runwayLength = 3000;
486
+
487
+        if (me._mapOptions.runwayLength >= 0) {
488
+            foreach (var apt; results) {
489
+                if (me._cache.airport.index >= me._cache.airport.max )
490
+                    break;
491
+
492
+                if (size(me._cache.airport.data) > me._cache.airport.index)
493
+                    item = me._cache.airport.data[me._cache.airport.index];
494
+                else {
495
+                    item = MapAirportItem.new(me._cache.airport.index);
496
+                    item.create(me._can.airport);
497
+                    append(me._cache.airport.data, item);
498
+                }
218 499
 
219
-    refresh : func {
220
-        var r = func(name,vis=1,zindex=nil) return caller(0)[0];
221
-        # TODO: we'll need some z-indexing here, right now it's just random
222
-        foreach(var type; [r('TFC',0),r('APT'),r('DME'),r('VOR'),r('NDB'),r('FIX',0),r('RTE'),r('WPT'),r('FLT'),r('WXR',0),r('APS'), ] ) {
223
-            if (1 and type.name != 'APS' and type.name != 'FLT') me.make_update_wrapper(type.name);
224
-            me.map.addLayer(factory: canvas.SymbolLayer, type_arg: type.name,
225
-                    visible: type.vis, priority: type.zindex,
226
-                    style: me.Styles.get(type.name),
227
-                    options: me.Options.get(type.name) 
228
-                    );
229
-            (func {
230
-                 # Notify MapStructure about layer visibility changes:
231
-                 var name = type.name;
232
-                 props.globals.initNode("/sim/gui/dialogs/map-canvas/draw-"~name, type.vis, "BOOL");
233
-                 append(me.listeners,
234
-                         setlistener("/sim/gui/dialogs/map-canvas/draw-"~name,
235
-                             func(n) me.SetLayerVisible(name,n.getValue()), 1, 2)
236
-                       );
237
-             })();
500
+                if (item.draw(apt, me._mapOptions)) {
501
+                    item.setVisible(1);
502
+                    me._cache.airport.index += 1;
503
+                }
504
+            }
505
+        }
506
+
507
+        for (var i = me._cache.airport.index ; i < size(me._cache.airport.data) ; i +=1) {
508
+            item = me._cache.airport.data[i];
509
+            item.setVisible(0);
510
+        }
511
+    },
512
+    loadNavaid : func (type) {
513
+        me._cache[type].index = 0;
514
+        if (me._mapOptions.declutterNAV >= 3) { # TODO test for DME and NDB range < 100nm
515
+            var range = me._mapOptions.range * 2.5;
516
+            var txRange = MAP_TXRANGE_VOR[me._mapOptions.range];
517
+            var results = positioned.findWithinRange(range, type);
518
+            var item = nil;
519
+            foreach (var n; results) {
520
+                if (n.range_nm < txRange)
521
+                    break;
522
+
523
+                if (me._cache[type].index >= me._cache[type].max )
524
+                    break;
525
+
526
+                if (size(me._cache[type].data) > me._cache[type].index) {
527
+                    item = me._cache[type].data[me._cache[type].index];
528
+                    item.setData(n, type);
529
+                }
530
+                else {
531
+                    item = MapNavaidItem.new(me._cache[type].index, type);
532
+                    item.create(me._can[type]);
533
+                    item.setData(n, type);
534
+                    append(me._cache[type].data, item);
535
+                }
536
+                item.setVisible(1);
537
+                me._cache[type].index += 1;
538
+            }
539
+        }
540
+        for (var i = me._cache[type].index ; i < size(me._cache[type].data) ; i +=1) {
541
+            item = me._cache[type].data[i];
542
+            item.setVisible(0);
238 543
         }
239 544
     },
240 545
 };
546
+# }}}