1
0
Fork 0

FG1000 Nearest Airports page

- DTO MapStructure layer to provide a DTO line to a lat/lon
- Support for scrolling lists in the PFD/GroupElement
- Support MAP (NavigationMap) and ENGINE (EIS) soft-keys from other pages.
This commit is contained in:
Stuart Buchanan 2017-12-31 16:10:52 +00:00
parent cc152b67ad
commit 9eb91171b4
13 changed files with 834 additions and 480 deletions

View file

@ -67,7 +67,7 @@
inkscape:label="NavigationMapGroup" inkscape:label="NavigationMapGroup"
style="display:inline"> style="display:inline">
<g <g
id="NavigationMapGroupFull" id="NavigationMapGroup"
inkscape:label="#g4869"> inkscape:label="#g4869">
<rect <rect
y="718.50403" y="718.50403"

Before

(image error) Size: 7.6 KiB

After

(image error) Size: 7.6 KiB

View file

@ -23,9 +23,9 @@
borderopacity="0" borderopacity="0"
inkscape:pageopacity="0.0" inkscape:pageopacity="0.0"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="1.2863052" inkscape:zoom="2.5726105"
inkscape:cx="796.08532" inkscape:cx="963.17786"
inkscape:cy="344.63751" inkscape:cy="88.847167"
inkscape:document-units="px" inkscape:document-units="px"
inkscape:current-layer="NearestAirportsGroup" inkscape:current-layer="NearestAirportsGroup"
showgrid="true" showgrid="true"
@ -71,211 +71,226 @@
id="NearestAirportsGroup"> id="NearestAirportsGroup">
<rect <rect
inkscape:label="#rect8921" inkscape:label="#rect8921"
y="58.493786" y="53.505371"
x="705.49377" x="724.50537"
height="684.51239" height="688.98926"
width="319.51242" width="309.98926"
id="Background" id="Background"
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.987571;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.01074231;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect <rect
y="78.004555" y="77.483986"
x="710.41968" x="730.48395"
height="134.48459" height="135.00078"
width="309.66068" width="289.03204"
id="rect9743" id="rect9743"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00844526;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect <rect
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.72408265;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99796617;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect9745" id="rect9745"
width="309.94263" width="289.00204"
height="69.270592" height="69.002037"
x="711.26178" x="730.49902"
y="336.62552" /> y="350.49896" />
<rect <rect
y="421.24216" y="445.16284"
x="711.34943" x="730.50055"
height="107.3051" height="111.33662"
width="309.76727" width="288.99896"
id="rect9747" id="rect9747"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.90095061;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00104749;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect <rect
y="68.142975" y="67.488281"
x="720.14301" x="745.48828"
height="19.714043" height="20.02342"
width="134.21402" width="126.02343"
id="rect9753" id="rect9753"
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.28595793;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="text9749" id="text9749"
y="83" y="80.307159"
x="725" x="774.57446"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:15px;line-height:125%;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.51583004px;line-height:125%;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:0.967722px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan xml:space="preserve"
y="83" transform="scale(0.96767669,1.033403)"><tspan
x="725" y="80.307159"
x="774.57446"
id="tspan9751" id="tspan9751"
sodipodi:role="line" sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed'">NEAREST AIRPORTS</tspan></text> style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';stroke-width:0.967722px">NEAREST AIRPORTS</tspan></text>
<rect <rect
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:0.96605152;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:0.99874961;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4150" id="rect4150"
width="74.533928" width="67.001251"
height="20.033949" height="20.001251"
x="720.98303" x="745.49939"
y="325.59775" /> y="340.49939" />
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.51583004px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:0.967722px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="726" x="775.60754"
y="340.61472" y="344.45227"
id="text4152" id="text4152"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767669,1.033403)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4154" id="tspan4154"
x="726" x="775.60754"
y="340.61472">RUNWAYS</tspan></text> y="344.45227"
style="stroke-width:0.967722px">RUNWAYS</tspan></text>
<rect <rect
y="411.81696" y="435.50052"
x="721.05579" x="745.51575"
height="19.888502" height="19.93354"
width="99.388496" width="93.06028"
id="rect4156" id="rect4156"
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.11149907;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.00104749;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="text4158" id="text4158"
y="426.7612" y="435.40878"
x="726" x="776.46429"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.53103542px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:0.96873569px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan xml:space="preserve"
y="426.7612" transform="scale(0.96654693,1.0346109)"><tspan
x="726" y="435.40878"
x="776.46429"
sodipodi:role="line" sodipodi:role="line"
id="tspan4162">FREQUENCIES</tspan></text> id="tspan4162"
style="stroke-width:0.96873569px">FREQUENCIES</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="770.69727" x="807.53778"
y="371.42072" y="374.26392"
id="NearestAirportsRunwayID" id="NearestAirportsRunwayID"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767669,1.033403)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4238" id="tspan4238"
x="770.69727" x="807.53778"
y="371.42072">17-35</tspan></text> y="374.26392">17-35</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsID0" id="NearestAirportsID0"
y="106.96484" y="103.49844"
x="746.10352" x="794.41644"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="106.96484" transform="scale(0.96767632,1.0334034)"><tspan
x="746.10352" y="103.49844"
x="794.41644"
id="tspan4242" id="tspan4242"
sodipodi:role="line">KSFO</tspan></text> sodipodi:role="line">KSFO</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="1009.6523" x="1038.7799"
y="370.22604" y="373.10779"
id="NearestAirportsRunwaySurface" id="NearestAirportsRunwaySurface"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767669,1.033403)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4246" id="tspan4246"
x="1009.6523" x="1038.7799"
y="370.22604">HARD SURFACE</tspan></text> y="373.10779">HARD SURFACE</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsRunwayDimensions" id="NearestAirportsRunwayDimensions"
y="395.22604" y="397.30084"
x="729.65234" x="767.81775"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="395.22604" transform="scale(0.96767669,1.033403)"><tspan
x="729.65234" y="397.30084"
x="767.81775"
id="tspan4250" id="tspan4250"
sodipodi:role="line">PCL FREQUENCY - 122.90</tspan></text> sodipodi:role="line">PCL FREQUENCY - 122.90</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsFreqLabel0" id="NearestAirportsFreqLabel0"
y="460.59219" y="468.18204"
x="724.98047" x="764.1405"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="460.59219" transform="scale(0.96654693,1.0346109)"><tspan
x="724.98047" y="468.18204"
x="764.1405"
id="tspan4254" id="tspan4254"
sodipodi:role="line">TOWER</tspan></text> sodipodi:role="line">TOWER</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="999.7793" x="1030.3479"
y="460.59219" y="468.18204"
id="NearestAirportsFreq0" id="NearestAirportsFreq0"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96654693,1.0346109)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4258" id="tspan4258"
x="999.7793" x="1030.3479"
y="460.59219">119.875</tspan></text> y="468.18204">119.875</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="724.98047" x="764.1405"
y="484.8779" y="491.70847"
id="NearestAirportsFreqLabel1" id="NearestAirportsFreqLabel1"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96654693,1.0346109)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4262" id="tspan4262"
x="724.98047" x="764.1405"
y="484.8779">TOWER</tspan></text> y="491.70847">TOWER</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsFreq1" id="NearestAirportsFreq1"
y="484.8779" y="491.70847"
x="999.7793" x="1030.3479"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="484.8779" transform="scale(0.96654693,1.0346109)"><tspan
x="999.7793" y="491.70847"
x="1030.3479"
id="tspan4266" id="tspan4266"
sodipodi:role="line">119.875</tspan></text> sodipodi:role="line">119.875</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsFreqLabel2" id="NearestAirportsFreqLabel2"
y="509.16367" y="515.23486"
x="724.98047" x="764.1405"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="509.16367" transform="scale(0.96654693,1.0346109)"><tspan
x="724.98047" y="515.23486"
x="764.1405"
id="tspan4270" id="tspan4270"
sodipodi:role="line">TOWER</tspan></text> sodipodi:role="line">TOWER</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.3747139px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="999.7793" x="1030.3479"
y="509.16367" y="515.23486"
id="NearestAirportsFreq2" id="NearestAirportsFreq2"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96654693,1.0346109)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4274" id="tspan4274"
x="999.7793" x="1030.3479"
y="509.16367">119.875</tspan></text> y="515.23486">119.875</tspan></text>
<path <path
style="fill:#404040;fill-opacity:1;fill-rule:evenodd;stroke:#404040;stroke-width:0.88437384px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:#404040;fill-opacity:1;fill-rule:evenodd;stroke:#404040;stroke-width:0.85582805px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 735.55778,360.09923 0,9.08226 -4.41338,-4.48437 z" d="m 748.52946,375.44339 0,9.08269 -4.13287,-4.48458 z"
id="NearestAirportsRunwayIDLeft" id="NearestAirportsRunwayIDLeft"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" sodipodi:nodetypes="cccc"
@ -285,35 +300,37 @@
sodipodi:nodetypes="cccc" sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="NearestAirportsRunwayIDRight" id="NearestAirportsRunwayIDRight"
d="m 805.96996,360.09923 0,9.08226 4.41338,-4.48437 z" d="m 814.46639,375.44339 0,9.08269 4.13287,-4.48458 z"
style="fill:#404040;fill-opacity:1;fill-rule:evenodd;stroke:#404040;stroke-width:0.88437384px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> style="fill:#404040;fill-opacity:1;fill-rule:evenodd;stroke:#404040;stroke-width:0.85582805px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="863.65973" x="908.79016"
y="106.96484" y="103.49844"
id="NearestAirportsCRS0" id="NearestAirportsCRS0"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4253" id="tspan4253"
x="863.65973" x="908.79016"
y="106.96484">359</tspan></text> y="103.49844">359</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsDST0" id="NearestAirportsDST0"
y="107.79551" y="104.30227"
x="996.14514" x="1031.7998"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.94000101px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.26409912px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="107.79551" transform="scale(0.96767632,1.0334034)"><tspan
x="996.14514" y="104.30227"
x="1031.7998"
id="tspan4257" id="tspan4257"
sodipodi:role="line">200nm</tspan></text> sodipodi:role="line">200nm</tspan></text>
<path <path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.90505791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87584442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 717.38253,98.051495 0,4.061885 10.08314,0 0,4.06188 9.26683,-6.06161 -9.26683,-6.124022 0,4.061867 z" d="m 740.43792,98.041859 0,4.062081 9.44228,0 0,4.06207 8.67785,-6.0619 -8.67785,-6.124308 0,4.062057 z"
id="NearestAirportsArrow0" id="NearestAirportsArrow0"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" sodipodi:nodetypes="cccccccc"
@ -321,85 +338,91 @@
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="746.10352" x="794.41644"
y="130.9248" y="126.68501"
id="NearestAirportsID1" id="NearestAirportsID1"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4263" id="tspan4263"
x="746.10352" x="794.41644"
y="130.9248">KSFO</tspan></text> y="126.68501">KSFO</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsCRS1" id="NearestAirportsCRS1"
y="130.9248" y="126.68501"
x="863.65973" x="908.79016"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="130.9248" transform="scale(0.96767632,1.0334034)"><tspan
x="863.65973" y="126.68501"
x="908.79016"
id="tspan4267" id="tspan4267"
sodipodi:role="line">359</tspan></text> sodipodi:role="line">359</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.94000053px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.26409912px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="996.14514" x="1031.7998"
y="131.24841" y="126.99815"
id="NearestAirportsDST1" id="NearestAirportsDST1"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4271" id="tspan4271"
x="996.14514" x="1031.7998"
y="131.24841">200nm</tspan></text> y="126.99815">200nm</tspan></text>
<path <path
inkscape:label="#path4259" inkscape:label="#path4259"
sodipodi:nodetypes="cccccccc" sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="NearestAirportsArrow1" id="NearestAirportsArrow1"
d="m 717.38253,122.01146 0,4.06188 10.08314,0 0,4.06188 9.26683,-6.06161 -9.26683,-6.12402 0,4.06187 z" d="m 740.43792,122.00295 0,4.06207 9.44228,0 0,4.06207 8.67785,-6.0619 -8.67785,-6.1243 0,4.06206 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.90505791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87584442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsID2" id="NearestAirportsID2"
y="154.88477" y="149.87158"
x="746.10352" x="794.41644"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="154.88477" transform="scale(0.96767632,1.0334034)"><tspan
x="746.10352" y="149.87158"
x="794.41644"
id="tspan4277" id="tspan4277"
sodipodi:role="line">KSFO</tspan></text> sodipodi:role="line">KSFO</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="863.65973" x="908.79016"
y="154.88477" y="149.87158"
id="NearestAirportsCRS2" id="NearestAirportsCRS2"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4281" id="tspan4281"
x="863.65973" x="908.79016"
y="154.88477">359</tspan></text> y="149.87158">359</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsDST2" id="NearestAirportsDST2"
y="155.20837" y="150.18474"
x="996.14514" x="1031.7998"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.94000053px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.26409912px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="155.20837" transform="scale(0.96767632,1.0334034)"><tspan
x="996.14514" y="150.18474"
x="1031.7998"
id="tspan4285" id="tspan4285"
sodipodi:role="line">200nm</tspan></text> sodipodi:role="line">200nm</tspan></text>
<path <path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.90505791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87584442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 717.38253,145.97142 0,4.06188 10.08314,0 0,4.06188 9.26683,-6.06161 -9.26683,-6.12402 0,4.06187 z" d="m 740.43792,145.96403 0,4.06207 9.44228,0 0,4.06207 8.67785,-6.06189 -8.67785,-6.12431 0,4.06206 z"
id="NearestAirportsArrow2" id="NearestAirportsArrow2"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" sodipodi:nodetypes="cccccccc"
@ -407,210 +430,274 @@
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="746.10352" x="794.41644"
y="178.84473" y="173.05815"
id="NearestAirportsID3" id="NearestAirportsID3"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4291" id="tspan4291"
x="746.10352" x="794.41644"
y="178.84473">KSFO</tspan></text> y="173.05815">KSFO</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsCRS3" id="NearestAirportsCRS3"
y="178.84473" y="173.05815"
x="863.65973" x="908.79016"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="178.84473" transform="scale(0.96767632,1.0334034)"><tspan
x="863.65973" y="173.05815"
x="908.79016"
id="tspan4295" id="tspan4295"
sodipodi:role="line">359</tspan></text> sodipodi:role="line">359</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.94000053px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.26409912px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="996.14514" x="1031.7998"
y="177.62126" y="171.87416"
id="NearestAirportsDST3" id="NearestAirportsDST3"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4299" id="tspan4299"
x="996.14514" x="1031.7998"
y="177.62126">200nm</tspan></text> y="171.87416">200nm</tspan></text>
<path <path
inkscape:label="#path4259" inkscape:label="#path4259"
sodipodi:nodetypes="cccccccc" sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
id="NearestAirportsArrow3" id="NearestAirportsArrow3"
d="m 717.38253,169.93138 0,4.06188 10.08314,0 0,4.06188 9.26683,-6.06161 -9.26683,-6.12402 0,4.06187 z" d="m 740.43792,169.92511 0,4.06207 9.44228,0 0,4.06207 8.67785,-6.06189 -8.67785,-6.12431 0,4.06206 z"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.90505791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87584442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsID4" id="NearestAirportsID4"
y="202.80469" y="196.24472"
x="746.10352" x="794.41644"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="202.80469" transform="scale(0.96767632,1.0334034)"><tspan
x="746.10352" y="196.24472"
x="794.41644"
id="tspan4319" id="tspan4319"
sodipodi:role="line">KSFO</tspan></text> sodipodi:role="line">KSFO</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="863.65973" x="908.79016"
y="202.80469" y="196.24472"
id="NearestAirportsCRS4" id="NearestAirportsCRS4"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767632,1.0334034)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4323" id="tspan4323"
x="863.65973" x="908.79016"
y="202.80469">359</tspan></text> y="196.24472">359</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsDST4" id="NearestAirportsDST4"
y="203.1283" y="196.55789"
x="996.14514" x="1031.7998"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.94000053px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20.26409912px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow, Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="203.1283" transform="scale(0.96767632,1.0334034)"><tspan
x="996.14514" y="196.55789"
x="1031.7998"
id="tspan4327" id="tspan4327"
sodipodi:role="line">200nm</tspan></text> sodipodi:role="line">200nm</tspan></text>
<path <path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.90505791px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.87584442px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 717.38253,193.89134 0,4.06188 10.08314,0 0,4.06188 9.26683,-6.06161 -9.26683,-6.12402 0,4.06187 z" d="m 740.43792,193.88619 0,4.06207 9.44228,0 0,4.06207 8.67785,-6.06189 -8.67785,-6.12431 0,4.06206 z"
id="NearestAirportsArrow4" id="NearestAirportsArrow4"
inkscape:connector-curvature="0" inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" sodipodi:nodetypes="cccccccc"
inkscape:label="#path4259" /> inkscape:label="#path4259" />
<rect <rect
y="234.54692" y="240.49937"
x="710.80701" x="730.49939"
height="84.196045" height="84.001251"
width="309.86914" width="289.00125"
id="rect4331" id="rect4331"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.79819334;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99875104;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect <rect
y="223.54343" y="228.5"
x="720.54346" x="745.5"
height="19.913141" height="20.02869"
width="94.913132" width="89.028687"
id="rect4333" id="rect4333"
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.08685863;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="text4335" id="text4335"
y="238.49998" y="236.45425"
x="725.5" x="775.05835"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.51583004px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:0.967722px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan xml:space="preserve"
y="238.49998" transform="scale(0.96767669,1.033403)"><tspan
x="725.5" y="236.45425"
x="775.05835"
id="tspan4337" id="tspan4337"
sodipodi:role="line">INFORMATION</tspan></text> sodipodi:role="line"
style="stroke-width:0.967722px">INFORMATION</tspan></text>
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:19.35444069px;line-height:125%;font-family:Sans;-inkscape-font-specification:Sans;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="715" x="753.573"
y="258" y="249.65851"
id="text4355" id="text4355"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96767669,1.033403)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4357" id="tspan4357"
x="715" x="753.573"
y="258" /></text> y="249.65851" /></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsName" id="NearestAirportsName"
y="263.95117" y="261.08392"
x="719.25781" x="757.69336"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="263.95117" transform="scale(0.96767669,1.033403)"><tspan
x="719.25781" y="261.08392"
x="757.69336"
id="tspan4361" id="tspan4361"
sodipodi:role="line">SAN FRANCISCO INTERNATIONAL</tspan></text> sodipodi:role="line">SAN FRANCISCO INTERNATIONAL</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsAlt" id="NearestAirportsAlt"
y="313.61914" y="309.14871"
x="1016.127" x="1044.9802"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.35444069px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:end;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="313.61914" transform="scale(0.96767669,1.033403)"><tspan
x="1016.127" y="309.14871"
x="1044.9802"
id="tspan4375" id="tspan4375"
sodipodi:role="line">123ft</tspan></text> sodipodi:role="line">123ft</tspan></text>
<rect <rect
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.88014376;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.00069809;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4377" id="rect4377"
width="309.78793" width="288.9993"
height="102.39922" height="111.25876"
x="711.33911" x="730.50037"
y="545.15997" /> y="580.24091" />
<rect <rect
style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.11149907;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" style="opacity:1;fill:#1a3030;fill-opacity:1;fill-rule:nonzero;stroke:#fffcfa;stroke-width:1.00069809;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4379" id="rect4379"
width="99.388496" width="87.522202"
height="19.888502" height="19.949141"
x="721.05579" x="745.51562"
y="535.74377" /> y="572.50037" />
<text <text
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:15px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.52596188px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:#fffcfa;stroke-width:0.9683975px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="726" x="776.19214"
y="550.68799" y="568.02856"
id="text4381" id="text4381"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96688562,1.0342485)"><tspan
id="tspan4383" id="tspan4383"
sodipodi:role="line" sodipodi:role="line"
x="726" x="776.19214"
y="550.68799">APPROACHES</tspan></text> y="568.02856"
style="stroke-width:0.9683975px">APPROACHES</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.36795044px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="724.98047" x="763.87268"
y="584.51898" y="600.79041"
id="NearestAirportsApproach0" id="NearestAirportsApproach0"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96688562,1.0342485)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4387" id="tspan4387"
x="724.98047" x="763.87268"
y="584.51898">TOWER</tspan></text> y="600.79041">TOWER</tspan></text>
<text <text
sodipodi:linespacing="125%" sodipodi:linespacing="125%"
id="NearestAirportsApproach1" id="NearestAirportsApproach1"
y="608.80469" y="624.30859"
x="724.98047" x="763.87268"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.36795044px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve" xml:space="preserve"
inkscape:label="#text4232"><tspan inkscape:label="#text4232"
y="608.80469" transform="scale(0.96688562,1.0342485)"><tspan
x="724.98047" y="624.30859"
x="763.87268"
id="tspan4395" id="tspan4395"
sodipodi:role="line">TOWER</tspan></text> sodipodi:role="line">TOWER</tspan></text>
<text <text
inkscape:label="#text4232" inkscape:label="#text4232"
xml:space="preserve" xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:20px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:19.36795044px;line-height:125%;font-family:'Liberation Sans Narrow';-inkscape-font-specification:'Liberation Sans Narrow Condensed';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#80ffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="724.98047" x="763.87268"
y="633.09045" y="647.8269"
id="NearestAirportsApproach2" id="NearestAirportsApproach2"
sodipodi:linespacing="125%"><tspan sodipodi:linespacing="125%"
transform="scale(0.96688562,1.0342485)"><tspan
sodipodi:role="line" sodipodi:role="line"
id="tspan4403" id="tspan4403"
x="724.98047" x="763.87268"
y="633.09045">TOWER</tspan></text> y="647.8269">TOWER</tspan></text>
<rect
style="opacity:1;fill:#c0c0c0;fill-opacity:1;fill-rule:nonzero;stroke:#c0c0c0;stroke-width:0.99568439;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="NearestAirportsAirportScrollBar"
width="4.9967451"
height="124.00414"
x="1010.4977"
y="83.498024"
inkscape:label="#rect4231" />
<rect
inkscape:label="#rect4231"
y="83.236771"
x="1010.2327"
height="24.534019"
width="5.5263038"
id="NearestAirportsAirportScroll"
style="opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:0.46575949;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
inkscape:label="#rect4231"
y="452.17084"
x="1010.4186"
height="99.325096"
width="4.7759156"
id="NearestAirportsFreqScrollBar"
style="opacity:1;fill:#c0c0c0;fill-opacity:1;fill-rule:nonzero;stroke:#c0c0c0;stroke-width:0.87119991;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:0.45150775;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="NearestAirportsFreqScroll"
width="5.1815677"
height="24.589478"
x="1010.2089"
y="451.95374"
inkscape:label="#rect4231" />
<rect
style="opacity:1;fill:#c0c0c0;fill-opacity:1;fill-rule:nonzero;stroke:#c0c0c0;stroke-width:0.8708958;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="NearestAirportsApproachScrollBar"
width="4.7759213"
height="99.255646"
x="1010.4187"
y="585.24091"
inkscape:label="#rect4231" />
<rect
inkscape:label="#rect4231"
y="585.02399"
x="1010.209"
height="24.572283"
width="5.1815743"
id="NearestAirportsApproachScroll"
style="opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:#808080;stroke-width:0.45135012;stroke-linecap:butt;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g> </g>
</g> </g>
</svg> </svg>

Before

(image error) Size: 35 KiB

After

(image error) Size: 39 KiB

View file

@ -163,7 +163,7 @@ var AirportInfo =
# runways displayed twice. # runways displayed twice.
var rwys = []; var rwys = [];
var recips = {}; var recips = {};
foreach(var rwy; keys(apt_info.runways)) { foreach(var rwy; sort(keys(apt_info.runways), string.icmp)) {
var rwy_info = apt_info.runways[rwy]; var rwy_info = apt_info.runways[rwy];
if (recips[rwy_info.id] == nil) { if (recips[rwy_info.id] == nil) {
var lbl = rwy_info.id ~ "-" ~ rwy_info.reciprocal.id; var lbl = rwy_info.id ~ "-" ~ rwy_info.reciprocal.id;

View file

@ -140,7 +140,58 @@ var EIS =
foreach(var se; me._rotationElements) { foreach(var se; me._rotationElements) {
se.update(me._EISDriver); se.update(me._EISDriver);
} }
},
} # Menu tree . engineMenu is referenced from most pages as softkey 0:
# pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
engineMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(1, "LEAN", pg, pg.mfd.EIS.leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, pg.mfd.EIS.systemMenu);
pg.addMenuItem(8, "BACK", pg, pg.topMenu);
device.updateMenus();
},
leanMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(1, "LEAN", pg, pg.mfd.EIS.leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, pg.mfd.EIS.systemMenu);
pg.addMenuItem(3, "CYL SELECT", pg);
pg.addMenuItem(4, "ASSIST", pg);
pg.addMenuItem(9, "BACK", pg, pg.mfd.EIS.engineMenu);
device.updateMenus();
},
systemMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(1, "LEAN", pg, pg.mfd.EIS.leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, pg.mfd.EIS.systemMenu);
pg.addMenuItem(3, "RST FUEL", pg);
pg.addMenuItem(4, "GAL REM", pg, pg.mfd.EIS.galRemMenu);
pg.addMenuItem(5, "BACK", pg, pg.mfd.EIS.engineMenu);
device.updateMenus();
},
galRemMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(1, "LEAN", pg, pg.mfd.EIS.leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, pg.mfd.EIS.systemMenu);
pg.addMenuItem(3, "-10 GAL", pg);
pg.addMenuItem(4, "-1 GAL", pg);
pg.addMenuItem(5, "+1 GAL", pg);
pg.addMenuItem(6, "+10 GAL", pg);
pg.addMenuItem(7, "44 GAL", pg);
pg.addMenuItem(8, "BACK", pg, pg.mfd.EIS.engineMenu);
device.updateMenus();
},
}; };

View file

@ -66,7 +66,13 @@ var MFD =
{ {
new : func (myCanvas) new : func (myCanvas)
{ {
var obj = { parents : [ MFD ] }; var obj = {
parents : [ MFD ],
EIS : nil,
NavigationMap: nil,
};
obj._svg = myCanvas.createGroup("softkeys"); obj._svg = myCanvas.createGroup("softkeys");
@ -99,20 +105,23 @@ var MFD =
# Engine Information System # Engine Information System
obj._eisDriver = fg1000.EISDriver.new(); obj._eisDriver = fg1000.EISDriver.new();
obj._eis = fg1000.EIS.new(myCanvas, obj._eisDriver); obj.EIS = fg1000.EIS.new(myCanvas, obj._eisDriver);
# Controller for the display on the bottom left which allows selection # Controller for the display on the bottom left which allows selection
# of page groups and individual pages using the FMS controller. # of page groups and individual pages using the FMS controller.
obj._pageGroupController = fg1000.PageGroupController.new(myCanvas, obj._svg, obj._MFDDevice); obj._pageGroupController = fg1000.PageGroupController.new(myCanvas, obj._svg, obj._MFDDevice);
foreach (var page; MFDPages) {
var code = "obj._pageGroupController.addPage(\"" ~ page ~ "\", fg1000." ~ page ~ ".new(obj, myCanvas, obj._MFDDevice, obj._svg));";
var addPageFn = compile(code);
addPageFn();
}
# The NavigationMap page is a special case, as it is displayed with the Nearest... pages as an overlay # The NavigationMap page is a special case, as it is displayed with the Nearest... pages as an overlay
obj.NavigationMap = obj._pageGroupController.getPage("NavigationMap"); obj.NavigationMap = obj._pageGroupController.addPage("NavigationMap", fg1000.NavigationMap.new(obj, myCanvas, obj._MFDDevice, obj._svg));
obj.NavigationMap.topMenu(obj._MFDDevice, obj.NavigationMap, nil);
foreach (var page; MFDPages) {
if (page != "NavigationMap") {
var code = "obj._pageGroupController.addPage(\"" ~ page ~ "\", fg1000." ~ page ~ ".new(obj, myCanvas, obj._MFDDevice, obj._svg));";
var addPageFn = compile(code);
addPageFn();
}
}
# Display the NavMap and the appropriate top level on startup. # Display the NavMap and the appropriate top level on startup.
obj._MFDDevice.selectPage(obj.NavigationMap); obj._MFDDevice.selectPage(obj.NavigationMap);
@ -129,7 +138,7 @@ var MFD =
var updateTimer = func() { var updateTimer = func() {
obj._eisDriver.update(); obj._eisDriver.update();
obj._eis.update(); obj.EIS.update();
settimer(updateTimer, 0.1); settimer(updateTimer, 0.1);
}; };

View file

@ -63,6 +63,15 @@ setTextElement : func(symbolName, value) {
assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)"); assert(sym != nil, "Unknown text element " ~ symbolName ~ " (check your addTextElements call?)");
if (value == nil ) value = ""; if (value == nil ) value = "";
sym.setValue(value); sym.setValue(value);
} },
# Function to undo any colors set by display_toggle when loading a new menu
resetMenuColors : func() {
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
me.device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
me.device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
},
}; };

View file

@ -18,8 +18,8 @@ var NavigationMap =
obj.addTextElements(["RangeDisplay", "Orientation"]); obj.addTextElements(["RangeDisplay", "Orientation"]);
obj.addTextElements(["RangeDisplayPartial", "OrientationPartial"]); obj.addTextElements(["RangeDisplayPartial", "OrientationPartial"]);
obj._labelsFull = svg.getElementById("NavigationMapGroupFull"); obj._labelsFull = svg.getElementById("NavigationMapGroup");
assert(obj._labelsFull != nil, "Unable to find NavigationMapGroupFull"); assert(obj._labelsFull != nil, "Unable to find NavigationMapGroup");
obj._labelsPartial = svg.getElementById("NavigationMapGroupPartial"); obj._labelsPartial = svg.getElementById("NavigationMapGroupPartial");
assert(obj._labelsPartial != nil, "Unable to find NavigationMapGroupPartial"); assert(obj._labelsPartial != nil, "Unable to find NavigationMapGroupPartial");
@ -54,7 +54,7 @@ var NavigationMap =
var r = func(name,vis=1,zindex=nil) return caller(0)[0]; var r = func(name,vis=1,zindex=nil) return caller(0)[0];
# TODO: we'll need some z-indexing here, right now it's just random # TODO: we'll need some z-indexing here, right now it's just random
foreach(var type; [r('GRID'),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')] ) { foreach(var type; [r('GRID'),r('DTO',0),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')] ) {
obj.MFDMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name, obj.MFDMap.addLayer(factory: canvas.SymbolLayer, type_arg: type.name,
visible: type.vis, priority: 4, visible: type.vis, priority: 4,
style: obj.Styles.getStyle(type.name), style: obj.Styles.getStyle(type.name),
@ -68,121 +68,7 @@ var NavigationMap =
options: obj.Options.getOption(type.name) ); options: obj.Options.getOption(type.name) );
} }
var topMenu = func(device, pg, menuitem) { #obj.topMenu(device, obj, nil);
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(2, "MAP", pg, mapMenu);
pg.addMenuItem(8, "DCLTR", pg, func(dev, pg, mi) { obj.controller.incrDCLTR(dev, mi); } );
#pg.addMenuItem(9, "SHW CHRT", pg); # Optional
#pg.addMenuItem(10, "CHKLIST", pg); # Optional
device.updateMenus();
};
var engineMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(8, "BACK", pg, topMenu);
device.updateMenus();
};
# Display map toggle softkeys which change color depending
# on whether a particular layer is enabled or not.
var display_toggle = func(device, svg, mi, layer) {
var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
if (obj.controller.isEnabled(layer)) {
device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
svg.setColor(0.0,0.0,0.0);
} else {
device.svg.getElementById(bg_name).setColorFill(0.0,0.0,0.0);
svg.setColor(1.0,1.0,1.0);
}
svg.setText(mi.title);
svg.setVisible(1); # display function
};
# Function to undo any colors set by display_toggle when loading a new menu
var resetMenuColors = func(device) {
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
}
var mapMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "TRAFFIC", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("TFC"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "TFC"); }
);
pg.addMenuItem(1, "PROFILE", pg);
pg.addMenuItem(2, "TOPO", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("STAMEN"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "STAMEN"); }
);
pg.addMenuItem(3, "TERRAIN", pg,
func(dev, pg, mi) { obj.controller.toggleLayer("STAMEN_terrain"); device.updateMenus(); }, # callback
func(svg, mi) { display_toggle(device, svg, mi, "STAMEN_terrain"); }
);
pg.addMenuItem(4, "AIRWAYS", pg, func(dev, pg, mi) { obj.controller.incrAIRWAYS(dev, mi); } );
#pg.addMenuItem(5, "STRMSCP", pg); Optional
#pg.addMenuItem(6, "PRECIP", pg); Optional, or NEXRAD
#pg.addMenuItem(7, "XM LTNG", pg); Optional, or DL LTNG
#pg.addMenuItem(8, "METAR", pg);
#pg.addMenuItem(9, "LEGEND", pg); Optional - only available with NEXRAD/XM LTNG/METAR/PROFILE selected
pg.addMenuItem(10, "BACK", pg, topMenu); # Or should this just be the next button?
device.updateMenus();
};
var leanMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "CYL SELECT", pg);
pg.addMenuItem(4, "ASSIST", pg);
pg.addMenuItem(9, "BACK", pg, engineMenu);
device.updateMenus();
};
var systemMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "RST FUEL", pg);
pg.addMenuItem(4, "GAL REM", pg, galRemMenu);
pg.addMenuItem(5, "BACK", pg, engineMenu);
device.updateMenus();
};
var galRemMenu = func(device, pg, menuitem) {
pg.clearMenu();
resetMenuColors(device);
pg.addMenuItem(0, "ENGINE", pg, engineMenu);
pg.addMenuItem(1, "LEAN", pg, leanMenu);
pg.addMenuItem(2, "SYSTEM", pg, systemMenu);
pg.addMenuItem(3, "-10 GAL", pg);
pg.addMenuItem(4, "-1 GAL", pg);
pg.addMenuItem(5, "+1 GAL", pg);
pg.addMenuItem(6, "+10 GAL", pg);
pg.addMenuItem(7, "44 GAL", pg);
pg.addMenuItem(8, "BACK", pg, engineMenu);
device.updateMenus();
};
topMenu(device, obj, nil);
obj.controller = fg1000.NavigationMapController.new(obj, svg); obj.controller = fg1000.NavigationMapController.new(obj, svg);
@ -252,4 +138,67 @@ var NavigationMap =
me._group.setVisible(0); me._group.setVisible(0);
me.controller.offdisplayPartial(); me.controller.offdisplayPartial();
}, },
# Softkey assigments. For some pages (notably the NEAREST pages)
# the MAP softkey is available as key 2:
# pg.addMenuItem(2, "MAP", pg, pg.mfd.NavigationMap.mapMenu);
topMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(2, "MAP", pg, pg.mfd.NavigationMap.mapMenu);
pg.addMenuItem(8, "DCLTR", pg, func(dev, pg, mi) { pg.mfd.NavigationMap.controller.incrDCLTR(dev, mi); } );
#pg.addMenuItem(9, "SHW CHRT", pg); # Optional
#pg.addMenuItem(10, "CHKLIST", pg); # Optional
device.updateMenus();
},
mapMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "TRAFFIC", pg,
func(dev, pg, mi) { pg.mfd.NavigationMap.controller.toggleLayer("TFC"); device.updateMenus(); }, # callback
func(svg, mi) { pg.mfd.NavigationMap.display_toggle(device, svg, mi, "TFC"); }
);
pg.addMenuItem(1, "PROFILE", pg);
pg.addMenuItem(2, "TOPO", pg,
func(dev, pg, mi) { pg.mfd.NavigationMap.controller.toggleLayer("STAMEN"); device.updateMenus(); }, # callback
func(svg, mi) { pg.mfd.NavigationMap.display_toggle(device, svg, mi, "STAMEN"); }
);
pg.addMenuItem(3, "TERRAIN", pg,
func(dev, pg, mi) { pg.mfd.NavigationMap.controller.toggleLayer("STAMEN_terrain"); device.updateMenus(); }, # callback
func(svg, mi) { pg.mfd.NavigationMap.display_toggle(device, svg, mi, "STAMEN_terrain"); }
);
pg.addMenuItem(4, "AIRWAYS", pg, func(dev, pg, mi) { pg.mfd.NavigationMap.controller.incrAIRWAYS(dev, mi); } );
#pg.addMenuItem(5, "STRMSCP", pg); Optional
#pg.addMenuItem(6, "PRECIP", pg); Optional, or NEXRAD
#pg.addMenuItem(7, "XM LTNG", pg); Optional, or DL LTNG
#pg.addMenuItem(8, "METAR", pg);
#pg.addMenuItem(9, "LEGEND", pg); Optional - only available with NEXRAD/XM LTNG/METAR/PROFILE selected
pg.addMenuItem(10, "BACK", pg, pg.topMenu); # Or should this just be the next button?
device.updateMenus();
},
# Display map toggle softkeys which change color depending
# on whether a particular layer is enabled or not.
display_toggle : func(device, svg, mi, layer) {
var bg_name = sprintf("SoftKey%d-bg",mi.menu_id);
if (me.controller.isEnabled(layer)) {
device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
svg.setColor(0.0,0.0,0.0);
} else {
device.svg.getElementById(bg_name).setColorFill(0.0,0.0,0.0);
svg.setColor(1.0,1.0,1.0);
}
svg.setText(mi.title);
svg.setVisible(1); # display function
},
}; };

View file

@ -47,6 +47,8 @@ var NavigationMapController =
# range - the maximum range this layer is visible (configured by user) # range - the maximum range this layer is visible (configured by user)
# max_range - the maximum range value that a user can configure for this layer. # max_range - the maximum range value that a user can configure for this layer.
LAYER_RANGES : { LAYER_RANGES : {
DTO : { enabled: 0, declutter: 3, range: 2000, max_range: 2000 },
GRID : { enabled: 0, declutter: 1, range: 20, max_range: 2000 }, GRID : { enabled: 0, declutter: 1, range: 20, max_range: 2000 },
DME : { enabled: 1, declutter: 1, range: 150, max_range: 300 }, DME : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
VOR : { enabled: 1, declutter: 1, range: 150, max_range: 300 }, VOR : { enabled: 1, declutter: 1, range: 150, max_range: 300 },
@ -162,6 +164,16 @@ var NavigationMapController =
device.updateMenus(); device.updateMenus();
me.updateVisibility(); me.updateVisibility();
}, },
# Set the DTO line target
setDTOLineTarget : func(lat, lon) {
me.page.MFDMap.getLayer("DTO").controller.setTarget(lat,lon);
},
enableDTO : func(enable) {
me.LAYER_RANGES["DTO"].enabled = enable;
me.updateVisibility();
},
handleFMSInner : func(value) { handleFMSInner : func(value) {
# This page has no use for the FMS knob, so we pass all such # This page has no use for the FMS knob, so we pass all such
# events to the pageGroupController which displays the page menu in the # events to the pageGroupController which displays the page menu in the

View file

@ -27,7 +27,10 @@ var NearestAirports =
[ "Arrow", "ID", "CRS", "DST"], [ "Arrow", "ID", "CRS", "DST"],
5, 5,
"Arrow", "Arrow",
1 1,
"AirportScrollBar",
"AirportScroll",
100
); );
obj.runwaySelect = PFD.ScrollElement.new(obj.pageName, svg, "RunwayID", [36,18]); # Dummy values obj.runwaySelect = PFD.ScrollElement.new(obj.pageName, svg, "RunwayID", [36,18]); # Dummy values
@ -37,7 +40,11 @@ var NearestAirports =
svg, svg,
["FreqLabel", "Freq"], ["FreqLabel", "Freq"],
3, 3,
"Freq" "Freq",
0,
"FreqScrollBar",
"FreqScroll",
75
); );
obj.approachSelect = PFD.GroupElement.new( obj.approachSelect = PFD.GroupElement.new(
@ -45,40 +52,17 @@ var NearestAirports =
svg, svg,
["Approach"], ["Approach"],
3, 3,
"Approach" "Approach",
0,
"ApproachScrollBar",
"ApproachScroll",
75
); );
# Other dynamic text elements # Other dynamic text elements
obj.addTextElements(["Name", "Alt", "RunwaySurface", "RunwayDimensions"]); obj.addTextElements(["Name", "Alt", "RunwaySurface", "RunwayDimensions"]);
var topMenu = func(device, pg, menuitem) { obj.topMenu(device, obj, nil);
pg.clearMenu();
pg.resetMenuColors(device);
pg.addMenuItem(4, "APT", pg,
func(dev, pg, mi) { pg.controller.selectAirports(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.APT); }
);
pg.addMenuItem(5, "RNWY", pg,
func(dev, pg, mi) { pg.controller.selectRunways(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.RNWY); }
);
pg.addMenuItem(6, "FREQ", pg,
func(dev, pg, mi) { pg.controller.selectFrequencies(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.FREQ); }
);
pg.addMenuItem(7, "APR", pg,
func(dev, pg, mi) { pg.controller.selectApproaches(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.APR); }
);
device.updateMenus();
};
topMenu(device, obj, nil);
return obj; return obj;
}, },
@ -100,7 +84,7 @@ var NearestAirports =
# Function to highlight the APT softkey - used when CRSR is pressed to indicate # Function to highlight the APT softkey - used when CRSR is pressed to indicate
# that we're editing the airports selection. # that we're editing the airports selection.
selectAirports : func() { selectAirports : func() {
me.resetMenuColors(me.device); me.resetMenuColors();
var bg_name = sprintf("SoftKey%d-bg",4); var bg_name = sprintf("SoftKey%d-bg",4);
var tname = sprintf("SoftKey%d",4); var tname = sprintf("SoftKey%d",4);
me.device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5); me.device.svg.getElementById(bg_name).setColorFill(0.5,0.5,0.5);
@ -112,16 +96,7 @@ var NearestAirports =
me.runwaySelect.unhighlightElement(); me.runwaySelect.unhighlightElement();
me.freqSelect.hideCRSR(); me.freqSelect.hideCRSR();
me.approachSelect.hideCRSR(); me.approachSelect.hideCRSR();
me.resetMenuColors(me.device); me.resetMenuColors();
},
# Function to undo any colors set by display_toggle when loading a new menu
resetMenuColors : func(device) {
for(var i = 0; i < 12; i +=1) {
var name = sprintf("SoftKey%d",i);
device.svg.getElementById(name ~ "-bg").setColorFill(0.0,0.0,0.0);
device.svg.getElementById(name).setColor(1.0,1.0,1.0);
}
}, },
offdisplay : func() { offdisplay : func() {
@ -130,7 +105,7 @@ var NearestAirports =
# Reset the menu colours. Shouldn't have to do this here, but # Reset the menu colours. Shouldn't have to do this here, but
# there's not currently an obvious other location to do so. # there's not currently an obvious other location to do so.
me.resetMenuColors(me.device); me.resetMenuColors();
me.controller.offdisplay(); me.controller.offdisplay();
}, },
@ -141,7 +116,6 @@ var NearestAirports =
me.mfd.NavigationMap.ondisplayPartial(); me.mfd.NavigationMap.ondisplayPartial();
me.mfd.setPageTitle(me.title); me.mfd.setPageTitle(me.title);
}, },
updateAirports : func(apts) { updateAirports : func(apts) {
@ -149,7 +123,10 @@ var NearestAirports =
for (var i = 0; i < size(apts); i = i + 1) { for (var i = 0; i < size(apts); i = i + 1) {
var apt = apts[i]; var apt = apts[i];
var crsAndDst = courseAndDistance(apt); var crsAndDst = courseAndDistance(apt);
var crs = sprintf("%i", crsAndDst[0]);
# Display the cours and distance in NM .
# 248 is the extended ASCII code for the degree symbol
var crs = sprintf("%i%c", crsAndDst[0], 248);
var dst = sprintf("%.1fnm", crsAndDst[1]); var dst = sprintf("%.1fnm", crsAndDst[1]);
# Convert into something we can pass straight to the UIGroup. # Convert into something we can pass straight to the UIGroup.
@ -176,11 +153,22 @@ var NearestAirports =
me.setTextElement("Name", apt.name); me.setTextElement("Name", apt.name);
me.setTextElement("Alt", sprintf("%ift", M2FT * apt.elevation)); me.setTextElement("Alt", sprintf("%ift", M2FT * apt.elevation));
var runwaylist = keys(apt.runways); # Set up the runways list, but ignoring reciprocals so we don't get
# runways displayed twice.
var rwys = [];
var recips = {};
foreach(var rwy; sort(keys(apt.runways), string.icmp)) {
var rwy_info = apt.runways[rwy];
if (recips[rwy_info.id] == nil) {
var lbl = rwy_info.id ~ "-" ~ rwy_info.reciprocal.id;
append(rwys, lbl);
recips[rwy_info.reciprocal.id] = 1;
}
}
if (size(runwaylist) > 0) { if (size(rwys) > 0) {
me.runwaySelect.setValues(runwaylist); me.runwaySelect.setValues(rwys);
me.updateRunwayInfo(apt.runways[runwaylist[0]]); me.updateRunwayInfo(apt.runways[keys(apt.runways)[0]]);
} else { } else {
me.runwaySelect.setValues([""]); me.runwaySelect.setValues([""]);
me.updateRunwayInfo(nil); me.updateRunwayInfo(nil);
@ -205,6 +193,9 @@ var NearestAirports =
# Approaches # Approaches
var approachList = apt.getApproachList(); var approachList = apt.getApproachList();
me.approachSelect.setValues(approachList); me.approachSelect.setValues(approachList);
# Display the DTO line to the airport
me.mfd.NavigationMap.controller.setDTOLineTarget(apt.lat, apt.lon);
}, },
updateRunwayInfo : func(rwy_info) { updateRunwayInfo : func(rwy_info) {
if (rwy_info != nil ) { if (rwy_info != nil ) {
@ -228,4 +219,32 @@ var NearestAirports =
getSelectedApproach : func() { getSelectedApproach : func() {
return me.approachSelect.getValue(); return me.approachSelect.getValue();
}, },
topMenu : func(device, pg, menuitem) {
pg.clearMenu();
pg.resetMenuColors();
pg.addMenuItem(0, "ENGINE", pg, pg.mfd.EIS.engineMenu);
pg.addMenuItem(2, "MAP", pg, pg.mfd.NavigationMap.mapMenu);
pg.addMenuItem(4, "APT", pg,
func(dev, pg, mi) { pg.controller.selectAirports(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.APT); }
);
pg.addMenuItem(5, "RNWY", pg,
func(dev, pg, mi) { pg.controller.selectRunways(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.RNWY); }
);
pg.addMenuItem(6, "FREQ", pg,
func(dev, pg, mi) { pg.controller.selectFrequencies(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.FREQ); }
);
pg.addMenuItem(7, "APR", pg,
func(dev, pg, mi) { pg.controller.selectApproaches(); device.updateMenus(); }, # callback
func(svg, mi) { pg.display_toggle(device, svg, mi, NearestAirportsController.UIGROUP.APR); }
);
device.updateMenus();
},
}; };

View file

@ -99,8 +99,15 @@ var NearestAirportsController =
if ((rwy != nil) and (rwy != "")) { if ((rwy != nil) and (rwy != "")) {
var apt_info = airportinfo(apt_id); var apt_info = airportinfo(apt_id);
var rwy_info = apt_info.runways[rwy];
me.page.updateRunwayInfo(rwy_info); # Names in the runway selection are of the form "NNN-MMM", e.g. 11R-29L
# We just want the first of these.
var idx = find("-", rwy);
if (idx != -1) {
rwy = substr(rwy, 0, idx);
var rwy_info = apt_info.runways[rwy];
me.page.updateRunwayInfo(rwy_info);
}
} }
} }
@ -203,8 +210,10 @@ var NearestAirportsController =
me._currentGroup = NearestAirportsController.UIGROUP.NONE; me._currentGroup = NearestAirportsController.UIGROUP.NONE;
me.RegisterWithEmesary(); me.RegisterWithEmesary();
me.getAirports(); me.getAirports();
me.page.mfd.NavigationMap.controller.enableDTO(1);
}, },
offdisplay : func() { offdisplay : func() {
me.page.mfd.NavigationMap.controller.enableDTO(0);
me.DeRegisterWithEmesary(); me.DeRegisterWithEmesary();
}, },
}; };

View file

@ -2,13 +2,16 @@
var GroupElement = var GroupElement =
{ {
new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, style=nil) new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, scrollTroughElement=nil, scrollThumbElement=nil, scrollHeight=0, style=nil)
{ {
var obj = { var obj = {
parents : [ GroupElement ], parents : [ GroupElement ],
_pageName : pageName, _pageName : pageName,
_svg : svg, _svg : svg,
_style : style, _style : style,
_scrollTroughElement : nil,
_scrollThumbElement : nil,
_scrollBaseTransform : nil,
# A hash mapping keys to the element name prefix of an SVG element # A hash mapping keys to the element name prefix of an SVG element
_elementNames : elementNames, _elementNames : elementNames,
@ -27,10 +30,39 @@ new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, style=
# hidden/shown for highlighting purposes. # hidden/shown for highlighting purposes.
_arrow : arrow, _arrow : arrow,
# Length of the scroll bar.
_scrollHeight : scrollHeight,
# List of values to display
_values : [],
# List of SVG elements to display the values
_elements : [], _elements : [],
_crsrIndex : -1, # Cursor index into the elements array
# Cursor index into the elements array
_crsrIndex : -1,
# Page index
_pageIndex : 0,
}; };
# Optional scroll bar elements, consisting of the Thumb and the Trough *,
# which will be used to display the scroll position.
# * Yes, these are the terms of art for the elements.
assert(((scrollTroughElement == nil) and (scrollThumbElement == nil)) or
((scrollTroughElement != nil) and (scrollThumbElement != nil)),
"Both the scroll trough element and the scroll thumb element must be defined, or neither");
if (scrollTroughElement != nil) {
obj._scrollTroughElement = svg.getElementById(pageName ~ scrollTroughElement);
assert(obj._scrollTroughElement != nil, "Unable to find scroll element " ~ pageName ~ scrollTroughElement);
}
if (scrollThumbElement != nil) {
obj._scrollThumbElement = svg.getElementById(pageName ~ scrollThumbElement);
assert(obj._scrollThumbElement != nil, "Unable to find scroll element " ~ pageName ~ scrollThumbElement);
obj._scrollBaseTransform = obj._scrollThumbElement.getTranslation();
}
if (style == nil) obj._style = PFD.DefaultStyle; if (style == nil) obj._style = PFD.DefaultStyle;
for (var i = 0; i < size; i = i + 1) { for (var i = 0; i < size; i = i + 1) {
@ -47,22 +79,61 @@ new : func (pageName, svg, elementNames, size, highlightElement, arrow=0, style=
# Set the values of the group. values_array is an array of hashes, each of which # Set the values of the group. values_array is an array of hashes, each of which
# has keys that match those of ._elementNames # has keys that match those of ._elementNames
setValues : func (values_array) { setValues : func (values_array) {
me._values = values_array;
me._pageIndex = 0;
me._crsrIndex = 0;
# Determine how many of these we display if (size(me._values) > me._size) {
me._currentSize = math.min(me._size, size(values_array)); # Number of elements exceeds our ability to display them, so enable
# the scroll bar.
me._scrollThumbElement.setVisible(1);
me._scrollTroughElement.setVisible(1);
} else {
# There is no scrolling to do, so hide the scrollbar.
me._scrollThumbElement.setVisible(0);
me._scrollTroughElement.setVisible(0);
}
me.displayPage();
},
nextPage : func() {
if (size(me._values) > ((me._pageIndex +1) * me._size)) {
me._pageIndex = me._pageIndex + 1;
me._crsrIndex = 0;
me.displayPage();
} else {
me._crsrIndex = me._currentSize -1;
}
},
previousPage : func() {
if (me._pageIndex > 0) {
me._pageIndex = me._pageIndex - 1;
me._crsrIndex = me._size -1;
me.displayPage();
} else {
me._crsrIndex = 0;
}
},
displayPage : func () {
# Determine how many elements to display in this page
me._currentSize = math.min(me._size, size(me._values) - me._size * me._pageIndex);
for (var i = 0; i < me._currentSize; i = i + 1) { for (var i = 0; i < me._currentSize; i = i + 1) {
var values = values_array[i]; var value = me._values[i + me._size * me._pageIndex];
foreach (var k; keys(values)) { foreach (var k; keys(value)) {
if (k == me._highlightElement) { if (k == me._highlightElement) {
me._elements[i].setVisible(1);
me._elements[i].unhighlightElement(); me._elements[i].unhighlightElement();
me._elements[i].setValue(values[k]); me._elements[i].setValue(value[k]);
} else { } else {
var name = me._pageName ~ k ~ i; var name = me._pageName ~ k ~ i;
var element = me._svg.getElementById(name); var element = me._svg.getElementById(name);
assert(element != nil, "Unable to find element " ~ name); assert(element != nil, "Unable to find element " ~ name);
element.setVisible(1); element.setVisible(1);
element.setText(values[k]); element.setText(value[k]);
} }
} }
} }
@ -73,14 +144,27 @@ setValues : func (values_array) {
foreach (var k; me._elementNames) { foreach (var k; me._elementNames) {
if (k == me._highlightElement) { if (k == me._highlightElement) {
me._elements[i].setVisible(0); me._elements[i].setVisible(0);
me._elements[i].setValue("");
} else { } else {
me._svg.getElementById(k ~ i).setVisible(0); var name = me._pageName ~ k ~ i;
var element = me._svg.getElementById(name);
assert(element != nil, "Unable to find element " ~ name);
element.setVisible(0);
element.setText("");
} }
} }
} }
} }
},
if ((me._scrollThumbElement != nil) and (me._size < size(me._values))) {
# Shift the scrollbar if it's relevant
var numScrollPositions = math.ceil(size(me._values) / me._size) -1;
me._scrollThumbElement.setTranslation([
me._scrollBaseTransform[0],
me._scrollBaseTransform[1] + me._scrollHeight * (me._pageIndex / numScrollPositions)
]);
}
},
# Methods to add dynamic elements to the group. Must be called in the # Methods to add dynamic elements to the group. Must be called in the
# scroll order, as they are simply appended to the end of the list of elements! # scroll order, as they are simply appended to the end of the list of elements!
@ -126,6 +210,7 @@ clearElement : func() {
}, },
incrSmall : func(value) { incrSmall : func(value) {
if (me._crsrIndex == -1) return; if (me._crsrIndex == -1) return;
var incr_or_decr = (value > 0) ? 1 : -1; var incr_or_decr = (value > 0) ? 1 : -1;
if (me._elements[me._crsrIndex].isInEdit()) { if (me._elements[me._crsrIndex].isInEdit()) {
# We're editing, so pass to the element. # We're editing, so pass to the element.
@ -134,7 +219,12 @@ incrSmall : func(value) {
} else { } else {
# Move to next selection element # Move to next selection element
me._elements[me._crsrIndex].unhighlightElement(); me._elements[me._crsrIndex].unhighlightElement();
me._crsrIndex = math.mod(me._crsrIndex + incr_or_decr, me._currentSize);
me._crsrIndex = me._crsrIndex + incr_or_decr;
if (me._crsrIndex < 0 ) me.previousPage();
if (me._crsrIndex == me._currentSize) me.nextPage();
me._elements[me._crsrIndex].highlightElement(); me._elements[me._crsrIndex].highlightElement();
} }
}, },
@ -148,7 +238,12 @@ incrLarge : func(val) {
} else { } else {
# Move to next selection element # Move to next selection element
me._elements[me._crsrIndex].unhighlightElement(); me._elements[me._crsrIndex].unhighlightElement();
me._crsrIndex = math.mod(me._crsrIndex + incr_or_decr, me._currentSize);
me._crsrIndex = me._crsrIndex + incr_or_decr;
if (me._crsrIndex < 0 ) me.previousPage();
if (me._crsrIndex == me._currentSize) me.nextPage();
me._elements[me._crsrIndex].highlightElement(); me._elements[me._crsrIndex].highlightElement();
} }
}, },

View file

@ -0,0 +1,59 @@
# See: http://wiki.flightgear.org/MapStructure
# Direct TO line. Displays line from current position to a given Lat/Lon
# Class things:
var name = 'DTO';
var parents = [SymbolLayer.Controller];
var __self__ = caller(0)[0];
SymbolLayer.Controller.add(name, __self__);
SymbolLayer.add(name, {
parents: [MultiSymbolLayer],
type: name, # Symbol type
df_controller: __self__, # controller to use by default -- this one
df_options: { # default configuration options
}
});
var new = func(layer) {
var m = {
parents: [__self__],
layer: layer,
map: layer.map,
listeners: [],
target_lat: -999,
target_lon: -999,
target_alt: -999,
last_result: [],
};
layer.searcher._equals = func(l,r) 0; # TODO: create model objects instead?
m.addVisibilityListener();
return m;
};
var del = func() {
foreach (var l; me.listeners)
removelistener(l);
};
var setTarget = func(lat, lon, alt=0) {
me.target_lat = lat;
me.target_lon = lon;
me.target_alt = alt;
me.layer.update();
};
var searchCmd = func() {
var coords = [];
append(coords, {lon: me.target_lon, lat: me.target_lat, alt: me.target_alt});
var lines = [];
append(lines, {
id: me.target_lat ~ " " ~ me.target_lon,
type: "lon",
path: coords,
equals: func(o){
return (me.path == o.path and me.type == o.type);
}
});
return lines;
};

View file

@ -0,0 +1,55 @@
# See: http://wiki.flightgear.org/MapStructure
#
# Direct TO line. Displays line from current position to a given Lat/Lon
# Class things:
var name = 'DTO';
var parents = [LineSymbol];
var __self__ = caller(0)[0];
LineSymbol.makeinstance( name, __self__ );
SymbolLayer.get(name).df_style = { # style to use by default
line_width: 2,
color: [1.0,1.0,1.0],
dash_array: [5,5,5,5],
};
var init = func {
me.element.setColor(me.layer.style.color)
.setStrokeLineWidth(me.layer.style.line_width)
.setStrokeDashArray(me.layer.style.dash_array);
};
var draw = func() {
me.callback('draw_before');
printlog(_MP_dbg_lvl, "redrawing a LineSymbol "~me.layer.type);
me.element.reset();
var cmds = [];
var coords = [];
var cmd = canvas.Path.VG_LINE_TO;
append(coords,"N"~me.layer.map.getLat());
append(coords,"E"~me.layer.map.getLon());
append(cmds,canvas.Path.VG_MOVE_TO);
var path = me.model;
if(typeof(path) == 'hash'){
path = me.model.path;
if(path == nil)
__die("LineSymbol model requires a 'path' member (vector)");
}
foreach (var m; path) {
if(size(keys(m)) >= 2){
var (lat,lon) = me.controller.getpos(m);
append(coords,"N"~lat);
append(coords,"E"~lon);
append(cmds,cmd);
cmd = canvas.Path.VG_LINE_TO;
} else {
cmd = canvas.Path.VG_MOVE_TO;
}
}
me.element.setDataGeo(cmds, coords);
me.element.update(); # this doesn't help with flickering, it seems
me.callback('draw_after');
};