sensors: compass, maps
This commit is contained in:
parent
768179ab24
commit
0ce9f9c1a1
10 changed files with 1823 additions and 8 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -45,3 +45,7 @@ app.*.map.json
|
||||||
|
|
||||||
key.properties
|
key.properties
|
||||||
/key
|
/key
|
||||||
|
|
||||||
|
later.*
|
||||||
|
|
||||||
|
to_remember.txt
|
962
assets/compass.svg
Normal file
962
assets/compass.svg
Normal file
|
@ -0,0 +1,962 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
version="1.1"
|
||||||
|
width="1148"
|
||||||
|
height="1136.3206"
|
||||||
|
id="svg2">
|
||||||
|
<metadata
|
||||||
|
id="metadata8">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs6" />
|
||||||
|
<g
|
||||||
|
transform="translate(-27.40625,-2.9765625)"
|
||||||
|
id="layer3"
|
||||||
|
style="display:inline">
|
||||||
|
<g
|
||||||
|
id="g4456">
|
||||||
|
<path
|
||||||
|
d="m 600,935 0,-728"
|
||||||
|
id="path4392"
|
||||||
|
style="fill:none;stroke:#e56107;stroke-width:12;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="M 564.22374,934.24243 635.77626,207.75757"
|
||||||
|
id="path4394"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 528.79203,928.98663 671.20797,213.01337"
|
||||||
|
id="path4396"
|
||||||
|
style="fill:none;stroke:#646464;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 494.04609,920.28322 705.95391,221.71678"
|
||||||
|
id="path4398"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 460.32054,908.21603 739.67946,233.78397"
|
||||||
|
id="path4400"
|
||||||
|
style="fill:none;stroke:#ff0000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 427.94018,892.90126 772.05982,249.09874"
|
||||||
|
id="path4402"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 397.21685,874.48641 802.78315,267.51359"
|
||||||
|
id="path4404"
|
||||||
|
style="fill:none;stroke:#646464;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 368.44644,853.14882 831.55356,288.85118"
|
||||||
|
id="path4406"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 317.85117,802.55355 882.14883,339.44645"
|
||||||
|
id="path4410"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 296.51358,773.78313 903.48642,368.21687"
|
||||||
|
id="path4412"
|
||||||
|
style="fill:none;stroke:#646464;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 278.09873,743.0598 921.90127,398.9402"
|
||||||
|
id="path4414"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 262.78396,710.67944 937.21604,431.32056"
|
||||||
|
id="path4416"
|
||||||
|
style="fill:none;stroke:#ff0000;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 250.71677,676.95389 949.28323,465.04611"
|
||||||
|
id="path4418"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 242.01337,642.20795 957.98663,499.79205"
|
||||||
|
id="path4420"
|
||||||
|
style="fill:none;stroke:#646464;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 6;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 236.75757,606.77624 963.24243,535.22376"
|
||||||
|
id="path4422"
|
||||||
|
style="fill:none;stroke:#00ff00;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 3;stroke-dashoffset:0" />
|
||||||
|
<path
|
||||||
|
d="M 342.61313,828.38687 857.38687,313.61313"
|
||||||
|
id="path4608"
|
||||||
|
style="fill:none;stroke:#aa8416;stroke-width:12;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:12, 12;stroke-dashoffset:0;display:inline" />
|
||||||
|
</g>
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171,-29)"
|
||||||
|
id="use4474"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g4456" />
|
||||||
|
<path
|
||||||
|
d="m 990,416 a 310,310 0 1 1 -620,0 310,310 0 1 1 620,0 z"
|
||||||
|
transform="translate(-80,155)"
|
||||||
|
id="path4628"
|
||||||
|
style="opacity:0.6;fill:#ffffff;stroke:none;display:inline" />
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="306"
|
||||||
|
id="text4648"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="600"
|
||||||
|
y="306"
|
||||||
|
id="tspan4650">64</tspan></text>
|
||||||
|
<text
|
||||||
|
x="772.83997"
|
||||||
|
y="32.925156"
|
||||||
|
transform="matrix(0.92387953,0.38268343,-0.38268343,0.92387953,0,0)"
|
||||||
|
id="text4652"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="772.83997"
|
||||||
|
y="32.925156"
|
||||||
|
id="tspan4654">4</tspan></text>
|
||||||
|
<text
|
||||||
|
x="828.02203"
|
||||||
|
y="-285.5061"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
|
||||||
|
id="text4656"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="828.02203"
|
||||||
|
y="-285.5061"
|
||||||
|
id="tspan4658">8</tspan></text>
|
||||||
|
<text
|
||||||
|
x="757.14526"
|
||||||
|
y="-600.81549"
|
||||||
|
transform="matrix(0.38268343,0.92387953,-0.92387953,0.38268343,0,0)"
|
||||||
|
id="text4660"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="757.14526"
|
||||||
|
y="-600.81549"
|
||||||
|
id="tspan4662">12</tspan></text>
|
||||||
|
<text
|
||||||
|
x="571"
|
||||||
|
y="-865"
|
||||||
|
transform="matrix(0,1,-1,0,0,0)"
|
||||||
|
id="text4664"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="571"
|
||||||
|
y="-865"
|
||||||
|
id="tspan4666">16</tspan></text>
|
||||||
|
<text
|
||||||
|
x="335.81549"
|
||||||
|
y="492.14526"
|
||||||
|
transform="matrix(0.92387953,-0.38268343,0.38268343,0.92387953,0,0)"
|
||||||
|
id="text4684"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="335.81549"
|
||||||
|
y="492.14526"
|
||||||
|
id="tspan4686">60</tspan></text>
|
||||||
|
<text
|
||||||
|
x="20.506107"
|
||||||
|
y="563.02203"
|
||||||
|
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
|
||||||
|
id="text4688"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="20.506107"
|
||||||
|
y="563.02203"
|
||||||
|
id="tspan4690">56</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-297.92514"
|
||||||
|
y="507.83997"
|
||||||
|
transform="matrix(0.38268343,-0.92387953,0.92387953,0.38268343,0,0)"
|
||||||
|
id="text4692"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-297.92514"
|
||||||
|
y="507.83997"
|
||||||
|
id="tspan4694">52</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-571"
|
||||||
|
y="335"
|
||||||
|
transform="matrix(0,-1,1,0,0,0)"
|
||||||
|
id="text4696"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-571"
|
||||||
|
y="335"
|
||||||
|
id="tspan4698">48</tspan></text>
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="858"
|
||||||
|
id="text4700"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="600"
|
||||||
|
y="858"
|
||||||
|
id="tspan4702">32</tspan></text>
|
||||||
|
<text
|
||||||
|
x="335.81549"
|
||||||
|
y="1044.1453"
|
||||||
|
transform="matrix(0.92387953,-0.38268343,0.38268343,0.92387953,0,0)"
|
||||||
|
id="text4704"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="335.81549"
|
||||||
|
y="1044.1453"
|
||||||
|
id="tspan4706">28</tspan></text>
|
||||||
|
<text
|
||||||
|
x="20.506107"
|
||||||
|
y="1115.022"
|
||||||
|
transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,0,0)"
|
||||||
|
id="text4708"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="20.506107"
|
||||||
|
y="1115.022"
|
||||||
|
id="tspan4710">24</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-297.92514"
|
||||||
|
y="1059.8398"
|
||||||
|
transform="matrix(0.38268343,-0.92387953,0.92387953,0.38268343,0,0)"
|
||||||
|
id="text4712"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-297.92514"
|
||||||
|
y="1059.8398"
|
||||||
|
id="tspan4714">20</tspan></text>
|
||||||
|
<text
|
||||||
|
x="772.83997"
|
||||||
|
y="584.92517"
|
||||||
|
transform="matrix(0.92387953,0.38268343,-0.38268343,0.92387953,0,0)"
|
||||||
|
id="text4716"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="772.83997"
|
||||||
|
y="584.92517"
|
||||||
|
id="tspan4718">36</tspan></text>
|
||||||
|
<text
|
||||||
|
x="828.02203"
|
||||||
|
y="266.49393"
|
||||||
|
transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
|
||||||
|
id="text4720"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="828.02203"
|
||||||
|
y="266.49393"
|
||||||
|
id="tspan4722">40</tspan></text>
|
||||||
|
<text
|
||||||
|
x="757.14526"
|
||||||
|
y="-48.815453"
|
||||||
|
transform="matrix(0.38268343,0.92387953,-0.92387953,0.38268343,0,0)"
|
||||||
|
id="text4724"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="757.14526"
|
||||||
|
y="-48.815453"
|
||||||
|
id="tspan4726">44</tspan></text>
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
transform="translate(-27.40625,-2.9765625)"
|
||||||
|
id="layer2"
|
||||||
|
style="display:inline">
|
||||||
|
<path
|
||||||
|
d="M 600,206 C 398.41607,206 235,369.41607 235,571 235,772.58393 398.41607,936 600,936 801.58393,936 965,772.58393 965,571 965,369.41607 801.58393,206 600,206 z m 0.5,9.5 C 796.83723,215.5 956,374.66277 956,571 956,767.33723 796.83723,926.5 600.5,926.5 404.16277,926.5 245,767.33723 245,571 245,374.66277 404.16277,215.5 600.5,215.5 z"
|
||||||
|
id="path2989"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.98480775,0.17364818,-0.17364818,0.98480775,108.26846,-95.51413)"
|
||||||
|
id="use3787"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.93969262,0.34202015,-0.34202015,0.93969262,231.47793,-170.77657)"
|
||||||
|
id="use3789"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.8660254,0.50000001,-0.50000001,0.8660254,365.88476,-223.5005)"
|
||||||
|
id="use3791"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.76604444,0.64278762,-0.64278762,0.76604444,507.40506,-252.08393)"
|
||||||
|
id="use3793"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.6427876,0.76604445,-0.76604445,0.6427876,651.73881,-255.65839)"
|
||||||
|
id="use3795"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.49999999,0.86602541,-0.86602541,0.49999999,794.5005,-234.11523)"
|
||||||
|
id="use3797"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.34202013,0.93969263,-0.93969263,0.34202013,931.35239,-188.10907)"
|
||||||
|
id="use3799"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0.17364816,0.98480776,-0.98480776,0.17364816,1058.1363,-119.03775)"
|
||||||
|
id="use3801"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3803"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#g3783" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3805"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3787" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3807"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3789" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3809"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3791" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3811"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3793" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171,-28.99996)"
|
||||||
|
id="use3813"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3795" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3815"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3797" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3817"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3799" />
|
||||||
|
<use
|
||||||
|
transform="matrix(0,1,-1,0,1171.0001,-28.99996)"
|
||||||
|
id="use3819"
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="1203"
|
||||||
|
height="1106"
|
||||||
|
xlink:href="#use3801" />
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="146"
|
||||||
|
id="text3869"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="600"
|
||||||
|
y="146"
|
||||||
|
id="tspan3871">360</tspan></text>
|
||||||
|
<text
|
||||||
|
x="690.03815"
|
||||||
|
y="33.140388"
|
||||||
|
transform="matrix(0.98480775,0.17364818,-0.17364818,0.98480775,0,0)"
|
||||||
|
id="text3879"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="690.03815"
|
||||||
|
y="33.140388"
|
||||||
|
id="tspan3881">10</tspan></text>
|
||||||
|
<text
|
||||||
|
x="759.11053"
|
||||||
|
y="-93.639587"
|
||||||
|
transform="matrix(0.93969262,0.34202015,-0.34202015,0.93969262,0,0)"
|
||||||
|
id="text3883"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="759.11053"
|
||||||
|
y="-93.639587"
|
||||||
|
id="tspan3885">20</tspan></text>
|
||||||
|
<text
|
||||||
|
x="805.11841"
|
||||||
|
y="-230.48779"
|
||||||
|
transform="matrix(0.8660254,0.50000001,-0.50000001,0.8660254,0,0)"
|
||||||
|
id="text3887"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="805.11841"
|
||||||
|
y="-230.48779"
|
||||||
|
id="tspan3889">30</tspan></text>
|
||||||
|
<text
|
||||||
|
x="826.66388"
|
||||||
|
y="-373.24612"
|
||||||
|
transform="matrix(0.76604444,0.64278762,-0.64278762,0.76604444,0,0)"
|
||||||
|
id="text3891"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="826.66388"
|
||||||
|
y="-373.24612"
|
||||||
|
id="tspan3893">40</tspan></text>
|
||||||
|
<text
|
||||||
|
x="823.09235"
|
||||||
|
y="-517.57697"
|
||||||
|
transform="matrix(0.6427876,0.76604445,-0.76604445,0.6427876,0,0)"
|
||||||
|
id="text3895"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="823.09235"
|
||||||
|
y="-517.57697"
|
||||||
|
id="tspan3897">50</tspan></text>
|
||||||
|
<text
|
||||||
|
x="794.51227"
|
||||||
|
y="-659.09491"
|
||||||
|
transform="matrix(0.49999999,0.86602541,-0.86602541,0.49999999,0,0)"
|
||||||
|
id="text3899"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="794.51227"
|
||||||
|
y="-659.09491"
|
||||||
|
id="tspan3901">60</tspan></text>
|
||||||
|
<text
|
||||||
|
x="741.79205"
|
||||||
|
y="-793.5"
|
||||||
|
transform="matrix(0.34202013,0.93969262,-0.93969262,0.34202013,0,0)"
|
||||||
|
id="text3903"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="741.79205"
|
||||||
|
y="-793.5"
|
||||||
|
id="tspan3905">70</tspan></text>
|
||||||
|
<text
|
||||||
|
x="666.53357"
|
||||||
|
y="-916.70844"
|
||||||
|
transform="matrix(0.17364817,0.98480775,-0.98480775,0.17364817,0,0)"
|
||||||
|
id="text3907"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="666.53357"
|
||||||
|
y="-916.70844"
|
||||||
|
id="tspan3909">80</tspan></text>
|
||||||
|
<text
|
||||||
|
x="571.0235"
|
||||||
|
y="-1024.9766"
|
||||||
|
transform="matrix(0,1,-1,0,0,0)"
|
||||||
|
id="text3911"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="571.0235"
|
||||||
|
y="-1024.9766"
|
||||||
|
id="tspan3913">90</tspan></text>
|
||||||
|
<text
|
||||||
|
x="491.7319"
|
||||||
|
y="241.51007"
|
||||||
|
transform="matrix(0.98480775,-0.17364818,0.17364818,0.98480775,0,0)"
|
||||||
|
id="text3923"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="491.7319"
|
||||||
|
y="241.51007"
|
||||||
|
id="tspan3925">350</tspan></text>
|
||||||
|
<text
|
||||||
|
x="368.5235"
|
||||||
|
y="316.76855"
|
||||||
|
transform="matrix(0.93969262,-0.34202015,0.34202015,0.93969262,0,0)"
|
||||||
|
id="text3927"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="368.5235"
|
||||||
|
y="316.76855"
|
||||||
|
id="tspan3929">340</tspan></text>
|
||||||
|
<text
|
||||||
|
x="234.11839"
|
||||||
|
y="369.48877"
|
||||||
|
transform="matrix(0.8660254,-0.50000001,0.50000001,0.8660254,0,0)"
|
||||||
|
id="text3931"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="234.11839"
|
||||||
|
y="369.48877"
|
||||||
|
id="tspan3933">330</tspan></text>
|
||||||
|
<text
|
||||||
|
x="92.600433"
|
||||||
|
y="398.06885"
|
||||||
|
transform="matrix(0.76604444,-0.64278762,0.64278762,0.76604444,0,0)"
|
||||||
|
id="text3935"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="92.600433"
|
||||||
|
y="398.06885"
|
||||||
|
id="tspan3937">320</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-51.730431"
|
||||||
|
y="401.64041"
|
||||||
|
transform="matrix(0.6427876,-0.76604445,0.76604445,0.6427876,0,0)"
|
||||||
|
id="text3939"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-51.730431"
|
||||||
|
y="401.64041"
|
||||||
|
id="tspan3941">310</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-194.48878"
|
||||||
|
y="380.09491"
|
||||||
|
transform="matrix(0.49999999,-0.86602541,0.86602541,0.49999999,0,0)"
|
||||||
|
id="text3943"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-194.48878"
|
||||||
|
y="380.09491"
|
||||||
|
id="tspan3945">300</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-331.33698"
|
||||||
|
y="334.08701"
|
||||||
|
transform="matrix(0.34202013,-0.93969262,0.93969262,0.34202013,0,0)"
|
||||||
|
id="text3947"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-331.33698"
|
||||||
|
y="334.08701"
|
||||||
|
id="tspan3949">290</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-458.11694"
|
||||||
|
y="265.01462"
|
||||||
|
transform="matrix(0.17364817,-0.98480775,0.98480775,0.17364817,0,0)"
|
||||||
|
id="text3951"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-458.11694"
|
||||||
|
y="265.01462"
|
||||||
|
id="tspan3953">280</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-570.97656"
|
||||||
|
y="174.9765"
|
||||||
|
transform="matrix(0,-1,1,0,0,0)"
|
||||||
|
id="text3955"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-570.97656"
|
||||||
|
y="174.9765"
|
||||||
|
id="tspan3957">270</tspan></text>
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="1018.0313"
|
||||||
|
id="text3967"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="600"
|
||||||
|
y="1018.0313"
|
||||||
|
id="tspan3969">180</tspan></text>
|
||||||
|
<text
|
||||||
|
x="491.73154"
|
||||||
|
y="1113.5454"
|
||||||
|
transform="matrix(0.98480775,-0.17364818,0.17364818,0.98480775,0,0)"
|
||||||
|
id="text3992"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="491.73154"
|
||||||
|
y="1113.5454"
|
||||||
|
id="tspan3994">170</tspan></text>
|
||||||
|
<text
|
||||||
|
x="368.52206"
|
||||||
|
y="1188.8079"
|
||||||
|
transform="matrix(0.93969262,-0.34202015,0.34202015,0.93969262,0,0)"
|
||||||
|
id="text3996"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="368.52206"
|
||||||
|
y="1188.8079"
|
||||||
|
id="tspan3998">160</tspan></text>
|
||||||
|
<text
|
||||||
|
x="234.11523"
|
||||||
|
y="1241.5317"
|
||||||
|
transform="matrix(0.8660254,-0.50000001,0.50000001,0.8660254,0,0)"
|
||||||
|
id="text4000"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="234.11523"
|
||||||
|
y="1241.5317"
|
||||||
|
id="tspan4002">150</tspan></text>
|
||||||
|
<text
|
||||||
|
x="92.594925"
|
||||||
|
y="1270.1151"
|
||||||
|
transform="matrix(0.76604444,-0.64278762,0.64278762,0.76604444,0,0)"
|
||||||
|
id="text4004"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="92.594925"
|
||||||
|
y="1270.1151"
|
||||||
|
id="tspan4006">140</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-51.738831"
|
||||||
|
y="1273.6896"
|
||||||
|
transform="matrix(0.6427876,-0.76604445,0.76604445,0.6427876,0,0)"
|
||||||
|
id="text4008"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-51.738831"
|
||||||
|
y="1273.6896"
|
||||||
|
id="tspan4010">130</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-194.50053"
|
||||||
|
y="1252.1464"
|
||||||
|
transform="matrix(0.49999999,-0.86602541,0.86602541,0.49999999,0,0)"
|
||||||
|
id="text4012"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-194.50053"
|
||||||
|
y="1252.1464"
|
||||||
|
id="tspan4014">120</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-331.35242"
|
||||||
|
y="1206.1401"
|
||||||
|
transform="matrix(0.34202013,-0.93969262,0.93969262,0.34202013,0,0)"
|
||||||
|
id="text4016"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-331.35242"
|
||||||
|
y="1206.1401"
|
||||||
|
id="tspan4018">110</tspan></text>
|
||||||
|
<text
|
||||||
|
x="-458.13632"
|
||||||
|
y="1137.0688"
|
||||||
|
transform="matrix(0.17364817,-0.98480775,0.98480775,0.17364817,0,0)"
|
||||||
|
id="text4020"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="-458.13632"
|
||||||
|
y="1137.0688"
|
||||||
|
id="tspan4022">100</tspan></text>
|
||||||
|
<text
|
||||||
|
x="690.03778"
|
||||||
|
y="905.1676"
|
||||||
|
transform="matrix(0.98480775,0.17364818,-0.17364818,0.98480775,0,0)"
|
||||||
|
id="text4024"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="690.03778"
|
||||||
|
y="905.1676"
|
||||||
|
id="tspan4026">190</tspan></text>
|
||||||
|
<text
|
||||||
|
x="759.10907"
|
||||||
|
y="778.38367"
|
||||||
|
transform="matrix(0.93969262,0.34202015,-0.34202015,0.93969262,0,0)"
|
||||||
|
id="text4028"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="759.10907"
|
||||||
|
y="778.38367"
|
||||||
|
id="tspan4030">200</tspan></text>
|
||||||
|
<text
|
||||||
|
x="805.11523"
|
||||||
|
y="641.5318"
|
||||||
|
transform="matrix(0.8660254,0.50000001,-0.50000001,0.8660254,0,0)"
|
||||||
|
id="text4032"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="805.11523"
|
||||||
|
y="641.5318"
|
||||||
|
id="tspan4034">210</tspan></text>
|
||||||
|
<text
|
||||||
|
x="826.65839"
|
||||||
|
y="498.77014"
|
||||||
|
transform="matrix(0.76604444,0.64278762,-0.64278762,0.76604444,0,0)"
|
||||||
|
id="text4036"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="826.65839"
|
||||||
|
y="498.77014"
|
||||||
|
id="tspan4038">220</tspan></text>
|
||||||
|
<text
|
||||||
|
x="823.08392"
|
||||||
|
y="354.43634"
|
||||||
|
transform="matrix(0.6427876,0.76604445,-0.76604445,0.6427876,0,0)"
|
||||||
|
id="text4040"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="823.08392"
|
||||||
|
y="354.43634"
|
||||||
|
id="tspan4042">230</tspan></text>
|
||||||
|
<text
|
||||||
|
x="794.50049"
|
||||||
|
y="212.91605"
|
||||||
|
transform="matrix(0.49999999,0.86602541,-0.86602541,0.49999999,0,0)"
|
||||||
|
id="text4044"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="794.50049"
|
||||||
|
y="212.91605"
|
||||||
|
id="tspan4046">240</tspan></text>
|
||||||
|
<text
|
||||||
|
x="741.77655"
|
||||||
|
y="78.509193"
|
||||||
|
transform="matrix(0.34202013,0.93969262,-0.93969262,0.34202013,0,0)"
|
||||||
|
id="text4048"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="741.77655"
|
||||||
|
y="78.509193"
|
||||||
|
id="tspan4050">250</tspan></text>
|
||||||
|
<text
|
||||||
|
x="666.5141"
|
||||||
|
y="-44.700287"
|
||||||
|
transform="matrix(0.17364817,0.98480775,-0.98480775,0.17364817,0,0)"
|
||||||
|
id="text4052"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans"><tspan
|
||||||
|
x="666.5141"
|
||||||
|
y="-44.700287"
|
||||||
|
id="tspan4054">260</tspan></text>
|
||||||
|
<g
|
||||||
|
id="g3783">
|
||||||
|
<path
|
||||||
|
d="m 600,935 0,46"
|
||||||
|
id="path4496"
|
||||||
|
style="fill:none;stroke:#604b1d;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 600,161 0,46"
|
||||||
|
id="path2986"
|
||||||
|
style="fill:none;stroke:#604b1d;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 587.26168,935.77765 -0.83758,23.98538"
|
||||||
|
id="path4572"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 613.5759,182.23697 -0.83758,23.98538"
|
||||||
|
id="path4570"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 574.54434,935.03293 -1.6796,24.01948"
|
||||||
|
id="path4568"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 627.13526,182.94759 -1.6796,24.01947"
|
||||||
|
id="path4564"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 561.85651,933.91114 -2.51807,23.95787"
|
||||||
|
id="path4562"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 640.66156,184.13099 -2.51807,23.95787"
|
||||||
|
id="path4558"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 549.19823,932.47346 -3.33655,23.74081"
|
||||||
|
id="path4556"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
d="m 654.13832,185.78573 -3.33655,23.74081"
|
||||||
|
id="path3012"
|
||||||
|
style="fill:none;stroke:#df1000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="46"
|
||||||
|
id="text4732"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Liberation Sans Bold"><tspan
|
||||||
|
x="600"
|
||||||
|
y="46"
|
||||||
|
id="tspan4734">N</tspan></text>
|
||||||
|
<text
|
||||||
|
x="60"
|
||||||
|
y="586"
|
||||||
|
id="text4752"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Liberation Sans;-inkscape-font-specification:Sans Bold"><tspan
|
||||||
|
x="60"
|
||||||
|
y="586"
|
||||||
|
id="tspan4754">W</tspan></text>
|
||||||
|
<text
|
||||||
|
x="1140"
|
||||||
|
y="586"
|
||||||
|
id="text4777"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Liberation Sans;-inkscape-font-specification:Sans Bold"><tspan
|
||||||
|
x="1140"
|
||||||
|
y="586"
|
||||||
|
id="tspan4779">O</tspan></text>
|
||||||
|
<text
|
||||||
|
x="600"
|
||||||
|
y="1128.8284"
|
||||||
|
id="text4802"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:48px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Liberation Sans;-inkscape-font-specification:Sans Bold"><tspan
|
||||||
|
x="600"
|
||||||
|
y="1128.8284"
|
||||||
|
id="tspan4804">S</tspan></text>
|
||||||
|
<text
|
||||||
|
x="130"
|
||||||
|
y="396"
|
||||||
|
id="text4875"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="130"
|
||||||
|
y="396"
|
||||||
|
id="tspan4877">WNW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="414.5"
|
||||||
|
y="136"
|
||||||
|
id="text4879"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="414.5"
|
||||||
|
y="136"
|
||||||
|
id="tspan4881">NNW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="400"
|
||||||
|
y="1036"
|
||||||
|
id="text4899"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="400"
|
||||||
|
y="1036"
|
||||||
|
id="tspan4901">SSW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="119.99963"
|
||||||
|
y="766"
|
||||||
|
id="text4903"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="119.99963"
|
||||||
|
y="766"
|
||||||
|
id="tspan4905">WSW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="250"
|
||||||
|
y="236"
|
||||||
|
id="text4907"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="250"
|
||||||
|
y="236"
|
||||||
|
id="tspan4909">NW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="230"
|
||||||
|
y="926"
|
||||||
|
id="text4919"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="230"
|
||||||
|
y="926"
|
||||||
|
id="tspan4921">SW</tspan></text>
|
||||||
|
<text
|
||||||
|
x="790"
|
||||||
|
y="136"
|
||||||
|
id="text3194"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="790"
|
||||||
|
y="136"
|
||||||
|
id="tspan3196">NNO</tspan></text>
|
||||||
|
<text
|
||||||
|
x="970"
|
||||||
|
y="236"
|
||||||
|
id="text3198"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="970"
|
||||||
|
y="236"
|
||||||
|
id="tspan3200">NO</tspan></text>
|
||||||
|
<text
|
||||||
|
x="1070"
|
||||||
|
y="396"
|
||||||
|
id="text3202"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="1070"
|
||||||
|
y="396"
|
||||||
|
id="tspan3204">ONO</tspan></text>
|
||||||
|
<text
|
||||||
|
x="790"
|
||||||
|
y="1036"
|
||||||
|
id="text3206"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="790"
|
||||||
|
y="1036"
|
||||||
|
id="tspan3208">SSO</tspan></text>
|
||||||
|
<text
|
||||||
|
x="970"
|
||||||
|
y="926"
|
||||||
|
id="text3210"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="970"
|
||||||
|
y="926"
|
||||||
|
id="tspan3212">SO</tspan></text>
|
||||||
|
<text
|
||||||
|
x="1070"
|
||||||
|
y="766"
|
||||||
|
id="text3214"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:120.00000477%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Liberation Sans;-inkscape-font-specification:Sans"><tspan
|
||||||
|
x="1070"
|
||||||
|
y="766"
|
||||||
|
id="tspan3216">OSO</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 49 KiB |
71
assets/needle.svg
Normal file
71
assets/needle.svg
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="-200 -200 1040 1040">
|
||||||
|
|
||||||
|
<path id="right_top"
|
||||||
|
fill="#d64355" stroke="#797979" stroke-width="1"
|
||||||
|
d="M 320.00,74.00
|
||||||
|
C 320.00,74.00 326.88,103.00 326.88,103.00
|
||||||
|
326.88,103.00 341.42,169.00 341.42,169.00
|
||||||
|
341.42,169.00 356.58,237.00 356.58,237.00
|
||||||
|
356.58,237.00 361.88,262.00 361.88,262.00
|
||||||
|
361.88,262.00 368.88,294.00 368.88,294.00
|
||||||
|
368.88,294.00 374.00,320.00 374.00,320.00
|
||||||
|
374.00,320.00 360.00,320.00 360.00,320.00
|
||||||
|
359.95,301.68 347.16,285.39 329.00,281.52
|
||||||
|
326.04,280.88 323.01,281.00 320.00,281.00
|
||||||
|
320.00,281.00 320.00,74.00 320.00,74.00 Z" />
|
||||||
|
<path id="let_top"
|
||||||
|
fill="#eb4b57" stroke="#797979" stroke-width="1"
|
||||||
|
d="M 320.00,74.00
|
||||||
|
C 320.00,74.00 313.12,103.00 313.12,103.00
|
||||||
|
313.12,103.00 298.58,169.00 298.58,169.00
|
||||||
|
298.58,169.00 283.42,237.00 283.42,237.00
|
||||||
|
283.42,237.00 278.12,262.00 278.12,262.00
|
||||||
|
278.12,262.00 271.12,294.00 271.12,294.00
|
||||||
|
271.12,294.00 266.00,320.00 266.00,320.00
|
||||||
|
266.00,320.00 280.00,320.00 280.00,320.00
|
||||||
|
280.05,301.68 292.84,285.39 311.00,281.52
|
||||||
|
313.96,280.88 316.99,281.00 320.00,281.00
|
||||||
|
320.00,281.00 320.00,74.00 320.00,74.00 Z" />
|
||||||
|
<path id="bottom_left"
|
||||||
|
fill="#b3b3b3" stroke="#797979" stroke-width="1"
|
||||||
|
d="M 320.00,566.00
|
||||||
|
C 320.00,566.00 313.12,537.00 313.12,537.00
|
||||||
|
313.12,537.00 298.58,471.00 298.58,471.00
|
||||||
|
298.58,471.00 283.42,403.00 283.42,403.00
|
||||||
|
283.42,403.00 278.12,378.00 278.12,378.00
|
||||||
|
278.12,378.00 271.12,346.00 271.12,346.00
|
||||||
|
271.12,346.00 266.00,320.00 266.00,320.00
|
||||||
|
266.00,320.00 280.00,320.00 280.00,320.00
|
||||||
|
280.05,338.32 292.84,354.61 311.00,358.48
|
||||||
|
313.96,359.12 316.99,359.00 320.00,359.00
|
||||||
|
320.00,359.00 320.00,566.00 320.00,566.00 Z" />
|
||||||
|
<path id="bottom_right"
|
||||||
|
fill="#999999" stroke="#797979" stroke-width="1"
|
||||||
|
d="M 320.00,566.00
|
||||||
|
C 320.00,566.00 326.88,537.00 326.88,537.00
|
||||||
|
326.88,537.00 341.42,471.00 341.42,471.00
|
||||||
|
341.42,471.00 356.58,403.00 356.58,403.00
|
||||||
|
356.58,403.00 361.88,378.00 361.88,378.00
|
||||||
|
361.88,378.00 368.88,346.00 368.88,346.00
|
||||||
|
368.88,346.00 374.00,320.00 374.00,320.00
|
||||||
|
374.00,320.00 360.00,320.00 360.00,320.00
|
||||||
|
359.95,338.32 347.16,354.61 329.00,358.48
|
||||||
|
326.04,359.12 323.01,359.00 320.00,359.00
|
||||||
|
320.00,359.00 320.00,566.00 320.00,566.00 Z" />
|
||||||
|
<path id="point"
|
||||||
|
fill="#555" stroke="black" stroke-width="1"
|
||||||
|
d="M 316.00,300.47
|
||||||
|
C 323.06,299.50 329.60,300.78 334.67,306.18
|
||||||
|
344.20,316.34 340.82,336.33 324.00,339.53
|
||||||
|
302.82,343.57 292.55,318.12 306.18,305.33
|
||||||
|
309.31,302.39 311.96,301.45 316.00,300.47 Z" />
|
||||||
|
<path id="dott"
|
||||||
|
fill="black" stroke="black" stroke-width="1"
|
||||||
|
d="M 318.31,317.08
|
||||||
|
C 324.37,315.74 324.33,321.40 321.69,322.92
|
||||||
|
319.05,324.44 314.12,321.65 318.31,317.08 Z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
133
lib/boxes/compass.dart
Normal file
133
lib/boxes/compass.dart
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:ju_rc_app/lib/boxes.dart';
|
||||||
|
import 'package:ju_rc_app/lib/sensors.dart';
|
||||||
|
import 'package:ju_rc_app/lib/serial.dart';
|
||||||
|
|
||||||
|
// c-structs
|
||||||
|
base class GnssLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Int32()
|
||||||
|
external int X;
|
||||||
|
@Int32()
|
||||||
|
external int Y;
|
||||||
|
@Int32()
|
||||||
|
external int Z;
|
||||||
|
@Int32()
|
||||||
|
external int angle;
|
||||||
|
}
|
||||||
|
// end c-structs
|
||||||
|
|
||||||
|
class Compass extends JuBox {
|
||||||
|
const Compass({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _CompassState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CompassState extends State<Compass> {
|
||||||
|
USerial serial = getSerial();
|
||||||
|
late Timer timer;
|
||||||
|
|
||||||
|
int _magX = 0, _magY = 0, _magZ = 0, _magAngle = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
SensorReader.listen(serialListen);
|
||||||
|
timer = Timer.periodic(const Duration(milliseconds: 500), (_) async {
|
||||||
|
serial.sprintln("<rfSystemSensor>2200", system: true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
SensorReader.removeListen(serialListen);
|
||||||
|
timer.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialListen(int type, int command, Pointer<ArrayCStruct> ptr) {
|
||||||
|
if (type != 0x22 || command != 0x00) return;
|
||||||
|
var loc = ptr as Pointer<GnssLocData>;
|
||||||
|
setState(() {
|
||||||
|
_magX = loc.ref.X;
|
||||||
|
_magY = loc.ref.Y;
|
||||||
|
_magZ = loc.ref.Z;
|
||||||
|
int newAngle = loc.ref.angle;
|
||||||
|
if (newAngle - _magAngle > 200) newAngle -= 360;
|
||||||
|
if (newAngle - _magAngle < -200) newAngle += 360;
|
||||||
|
_magAngle = newAngle;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => Stack(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset('assets/compass.svg'),
|
||||||
|
AnimatedRotation(
|
||||||
|
turns: _magAngle / 360.0,
|
||||||
|
duration: const Duration(milliseconds: 500),
|
||||||
|
alignment: Alignment.center, // Rotate around the center
|
||||||
|
child: SvgPicture.asset('assets/needle.svg')),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"x: ${(_magX * 8.0 / 32768.0 * 100.0).toStringAsFixed(2)}µT"),
|
||||||
|
Text(
|
||||||
|
"y: ${(_magY * 8.0 / 32768.0 * 100.0).toStringAsFixed(2)}µT"),
|
||||||
|
Text(
|
||||||
|
"z: ${(_magZ * 8.0 / 32768.0 * 100.0).toStringAsFixed(2)}µT"),
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.bottomLeft,
|
||||||
|
child: FilledButton(
|
||||||
|
child: const Icon(Icons.calculate),
|
||||||
|
onPressed: () {
|
||||||
|
showDialog<String>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => AlertDialog(
|
||||||
|
title: const Text('Callibrate Compass'),
|
||||||
|
content: const Text(
|
||||||
|
'When clicking okay the compass will be calibrated, \ncompletely blocking all radio communication for 10 sec. \nWhile calibrating rotate the sensor in ever direction.'),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, 'Cancel'),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
serial.sprintln("<rfSystemSensor>2201",
|
||||||
|
system: true);
|
||||||
|
Navigator.pop(context, 'OK');
|
||||||
|
},
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
//
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
child: Text(
|
||||||
|
"t: ${(sqrt(_magX * _magX + _magY * _magY + _magZ * _magZ) * 8.0 / 32768.0 * 100.0).toStringAsFixed(2)}µT"),
|
||||||
|
))
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
475
lib/boxes/maps.dart
Normal file
475
lib/boxes/maps.dart
Normal file
|
@ -0,0 +1,475 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
|
import 'package:latlong2/latlong.dart';
|
||||||
|
|
||||||
|
import 'package:ju_rc_app/lib/boxes.dart';
|
||||||
|
import 'package:ju_rc_app/lib/sensors.dart';
|
||||||
|
import 'package:ju_rc_app/lib/serial.dart';
|
||||||
|
|
||||||
|
// c-structs
|
||||||
|
base class GnssLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Double()
|
||||||
|
external double lat;
|
||||||
|
@Double()
|
||||||
|
external double lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
base class SpeedLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Double()
|
||||||
|
external double speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
base class CourseLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Double()
|
||||||
|
external double course;
|
||||||
|
}
|
||||||
|
|
||||||
|
base class AltLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Double()
|
||||||
|
external double alt;
|
||||||
|
}
|
||||||
|
|
||||||
|
base class SatLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Uint32()
|
||||||
|
external int n;
|
||||||
|
}
|
||||||
|
|
||||||
|
base class HdopLocData extends Struct {
|
||||||
|
@Uint8()
|
||||||
|
external int type;
|
||||||
|
@Uint8()
|
||||||
|
external int command;
|
||||||
|
|
||||||
|
@Uint8()
|
||||||
|
external int isValid;
|
||||||
|
|
||||||
|
@Double()
|
||||||
|
external double hdop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// c-structs end
|
||||||
|
|
||||||
|
class Maps extends JuBox {
|
||||||
|
const Maps({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _MapsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MapsState extends State<Maps> with TickerProviderStateMixin {
|
||||||
|
USerial serial = getSerial();
|
||||||
|
late Timer timer;
|
||||||
|
|
||||||
|
double _lat = 51.1667, _long = 10.4500;
|
||||||
|
int _state = 0;
|
||||||
|
bool _wasVaild = false;
|
||||||
|
final _mapController = MapController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
SensorReader.listen(serialListen);
|
||||||
|
timer = Timer.periodic(const Duration(seconds: 1), (_) async {
|
||||||
|
serial.sprintln("<rfSystemSensor>2300", system: true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
SensorReader.removeListen(serialListen);
|
||||||
|
timer.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialListen(int type, int command, Pointer<ArrayCStruct> ptr) {
|
||||||
|
if (type != 0x23 || command != 0x00) return;
|
||||||
|
var loc = ptr as Pointer<GnssLocData>;
|
||||||
|
setState(() {
|
||||||
|
_lat = loc.ref.lat;
|
||||||
|
_long = loc.ref.lng;
|
||||||
|
_state = loc.ref.isValid;
|
||||||
|
//_mapController.move(LatLng(_lat, _long), _wasVaild ? 17 : 6);
|
||||||
|
_animatedMapMove(
|
||||||
|
_mapController, this, LatLng(_lat, _long), _wasVaild ? 17 : 6);
|
||||||
|
if (_state & 1 > 0) _wasVaild = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => FlutterMap(
|
||||||
|
options: MapOptions(
|
||||||
|
center: LatLng(_lat, _long),
|
||||||
|
zoom: _wasVaild ? 17 : 6,
|
||||||
|
maxZoom: _wasVaild ? 17 : 6,
|
||||||
|
minZoom: _wasVaild ? 17 : 6,
|
||||||
|
interactiveFlags: InteractiveFlag.none,
|
||||||
|
onTap: (TapPosition pos, LatLng ll) {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const SerialDetailPage()),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
mapController: _mapController,
|
||||||
|
children: [
|
||||||
|
TileLayer(
|
||||||
|
urlTemplate: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
|
||||||
|
userAgentPackageName: 'de.jusax.ju_rc_app',
|
||||||
|
),
|
||||||
|
MarkerLayer(
|
||||||
|
markers: [
|
||||||
|
Marker(
|
||||||
|
point: LatLng(_lat, _long),
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
builder: (context) => Icon(
|
||||||
|
switch (_state) {
|
||||||
|
3 => Icons.location_on,
|
||||||
|
2 => Icons.location_off,
|
||||||
|
1 => Icons.location_on_outlined,
|
||||||
|
int() => Icons.location_off_outlined,
|
||||||
|
},
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class SerialDetailPage extends StatefulWidget {
|
||||||
|
const SerialDetailPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _SerialDetailPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SerialDetailPageState extends State<SerialDetailPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
USerial serial = getSerial();
|
||||||
|
late Timer timer;
|
||||||
|
final _mapController = MapController();
|
||||||
|
|
||||||
|
double _lat = 51.1667, _long = 10.4500;
|
||||||
|
int _state = 0;
|
||||||
|
|
||||||
|
double _mps = -1, _course = -1, _alt = -1, _hdop = -1;
|
||||||
|
bool _mpsState = false,
|
||||||
|
_courseState = false,
|
||||||
|
_altState = false,
|
||||||
|
_satNState = false,
|
||||||
|
_hdopState = false;
|
||||||
|
int _satN = -1;
|
||||||
|
bool _follow = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
timer = Timer.periodic(const Duration(seconds: 2), (_) async {
|
||||||
|
serial.sprintln("<rfSystemSensor>2303", system: true);
|
||||||
|
sleep(const Duration(milliseconds: 200));
|
||||||
|
serial.sprintln("<rfSystemSensor>2304", system: true);
|
||||||
|
sleep(const Duration(milliseconds: 200));
|
||||||
|
serial.sprintln("<rfSystemSensor>2305", system: true);
|
||||||
|
sleep(const Duration(milliseconds: 200));
|
||||||
|
serial.sprintln("<rfSystemSensor>2306", system: true);
|
||||||
|
sleep(const Duration(milliseconds: 200));
|
||||||
|
serial.sprintln("<rfSystemSensor>2307", system: true);
|
||||||
|
});
|
||||||
|
SensorReader.listen(serialListen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
SensorReader.removeListen(serialListen);
|
||||||
|
timer.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialListen(int type, int command, Pointer<ArrayCStruct> ptr) {
|
||||||
|
if (type != 0x23) return;
|
||||||
|
switch (command) {
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<GnssLocData>;
|
||||||
|
setState(() {
|
||||||
|
_lat = loc.ref.lat;
|
||||||
|
_long = loc.ref.lng;
|
||||||
|
_state = loc.ref.isValid;
|
||||||
|
if (_follow) {
|
||||||
|
_animatedMapMove(_mapController, this, LatLng(_lat, _long),
|
||||||
|
_mapController.zoom,
|
||||||
|
currentZoom: true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<SpeedLocData>;
|
||||||
|
setState(() {
|
||||||
|
_mps = loc.ref.speed;
|
||||||
|
_mpsState = loc.ref.isValid == 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<CourseLocData>;
|
||||||
|
setState(() {
|
||||||
|
_course = loc.ref.course;
|
||||||
|
_courseState = loc.ref.isValid == 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<AltLocData>;
|
||||||
|
setState(() {
|
||||||
|
_alt = loc.ref.alt;
|
||||||
|
_altState = loc.ref.isValid == 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<SatLocData>;
|
||||||
|
setState(() {
|
||||||
|
_satN = loc.ref.n;
|
||||||
|
_satNState = loc.ref.isValid == 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
{
|
||||||
|
var loc = ptr as Pointer<HdopLocData>;
|
||||||
|
setState(() {
|
||||||
|
_hdop = loc.ref.hdop;
|
||||||
|
_hdopState = loc.ref.isValid == 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xff:
|
||||||
|
{}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int shade() {
|
||||||
|
return MediaQuery.of(context).platformBrightness == Brightness.light
|
||||||
|
? 100
|
||||||
|
: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||||
|
title: const Text(
|
||||||
|
"Maps",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
toolbarHeight: 40,
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
if (!_follow) _mapController.move(LatLng(_lat, _long), 17);
|
||||||
|
_follow = !_follow;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Icon(_follow ? Icons.near_me : Icons.near_me_outlined),
|
||||||
|
),
|
||||||
|
body: Column(children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Speed: ${_mps.toStringAsPrecision(3)}m/s",
|
||||||
|
style: TextStyle(
|
||||||
|
backgroundColor:
|
||||||
|
_mpsState ? Colors.green[shade()] : Colors.red[shade()]),
|
||||||
|
),
|
||||||
|
const VerticalDivider(width: 5),
|
||||||
|
Text("Course: ${_course.toStringAsFixed(0)}°",
|
||||||
|
style: TextStyle(
|
||||||
|
backgroundColor: _courseState
|
||||||
|
? Colors.green[shade()]
|
||||||
|
: Colors.red[shade()])),
|
||||||
|
const VerticalDivider(width: 5),
|
||||||
|
Text("Alt: ${_alt.toStringAsPrecision(4)}m",
|
||||||
|
style: TextStyle(
|
||||||
|
backgroundColor: _altState
|
||||||
|
? Colors.green[shade()]
|
||||||
|
: Colors.red[shade()])),
|
||||||
|
const VerticalDivider(width: 5),
|
||||||
|
Text("Sats: $_satN",
|
||||||
|
style: TextStyle(
|
||||||
|
backgroundColor: _satNState
|
||||||
|
? Colors.green[shade()]
|
||||||
|
: Colors.red[shade()])),
|
||||||
|
const VerticalDivider(width: 5),
|
||||||
|
Text("Hdop: ${_hdop.toStringAsPrecision(2)}",
|
||||||
|
style: TextStyle(
|
||||||
|
backgroundColor: _hdopState
|
||||||
|
? Colors.green[shade()]
|
||||||
|
: Colors.red[shade()])),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: FlutterMap(
|
||||||
|
mapController: _mapController,
|
||||||
|
options: MapOptions(
|
||||||
|
center: const LatLng(51.1667, 10.4500),
|
||||||
|
zoom: 6,
|
||||||
|
maxZoom: 18,
|
||||||
|
interactiveFlags: InteractiveFlag.drag |
|
||||||
|
InteractiveFlag.flingAnimation |
|
||||||
|
InteractiveFlag.pinchMove |
|
||||||
|
InteractiveFlag.pinchZoom |
|
||||||
|
InteractiveFlag.doubleTapZoom,
|
||||||
|
onPositionChanged: (MapPosition pos, bool user) {
|
||||||
|
if (user) {
|
||||||
|
setState(() {
|
||||||
|
_follow = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
children: [
|
||||||
|
TileLayer(
|
||||||
|
urlTemplate: 'https://tile.openstreetmap.de/{z}/{x}/{y}.png',
|
||||||
|
//urlTemplate: 'https://sgx.geodatenzentrum.de/wmts_basemapde/tile/1.0.0/de_basemapde_web_raster_farbe/default/GLOBAL_WEBMERCATOR/{z}/{y}/{x}.png',
|
||||||
|
userAgentPackageName: 'de.jusax.ju_rc_app',
|
||||||
|
),
|
||||||
|
MarkerLayer(
|
||||||
|
markers: [
|
||||||
|
Marker(
|
||||||
|
point: LatLng(_lat, _long),
|
||||||
|
width: 100,
|
||||||
|
height: 100,
|
||||||
|
builder: (context) => Transform.rotate(
|
||||||
|
angle: _course *
|
||||||
|
(pi / 180), // Convert degrees to radians
|
||||||
|
child: Icon(
|
||||||
|
switch (_state) {
|
||||||
|
3 => Icons.navigation,
|
||||||
|
2 => Icons.location_off,
|
||||||
|
1 => Icons.navigation_outlined,
|
||||||
|
int() => Icons.location_off_outlined,
|
||||||
|
},
|
||||||
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// animated Map from Map lib provider
|
||||||
|
|
||||||
|
void _animatedMapMove(MapController mapController, TickerProvider ticker,
|
||||||
|
LatLng destLocation, double destZoom,
|
||||||
|
{bool currentZoom = false}) {
|
||||||
|
const startedId = 'AnimatedMapController#MoveStarted';
|
||||||
|
const inProgressId = 'AnimatedMapController#MoveInProgress';
|
||||||
|
const finishedId = 'AnimatedMapController#MoveFinished';
|
||||||
|
// Create some tweens. These serve to split up the transition from one location to another.
|
||||||
|
// In our case, we want to split the transition be<tween> our current map center and the destination.
|
||||||
|
final camera = mapController;
|
||||||
|
final latTween =
|
||||||
|
Tween<double>(begin: camera.center.latitude, end: destLocation.latitude);
|
||||||
|
final lngTween = Tween<double>(
|
||||||
|
begin: camera.center.longitude, end: destLocation.longitude);
|
||||||
|
final zoomTween = Tween<double>(begin: camera.zoom, end: destZoom);
|
||||||
|
|
||||||
|
// Create a animation controller that has a duration and a TickerProvider.
|
||||||
|
final controller = AnimationController(
|
||||||
|
duration: const Duration(milliseconds: 500), vsync: ticker);
|
||||||
|
// The animation determines what path the animation will take. You can try different Curves values, although I found
|
||||||
|
// fastOutSlowIn to be my favorite.
|
||||||
|
final Animation<double> animation =
|
||||||
|
CurvedAnimation(parent: controller, curve: Curves.fastOutSlowIn);
|
||||||
|
|
||||||
|
// Note this method of encoding the target destination is a workaround.
|
||||||
|
// When proper animated movement is supported (see #1263) we should be able
|
||||||
|
// to detect an appropriate animated movement event which contains the
|
||||||
|
// target zoom/center.
|
||||||
|
final startIdWithTarget =
|
||||||
|
'$startedId#${destLocation.latitude},${destLocation.longitude},$destZoom';
|
||||||
|
bool hasTriggeredMove = false;
|
||||||
|
|
||||||
|
controller.addListener(() {
|
||||||
|
final String id;
|
||||||
|
if (animation.value == 1.0) {
|
||||||
|
id = finishedId;
|
||||||
|
} else if (!hasTriggeredMove) {
|
||||||
|
id = startIdWithTarget;
|
||||||
|
} else {
|
||||||
|
id = inProgressId;
|
||||||
|
}
|
||||||
|
hasTriggeredMove |= mapController.move(
|
||||||
|
LatLng(latTween.evaluate(animation), lngTween.evaluate(animation)),
|
||||||
|
currentZoom ? mapController.zoom : zoomTween.evaluate(animation),
|
||||||
|
id: id,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
animation.addStatusListener((status) {
|
||||||
|
if (status == AnimationStatus.completed) {
|
||||||
|
controller.dispose();
|
||||||
|
} else if (status == AnimationStatus.dismissed) {
|
||||||
|
controller.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
controller.forward();
|
||||||
|
}
|
51
lib/lib/sensors.dart
Normal file
51
lib/lib/sensors.dart
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import 'package:ju_rc_app/lib/boxes.dart';
|
||||||
|
import 'package:ju_rc_app/lib/serial.dart';
|
||||||
|
import 'package:convert/convert.dart';
|
||||||
|
import 'dart:ffi';
|
||||||
|
import 'package:ffi/ffi.dart';
|
||||||
|
|
||||||
|
base class ArrayCStruct extends Struct {
|
||||||
|
@Array<Uint8>(32)
|
||||||
|
external Array<Uint8> buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SensorReader {
|
||||||
|
static USerial serial = getSerial();
|
||||||
|
|
||||||
|
static final List<Function(int, int, Pointer<ArrayCStruct>)> _callback = [];
|
||||||
|
|
||||||
|
static void _serialListen(String line, SerialCommand? cmdo) {
|
||||||
|
if (cmdo == null) return;
|
||||||
|
var cmd = cmdo;
|
||||||
|
if (cmd.command != "rfSystemSensor") return;
|
||||||
|
if (cmd.arg == "lost") print("lost");
|
||||||
|
if (["noconn", "lost", "send"].contains(cmd.arg)) return;
|
||||||
|
final bytes = hex.decode(cmd.arg);
|
||||||
|
final Pointer<ArrayCStruct> buffer = calloc<ArrayCStruct>();
|
||||||
|
for (int i = 0; i < bytes.length && i < 32; i++) {
|
||||||
|
buffer.ref.buffer[i] = bytes[i];
|
||||||
|
}
|
||||||
|
for (var fnk in _callback) {
|
||||||
|
fnk(buffer.ref.buffer[0], buffer.ref.buffer[1], buffer);
|
||||||
|
}
|
||||||
|
calloc.free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _active = false;
|
||||||
|
|
||||||
|
static void listen(Function(int, int, Pointer<ArrayCStruct>) callback) {
|
||||||
|
_callback.add(callback);
|
||||||
|
if (!_active) {
|
||||||
|
_active = true;
|
||||||
|
serial.listen(_serialListen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeListen(Function(int, int, Pointer<ArrayCStruct>) callback) {
|
||||||
|
_callback.remove(callback);
|
||||||
|
if (_callback.isEmpty) {
|
||||||
|
_active = false;
|
||||||
|
serial.removeListen(_serialListen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ abstract class USerial {
|
||||||
}
|
}
|
||||||
|
|
||||||
LimitedList<(SerialMessageType, DateTime, String)> lines =
|
LimitedList<(SerialMessageType, DateTime, String)> lines =
|
||||||
LimitedList(524288);
|
LimitedList(1024);
|
||||||
final List<Function(String, SerialCommand?)> _callback = [];
|
final List<Function(String, SerialCommand?)> _callback = [];
|
||||||
void _receive(String line) {
|
void _receive(String line) {
|
||||||
lines.add((SerialMessageType.received, DateTime.now(), line));
|
lines.add((SerialMessageType.received, DateTime.now(), line));
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:ju_rc_app/boxes/compass.dart';
|
||||||
import 'package:ju_rc_app/boxes/console.dart';
|
import 'package:ju_rc_app/boxes/console.dart';
|
||||||
|
import 'package:ju_rc_app/boxes/maps.dart';
|
||||||
import 'package:ju_rc_app/boxes/state.dart';
|
import 'package:ju_rc_app/boxes/state.dart';
|
||||||
import 'package:ju_rc_app/connector.dart';
|
import 'package:ju_rc_app/connector.dart';
|
||||||
import 'package:ju_rc_app/lib/boxes.dart';
|
import 'package:ju_rc_app/lib/boxes.dart';
|
||||||
|
@ -45,7 +47,12 @@ class MyHomePage extends StatefulWidget {
|
||||||
class _MyHomePageState extends State<MyHomePage> {
|
class _MyHomePageState extends State<MyHomePage> {
|
||||||
ConnectionBar conBar = ConnectionBar();
|
ConnectionBar conBar = ConnectionBar();
|
||||||
|
|
||||||
static List<JuBox> boxes = [const SerialBox(), const ControllerState()];
|
static List<JuBox> boxes = [
|
||||||
|
const ControllerState(),
|
||||||
|
const Maps(),
|
||||||
|
const Compass(),
|
||||||
|
const SerialBox(),
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
114
pubspec.lock
114
pubspec.lock
|
@ -74,7 +74,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.18.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
|
||||||
|
@ -114,7 +114,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.1"
|
version: "1.3.1"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
|
||||||
|
@ -150,6 +150,22 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.3"
|
version: "2.0.3"
|
||||||
|
flutter_map:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_map
|
||||||
|
sha256: "5286f72f87deb132daa1489442d6cc46e986fc105cb727d9ae1b602b35b1d1f3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.0"
|
||||||
|
flutter_svg:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_svg
|
||||||
|
sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.7"
|
||||||
flutter_test:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -216,6 +232,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.8.1"
|
version: "4.8.1"
|
||||||
|
latlong2:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: latlong2
|
||||||
|
sha256: "18712164760cee655bc790122b0fd8f3d5b3c36da2cb7bf94b68a197fbb0811b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.0"
|
||||||
libserialport:
|
libserialport:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -232,6 +256,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "2.1.1"
|
||||||
|
lists:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: lists
|
||||||
|
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -256,6 +288,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.9.1"
|
||||||
|
mgrs_dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mgrs_dart
|
||||||
|
sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -264,6 +304,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.3"
|
version: "1.8.3"
|
||||||
|
path_parsing:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_parsing
|
||||||
|
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -296,14 +344,30 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.7.3"
|
version: "3.7.3"
|
||||||
|
polylabel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: polylabel
|
||||||
|
sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
proj4dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: proj4dart
|
||||||
|
sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
rive:
|
rive:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: rive
|
name: rive
|
||||||
sha256: "5fbb92f9f880cddbb9181342dc24099eee323ca43339e2c8e1ae6fad85df915e"
|
sha256: f2117a96a189758bc79bf7933865625c7a44a420ae537d2a8f6c492900136a71
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.16"
|
version: "0.11.17"
|
||||||
rive_common:
|
rive_common:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -373,6 +437,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.2"
|
||||||
|
unicode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: unicode
|
||||||
|
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1"
|
||||||
usb_serial:
|
usb_serial:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -381,6 +453,30 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.5.1"
|
||||||
|
vector_graphics:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics
|
||||||
|
sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.7"
|
||||||
|
vector_graphics_codec:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics_codec
|
||||||
|
sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.7"
|
||||||
|
vector_graphics_compiler:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: vector_graphics_compiler
|
||||||
|
sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.7"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -397,6 +493,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.4-beta"
|
version: "0.1.4-beta"
|
||||||
|
wkt_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: wkt_parser
|
||||||
|
sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -415,4 +519,4 @@ packages:
|
||||||
version: "3.1.2"
|
version: "3.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.1.0-185.0.dev <4.0.0"
|
dart: ">=3.1.0-185.0.dev <4.0.0"
|
||||||
flutter: ">=3.0.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
|
@ -39,6 +39,11 @@ dependencies:
|
||||||
usb_serial: ^0.5.1
|
usb_serial: ^0.5.1
|
||||||
rive: ^0.11.16
|
rive: ^0.11.16
|
||||||
intl: ^0.18.1
|
intl: ^0.18.1
|
||||||
|
ffi: ^2.1.0
|
||||||
|
convert: ^3.1.1
|
||||||
|
flutter_map: ^5.0.0
|
||||||
|
latlong2: ^0.9.0
|
||||||
|
flutter_svg: ^2.0.7
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -74,6 +79,9 @@ flutter_launcher_icons:
|
||||||
|
|
||||||
# The following section is specific to Flutter packages.
|
# The following section is specific to Flutter packages.
|
||||||
flutter:
|
flutter:
|
||||||
|
assets:
|
||||||
|
- assets/compass.svg
|
||||||
|
- assets/needle.svg
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
# The following line ensures that the Material Icons font is
|
||||||
# included with your application, so that you can use the icons in
|
# included with your application, so that you can use the icons in
|
||||||
|
|
Loading…
Reference in a new issue