├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── CONTRIBUTING.md
├── README.md
├── dist
└── milgraphics.js
├── docs
├── README.md
├── milsymbol-2525c-tactical-points-svg.html
└── milsymbol-APP6b-tactical-points-svg.html
├── example-data
└── tacticaljson
│ ├── airspace-coordination-area.json
│ ├── ambush.json
│ ├── ambush_wrong_order.json
│ ├── artillery-target-intelligence-zone.json
│ ├── block.json
│ ├── breach.json
│ ├── bypass.json
│ ├── call-for-fire-zone.json
│ ├── canalize.json
│ ├── censor-zone.json
│ ├── clear.json
│ ├── critical-friendly-zone.json
│ ├── dead-space-area.json
│ ├── delay.json
│ ├── fire-support-areas.json
│ ├── free-fire-area.json
│ ├── named-area-of-interest.json
│ ├── restrictive-fire-area.json
│ ├── sensor-zone.json
│ ├── target-build-up-area.json
│ ├── target-value-area.json
│ ├── targeted-area-of-interest.json
│ ├── terminally-guided-munition-footprint.json
│ └── zone-of-responsibility.json
├── examples
├── armyxml-openlayers
│ ├── index.html
│ ├── preview.png
│ └── readme.md
├── geojson-openlayers
│ ├── index.html
│ ├── preview.png
│ └── readme.md
├── nvg-openlayers
│ ├── index.html
│ ├── preview.png
│ └── readme.md
├── slf-cesium
│ ├── index.html
│ ├── preview.png
│ └── readme.md
└── slf-openlayers
│ ├── index.html
│ ├── preview.png
│ ├── readme.md
│ └── sample.slf
├── license.txt
├── package.json
├── src
├── format.js
├── format
│ ├── armyxml.js
│ ├── geojson.js
│ ├── nvg.js
│ └── slf.js
├── geometry.js
├── geometry
│ ├── bearingbetween.js
│ ├── circle.js
│ ├── circlecorridorpolygon.js
│ ├── corridor.js
│ ├── distancebetween.js
│ ├── pointbetween.js
│ ├── rectangle.js
│ └── todistancebearing.js
├── geometryconverter.js
├── geometryconverter
│ ├── airspace-coordination-area.js
│ ├── ambush.js
│ ├── artillery-target-intelligence-zone.js
│ ├── block.js
│ ├── breach.js
│ ├── bypass.js
│ ├── call-for-fire-zone.js
│ ├── canalize.js
│ ├── censor-zone.js
│ ├── circle.js
│ ├── clear.js
│ ├── corridor.js
│ ├── cover.js
│ ├── critical-friendly-zone.js
│ ├── dead-space-area.js
│ ├── delay.js
│ ├── fire-support-area.js
│ ├── fix.js
│ ├── free-fire-area.js
│ ├── guard.js
│ ├── isolate.js
│ ├── main-attack.js
│ ├── named-area-of-interest.js
│ ├── occupy.js
│ ├── restrictive-fire-area.js
│ ├── search-area.js
│ ├── sensor-zone.js
│ ├── supporting-attack.js
│ ├── target-build-up-area.js
│ ├── target-value-area.js
│ ├── targeted-area-of-interest.js
│ ├── terminally-guided-munition-footprint.js
│ └── zone-of-responsibility.js
├── graphic.js
├── graphic
│ └── getproperties.js
├── graphicslayer.js
├── graphicslayer
│ ├── ascesium.js
│ └── asopenlayers.js
├── index.js
├── letter-sidc
│ ├── getgraphic.js
│ ├── properties.js
│ ├── tactical-2525.js
│ └── tactical-app6.js
├── ms
│ └── addsidcgraphics.js
└── number-sidc
│ └── properties.js
└── webpack.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | "browser": true,
4 | //"node": true,
5 | "commonjs": true
6 | },
7 | extends: "eslint:recommended",
8 | rules: {
9 | "linebreak-style": ["error", "unix"],
10 | "no-console": ["error", { allow: ["info","warn", "error"] }],
11 | //quotes: ["error", "double"],
12 | "no-unused-vars": ["error", { "vars": "all", "args": "none"}],
13 | semi: ["error", "always"]
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | node_modules/
3 |
4 | dev/
5 |
6 | examples/slf-cesium/cesium/
7 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | I welcome contributions from anyone and everyone. If you want to make any major changes please open an issue first, but for small changes you can simply create a pull.
4 |
5 | Before you make an contribution, please read GitHub Terms of Service: (Everything works as you think it works, but just make sure that you have the right to contribute the code you want to hand over.)
6 | https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license
7 |
8 | ## Priorities
9 |
10 | The big part of this library is the geometry converter functions that takes the input geometries and converts them to military symbology. These can be developed individualy, so if you plan to implement some of them, please add issues for the ones you have in mind making, so that noone else starts implementing the same converters.
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Milgraphics
2 |
3 | Military Tactical Graphics
4 |
5 | This is a work in progress with the goal of being able to render tactical graphics in the web browser.
6 |
7 | The library is still in initial development and should not be used in production environments. The goal is to release an initial version during the summer of 2017. What this initial version will include will be decided at a later stage.
8 |
9 | ## Main idea
10 |
11 | The main idea is to initially being able to convert input definition geometries to simple GeoJSON geometries.
12 |
13 | ### Input
14 |
15 | First data will be input in GeoJSON, at the moment the data will be defined with the same geometries as in 2525D, the data specification will be published as [TacticalJSON](https://github.com/spatialillusions/TacticalJSON).
16 |
17 | The library includes a parser for SitaWare SLF/SPF files just to be able to get some test data from an external source.
18 |
19 | ### Output
20 |
21 | Points will be points with style information for different libraries (Cesium/OpenLayers etc.)
22 |
23 | Lines will be lines, might have style information about simple label placement.
24 |
25 | Polygons will be polygons, might have style information about simple label placement.
26 |
27 | Other geometries (arrows and other complex geometries) will be converted to lines or polygons so that they can be displayed on a map and make sense.
28 |
29 | The over all main idea is to keep it simple from the beginning and then move forward where it is needed.
30 |
31 | ## Feedback
32 |
33 | Please add issues for feedback and ideas
34 |
35 | ## Technology
36 |
37 | Milgraphics is built on top of [milsymbol](https://github.com/spatialillusions/milsymbol) and adds functionality for reading tactical data in GeoJSON and outputting it in different ways that makes it easy to use in webmaps.
38 |
39 | ## Contact
40 |
41 | Milsymbol is created and maintained by Måns Beckman
42 | - http://www.spatialillusions.com to see more examples of what milsymbol can be used for
43 | - https://twitter.com/spatialillusion for milsymbol and mapping/military related information
44 |
45 | ## Licensing
46 |
47 | MIT, See [license.txt](license.txt) for details
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Milgraphics Documentation
2 |
3 |
4 | # Creating military graphics layers
5 |
6 | ## ms.GraphicsLayer(GeoJSON)
7 |
8 | Creates a new Graphics Layer from the provided GeoJSON. Properties in the GeoJSON should be mapped with the same names as in milsymbol. GeoJSON in other formats can be cloned and remapped using ms.format.GeoJSON.
9 |
10 |
11 | -----
12 | ### asCesium()
13 |
14 | Takes the current Graphics Layer and returns it as a Cesium Entity Collection with suitable styles applied.
15 |
16 | **Returns**
17 |
18 | ```javascript
19 | Cesium.EntityCollection
20 | ```
21 |
22 |
23 | ### asOpenLayers(*crs*)
24 |
25 | Takes the current Graphics Layer and returns it as Open Layers Feature Collection with suitable styles applied.
26 |
27 | **Returns**
28 |
29 | ```javascript
30 | Array.
31 | ```
32 |
33 | -----
34 |
35 | # Reading Files
36 |
37 |
38 | ## ms.format.GeoJSON(GeoJSON, mapping)
39 |
40 | Reads GeoJSON, clones it and maps properties according to the mapping object.
41 |
42 | ## ms.format.SLF( file )
43 |
44 | Reads a SitaWare SLF file and parses it to GeoJSON with attributes mapped to the values milgraphics expects.
45 |
46 | ### Known limitations
47 |
48 | The following location types are not supported at the moment:
49 |
50 | - Ellipse
51 | - FreehandDrawing
52 | - Sector
53 |
54 |
--------------------------------------------------------------------------------
/example-data/tacticaljson/airspace-coordination-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACAI------X",
8 | "uniqueDesignation": "53ID (M)",
9 | "altitudeDepth": "500 FT AGL",
10 | "altitudeDepth1": "300 FT AGL",
11 | "additionalInformation1": "NK2313 to NK3013",
12 | "dtg": "281400ZAPR",
13 | "dtg1": "281530ZAPR"
14 | },
15 | "geometry": {
16 | "type": "Polygon",
17 | "coordinates": [
18 | [
19 | [
20 | 8.725204467773438,
21 | 50.118706959423314
22 | ],
23 | [
24 | 8.699626922607422,
25 | 50.109680440473284
26 | ],
27 | [
28 | 8.700828552246094,
29 | 50.099440987634985
30 | ],
31 | [
32 | 8.719367980957031,
33 | 50.100982550598395
34 | ],
35 | [
36 | 8.741683959960938,
37 | 50.10912998793372
38 | ],
39 | [
40 | 8.732757568359375,
41 | 50.12101835522268
42 | ],
43 | [
44 | 8.725204467773438,
45 | 50.118706959423314
46 | ]
47 | ]
48 | ]
49 | }
50 | }
51 | ]
52 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/ambush.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "GFGPSLA-------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 6.609306335449219,
14 | 52.51517622886228
15 | ],
16 | [
17 | 6.5979766845703125,
18 | 52.52269704703948
19 | ],
20 | [
21 | 6.597633361816406,
22 | 52.50974372615093
23 | ]
24 | ]
25 | }
26 | },
27 | {
28 | "type": "Feature",
29 | "properties": {"sidc":"GFGPSLA-------X"},
30 | "geometry": {
31 | "type": "LineString",
32 | "coordinates": [
33 | [
34 | 6.588706970214844,
35 | 52.51663871100423
36 | ],
37 | [
38 | 6.573944091796875,
39 | 52.5197724373965
40 | ],
41 | [
42 | 6.5856170654296875,
43 | 52.5081765332574
44 | ]
45 | ]
46 | }
47 | },
48 | {
49 | "type": "Feature",
50 | "properties": {"sidc":"GFGPSLA-------X"},
51 | "geometry": {
52 | "type": "LineString",
53 | "coordinates": [
54 | [
55 | 6.576347351074219,
56 | 52.50734067419732
57 | ],
58 | [
59 | 6.560382843017577,
60 | 52.50253417611727
61 | ],
62 | [
63 | 6.586818695068359,
64 | 52.500339730516956
65 | ]
66 | ]
67 | }
68 | },
69 | {
70 | "type": "Feature",
71 | "properties": {"sidc":"GFGPSLA-------X"},
72 | "geometry": {
73 | "type": "LineString",
74 | "coordinates": [
75 | [
76 | 6.575145721435547,
77 | 52.49741363265356
78 | ],
79 | [
80 | 6.574115753173828,
81 | 52.48664809680302
82 | ],
83 | [
84 | 6.593341827392578,
85 | 52.49762264610208
86 | ]
87 | ]
88 | }
89 | },
90 | {
91 | "type": "Feature",
92 | "properties": {"sidc":"GFGPSLA-------X"},
93 | "geometry": {
94 | "type": "LineString",
95 | "coordinates": [
96 | [
97 | 6.5938568115234375,
98 | 52.49176989396086
99 | ],
100 | [
101 | 6.603641510009766,
102 | 52.48434832038955
103 | ],
104 | [
105 | 6.60552978515625,
106 | 52.49563697822492
107 | ]
108 | ]
109 | }
110 | },
111 | {
112 | "type": "Feature",
113 | "properties": {"sidc":"GFGPSLA-------X"},
114 | "geometry": {
115 | "type": "LineString",
116 | "coordinates": [
117 | [
118 | 6.613254547119141,
119 | 52.49145633168364
120 | ],
121 | [
122 | 6.629905700683594,
123 | 52.48800699907657
124 | ],
125 | [
126 | 6.620979309082031,
127 | 52.49971272594018
128 | ]
129 | ]
130 | }
131 | },
132 | {
133 | "type": "Feature",
134 | "properties": {"sidc":"GFGPSLA-------X"},
135 | "geometry": {
136 | "type": "LineString",
137 | "coordinates": [
138 | [
139 | 6.6302490234375,
140 | 52.49783165855699
141 | ],
142 | [
143 | 6.6474151611328125,
144 | 52.50535544522142
145 | ],
146 | [
147 | 6.618747711181641,
148 | 52.506191342034576
149 | ]
150 | ]
151 | }
152 | },
153 | {
154 | "type": "Feature",
155 | "properties": {"sidc":"GFGPSLA-------X"},
156 | "geometry": {
157 | "type": "LineString",
158 | "coordinates": [
159 | [
160 | 6.633853912353516,
161 | 52.51016163481784
162 | ],
163 | [
164 | 6.632823944091797,
165 | 52.5199813445422
166 | ],
167 | [
168 | 6.614799499511719,
169 | 52.51026611136366
170 | ]
171 | ]
172 | }
173 | },
174 | {
175 | "type": "Feature",
176 | "properties": {"sidc":"GFGPSLA-------X"},
177 | "geometry": {
178 | "type": "LineString",
179 | "coordinates": [
180 | [
181 | 6.695137023925781,
182 | 52.50859445682651
183 | ],
184 | [
185 | 6.680545806884766,
186 | 52.5022206905951
187 | ],
188 | [
189 | 6.706981658935547,
190 | 52.50054873005541
191 | ]
192 | ]
193 | }
194 | },
195 | {
196 | "type": "Feature",
197 | "properties": {"sidc":"GFGPSLA-------X"},
198 | "geometry": {
199 | "type": "LineString",
200 | "coordinates": [
201 | [
202 | 6.6886138916015625,
203 | 52.489993011495585
204 | ],
205 | [
206 | 6.705093383789062,
207 | 52.496159531097106
208 | ],
209 | [
210 | 6.679172515869141,
211 | 52.49845868996027
212 | ]
213 | ]
214 | }
215 | }
216 | ]
217 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/ambush_wrong_order.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {"sidc":"GFGPSLA-------X"},
7 | "geometry": {
8 | "type": "LineString",
9 | "coordinates": [
10 | [
11 | 15.851211547851562,
12 | 58.23853710414432
13 | ],
14 | [
15 | 15.839881896972656,
16 | 58.23329584804805
17 | ],
18 | [
19 | 15.840911865234373,
20 | 58.24359689253174
21 | ]
22 | ]
23 | }
24 | }
25 | ]
26 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/artillery-target-intelligence-zone.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-AZII------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-AZIR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | }
79 | ]
80 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/block.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-B---------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 8.730182647705078,
14 | 50.19767137199048
15 | ],
16 | [
17 | 8.726921081542969,
18 | 50.190967765585604
19 | ],
20 | [
21 | 8.711814880371094,
22 | 50.19778125933641
23 | ]
24 | ]
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/breach.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-H---------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 8.730182647705078,
14 | 50.19767137199048
15 | ],
16 | [
17 | 8.726921081542969,
18 | 50.190967765585604
19 | ],
20 | [
21 | 8.711814880371094,
22 | 50.19778125933641
23 | ]
24 | ]
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/bypass.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-Y---------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 8.730182647705078,
14 | 50.19767137199048
15 | ],
16 | [
17 | 8.726921081542969,
18 | 50.190967765585604
19 | ],
20 | [
21 | 8.711814880371094,
22 | 50.19778125933641
23 | ]
24 | ]
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/call-for-fire-zone.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-AZXI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-AZXR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | }
79 | ]
80 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/canalize.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-C---------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 8.730182647705078,
14 | 50.19767137199048
15 | ],
16 | [
17 | 8.726921081542969,
18 | 50.190967765585604
19 | ],
20 | [
21 | 8.711814880371094,
22 | 50.19778125933641
23 | ]
24 | ]
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/censor-zone.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-AZCI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-AZCR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | }
79 | ]
80 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/clear.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-X---------X"
8 | },
9 | "geometry": {
10 | "type": "LineString",
11 | "coordinates": [
12 | [
13 | 8.730182647705078,
14 | 50.19767137199048
15 | ],
16 | [
17 | 8.726921081542969,
18 | 50.190967765585604
19 | ],
20 | [
21 | 8.711814880371094,
22 | 50.19778125933641
23 | ]
24 | ]
25 | }
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/critical-friendly-zone.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-AZFI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-AZFR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | }
79 | ]
80 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/dead-space-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACDI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACDR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACDC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "Q37"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/delay.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-T-L---------X",
8 | "dtg": "272100Z SEP"
9 | },
10 | "geometry": {
11 | "type": "LineString",
12 | "coordinates": [
13 | [
14 | 8.66769790649414,
15 | 50.195253786387475
16 | ],
17 | [
18 | 8.680744171142576,
19 | 50.201297520859185
20 | ],
21 | [
22 | 8.676109313964844,
23 | 50.204593780814676
24 | ]
25 | ]
26 | }
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/fire-support-areas.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACSI------X",
8 | "uniqueDesignation": "I"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACSR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "II"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACSC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "III"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/free-fire-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACFI------X",
8 | "uniqueDesignation": "I"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACFR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "II"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACFC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "III"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/named-area-of-interest.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-G-SAN-------X",
8 | "uniqueDesignation": "DOCKS"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 8.725204467773438,
16 | 50.118706959423314
17 | ],
18 | [
19 | 8.699626922607422,
20 | 50.109680440473284
21 | ],
22 | [
23 | 8.700828552246094,
24 | 50.099440987634985
25 | ],
26 | [
27 | 8.719367980957031,
28 | 50.100982550598395
29 | ],
30 | [
31 | 8.741683959960938,
32 | 50.10912998793372
33 | ],
34 | [
35 | 8.732757568359375,
36 | 50.12101835522268
37 | ],
38 | [
39 | 8.725204467773438,
40 | 50.118706959423314
41 | ]
42 | ]
43 | ]
44 | }
45 | }
46 | ]
47 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/restrictive-fire-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACRI------X",
8 | "uniqueDesignation": "I"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACRR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "II"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACRC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "III"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/sensor-zone.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACEI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACER------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACEC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "Q37"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/target-build-up-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACBI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACBR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACBC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "Q37"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/target-value-area.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACVI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACVR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACVC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "Q37"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/targeted-area-of-interest.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-G-SAT-------X",
8 | "uniqueDesignation": "DOCKS"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 8.725204467773438,
16 | 50.118706959423314
17 | ],
18 | [
19 | 8.699626922607422,
20 | 50.109680440473284
21 | ],
22 | [
23 | 8.700828552246094,
24 | 50.099440987634985
25 | ],
26 | [
27 | 8.719367980957031,
28 | 50.100982550598395
29 | ],
30 | [
31 | 8.741683959960938,
32 | 50.10912998793372
33 | ],
34 | [
35 | 8.732757568359375,
36 | 50.12101835522268
37 | ],
38 | [
39 | 8.725204467773438,
40 | 50.118706959423314
41 | ]
42 | ]
43 | ]
44 | }
45 | }
46 | ]
47 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/terminally-guided-munition-footprint.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACT-------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | }
58 | ]
59 | }
--------------------------------------------------------------------------------
/example-data/tacticaljson/zone-of-responsibility.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "FeatureCollection",
3 | "features": [
4 | {
5 | "type": "Feature",
6 | "properties": {
7 | "sidc": "G-F-ACZI------X",
8 | "uniqueDesignation": "Q35"
9 | },
10 | "geometry": {
11 | "type": "Polygon",
12 | "coordinates": [
13 | [
14 | [
15 | 0.514984130859375,
16 | 47.42065432071318
17 | ],
18 | [
19 | 0.45799255371093744,
20 | 47.39695481668995
21 | ],
22 | [
23 | 0.454559326171875,
24 | 47.37184960049907
25 | ],
26 | [
27 | 0.46623229980468756,
28 | 47.33789206010502
29 | ],
30 | [
31 | 0.5101776123046875,
32 | 47.33789206010502
33 | ],
34 | [
35 | 0.5417633056640625,
36 | 47.35836223484991
37 | ],
38 | [
39 | 0.5108642578125,
40 | 47.37138457633079
41 | ],
42 | [
43 | 0.5417633056640625,
44 | 47.38812286319825
45 | ],
46 | [
47 | 0.538330078125,
48 | 47.41833131141311
49 | ],
50 | [
51 | 0.514984130859375,
52 | 47.42065432071318
53 | ]
54 | ]
55 | ]
56 | }
57 | },
58 | {
59 | "type": "Feature",
60 | "properties": {
61 | "sidc": "G-F-ACZR------X",
62 | "distance": 5000,
63 | "uniqueDesignation": "Q36"
64 | },
65 | "geometry": {
66 | "type": "LineString",
67 | "coordinates": [
68 | [
69 | 0.6008148193359375,
70 | 47.38672820892124
71 | ],
72 | [
73 | 0.6488800048828125,
74 | 47.40810885284093
75 | ]
76 | ]
77 | }
78 | },
79 | {
80 | "type": "Feature",
81 | "properties": {
82 | "sidc": "G-F-ACZC------X",
83 | "distance": 5000,
84 | "dtg": "10095900ZJAN92",
85 | "dtg1": "11095900ZJAN92",
86 | "uniqueDesignation": "Q37"
87 | },
88 | "geometry": {
89 | "type": "Point",
90 | "coordinates": [
91 | 0.7532501220703125,
92 | 47.3895174805737
93 | ]
94 | }
95 | }
96 | ]
97 | }
--------------------------------------------------------------------------------
/examples/armyxml-openlayers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Army XML:
24 |
25 |
26 |
27 |
53 |
54 |
56 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/examples/armyxml-openlayers/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spatialillusions/milgraphics/9cc4e608b577e61b0aacf22ba322c2b2ca4feae1/examples/armyxml-openlayers/preview.png
--------------------------------------------------------------------------------
/examples/armyxml-openlayers/readme.md:
--------------------------------------------------------------------------------
1 | ## Army XML to GeoJSON
2 |
3 | This is a demo of reading Army XML and converting them to GeoJSON. Not all location types are supported yet, but the plan is to support all of them.
4 |
--------------------------------------------------------------------------------
/examples/geojson-openlayers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | TacticalJSON:
26 |
27 |
28 |
29 |
55 |
56 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/examples/geojson-openlayers/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spatialillusions/milgraphics/9cc4e608b577e61b0aacf22ba322c2b2ca4feae1/examples/geojson-openlayers/preview.png
--------------------------------------------------------------------------------
/examples/geojson-openlayers/readme.md:
--------------------------------------------------------------------------------
1 | ## TacticalJSON
2 |
3 | This is a demo of reading GeoJON following the TacticalJSON specification.
4 |
--------------------------------------------------------------------------------
/examples/nvg-openlayers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Nato Vector Graphics:
24 |
25 |
26 |
27 |
53 |
54 |
56 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/examples/nvg-openlayers/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spatialillusions/milgraphics/9cc4e608b577e61b0aacf22ba322c2b2ca4feae1/examples/nvg-openlayers/preview.png
--------------------------------------------------------------------------------
/examples/nvg-openlayers/readme.md:
--------------------------------------------------------------------------------
1 | ## Nato Vector Graphics
2 |
3 | This is a demo of reading Nato Vector Graphics (NVG). The reader supports NVG in both JSON format and XML format, and should support most version of NVG.
4 |
--------------------------------------------------------------------------------
/examples/slf-cesium/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 | SitaWare Layer File (SLF) or SitaWare Plan File (SPF):
27 |
28 |
29 |
30 |
40 |
41 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/examples/slf-cesium/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spatialillusions/milgraphics/9cc4e608b577e61b0aacf22ba322c2b2ca4feae1/examples/slf-cesium/preview.png
--------------------------------------------------------------------------------
/examples/slf-cesium/readme.md:
--------------------------------------------------------------------------------
1 | ## SLF to GeoJSON
2 |
3 | This is a demo of reading SitaWare SLF fils and converting them to GeoJSON. Not all location types are supported yet, but the plan is to support all of them.
4 |
--------------------------------------------------------------------------------
/examples/slf-openlayers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | SitaWare Layer File (SLF) or SitaWare Plan File (SPF):
24 |
25 |
26 |
27 |
53 |
54 |
56 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/examples/slf-openlayers/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spatialillusions/milgraphics/9cc4e608b577e61b0aacf22ba322c2b2ca4feae1/examples/slf-openlayers/preview.png
--------------------------------------------------------------------------------
/examples/slf-openlayers/readme.md:
--------------------------------------------------------------------------------
1 | ## SLF to GeoJSON
2 |
3 | This is a demo of reading SitaWare SLF fils and converting them to GeoJSON. Not all location types are supported yet, but the plan is to support all of them.
4 |
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Måns Beckman - www.spatialillusions.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "milgraphics",
3 | "version": "0.0.1",
4 | "description": "MilGraphics is a library for drawing military graphics",
5 | "main": "dist/milgraphics.js",
6 | "directories": {
7 | "doc": "docs",
8 | "example": "examples"
9 | },
10 | "scripts": {
11 | "build": "webpack -p",
12 | "build-dev": "webpack",
13 | "test": "echo \"Error: no test specified\" && exit 1"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/spatialillusions/milgraphics"
18 | },
19 | "author": "Måns Beckman (http://www.spatialillusions.com)",
20 | "license": "MIT",
21 | "bugs": {
22 | "url": "https://github.com/spatialillusions/milgraphics/issues"
23 | },
24 | "homepage": "https://github.com/spatialillusions/milgraphics",
25 | "devDependencies": {
26 | "eslint": "^3.19.0",
27 | "milsymbol": "^1.0.0",
28 | "webpack": "^2.2.0",
29 | "webpack-custom-var-library-name-plugin": "^1.0.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/format.js:
--------------------------------------------------------------------------------
1 | var format = {};
2 |
3 | format.ArmyXML = require("./format/armyxml.js");
4 | format.GeoJSON = require("./format/geojson.js");
5 | format.NVG = require("./format/nvg.js");
6 | format.SLF = require("./format/slf.js");
7 |
8 | module.exports = format;
9 |
--------------------------------------------------------------------------------
/src/format/armyxml.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function ArmyXML(xml) {
4 | var features = [];
5 | /*
6 | function parseSIDC(sidc) {
7 | for (var i in sidc.childNodes){
8 | if (sidc.childNodes[i].nodeName == 'SymbolCodeString'){
9 | return sidc.childNodes[i].textContent;
10 | }
11 | }
12 | }
13 | */
14 | function parseArea(area) {
15 | var coordinates = [];
16 | area = area.getElementsByTagName(ns + "Point");
17 | for (var i in area) {
18 | if (area[i].nodeName == ns + "Point") {
19 | var point = area[i];
20 | var coord = [];
21 | coord[0] = parseFloat(point.getAttribute("Longitude"));
22 | coord[1] = parseFloat(point.getAttribute("Latitude"));
23 | if (point.getAttribute("Elevation")) {
24 | coord[2] = parseFloat(point.getAttribute("Elevation"));
25 | }
26 | coordinates.push(coord);
27 | }
28 | }
29 | coordinates.push(coordinates[0]); //close ring
30 | return coordinates;
31 | }
32 |
33 | /*
34 | function parseArrow(arrow) {
35 | var coordinates = [];
36 | var arrowHead = [];
37 | for (var i in arrow.childNodes){
38 | if (arrow.childNodes[i].nodeName == 'Arrowhead'){
39 | arrowHead = parsePoint(arrow.childNodes[i]);
40 | }
41 | if (arrow.childNodes[i].nodeName == 'Points'){
42 | for (var j in arrow.childNodes[i].childNodes){
43 | if (arrow.childNodes[i].childNodes[j].nodeName == 'Point'){
44 | coordinates.unshift( parsePoint(arrow.childNodes[i].childNodes[j]) );
45 | }
46 | }
47 | }
48 | }
49 | coordinates.push(arrowHead);//Add arrow head last in multipoint
50 | return coordinates;
51 | }
52 | */
53 | /*
54 | function parseCircle(line) {
55 | var coordinates = [0,0];
56 | for (var i in line.childNodes){
57 | if (line.childNodes[i].nodeName == 'CenterPoint'){
58 | coordinates[0] = parsePoint(line.childNodes[i]);
59 | }
60 | if (line.childNodes[i].nodeName == 'PerimeterPoint'){
61 | coordinates[1] = parsePoint(line.childNodes[i]);
62 | }
63 | }
64 | return coordinates;
65 | }
66 | */
67 | /*
68 | function parseCorridor(corridor) {
69 | var coordinates = [];
70 | var width = 0;
71 | for (var i in corridor.childNodes){
72 | if (corridor.childNodes[i].nodeName == 'Width'){
73 | width = corridor.childNodes[i].textContent;
74 | }
75 | if (corridor.childNodes[i].nodeName == 'Points'){
76 | for (var j in corridor.childNodes[i].childNodes){
77 | if (corridor.childNodes[i].childNodes[j].nodeName == 'Point'){
78 | coordinates.push( parsePoint(corridor.childNodes[i].childNodes[j]) );
79 | }
80 | }
81 | }
82 | }
83 | coordinates.push(width);//Add width last in array, we fix this later
84 | return coordinates;
85 | }
86 | */
87 |
88 | function parseLine(line) {
89 | var coordinates = [];
90 | line = line.getElementsByTagName(ns + "Point");
91 | for (var i in line) {
92 | if (line[i].nodeName == ns + "Point") {
93 | var point = line[i];
94 | var coord = [];
95 | coord[0] = parseFloat(point.getAttribute("Longitude"));
96 | coord[1] = parseFloat(point.getAttribute("Latitude"));
97 | if (point.getAttribute("Elevation")) {
98 | coord[2] = parseFloat(point.getAttribute("Elevation"));
99 | }
100 | coordinates.push(coord);
101 | }
102 | }
103 | return coordinates;
104 | }
105 |
106 | /*
107 | function parseTwoPointArrow(arrow) {
108 | var coordinates = [0,0,0];
109 | for (var i in arrow.childNodes){
110 | if (arrow.childNodes[i].nodeName == 'StartPoint'){
111 | coordinates[1] = parsePoint(arrow.childNodes[i]);
112 | }
113 | if (arrow.childNodes[i].nodeName == 'EndPoint' || arrow.childNodes[i].nodeName == 'Endpoint'){
114 | coordinates[0] = parsePoint(arrow.childNodes[i]);
115 | }
116 | if (arrow.childNodes[i].nodeName == 'Arrowhead' || arrow.childNodes[i].nodeName == 'ArrowHead'){
117 | coordinates[2] = parsePoint(arrow.childNodes[i]);
118 | }
119 | }
120 | console.log(coordinates)
121 | return coordinates;
122 | }
123 | */
124 | /*
125 | function parseTwoPointCorridor(line) {
126 | var coordinates = [0,0,0];
127 | for (var i in line.childNodes){
128 | if (line.childNodes[i].nodeName == 'StartPoint'){
129 | coordinates[0] = parsePoint(line.childNodes[i]);
130 | }
131 | if (line.childNodes[i].nodeName == 'EndPoint' || line.childNodes[i].nodeName == 'Endpoint'){
132 | coordinates[1] = parsePoint(line.childNodes[i]);
133 | }
134 | if (line.childNodes[i].nodeName == 'Width'){
135 | coordinates[2] = line.childNodes[i].textContent;
136 | }
137 | }
138 | return coordinates;
139 | }
140 | */
141 | /*
142 | function parseTwoPointLine(line) {
143 | var coordinates = [0,0];
144 | for (var i in line.childNodes){
145 | if (line.childNodes[i].nodeName == 'StartPoint'){
146 | //we reverse them because MIR vs 2525
147 | coordinates[1] = parsePoint(line.childNodes[i]);
148 | }
149 | if (line.childNodes[i].nodeName == 'EndPoint' || line.childNodes[i].nodeName == 'Endpoint'){
150 | coordinates[0] = parsePoint(line.childNodes[i]);
151 | }
152 | }
153 | return coordinates;
154 | }
155 | */
156 |
157 | function parsePoint(point) {
158 | var coordinates = [0, 0];
159 | point = point.getElementsByTagName(ns + "Point")[0];
160 | coordinates[0] = parseFloat(point.getAttribute("Longitude"));
161 | coordinates[1] = parseFloat(point.getAttribute("Latitude"));
162 | if (point.getAttribute("Elevation")) {
163 | coordinates[2] = parseFloat(point.getAttribute("Elevation"));
164 | }
165 | return coordinates;
166 | }
167 |
168 | function parseSymbol(symbol) {
169 | var feature = { type: "Feature", properties: {} };
170 |
171 | var symbolNodes = {};
172 | for (var i in symbol.childNodes) {
173 | symbolNodes[symbol.childNodes[i].nodeName] = symbol.childNodes[i];
174 | }
175 |
176 | var symbolDefinition = symbolNodes[ns + "Symbol_Definition"];
177 | for (i in symbolDefinition.childNodes) {
178 | var nodeName = symbolDefinition.childNodes[i].nodeName;
179 | if (nodeName == "#text" || typeof nodeName === "undefined") continue;
180 | if (nodeName.indexOf(":") != -1) nodeName = nodeName.split(":")[1];
181 | feature.properties[nodeName] = symbolDefinition.childNodes[i].textContent;
182 | }
183 |
184 | var operationalAttributes = symbolNodes[ns + "Operational_Attributes"];
185 | for (i in operationalAttributes.childNodes) {
186 | nodeName = operationalAttributes.childNodes[i].nodeName;
187 | if (nodeName == "#text" || typeof nodeName === "undefined") continue;
188 | if (nodeName.indexOf(":") != -1) nodeName = nodeName.split(":")[1];
189 | feature.properties[nodeName] =
190 | operationalAttributes.childNodes[i].textContent;
191 | }
192 |
193 | var displayAttributes = symbolNodes[ns + "Display_Attributes"];
194 | for (i in displayAttributes.childNodes) {
195 | nodeName = displayAttributes.childNodes[i].nodeName;
196 | if (nodeName == "#text" || typeof nodeName === "undefined") continue;
197 | if (nodeName.indexOf(":") != -1) nodeName = nodeName.split(":")[1];
198 | feature.properties[nodeName] =
199 | displayAttributes.childNodes[i].textContent;
200 | }
201 |
202 | switch (feature.properties["Symbol_Category"]) {
203 | case "AREA":
204 | feature.geometry = {
205 | type: "Polygon",
206 | coordinates: [parseArea(symbolNodes[ns + "Symbol_Points"])]
207 | };
208 | break;
209 | case "BIOCHEM":
210 | if (
211 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
212 | .length == 1
213 | ) {
214 | feature.geometry = {
215 | type: "Point",
216 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
217 | };
218 | } else {
219 | feature.geometry = {
220 | type: "Polygon",
221 | coordinates: [parseArea(symbolNodes[ns + "Symbol_Points"])]
222 | };
223 | }
224 | break;
225 | //BOUNDARY,
226 | case "EQUIPMENT":
227 | feature.geometry = {
228 | type: "Point",
229 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
230 | };
231 | break;
232 | //GROUP ,
233 | case "INSTALLATION":
234 | feature.geometry = {
235 | type: "Point",
236 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
237 | };
238 | break;
239 | case "LINE":
240 | feature.geometry = {
241 | type: "LineString",
242 | coordinates: parseLine(symbolNodes[ns + "Symbol_Points"])
243 | };
244 | break;
245 | case "MINE":
246 | if (
247 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
248 | .length == 1
249 | ) {
250 | feature.geometry = {
251 | type: "Point",
252 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
253 | };
254 | } else {
255 | feature.geometry = {
256 | type: "Polygon",
257 | coordinates: [parseArea(symbolNodes[ns + "Symbol_Points"])]
258 | };
259 | }
260 | break;
261 | case "MOOTW":
262 | feature.geometry = {
263 | type: "Point",
264 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
265 | };
266 | break;
267 | case "NOT_SPECIFIED":
268 | if (
269 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
270 | .length == 1
271 | ) {
272 | feature.geometry = {
273 | type: "Point",
274 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
275 | };
276 | } else {
277 | console.warn(
278 | "cannot handle Symbol_Category: " +
279 | feature.properties["Symbol_Category"]
280 | );
281 | console.warn(feature.properties["Symbol_Name"]);
282 | console.warn(symbol);
283 | }
284 | break;
285 | case "NUCLEAR":
286 | if (
287 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
288 | .length == 1
289 | ) {
290 | feature.geometry = {
291 | type: "Point",
292 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
293 | };
294 | } else {
295 | feature.geometry = {
296 | type: "Polygon",
297 | coordinates: [parseArea(symbolNodes[ns + "Symbol_Points"])]
298 | };
299 | }
300 | break;
301 | case "OBSTACLE":
302 | if (
303 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
304 | .length == 1
305 | ) {
306 | feature.geometry = {
307 | type: "Point",
308 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
309 | };
310 | } else {
311 | console.warn(
312 | "cannot handle Symbol_Category: " +
313 | feature.properties["Symbol_Category"]
314 | );
315 | console.warn(symbol);
316 | }
317 | break;
318 | case "POINT":
319 | if (
320 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
321 | .length == 1
322 | ) {
323 | feature.geometry = {
324 | type: "Point",
325 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
326 | };
327 | } else {
328 | // OK this is bonkers, but i found some errors in some of my sample files...
329 | feature.geometry = {
330 | type: "LineString",
331 | coordinates: parseLine(symbolNodes[ns + "Symbol_Points"])
332 | };
333 | }
334 | break;
335 | case "SIG_INT":
336 | if (
337 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
338 | .length == 1
339 | ) {
340 | feature.geometry = {
341 | type: "Point",
342 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
343 | };
344 | } else {
345 | console.warn(
346 | "cannot handle Symbol_Category: " +
347 | feature.properties["Symbol_Category"]
348 | );
349 | console.warn(symbol);
350 | }
351 | break;
352 | case "TARGET":
353 | if (
354 | symbolNodes[ns + "Symbol_Points"].getElementsByTagName(ns + "Point")
355 | .length == 1
356 | ) {
357 | feature.geometry = {
358 | type: "Point",
359 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
360 | };
361 | } else {
362 | feature.geometry = {
363 | type: "Polygon",
364 | coordinates: [parseArea(symbolNodes[ns + "Symbol_Points"])]
365 | };
366 | }
367 | break;
368 | case "UNIT":
369 | feature.geometry = {
370 | type: "Point",
371 | coordinates: parsePoint(symbolNodes[ns + "Symbol_Points"])
372 | };
373 | break;
374 | default:
375 | console.warn(
376 | "cannot handle Symbol_Category: " +
377 | feature.properties["Symbol_Category"]
378 | );
379 | console.warn(symbol);
380 | }
381 | return feature;
382 | }
383 |
384 | if (typeof xml == "string") {
385 | xml = new DOMParser().parseFromString(xml, "text/xml");
386 | }
387 | var ns = "";
388 | if (xml.firstChild.nodeName.indexOf(":") != -1) {
389 | ns = xml.firstChild.nodeName.split(":")[0] + ":";
390 | }
391 |
392 | var symbols = xml.getElementsByTagName(ns + "Symbol");
393 | for (var sym in symbols) {
394 | if (symbols[sym].nodeName) {
395 | features = features.concat(parseSymbol(symbols[sym]));
396 | }
397 | }
398 |
399 | var rawGeoJSON = { type: "FeatureCollection", features: features };
400 | return ms.format.GeoJSON(rawGeoJSON, {
401 | Additional_Info1: "additionalInformation",
402 | Additional_Info2: "additionalInformation1",
403 | Additional_Info3: "additionalInformation1",
404 | Common_Identifier: "commonIdentifier",
405 | Higher_Formation: "higherFormation",
406 | Unique_Designator1: "uniqueDesignation",
407 | Unique_Designator2: "uniqueDesignation1",
408 | Staff_Comments: "staffComments",
409 | Symbol_Code: "sidc",
410 | DTG_1: "dtg",
411 | DTG_2: "dtg1",
412 | //Speed: 'speed',
413 | //Direction: 'direction',
414 | //Altitude_Depth: 'altitudeDepth',
415 | Reinforced_or_Reduced: "reinforcedReduced",
416 | Quantity: "quantity",
417 | //Combat_Effectiveness: 'combatEffectiveness',
418 | Signature_Equipment: "signatureEquipment",
419 | IFF_SIF: "iffSif",
420 | Special_C2HQ: "specialHeadquarters"
421 | });
422 | }
423 |
424 | if (typeof module !== "undefined") {
425 | module.exports = ArmyXML;
426 | }
427 |
--------------------------------------------------------------------------------
/src/format/geojson.js:
--------------------------------------------------------------------------------
1 | function GeoJSON(data, mapping) {
2 | if (typeof mapping == "undefined") {
3 | mapping = {};
4 | }
5 | // If input is a string, parse it to JSON
6 | if (typeof data == "string") {
7 | data = JSON.parse(data);
8 | for (var key in data) {
9 | this[key] = data[key];
10 | }
11 | }
12 |
13 | // Parse and clone the JSON
14 | var feature_copy = [];
15 | for (var i = 0; i < data.features.length; i++) {
16 | var feature = data.features[i];
17 | var f = { type: "Feature", properties: {} };
18 | if (feature.geometry) {
19 | f.geometry = {
20 | type: feature.geometry.type,
21 | coordinates: feature.geometry.coordinates
22 | };
23 | }
24 | for (key in feature.properties) {
25 | if (mapping.hasOwnProperty(key)) {
26 | f.properties[mapping[key]] = feature.properties[key];
27 | } else {
28 | f.properties[key] = feature.properties[key];
29 | }
30 | }
31 | feature_copy.push(f);
32 | }
33 | return { type: "FeatureCollection", features: feature_copy };
34 | }
35 |
36 | module.exports = GeoJSON;
37 |
--------------------------------------------------------------------------------
/src/format/slf.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function SLF(xml) {
4 | var features = [];
5 |
6 | function parseSIDC(sidc) {
7 | for (var i in sidc.childNodes) {
8 | if (sidc.childNodes[i].nodeName == "SymbolCodeString") {
9 | return sidc.childNodes[i].textContent;
10 | }
11 | }
12 | }
13 |
14 | function parseArea(area) {
15 | var coordinates = [];
16 | for (var i in area.childNodes) {
17 | if (area.childNodes[i].nodeName == "Points") {
18 | for (var j in area.childNodes[i].childNodes) {
19 | if (area.childNodes[i].childNodes[j].nodeName == "Point") {
20 | coordinates.push(parsePoint(area.childNodes[i].childNodes[j]));
21 | }
22 | }
23 | }
24 | }
25 | coordinates.push(coordinates[0]); //close ring
26 | return coordinates;
27 | }
28 |
29 | function parseArrow(arrow) {
30 | var coordinates = [];
31 | var arrowHead = [];
32 | for (var i in arrow.childNodes) {
33 | if (arrow.childNodes[i].nodeName == "Arrowhead") {
34 | arrowHead = parsePoint(arrow.childNodes[i]);
35 | }
36 | if (arrow.childNodes[i].nodeName == "Points") {
37 | for (var j in arrow.childNodes[i].childNodes) {
38 | if (arrow.childNodes[i].childNodes[j].nodeName == "Point") {
39 | coordinates.unshift(parsePoint(arrow.childNodes[i].childNodes[j]));
40 | }
41 | }
42 | }
43 | }
44 | coordinates.push(arrowHead); //Add arrow head last in multipoint
45 | return coordinates;
46 | }
47 |
48 | function parseCircle(line) {
49 | var coordinates = [0, 0];
50 | for (var i in line.childNodes) {
51 | if (line.childNodes[i].nodeName == "CenterPoint") {
52 | coordinates[0] = parsePoint(line.childNodes[i]);
53 | }
54 | if (line.childNodes[i].nodeName == "PerimeterPoint") {
55 | coordinates[1] = parsePoint(line.childNodes[i]);
56 | }
57 | }
58 | return coordinates;
59 | }
60 |
61 | function parseCorridor(corridor) {
62 | var coordinates = [];
63 | var width = 0;
64 | for (var i in corridor.childNodes) {
65 | if (corridor.childNodes[i].nodeName == "Width") {
66 | width = corridor.childNodes[i].textContent;
67 | }
68 | if (corridor.childNodes[i].nodeName == "Points") {
69 | for (var j in corridor.childNodes[i].childNodes) {
70 | if (corridor.childNodes[i].childNodes[j].nodeName == "Point") {
71 | coordinates.push(parsePoint(corridor.childNodes[i].childNodes[j]));
72 | }
73 | }
74 | }
75 | }
76 | coordinates.push(width); //Add width last in array, we fix this later
77 | return coordinates;
78 | }
79 |
80 | function parseLine(line) {
81 | var coordinates = [];
82 | for (var i in line.childNodes) {
83 | if (line.childNodes[i].nodeName == "Points") {
84 | for (var j in line.childNodes[i].childNodes) {
85 | if (line.childNodes[i].childNodes[j].nodeName == "Point") {
86 | coordinates.push(parsePoint(line.childNodes[i].childNodes[j]));
87 | }
88 | }
89 | }
90 | }
91 | return coordinates;
92 | }
93 |
94 | function parseTwoPointArrow(arrow) {
95 | var coordinates = [0, 0, 0];
96 | for (var i in arrow.childNodes) {
97 | if (arrow.childNodes[i].nodeName == "StartPoint") {
98 | coordinates[1] = parsePoint(arrow.childNodes[i]);
99 | }
100 | if (
101 | arrow.childNodes[i].nodeName == "EndPoint" ||
102 | arrow.childNodes[i].nodeName == "Endpoint"
103 | ) {
104 | coordinates[0] = parsePoint(arrow.childNodes[i]);
105 | }
106 | if (
107 | arrow.childNodes[i].nodeName == "Arrowhead" ||
108 | arrow.childNodes[i].nodeName == "ArrowHead"
109 | ) {
110 | coordinates[2] = parsePoint(arrow.childNodes[i]);
111 | }
112 | }
113 | console.warn(coordinates);
114 | return coordinates;
115 | }
116 |
117 | function parseTwoPointCorridor(line) {
118 | var coordinates = [0, 0, 0];
119 | for (var i in line.childNodes) {
120 | if (line.childNodes[i].nodeName == "StartPoint") {
121 | coordinates[0] = parsePoint(line.childNodes[i]);
122 | }
123 | if (
124 | line.childNodes[i].nodeName == "EndPoint" ||
125 | line.childNodes[i].nodeName == "Endpoint"
126 | ) {
127 | coordinates[1] = parsePoint(line.childNodes[i]);
128 | }
129 | if (line.childNodes[i].nodeName == "Width") {
130 | coordinates[2] = line.childNodes[i].textContent;
131 | }
132 | }
133 | return coordinates;
134 | }
135 |
136 | function parseTwoPointLine(line) {
137 | var coordinates = [0, 0];
138 | for (var i in line.childNodes) {
139 | if (line.childNodes[i].nodeName == "StartPoint") {
140 | //we reverse them because MIR vs 2525
141 | coordinates[1] = parsePoint(line.childNodes[i]);
142 | }
143 | if (
144 | line.childNodes[i].nodeName == "EndPoint" ||
145 | line.childNodes[i].nodeName == "Endpoint"
146 | ) {
147 | coordinates[0] = parsePoint(line.childNodes[i]);
148 | }
149 | }
150 | return coordinates;
151 | }
152 |
153 | function parsePoint(point) {
154 | var coordinates = [0, 0];
155 | for (var i in point.childNodes) {
156 | if (point.childNodes[i].nodeName == "Longitude") {
157 | coordinates[0] = parseFloat(point.childNodes[i].textContent);
158 | }
159 | if (point.childNodes[i].nodeName == "Latitude") {
160 | coordinates[1] = parseFloat(point.childNodes[i].textContent);
161 | }
162 | }
163 | return coordinates;
164 | }
165 |
166 | function parseLocation(location) {
167 | var locationType = location.getAttribute("xsi:type");
168 | switch (locationType) {
169 | case "Area":
170 | return { type: "Polygon", coordinates: [parseArea(location)] };
171 | //break;
172 | case "Arrow":
173 | return { type: "LineString", coordinates: parseArrow(location) };
174 | //break;
175 | case "Circle":
176 | return { type: "LineString", coordinates: parseCircle(location) };
177 | //break;
178 | case "Corridor":
179 | return { type: "Corridor", coordinates: parseCorridor(location) }; // We fix Corridors later
180 | //break;
181 | case "Line":
182 | return { type: "LineString", coordinates: parseLine(location) };
183 | //break;
184 | case "Point":
185 | return { type: "Point", coordinates: parsePoint(location) };
186 | //break;
187 | case "PolyPoint":
188 | return { type: "LineString", coordinates: parseLine(location) }; //I know this isn't a line but they are stored in the same way.
189 | //break;
190 | case "Rectangle":
191 | return {
192 | type: "Rectangle",
193 | coordinates: parseTwoPointCorridor(location)
194 | }; // We will fix TwoPointCorridor later
195 | //break;
196 | case "TwoPointArrow":
197 | return {
198 | type: "LineString",
199 | coordinates: parseTwoPointArrow(location)
200 | };
201 | //break;
202 | case "TwoPointCorridor":
203 | return {
204 | type: "TwoPointCorridor",
205 | coordinates: parseTwoPointCorridor(location)
206 | }; // We will fix TwoPointCorridor later
207 | //break;
208 | case "TwoPointLine":
209 | return { type: "LineString", coordinates: parseTwoPointLine(location) };
210 | //break;
211 | default:
212 | console.warn(
213 | "SitaWare Layer File: TODO parse location type " + locationType
214 | );
215 | }
216 | }
217 |
218 | function parseSymbols(symbols) {
219 | var features = [];
220 | for (var i in symbols.childNodes) {
221 | if (symbols.childNodes[i].nodeName == "Symbol") {
222 | var symbol = symbols.childNodes[i];
223 | var symbolType = symbol.getAttribute("xsi:type");
224 | var feature = { type: "Feature", properties: {} };
225 |
226 | if (
227 | [
228 | "Aviation",
229 | "BattlePosition",
230 | "BoundaryLine",
231 | "Equipment",
232 | "GenericShape",
233 | "Incident",
234 | "Installation",
235 | "Minefield",
236 | "TacticalGraphic",
237 | "TextArea",
238 | "Unit"
239 | ].indexOf(symbolType) != -1
240 | ) {
241 | for (var j in symbol.childNodes) {
242 | var nodeName = symbol.childNodes[j].nodeName;
243 | if (typeof nodeName === "undefined") continue;
244 | switch (nodeName) {
245 | case "Location":
246 | feature.geometry = parseLocation(symbol.childNodes[j]);
247 | if (feature.geometry && feature.geometry.type == "Corridor") {
248 | var points = feature.geometry.coordinates;
249 | feature.properties.distance = points[points.length - 1];
250 | points.pop();
251 | feature.geometry = {
252 | type: "LineString",
253 | coordinates: points
254 | };
255 | }
256 | if (feature.geometry && feature.geometry.type == "Rectangle") {
257 | points = feature.geometry.coordinates;
258 | feature.properties.distance = points[points.length - 1];
259 | points.pop();
260 | feature.geometry = {
261 | type: "LineString",
262 | coordinates: points
263 | };
264 | }
265 | if (
266 | feature.geometry &&
267 | feature.geometry.type == "TwoPointCorridor"
268 | ) {
269 | //TODO make sure that we are drawing this in the right direction
270 | points = feature.geometry.coordinates;
271 | var coordinates = [points[0], points[1]];
272 | var width = points[2];
273 | var bearing = ms.geometry.bearingBetween(
274 | points[1],
275 | points[0]
276 | );
277 | coordinates.push(
278 | ms.geometry.toDistanceBearing(
279 | ms.geometry.pointBetween(points[0], points[1], 0.5),
280 | width / 2,
281 | bearing - 90
282 | )
283 | );
284 | //coordinates.push( ms.geometry.toDistanceBearing(points[1],width/2,bearing-90));
285 | //coordinates.push(points[0]);
286 |
287 | feature.geometry = {
288 | type: "LineString",
289 | coordinates: coordinates
290 | };
291 | }
292 | break;
293 | case "SymbolCode":
294 | feature.properties.SymbolCode = parseSIDC(symbol.childNodes[j]);
295 | break;
296 | case "#text":
297 | break;
298 | default:
299 | feature.properties[nodeName] = symbol.childNodes[j].textContent;
300 | }
301 | }
302 | if (typeof feature.geometry !== "undefined") {
303 | features.push(feature);
304 | }
305 | } else {
306 | console.warn(
307 | "SitaWare Layer File: TODO parse symbol type " + symbolType
308 | );
309 | }
310 | }
311 | }
312 | return features;
313 | }
314 |
315 | function parseLayer(layer) {
316 | var features = [];
317 | for (var i in layer.childNodes) {
318 | if (layer.childNodes[i].nodeName == "Name") {
319 | //console.log('LAYER: ' + layer.childNodes[i].textContent);
320 | }
321 | if (layer.childNodes[i].nodeName == "Symbols") {
322 | //console.log(parseSymbols( layer.childNodes[i] ))
323 | features = features.concat(parseSymbols(layer.childNodes[i]));
324 | }
325 | }
326 | return features;
327 | }
328 |
329 | if (typeof xml == "string") {
330 | xml = new DOMParser().parseFromString(xml, "text/xml");
331 | }
332 |
333 | var layers = xml.getElementsByTagName("Layer"); // For SLF files
334 | for (var lyr in layers) {
335 | features = features.concat(parseLayer(layers[lyr]));
336 | }
337 | layers = xml.getElementsByTagName("Overlay"); // For SPF files
338 | for (lyr in layers) {
339 | features = features.concat(parseLayer(layers[lyr]));
340 | }
341 |
342 | // Fix circles
343 | for (var f in features) {
344 | var sidc = features[f].properties.SymbolCode;
345 | var genericSIDC =
346 | sidc.substr(0, 1) + "-" + sidc.substr(2, 1) + "-" + sidc.substr(4, 6);
347 | if (
348 | [
349 | "G-F-ATC---",
350 | "G-F-ACSC--",
351 | "G-F-ACAC--",
352 | "G-F-ACFC--",
353 | "G-F-ACNC--",
354 | "G-F-ACRC--",
355 | "G-F-ACPC--",
356 | "G-F-AZIC--",
357 | "G-F-AZXC--",
358 | "G-F-AZSC--",
359 | "G-F-AZCC--",
360 | "G-F-AZDC--",
361 | "G-F-AZFC--",
362 | "G-F-AZZC--",
363 | "G-F-AZBC--",
364 | "G-F-AZVC--",
365 | "X---I-----"
366 | ].indexOf(genericSIDC) != -1
367 | ) {
368 | var points = features[f].geometry.coordinates;
369 | features[f].properties.distance = ms.geometry.distanceBetween(
370 | points[0],
371 | points[1]
372 | );
373 | features[f].geometry = { type: "Point", coordinates: points[0] };
374 | }
375 | }
376 |
377 | var rawGeoJSON = { type: "FeatureCollection", features: features };
378 | return ms.format.GeoJSON(rawGeoJSON, {
379 | Aliases: "commonIdentifier",
380 | Name: "uniqueDesignation",
381 | StaffComments: "staffComments",
382 | SymbolCode: "sidc",
383 | Timestamp: "dtg"
384 | });
385 | }
386 |
387 | if (typeof module !== "undefined") {
388 | module.exports = SLF;
389 | }
390 |
--------------------------------------------------------------------------------
/src/geometry.js:
--------------------------------------------------------------------------------
1 | var geometry = {};
2 |
3 | geometry.bearingBetween = require("./geometry/bearingbetween.js");
4 | geometry.circle = require("./geometry/circle.js");
5 | geometry.circleCorridorPolygon = require("./geometry/circlecorridorpolygon.js");
6 | geometry.corridor = require("./geometry/corridor.js");
7 | geometry.distanceBetween = require("./geometry/distancebetween.js");
8 | geometry.pointBetween = require("./geometry/pointbetween.js");
9 | geometry.rectangle = require("./geometry/rectangle.js");
10 | geometry.toDistanceBearing = require("./geometry/todistancebearing.js");
11 |
12 | module.exports = geometry;
13 |
--------------------------------------------------------------------------------
/src/geometry/bearingbetween.js:
--------------------------------------------------------------------------------
1 | // Calculates the bearing between two points in meter
2 | function bearingBetween(p1, p2) {
3 | var l1 = p1[0] * (Math.PI / 180);
4 | var l2 = p2[0] * (Math.PI / 180);
5 | var f1 = p1[1] * (Math.PI / 180);
6 | var f2 = p2[1] * (Math.PI / 180);
7 | var y = Math.sin(l2 - l1) * Math.cos(f2);
8 | var x =
9 | Math.cos(f1) * Math.sin(f2) -
10 | Math.sin(f1) * Math.cos(f2) * Math.cos(l2 - l1);
11 | return Math.atan2(y, x) / (Math.PI / 180);
12 | }
13 |
14 | module.exports = bearingBetween;
15 |
--------------------------------------------------------------------------------
/src/geometry/circle.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a circle withe a radius in meters
4 | module.exports = function(feature) {
5 | var p = feature.geometry.coordinates;
6 | var r = feature.properties.distance;
7 | var geometry = { type: "Polygon" };
8 | geometry.coordinates = [[]];
9 | for (var direction = 360; direction >= 0; direction -= 5) {
10 | geometry.coordinates[0].push(
11 | ms.geometry.toDistanceBearing(p, r, direction)
12 | );
13 | }
14 | return { geometry: geometry };
15 | };
16 |
--------------------------------------------------------------------------------
/src/geometry/circlecorridorpolygon.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | module.exports = function(feature) {
4 | var annotation = {};
5 | var geometry;
6 | annotation.geometry = { type: "Point" };
7 |
8 | switch (feature.geometry.type) {
9 | case "Point":
10 | geometry = ms.geometry.circle(feature).geometry;
11 | annotation.geometry.coordinates = feature.geometry.coordinates;
12 | break;
13 | case "LineString":
14 | geometry = ms.geometry.rectangle(feature).geometry;
15 | annotation.geometry.coordinates = ms.geometry.pointBetween(
16 | feature.geometry.coordinates[0],
17 | feature.geometry.coordinates[1],
18 | 0.5
19 | );
20 | break;
21 | case "Polygon":
22 | geometry = { type: feature.geometry.type };
23 | geometry.coordinates = feature.geometry.coordinates;
24 | // add annotation geometry
25 | break;
26 | default:
27 | console.warn("Invalid feature type in SIDC: " + feature.properties.sidc);
28 | }
29 |
30 | return { annotation: annotation, geometry: geometry };
31 | };
32 |
--------------------------------------------------------------------------------
/src/geometry/corridor.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a corridor with a widht in meters
4 | function corridor(feature) {
5 | var direction;
6 | var points = feature.geometry.coordinates;
7 | var width = feature.properties.distance;
8 | var geometry = { type: "Polygon" };
9 | geometry.coordinates = [[]];
10 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 360) % 360;
11 | geometry.coordinates[0].push(
12 | ms.geometry.toDistanceBearing(points[0], width / 2, direction - 90)
13 | );
14 | for (var j = 1; j < points.length - 1; j++) {
15 | var direction1 =
16 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
17 | var direction2 =
18 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
19 | var factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
20 | geometry.coordinates[0].push(
21 | ms.geometry.toDistanceBearing(
22 | points[j],
23 | width / 2 * factor,
24 | (direction1 + direction2) / 2
25 | )
26 | );
27 | }
28 |
29 | direction =
30 | (ms.geometry.bearingBetween(
31 | points[points.length - 1],
32 | points[points.length - 2]
33 | ) +
34 | 180) %
35 | 360;
36 | geometry.coordinates[0].push(
37 | ms.geometry.toDistanceBearing(
38 | points[points.length - 1],
39 | width / 2,
40 | direction - 90
41 | )
42 | );
43 | geometry.coordinates[0].push(
44 | ms.geometry.toDistanceBearing(
45 | points[points.length - 1],
46 | width / 2,
47 | direction + 90
48 | )
49 | );
50 |
51 | for (j = points.length - 2; j > 0; j--) {
52 | direction1 =
53 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
54 | direction2 =
55 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
56 | factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
57 | geometry.coordinates[0].push(
58 | ms.geometry.toDistanceBearing(
59 | points[j],
60 | -(width / 2) * factor,
61 | (direction1 + direction2) / 2
62 | )
63 | );
64 | }
65 |
66 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 360) % 360;
67 | geometry.coordinates[0].push(
68 | ms.geometry.toDistanceBearing(points[0], width / 2, direction + 90)
69 | );
70 | geometry.coordinates[0].push(
71 | ms.geometry.toDistanceBearing(points[0], width / 2, direction - 90)
72 | ); //Close line
73 | return { geometry: geometry };
74 | }
75 |
76 | module.exports = corridor;
77 |
--------------------------------------------------------------------------------
/src/geometry/distancebetween.js:
--------------------------------------------------------------------------------
1 | // Calculates the great circle distance between two points in meter
2 | function distanceBetween(p1, p2) {
3 | var lng1 = p1[0];
4 | var lng2 = p2[0];
5 | var lat1 = p1[1];
6 | var lat2 = p2[1];
7 |
8 | var latRad1 = lat1 * (Math.PI / 180);
9 | var latRad2 = lat2 * (Math.PI / 180);
10 | var deltaLat = (lat2 - lat1) * (Math.PI / 180);
11 | var delataLng = (lng2 - lng1) * (Math.PI / 180);
12 |
13 | var a =
14 | Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
15 | Math.cos(latRad1) *
16 | Math.cos(latRad2) *
17 | Math.sin(delataLng / 2) *
18 | Math.sin(delataLng / 2);
19 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
20 | return (6371e3 * c).toFixed(1); // we don't expect more precision than this...
21 | }
22 |
23 | module.exports = distanceBetween;
24 |
--------------------------------------------------------------------------------
/src/geometry/pointbetween.js:
--------------------------------------------------------------------------------
1 | // Calculates a point between two other points at any fractional distance f between them
2 | function pointBetween(p1, p2, f) {
3 | var lng1 = p1[0];
4 | var lng2 = p2[0];
5 | var lat1 = p1[1];
6 | var lat2 = p2[1];
7 |
8 | var lngRad1 = lng1 * (Math.PI / 180);
9 | var lngRad2 = lng2 * (Math.PI / 180);
10 | var latRad1 = lat1 * (Math.PI / 180);
11 | var latRad2 = lat2 * (Math.PI / 180);
12 |
13 | var deltaLat = (lat2 - lat1) * (Math.PI / 180);
14 | var delataLng = (lng2 - lng1) * (Math.PI / 180);
15 | var a =
16 | Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
17 | Math.cos(latRad1) *
18 | Math.cos(latRad2) *
19 | Math.sin(delataLng / 2) *
20 | Math.sin(delataLng / 2);
21 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); // Angular distance
22 |
23 | var A = Math.sin((1 - f) * c) / Math.sin(c);
24 | var B = Math.sin(f * c) / Math.sin(c);
25 |
26 | var x =
27 | A * Math.cos(latRad1) * Math.cos(lngRad1) +
28 | B * Math.cos(latRad2) * Math.cos(lngRad2);
29 | var y =
30 | A * Math.cos(latRad1) * Math.sin(lngRad1) +
31 | B * Math.cos(latRad2) * Math.sin(lngRad2);
32 | var z = A * Math.sin(latRad1) + B * Math.sin(latRad2);
33 |
34 | var lng3 = Math.atan2(y, x) / (Math.PI / 180);
35 | var lat3 =
36 | (Math.atan2(z, Math.sqrt(x * x + y * y)) / (Math.PI / 180) + 540) % 360 -
37 | 180;
38 |
39 | return [lng3, lat3];
40 | }
41 |
42 | module.exports = pointBetween;
43 |
--------------------------------------------------------------------------------
/src/geometry/rectangle.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws rectangle from input feature
4 | module.exports = function(feature) {
5 | // A rectangle is just a two point corridor
6 | return ms.geometry.corridor(feature);
7 | };
8 |
--------------------------------------------------------------------------------
/src/geometry/todistancebearing.js:
--------------------------------------------------------------------------------
1 | // Calculates the bearing between two points in meter
2 | function toDistanceBearing(point, dist, bearing) {
3 | var angularDist = dist / 6371e3;
4 | bearing = bearing * (Math.PI / 180);
5 | var lng = point[0] * (Math.PI / 180);
6 | var lat = point[1] * (Math.PI / 180);
7 | var lat2 = Math.asin(
8 | Math.sin(lat) * Math.cos(angularDist) +
9 | Math.cos(lat) * Math.sin(angularDist) * Math.cos(bearing)
10 | );
11 | var lng2 =
12 | lng +
13 | Math.atan2(
14 | Math.sin(bearing) * Math.sin(angularDist) * Math.cos(lat),
15 | Math.cos(angularDist) - Math.sin(lat) * Math.sin(lat2)
16 | );
17 | lat2 = lat2 / (Math.PI / 180);
18 | lng2 = (lng2 / (Math.PI / 180) + 540) % 360 - 180;
19 | return [lng2, lat2];
20 | }
21 |
22 | module.exports = toDistanceBearing;
23 |
--------------------------------------------------------------------------------
/src/geometryconverter.js:
--------------------------------------------------------------------------------
1 | var geometryConverter = {};
2 |
3 | geometryConverter[
4 | "AIRSPACE COORDINATION AREA"
5 | ] = require("./geometryconverter/airspace-coordination-area.js");
6 | geometryConverter["AMBUSH"] = require("./geometryconverter/ambush.js");
7 | geometryConverter[
8 | "ARTILLERY TARGET INTELLIGENCE ZONE"
9 | ] = require("./geometryconverter/artillery-target-intelligence-zone.js");
10 | geometryConverter["BLOCK"] = require("./geometryconverter/block.js");
11 | geometryConverter["BREACH"] = require("./geometryconverter/breach.js");
12 | geometryConverter["BYPASS"] = require("./geometryconverter/bypass.js");
13 | geometryConverter[
14 | "CALL FOR FIRE ZONE"
15 | ] = require("./geometryconverter/call-for-fire-zone.js");
16 | geometryConverter["CANALIZE"] = require("./geometryconverter/canalize.js");
17 | geometryConverter[
18 | "CENSOR ZONE"
19 | ] = require("./geometryconverter/censor-zone.js");
20 | //geometryConverter.circle = require("./geometryconverter/circle.js");
21 | geometryConverter["CLEAR"] = require("./geometryconverter/clear.js");
22 | geometryConverter.corridor = require("./geometryconverter/corridor.js");
23 | geometryConverter.cover = require("./geometryconverter/cover.js");
24 | geometryConverter[
25 | "CRITICAL FRIENDLY ZONE"
26 | ] = require("./geometryconverter/critical-friendly-zone.js");
27 | geometryConverter[
28 | "DEAD SPACE AREA"
29 | ] = require("./geometryconverter/dead-space-area.js");
30 | geometryConverter["DELAY"] = require("./geometryconverter/delay.js");
31 | geometryConverter[
32 | "FIRE SUPPORT AREA"
33 | ] = require("./geometryconverter/fire-support-area.js");
34 | geometryConverter["FIX"] = require("./geometryconverter/fix.js");
35 | geometryConverter[
36 | "FREE FIRE AREA"
37 | ] = require("./geometryconverter/free-fire-area.js");
38 | geometryConverter.guard = require("./geometryconverter/guard.js");
39 | geometryConverter["ISOLATE"] = require("./geometryconverter/isolate.js");
40 | geometryConverter[
41 | "MAIN ATTACK"
42 | ] = require("./geometryconverter/main-attack.js");
43 | geometryConverter[
44 | "NAMED AREA OF INTEREST"
45 | ] = require("./geometryconverter/named-area-of-interest.js");
46 | geometryConverter.occupy = require("./geometryconverter/occupy.js");
47 | geometryConverter[
48 | "RESTRICTIVE FIRE AREA"
49 | ] = require("./geometryconverter/restrictive-fire-area.js");
50 | geometryConverter.searchArea = require("./geometryconverter/search-area.js");
51 | geometryConverter[
52 | "SENSOR ZONE"
53 | ] = require("./geometryconverter/sensor-zone.js");
54 | geometryConverter[
55 | "SUPPORTING ATTACK"
56 | ] = require("./geometryconverter/supporting-attack.js");
57 | geometryConverter[
58 | "TARGET BUILD-UP AREA"
59 | ] = require("./geometryconverter/target-build-up-area.js");
60 | geometryConverter[
61 | "TARGET VALUE AREA"
62 | ] = require("./geometryconverter/target-value-area.js");
63 | geometryConverter[
64 | "TARGETED AREA OF INTEREST"
65 | ] = require("./geometryconverter/targeted-area-of-interest.js");
66 | geometryConverter[
67 | "TERMINALLY GUIDED MUNITION FOOTPRINT"
68 | ] = require("./geometryconverter/terminally-guided-munition-footprint.js");
69 | geometryConverter[
70 | "ZONE OF RESPONSIBILITY"
71 | ] = require("./geometryconverter/zone-of-responsibility.js");
72 |
73 | module.exports = geometryConverter;
74 |
--------------------------------------------------------------------------------
/src/geometryconverter/airspace-coordination-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a NAI
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "ACA";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.altitudeDepth)
15 | annotations[0].properties.text +=
16 | "\nMIN ALT: " + feature.properties.altitudeDepth;
17 | if (feature.properties.altitudeDepth1)
18 | annotations[0].properties.text +=
19 | "\nMAX ALT: " + feature.properties.altitudeDepth1;
20 | if (feature.properties.additionalInformation1)
21 | annotations[0].properties.text +=
22 | "\nGrids " + feature.properties.additionalInformation1;
23 | if (feature.properties.dtg)
24 | annotations[0].properties.text += "\nEFF: " + feature.properties.dtg;
25 | if (feature.properties.dtg1)
26 | annotations[0].properties.text += "\n- " + feature.properties.dtg1;
27 |
28 | var polygon = ms.geometry.circleCorridorPolygon(feature);
29 | geometry = polygon.geometry;
30 | if (polygon.annotation.hasOwnProperty("geometry")) {
31 | annotations[0].geometry = polygon.annotation.geometry;
32 | }
33 |
34 | return { geometry: geometry, annotations: annotations };
35 | };
36 |
--------------------------------------------------------------------------------
/src/geometryconverter/ambush.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function block(feature) {
4 | var geom;
5 | var points = feature.geometry.coordinates;
6 | var geometry = { type: "MultiLineString" };
7 | geometry.coordinates = [];
8 |
9 | var midpoint = ms.geometry.pointBetween(points[1], points[2], 0.5);
10 | var bearing1 = (ms.geometry.bearingBetween(points[1], points[2]) + 360) % 360;
11 | var bearing2 = (ms.geometry.bearingBetween(points[1], points[0]) + 360) % 360;
12 |
13 | var distance =
14 | Math.sin((bearing1 - bearing2) * (Math.PI / 180)) *
15 | ms.geometry.distanceBetween(points[0], points[1]);
16 | if (distance < 0) {
17 | // Wrong order in input
18 | points = [points[0], points[2], points[1]];
19 | bearing1 = (ms.geometry.bearingBetween(points[1], points[2]) + 360) % 360;
20 | bearing2 = (ms.geometry.bearingBetween(points[1], points[0]) + 360) % 360;
21 | distance = -distance;
22 | }
23 | var rotationpoint = ms.geometry.toDistanceBearing(
24 | midpoint,
25 | distance,
26 | bearing1 + 90
27 | );
28 | var radius = ms.geometry.distanceBetween(rotationpoint, points[1]);
29 | var b1 = (ms.geometry.bearingBetween(rotationpoint, points[1]) + 360) % 360;
30 | var b2 = (ms.geometry.bearingBetween(rotationpoint, points[2]) + 360) % 360;
31 | if (b1 > b2) {
32 | b2 = b2 + 360;
33 | }
34 | var midAngle = (b1 + b2) / 2;
35 | var tip = ms.geometry.toDistanceBearing(
36 | rotationpoint,
37 | distance * 2,
38 | midAngle
39 | );
40 | var b3 = (ms.geometry.bearingBetween(tip, rotationpoint) + 360) % 360;
41 |
42 | // Arc
43 | geom = [];
44 | geom.push(points[1]);
45 |
46 | for (var i = b1; i <= b2; i += 5) {
47 | geom.push(ms.geometry.toDistanceBearing(rotationpoint, radius, i));
48 | }
49 | geom.push(points[2]);
50 | geometry.coordinates.push(geom);
51 |
52 | // Lines
53 | var diff = (b2 - b1) / 7;
54 | var p1, p2;
55 | for (i = 1; i <= 6; i++) {
56 | geom = [];
57 | p1 = ms.geometry.toDistanceBearing(rotationpoint, radius, b1 + diff * i);
58 | p2 = ms.geometry.toDistanceBearing(p1, distance * 0.3, b3);
59 | geom.push(p1, p2);
60 | geometry.coordinates.push(geom);
61 | }
62 |
63 | // Arrow
64 | geom = [];
65 | geom.push(ms.geometry.toDistanceBearing(rotationpoint, radius, midAngle));
66 | geom.push(
67 | ms.geometry.toDistanceBearing(rotationpoint, distance * 2, midAngle)
68 | );
69 | geometry.coordinates.push(geom);
70 |
71 | // Arrow head
72 | geom = [];
73 | geom.push(ms.geometry.toDistanceBearing(tip, distance * 0.2, b3 + 45));
74 | geom.push(tip);
75 | geom.push(ms.geometry.toDistanceBearing(tip, distance * 0.2, b3 - 45));
76 | geometry.coordinates.push(geom);
77 |
78 | return { geometry: geometry };
79 | }
80 |
81 | module.exports = block;
82 |
--------------------------------------------------------------------------------
/src/geometryconverter/artillery-target-intelligence-zone.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "ATI ZONE";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | /*if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;*/
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/block.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function block(feature) {
4 | //var direction, width;
5 | var annotations = [{}];
6 | var points = feature.geometry.coordinates;
7 |
8 | var geometry = { type: "MultiLineString" };
9 | geometry.coordinates = [];
10 |
11 | var geometry1 = [];
12 | geometry1.push(points[0], points[1]);
13 |
14 | var geometry2 = [];
15 | var midpoint = ms.geometry.pointBetween(points[0], points[1], 0.5);
16 | geometry2.push(points[2], midpoint);
17 |
18 | geometry.coordinates = [geometry1, geometry2];
19 |
20 | annotations[0].geometry = { type: "Point" };
21 | annotations[0].properties = {};
22 | annotations[0].properties.text = "B";
23 | annotations[0].geometry.coordinates = ms.geometry.pointBetween(
24 | midpoint,
25 | points[2],
26 | 0.5
27 | );
28 |
29 | return { geometry: geometry, annotations: annotations };
30 | }
31 |
32 | module.exports = block;
33 |
--------------------------------------------------------------------------------
/src/geometryconverter/breach.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function canalize(feature) {
4 | //var direction, width;
5 | var annotations = [{}];
6 |
7 | var points = feature.geometry.coordinates;
8 | var geometry = { type: "MultiLineString" };
9 | var scale = ms.geometry.distanceBetween(points[0], points[1]);
10 | var pMid = ms.geometry.pointBetween(points[0], points[1], 0.5);
11 | var length = ms.geometry.distanceBetween(pMid, points[2]);
12 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
13 |
14 | geometry.coordinates = [];
15 |
16 | var geom = [points[0]];
17 | geom.push(ms.geometry.toDistanceBearing(points[0], length, bearing + 90));
18 | geom.push(ms.geometry.toDistanceBearing(points[1], length, bearing + 90));
19 | geom.push(points[1]);
20 | geometry.coordinates.push(geom);
21 |
22 | geom = [];
23 | geom.push(
24 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing - 45)
25 | );
26 | geom.push(
27 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing - 45 + 180)
28 | );
29 | geometry.coordinates.push(geom);
30 |
31 | geom = [];
32 | geom.push(
33 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing + 45)
34 | );
35 | geom.push(
36 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing + 45 + 180)
37 | );
38 | geometry.coordinates.push(geom);
39 |
40 | annotations[0].geometry = { type: "Point" };
41 | annotations[0].properties = {};
42 | annotations[0].properties.text = "B";
43 | annotations[0].geometry.coordinates = points[2];
44 |
45 | return { geometry: geometry, annotations: annotations };
46 | }
47 |
48 | module.exports = canalize;
49 |
--------------------------------------------------------------------------------
/src/geometryconverter/bypass.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function bypass(feature) {
4 | //var direction, width;
5 | var annotations = [{}];
6 |
7 | var points = feature.geometry.coordinates;
8 | var geometry = { type: "MultiLineString" };
9 | var scale = ms.geometry.distanceBetween(points[0], points[1]);
10 | var pMid = ms.geometry.pointBetween(points[0], points[1], 0.5);
11 | var length = ms.geometry.distanceBetween(pMid, points[2]);
12 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
13 |
14 | geometry.coordinates = [];
15 |
16 | var geom = [points[0]];
17 | geom.push(ms.geometry.toDistanceBearing(points[0], length, bearing + 90));
18 | geom.push(ms.geometry.toDistanceBearing(points[1], length, bearing + 90));
19 | geom.push(points[1]);
20 | geometry.coordinates.push(geom);
21 |
22 | geom = [];
23 | geom.push(
24 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing + 90 - 30)
25 | );
26 | geom.push(points[0]);
27 | geom.push(
28 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing + 90 + 30)
29 | );
30 | geometry.coordinates.push(geom);
31 |
32 | geom = [];
33 | geom.push(
34 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing + 90 - 30)
35 | );
36 | geom.push(points[1]);
37 | geom.push(
38 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing + 90 + 30)
39 | );
40 | geometry.coordinates.push(geom);
41 |
42 | annotations[0].geometry = { type: "Point" };
43 | annotations[0].properties = {};
44 | annotations[0].properties.text = "B";
45 | annotations[0].geometry.coordinates = points[2];
46 |
47 | return { geometry: geometry, annotations: annotations };
48 | }
49 |
50 | module.exports = bypass;
51 |
--------------------------------------------------------------------------------
/src/geometryconverter/call-for-fire-zone.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "CFF ZONE";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | /*if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;*/
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/canalize.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function canalize(feature) {
4 | //var direction, width;
5 | var annotations = [{}];
6 |
7 | var points = feature.geometry.coordinates;
8 | var geometry = { type: "MultiLineString" };
9 | var scale = ms.geometry.distanceBetween(points[0], points[1]);
10 | var pMid = ms.geometry.pointBetween(points[0], points[1], 0.5);
11 | var length = ms.geometry.distanceBetween(pMid, points[2]);
12 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
13 |
14 | geometry.coordinates = [];
15 |
16 | var geom = [points[0]];
17 | geom.push(ms.geometry.toDistanceBearing(points[0], length, bearing + 90));
18 | geom.push(ms.geometry.toDistanceBearing(points[1], length, bearing + 90));
19 | geom.push(points[1]);
20 | geometry.coordinates.push(geom);
21 |
22 | geom = [];
23 | geom.push(
24 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing + 45)
25 | );
26 | geom.push(
27 | ms.geometry.toDistanceBearing(points[0], scale * 0.2, bearing + 45 + 180)
28 | );
29 | geometry.coordinates.push(geom);
30 |
31 | geom = [];
32 | geom.push(
33 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing - 45)
34 | );
35 | geom.push(
36 | ms.geometry.toDistanceBearing(points[1], scale * 0.2, bearing - 45 + 180)
37 | );
38 | geometry.coordinates.push(geom);
39 |
40 | annotations[0].geometry = { type: "Point" };
41 | annotations[0].properties = {};
42 | annotations[0].properties.text = "C";
43 | annotations[0].geometry.coordinates = points[2];
44 |
45 | return { geometry: geometry, annotations: annotations };
46 | }
47 |
48 | module.exports = canalize;
49 |
--------------------------------------------------------------------------------
/src/geometryconverter/censor-zone.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "CENSOR ZONE";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/circle.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a circle withe a radius in meters
4 | module.exports = function(feature) {
5 | var p = feature.geometry.coordinates;
6 | var r = feature.properties.distance;
7 | var geometry = { type: "Polygon" };
8 | geometry.coordinates = [[]];
9 | for (var direction = 360; direction >= 0; direction -= 5) {
10 | geometry.coordinates[0].push(
11 | ms.geometry.toDistanceBearing(p, r, direction)
12 | );
13 | }
14 | return { geometry: geometry };
15 | };
16 |
--------------------------------------------------------------------------------
/src/geometryconverter/clear.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function clear(feature) {
4 | //var direction, width;
5 | var annotations = [{}];
6 |
7 | var points = feature.geometry.coordinates;
8 | var geometry = { type: "MultiLineString" };
9 | var scale = ms.geometry.distanceBetween(points[0], points[1]);
10 |
11 | geometry.coordinates = [];
12 |
13 | var geom = [points[0], points[1]];
14 | geometry.coordinates.push(geom);
15 |
16 | var pMid = ms.geometry.pointBetween(points[0], points[1], 0.5);
17 | var length = ms.geometry.distanceBetween(pMid, points[2]);
18 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
19 |
20 | geom = [pMid, ms.geometry.toDistanceBearing(pMid, length, bearing + 90)];
21 | geometry.coordinates.push(geom);
22 |
23 | annotations[0].geometry = { type: "Point" };
24 | annotations[0].properties = {};
25 | annotations[0].properties.text = "C";
26 | annotations[0].geometry.coordinates = ms.geometry.pointBetween(
27 | pMid,
28 | geom[1],
29 | 0.5
30 | );
31 |
32 | geom = [];
33 | geom.push(ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60));
34 | geom.push(pMid);
35 | geom.push(
36 | ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60 + 60)
37 | );
38 | geometry.coordinates.push(geom);
39 |
40 | pMid = ms.geometry.pointBetween(points[0], points[1], 0.2);
41 | geom = [pMid, ms.geometry.toDistanceBearing(pMid, length, bearing + 90)];
42 | geometry.coordinates.push(geom);
43 |
44 | geom = [];
45 | geom.push(ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60));
46 | geom.push(pMid);
47 | geom.push(
48 | ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60 + 60)
49 | );
50 | geometry.coordinates.push(geom);
51 |
52 | pMid = ms.geometry.pointBetween(points[0], points[1], 0.8);
53 | geom = [pMid, ms.geometry.toDistanceBearing(pMid, length, bearing + 90)];
54 | geometry.coordinates.push(geom);
55 |
56 | geom = [];
57 | geom.push(ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60));
58 | geom.push(pMid);
59 | geom.push(
60 | ms.geometry.toDistanceBearing(pMid, scale * 0.15, bearing + 60 + 60)
61 | );
62 | geometry.coordinates.push(geom);
63 |
64 | return { geometry: geometry, annotations: annotations };
65 | }
66 |
67 | module.exports = clear;
68 |
--------------------------------------------------------------------------------
/src/geometryconverter/corridor.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a corridor with a widht in meters
4 | function corridor(feature) {
5 | var direction;
6 | var points = feature.geometry.coordinates;
7 | var width = feature.properties.distance;
8 | var geometry = { type: "Polygon" };
9 | geometry.coordinates = [[]];
10 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 360) % 360;
11 | geometry.coordinates[0].push(
12 | ms.geometry.toDistanceBearing(points[0], width / 2, direction - 90)
13 | );
14 | for (var j = 1; j < points.length - 1; j++) {
15 | var direction1 =
16 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
17 | var direction2 =
18 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
19 | var factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
20 | geometry.coordinates[0].push(
21 | ms.geometry.toDistanceBearing(
22 | points[j],
23 | width / 2 * factor,
24 | (direction1 + direction2) / 2
25 | )
26 | );
27 | }
28 |
29 | direction =
30 | (ms.geometry.bearingBetween(
31 | points[points.length - 1],
32 | points[points.length - 2]
33 | ) +
34 | 180) %
35 | 360;
36 | geometry.coordinates[0].push(
37 | ms.geometry.toDistanceBearing(
38 | points[points.length - 1],
39 | width / 2,
40 | direction - 90
41 | )
42 | );
43 | geometry.coordinates[0].push(
44 | ms.geometry.toDistanceBearing(
45 | points[points.length - 1],
46 | width / 2,
47 | direction + 90
48 | )
49 | );
50 |
51 | for (j = points.length - 2; j > 0; j--) {
52 | direction1 =
53 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
54 | direction2 =
55 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
56 | factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
57 | geometry.coordinates[0].push(
58 | ms.geometry.toDistanceBearing(
59 | points[j],
60 | -(width / 2) * factor,
61 | (direction1 + direction2) / 2
62 | )
63 | );
64 | }
65 |
66 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 360) % 360;
67 | geometry.coordinates[0].push(
68 | ms.geometry.toDistanceBearing(points[0], width / 2, direction + 90)
69 | );
70 | geometry.coordinates[0].push(
71 | ms.geometry.toDistanceBearing(points[0], width / 2, direction - 90)
72 | ); //Close line
73 | return { geometry: geometry };
74 | }
75 |
76 | module.exports = corridor;
77 |
--------------------------------------------------------------------------------
/src/geometryconverter/cover.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a circle withe a radius in meters
4 | function cover(feature) {
5 | var p = feature.geometry.coordinates;
6 | var scale = Math.max(
7 | ms.geometry.distanceBetween(p[0], p[1]),
8 | ms.geometry.distanceBetween(p[0], p[2])
9 | );
10 | var geometry = { type: "MultiLineString" };
11 | geometry.coordinates = [[]];
12 |
13 | var geom = [];
14 | var pMid = ms.geometry.pointBetween(p[0], p[1], 0.5);
15 | var bearing = ms.geometry.bearingBetween(p[0], p[1]);
16 | geom.push(p[0]);
17 | geom.push(
18 | ms.geometry.toDistanceBearing(pMid, scale * 0.05, bearing + (120 - 180))
19 | );
20 | var pMid2 = ms.geometry.toDistanceBearing(pMid, scale * 0.05, bearing + 120);
21 | geom.push(pMid2);
22 | geom.push(p[1]);
23 | geometry.coordinates.push(geom);
24 |
25 | geom = [];
26 | bearing = ms.geometry.bearingBetween(p[1], pMid2);
27 | geom.push(ms.geometry.toDistanceBearing(p[1], scale * 0.08, bearing - 45));
28 | geom.push(p[1]);
29 | geom.push(ms.geometry.toDistanceBearing(p[1], scale * 0.08, bearing + 45));
30 | geometry.coordinates.push(geom);
31 |
32 | geom = [];
33 | pMid = ms.geometry.pointBetween(p[0], p[2], 0.5);
34 | bearing = ms.geometry.bearingBetween(p[0], p[2]);
35 | geom.push(p[0]);
36 | geom.push(
37 | ms.geometry.toDistanceBearing(pMid, scale * 0.05, bearing + (120 - 180))
38 | );
39 | pMid2 = ms.geometry.toDistanceBearing(pMid, scale * 0.05, bearing + 120);
40 | geom.push(pMid2);
41 | geom.push(p[2]);
42 | geometry.coordinates.push(geom);
43 |
44 | geom = [];
45 | bearing = ms.geometry.bearingBetween(p[2], pMid2);
46 | geom.push(ms.geometry.toDistanceBearing(p[2], scale * 0.08, bearing - 45));
47 | geom.push(p[2]);
48 | geom.push(ms.geometry.toDistanceBearing(p[2], scale * 0.08, bearing + 45));
49 | geometry.coordinates.push(geom);
50 |
51 | return { geometry: geometry };
52 | }
53 |
54 | module.exports = cover;
55 |
--------------------------------------------------------------------------------
/src/geometryconverter/critical-friendly-zone.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "CF ZONE";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/dead-space-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "DA";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/delay.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function delay(feature) {
4 | var annotations = [{}];
5 | var directionFactor = -1;
6 | var points = feature.geometry.coordinates;
7 |
8 | var width = ms.geometry.distanceBetween(points[1], points[2]);
9 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
10 |
11 | var geometry = { type: "MultiLineString" };
12 |
13 | geometry.coordinates = [];
14 |
15 | var geometry1 = [];
16 | geometry1.push(points[0]);
17 | geometry1.push(points[1]);
18 | //console.log('arrow bearing ' + bearing)
19 | //console.log('fjomp bearing ' + ms.geometry.bearingBetween(points[1],points[2]))
20 |
21 | var midpoint = ms.geometry.pointBetween(points[1], points[2], 0.5);
22 | var curveBearing = ms.geometry.bearingBetween(points[1], points[2]);
23 | if (curveBearing < 0 && bearing < 0) directionFactor = 1; // OK
24 | //if (curveBearing > 0 && bearing < 0)directionFactor = -1; // OK
25 | //if (curveBearing < 0 && bearing > 0)directionFactor = -1; // OK
26 | //if (curveBearing > 0 && bearing > 0)directionFactor = -1; // OK
27 | //var directionFactor = (Math.abs(curveBearing)/curveBearing)*(Math.abs(bearing)/bearing);
28 |
29 | for (var i = 10; i < 180; i += 10) {
30 | geometry1.push(
31 | ms.geometry.toDistanceBearing(
32 | midpoint,
33 | width / 2,
34 | curveBearing + i * directionFactor + 180
35 | )
36 | );
37 | }
38 |
39 | geometry1.push(points[2]);
40 |
41 | var geometry2 = [];
42 | geometry2.push(
43 | ms.geometry.toDistanceBearing(points[0], width * 0.4, bearing + 45)
44 | );
45 | geometry2.push(points[0]);
46 | geometry2.push(
47 | ms.geometry.toDistanceBearing(points[0], width * 0.4, bearing - 45)
48 | );
49 |
50 | geometry.coordinates = [geometry1, geometry2];
51 |
52 | annotations[0].geometry = { type: "Point" };
53 | annotations[0].properties = {};
54 | annotations[0].properties.text = feature.properties.dtg
55 | ? feature.properties.dtg + "\n"
56 | : "";
57 | annotations[0].properties.text += "D";
58 | annotations[0].geometry.coordinates = ms.geometry.pointBetween(
59 | points[0],
60 | points[1],
61 | 0.5
62 | );
63 |
64 | return { geometry: geometry, annotations: annotations };
65 | }
66 |
67 | module.exports = delay;
68 |
--------------------------------------------------------------------------------
/src/geometryconverter/fire-support-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text =
11 | "FSA " + (feature.properties.uniqueDesignation || "");
12 | if (feature.properties.dtg)
13 | annotations[0].properties.text += "\n" + feature.properties.dtg;
14 | if (feature.properties.dtg1)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
16 |
17 | var polygon = ms.geometry.circleCorridorPolygon(feature);
18 | geometry = polygon.geometry;
19 | if (polygon.annotation.hasOwnProperty("geometry")) {
20 | annotations[0].geometry = polygon.annotation.geometry;
21 | }
22 |
23 | return { geometry: geometry, annotations: annotations };
24 | };
25 |
--------------------------------------------------------------------------------
/src/geometryconverter/fix.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function fix(feature) {
4 | //var direction, width;
5 | var points = feature.geometry.coordinates;
6 |
7 | var length = ms.geometry.distanceBetween(points[0], points[1]);
8 | var bearing = ms.geometry.bearingBetween(points[0], points[1]);
9 | var widht = length * 0.10;
10 |
11 | var geometry = { type: "MultiLineString" };
12 |
13 | geometry.coordinates = [];
14 |
15 | var geometry1 = [];
16 |
17 | geometry1.push(points[0]);
18 |
19 | geometry1.push(ms.geometry.pointBetween(points[0], points[1], 0.2));
20 |
21 | geometry1.push(
22 | ms.geometry.toDistanceBearing(
23 | ms.geometry.pointBetween(points[0], points[1], 0.25),
24 | widht,
25 | bearing + 90
26 | )
27 | );
28 | geometry1.push(
29 | ms.geometry.toDistanceBearing(
30 | ms.geometry.pointBetween(points[0], points[1], 0.3),
31 | widht,
32 | bearing - 90
33 | )
34 | );
35 | geometry1.push(
36 | ms.geometry.toDistanceBearing(
37 | ms.geometry.pointBetween(points[0], points[1], 0.35),
38 | widht,
39 | bearing + 90
40 | )
41 | );
42 | geometry1.push(
43 | ms.geometry.toDistanceBearing(
44 | ms.geometry.pointBetween(points[0], points[1], 0.4),
45 | widht,
46 | bearing - 90
47 | )
48 | );
49 | geometry1.push(
50 | ms.geometry.toDistanceBearing(
51 | ms.geometry.pointBetween(points[0], points[1], 0.45),
52 | widht,
53 | bearing + 90
54 | )
55 | );
56 | geometry1.push(
57 | ms.geometry.toDistanceBearing(
58 | ms.geometry.pointBetween(points[0], points[1], 0.5),
59 | widht,
60 | bearing - 90
61 | )
62 | );
63 | geometry1.push(
64 | ms.geometry.toDistanceBearing(
65 | ms.geometry.pointBetween(points[0], points[1], 0.55),
66 | widht,
67 | bearing + 90
68 | )
69 | );
70 | geometry1.push(
71 | ms.geometry.toDistanceBearing(
72 | ms.geometry.pointBetween(points[0], points[1], 0.6),
73 | widht,
74 | bearing - 90
75 | )
76 | );
77 | geometry1.push(
78 | ms.geometry.toDistanceBearing(
79 | ms.geometry.pointBetween(points[0], points[1], 0.65),
80 | widht,
81 | bearing + 90
82 | )
83 | );
84 | geometry1.push(
85 | ms.geometry.toDistanceBearing(
86 | ms.geometry.pointBetween(points[0], points[1], 0.7),
87 | widht,
88 | bearing - 90
89 | )
90 | );
91 | geometry1.push(
92 | ms.geometry.toDistanceBearing(
93 | ms.geometry.pointBetween(points[0], points[1], 0.75),
94 | widht,
95 | bearing + 90
96 | )
97 | );
98 |
99 | geometry1.push(ms.geometry.pointBetween(points[0], points[1], 0.8));
100 |
101 | geometry1.push(points[1]);
102 |
103 | var geometry2 = [];
104 | geometry2.push(
105 | ms.geometry.toDistanceBearing(points[0], widht * 1.5, bearing + 45)
106 | );
107 | geometry2.push(points[0]);
108 | geometry2.push(
109 | ms.geometry.toDistanceBearing(points[0], widht * 1.5, bearing - 45)
110 | );
111 |
112 | geometry.coordinates = [geometry1, geometry2];
113 | return { geometry: geometry };
114 | }
115 |
116 | module.exports = fix;
117 |
--------------------------------------------------------------------------------
/src/geometryconverter/free-fire-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "FFA";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/guard.js:
--------------------------------------------------------------------------------
1 | // Draws a circle withe a radius in meters
2 | function guard(feature) {}
3 |
4 | module.exports = guard;
5 |
--------------------------------------------------------------------------------
/src/geometryconverter/isolate.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a circle withe a radius in meters
4 | function isolate(feature) {
5 | var p = feature.geometry.coordinates;
6 | var r = ms.geometry.distanceBetween(p[0], p[1]);
7 | var bearing = ms.geometry.bearingBetween(p[0], p[1]);
8 |
9 | var geometry = { type: "MultiLineString" };
10 | geometry.coordinates = [[]];
11 | for (var d = 0; d <= 340; d += 5) {
12 | geometry.coordinates[0].push(
13 | ms.geometry.toDistanceBearing(p[0], r, d + bearing)
14 | );
15 | }
16 |
17 | for (d = 20; d <= 320; d += 40) {
18 | var geom = [];
19 | geom.push(ms.geometry.toDistanceBearing(p[0], r, d + bearing));
20 | geom.push(ms.geometry.toDistanceBearing(p[0], r * 0.7, 10 + d + bearing));
21 | geom.push(ms.geometry.toDistanceBearing(p[0], r, 20 + d + bearing));
22 | geometry.coordinates.push(geom);
23 | }
24 |
25 | geom = [];
26 | var pEnd = ms.geometry.toDistanceBearing(p[0], r, 340 + bearing);
27 | geom.push(
28 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing - (90 - 15) + 45)
29 | );
30 | geom.push(pEnd);
31 | geom.push(
32 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing - (90 - 15) - 45)
33 | );
34 | geometry.coordinates.push(geom);
35 |
36 | return { geometry: geometry };
37 | }
38 |
39 | module.exports = isolate;
40 |
--------------------------------------------------------------------------------
/src/geometryconverter/main-attack.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a corridor with a widht in meters
4 | function mainAttack(feature) {
5 | var direction, width;
6 | var points = feature.geometry.coordinates;
7 | var arrowHead = points.pop();
8 | var widthHeadRatio = 0.7;
9 |
10 | var geometry = { type: "MultiLineString" };
11 | geometry.coordinates = [];
12 |
13 | var geometry1 = [];
14 | var geometry2 = [];
15 |
16 | // Width of the arrow
17 | direction = ms.geometry.bearingBetween(points[0], points[1]);
18 | var deltaDirection =
19 | direction - ms.geometry.bearingBetween(points[0], arrowHead);
20 | //console.log(deltaDirection)
21 | var distance = ms.geometry.distanceBetween(points[0], arrowHead);
22 | var arrowHead2 = ms.geometry.toDistanceBearing(
23 | points[0],
24 | distance,
25 | direction + deltaDirection
26 | );
27 | width = ms.geometry.distanceBetween(arrowHead, arrowHead2) / 2;
28 |
29 | direction =
30 | (ms.geometry.bearingBetween(
31 | points[points.length - 1],
32 | points[points.length - 2]
33 | ) +
34 | 360) %
35 | 360;
36 | geometry1.push(
37 | ms.geometry.toDistanceBearing(
38 | points[points.length - 1],
39 | width * widthHeadRatio,
40 | direction - 90
41 | )
42 | );
43 |
44 | for (var j = points.length - 2; j > 0; j--) {
45 | var direction1 =
46 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
47 | var direction2 =
48 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
49 | var factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
50 | geometry1.push(
51 | ms.geometry.toDistanceBearing(
52 | points[j],
53 | width * widthHeadRatio * factor,
54 | (direction1 + direction2) / 2
55 | )
56 | );
57 | }
58 |
59 | // Arrowhead
60 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 180) % 360;
61 | geometry1.push(
62 | ms.geometry.toDistanceBearing(
63 | arrowHead,
64 | width * (1 - widthHeadRatio),
65 | direction + 90
66 | )
67 | );
68 | geometry1.push(arrowHead);
69 | geometry1.push(points[0]);
70 | geometry1.push(arrowHead2);
71 | geometry1.push(
72 | ms.geometry.toDistanceBearing(
73 | arrowHead2,
74 | width * (1 - widthHeadRatio),
75 | direction - 90
76 | )
77 | );
78 |
79 | geometry2.push(
80 | ms.geometry.toDistanceBearing(
81 | arrowHead,
82 | width * (1 - widthHeadRatio),
83 | direction + 90
84 | )
85 | );
86 | geometry2.push(
87 | ms.geometry.toDistanceBearing(
88 | points[0],
89 | width *
90 | (1 - widthHeadRatio) *
91 | Math.abs(1 / Math.tan(deltaDirection * (Math.PI / 180))),
92 | direction - 180
93 | )
94 | );
95 | geometry2.push(
96 | ms.geometry.toDistanceBearing(
97 | arrowHead2,
98 | width * (1 - widthHeadRatio),
99 | direction - 90
100 | )
101 | );
102 |
103 | for (j = 1; j < points.length - 1; j++) {
104 | direction1 =
105 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
106 | direction2 =
107 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
108 | factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
109 | geometry1.push(
110 | ms.geometry.toDistanceBearing(
111 | points[j],
112 | -(width * widthHeadRatio) * factor,
113 | (direction1 + direction2) / 2
114 | )
115 | );
116 | }
117 |
118 | direction =
119 | (ms.geometry.bearingBetween(
120 | points[points.length - 1],
121 | points[points.length - 2]
122 | ) +
123 | 360) %
124 | 360;
125 | geometry1.push(
126 | ms.geometry.toDistanceBearing(
127 | points[points.length - 1],
128 | width * widthHeadRatio,
129 | direction + 90
130 | )
131 | );
132 |
133 | geometry.coordinates = [geometry1, geometry2];
134 | return { geometry: geometry };
135 | }
136 |
137 | module.exports = mainAttack;
138 |
--------------------------------------------------------------------------------
/src/geometryconverter/named-area-of-interest.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a NAI
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "NAI";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 |
15 | var polygon = ms.geometry.circleCorridorPolygon(feature);
16 | geometry = polygon.geometry;
17 | if (polygon.annotation.hasOwnProperty("geometry")) {
18 | annotations[0].geometry = polygon.annotation.geometry;
19 | }
20 |
21 | return { geometry: geometry, annotations: annotations };
22 | };
23 |
--------------------------------------------------------------------------------
/src/geometryconverter/occupy.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a circle withe a radius in meters
4 | function occupy(feature) {
5 | var p = feature.geometry.coordinates;
6 | var r = ms.geometry.distanceBetween(p[0], p[1]);
7 | var bearing = ms.geometry.bearingBetween(p[0], p[1]);
8 |
9 | var geometry = { type: "MultiLineString" };
10 | geometry.coordinates = [[]];
11 | for (var d = 0; d <= 340; d += 5) {
12 | geometry.coordinates[0].push(
13 | ms.geometry.toDistanceBearing(p[0], r, d + bearing)
14 | );
15 | }
16 |
17 | var geom = [];
18 | var pEnd = ms.geometry.toDistanceBearing(p[0], r, 340 + bearing);
19 | geom.push(
20 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing - (90 - 15) + 45)
21 | );
22 | geom.push(pEnd);
23 | geom.push(
24 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing - (90 - 15) - 45)
25 | );
26 | geometry.coordinates.push(geom);
27 |
28 | geom = [];
29 | pEnd = ms.geometry.toDistanceBearing(p[0], r, 340 + bearing);
30 | geom.push(
31 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing + (90 + 15) + 45)
32 | );
33 | geom.push(pEnd);
34 | geom.push(
35 | ms.geometry.toDistanceBearing(pEnd, r * 0.2, 320 + bearing + (90 + 15) - 45)
36 | );
37 | geometry.coordinates.push(geom);
38 |
39 | return { geometry: geometry };
40 | }
41 |
42 | module.exports = occupy;
43 |
--------------------------------------------------------------------------------
/src/geometryconverter/restrictive-fire-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "RFA";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/search-area.js:
--------------------------------------------------------------------------------
1 | // Draws a circle withe a radius in meters
2 | function searchArea(feature) {}
3 |
4 | module.exports = searchArea;
5 |
--------------------------------------------------------------------------------
/src/geometryconverter/sensor-zone.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "SENSOR ZONE";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/supporting-attack.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 | // Draws a corridor with a widht in meters
3 | function supportingAttack(feature) {
4 | var direction, width;
5 | var points = feature.geometry.coordinates;
6 | var arrowHead = points.pop();
7 | var widthHeadRatio = 0.7;
8 |
9 | var geometry = { type: "LineString" };
10 | geometry.coordinates = [];
11 |
12 | var geometry1 = [];
13 |
14 | // Width of the arrow
15 | direction = ms.geometry.bearingBetween(points[0], points[1]);
16 | var deltaDirection =
17 | direction - ms.geometry.bearingBetween(points[0], arrowHead);
18 | //console.log(deltaDirection)
19 | var distance = ms.geometry.distanceBetween(points[0], arrowHead);
20 | var arrowHead2 = ms.geometry.toDistanceBearing(
21 | points[0],
22 | distance,
23 | direction + deltaDirection
24 | );
25 | width = ms.geometry.distanceBetween(arrowHead, arrowHead2) / 2;
26 |
27 | direction =
28 | (ms.geometry.bearingBetween(
29 | points[points.length - 1],
30 | points[points.length - 2]
31 | ) +
32 | 360) %
33 | 360;
34 | geometry1.push(
35 | ms.geometry.toDistanceBearing(
36 | points[points.length - 1],
37 | width * widthHeadRatio,
38 | direction - 90
39 | )
40 | );
41 |
42 | for (var j = points.length - 2; j > 0; j--) {
43 | var direction1 =
44 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
45 | var direction2 =
46 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
47 | var factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
48 | geometry1.push(
49 | ms.geometry.toDistanceBearing(
50 | points[j],
51 | width * widthHeadRatio * factor,
52 | (direction1 + direction2) / 2
53 | )
54 | );
55 | }
56 |
57 | // Arrowhead
58 | direction = (ms.geometry.bearingBetween(points[0], points[1]) + 180) % 360;
59 | geometry1.push(
60 | ms.geometry.toDistanceBearing(
61 | arrowHead,
62 | width * (1 - widthHeadRatio),
63 | direction + 90
64 | )
65 | );
66 | geometry1.push(arrowHead);
67 | geometry1.push(points[0]);
68 | geometry1.push(arrowHead2);
69 | geometry1.push(
70 | ms.geometry.toDistanceBearing(
71 | arrowHead2,
72 | width * (1 - widthHeadRatio),
73 | direction - 90
74 | )
75 | );
76 |
77 | for (j = 1; j < points.length - 1; j++) {
78 | direction1 =
79 | (ms.geometry.bearingBetween(points[j], points[j + 1]) + 360) % 360;
80 | direction2 =
81 | (ms.geometry.bearingBetween(points[j], points[j - 1]) + 360) % 360;
82 | factor = 1 / Math.sin((direction2 - direction1) / 2 * (Math.PI / 180));
83 | geometry1.push(
84 | ms.geometry.toDistanceBearing(
85 | points[j],
86 | -(width * widthHeadRatio) * factor,
87 | (direction1 + direction2) / 2
88 | )
89 | );
90 | }
91 |
92 | direction =
93 | (ms.geometry.bearingBetween(
94 | points[points.length - 1],
95 | points[points.length - 2]
96 | ) +
97 | 360) %
98 | 360;
99 | geometry1.push(
100 | ms.geometry.toDistanceBearing(
101 | points[points.length - 1],
102 | width * widthHeadRatio,
103 | direction + 90
104 | )
105 | );
106 |
107 | geometry.coordinates = geometry1;
108 | return { geometry: geometry };
109 | }
110 |
111 | module.exports = supportingAttack;
112 |
--------------------------------------------------------------------------------
/src/geometryconverter/target-build-up-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "TBA";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/target-value-area.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "TVAR";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/targeted-area-of-interest.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a NAI
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "TAI";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 |
15 | var polygon = ms.geometry.circleCorridorPolygon(feature);
16 | geometry = polygon.geometry;
17 | if (polygon.annotation.hasOwnProperty("geometry")) {
18 | annotations[0].geometry = polygon.annotation.geometry;
19 | }
20 |
21 | return { geometry: geometry, annotations: annotations };
22 | };
23 |
--------------------------------------------------------------------------------
/src/geometryconverter/terminally-guided-munition-footprint.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "TGMF";
11 | /*if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;*/
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/geometryconverter/zone-of-responsibility.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | // Draws a Fire Support Area
4 | module.exports = function(feature) {
5 | var annotations = [{}];
6 | var geometry;
7 |
8 | annotations[0].geometry = { type: "Point" };
9 | annotations[0].properties = {};
10 | annotations[0].properties.text = "ZOR";
11 | if (feature.properties.uniqueDesignation)
12 | annotations[0].properties.text +=
13 | "\n" + feature.properties.uniqueDesignation;
14 | if (feature.properties.dtg)
15 | annotations[0].properties.text += "\n" + feature.properties.dtg;
16 | if (feature.properties.dtg1)
17 | annotations[0].properties.text += "\n" + feature.properties.dtg1;
18 |
19 | var polygon = ms.geometry.circleCorridorPolygon(feature);
20 | geometry = polygon.geometry;
21 | if (polygon.annotation.hasOwnProperty("geometry")) {
22 | annotations[0].geometry = polygon.annotation.geometry;
23 | }
24 |
25 | return { geometry: geometry, annotations: annotations };
26 | };
27 |
--------------------------------------------------------------------------------
/src/graphic.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function graphic(feature) {
4 | this.SIDC = feature.properties.sidc;
5 | this.converted = false;
6 | this.geometry = feature.geometry;
7 | this.properties = this.getProperties();
8 |
9 | if (this.properties.graphic) {
10 | // If we don't have a graphics cache, create one
11 | if (typeof ms._graphicCache === "undefined") {
12 | ms._graphicCache = {};
13 | }
14 |
15 | // Letter based SIDC.
16 | if (!this.properties.numberSIDC) {
17 | if (
18 | !ms._graphicCache.hasOwnProperty("letter-" + this.properties.numberSIDC)
19 | ) {
20 | var sidc = {};
21 | ms._getLetterSIDCgraphic(sidc, this.properties.numberSIDC);
22 | ms._graphicCache["letter-" + this.properties.numberSIDC] = sidc;
23 | }
24 | var graphics = ms._graphicCache["letter-" + this.properties.numberSIDC];
25 | var genericSIDC =
26 | this.SIDC.substr(0, 1) +
27 | "-" +
28 | this.SIDC.substr(2, 1) +
29 | "-" +
30 | this.SIDC.substr(4, 6);
31 | if (graphics[genericSIDC]) {
32 | var graphicObject = graphics[genericSIDC].call(this, feature);
33 | this.geometry = graphicObject.geometry;
34 | this.annotations = graphicObject.annotations;
35 | this.converted = true;
36 | } else {
37 | if (this.geometry.type != "Point") {
38 | // Points is likely symbols, remove this when everything is implemented.
39 | console.log(
40 | "Did not find graphic converter for: " +
41 | this.SIDC +
42 | " (" +
43 | this.geometry.type +
44 | ")"
45 | );
46 | }
47 | }
48 | } else {
49 | // Number based SIDC
50 | console.log("TODO number sidc stuff");
51 | }
52 | }
53 | }
54 |
55 | graphic.prototype.getProperties = require("./graphic/getproperties.js");
56 | graphic.prototype.isConverted = function() {
57 | return this.converted;
58 | };
59 |
60 | module.exports = graphic;
61 |
--------------------------------------------------------------------------------
/src/graphic/getproperties.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | module.exports = function() {
4 | var properties = {
5 | // "activity" : false, //Is it an Activity
6 | affiliation: "", //Affiliation it is shown as (Friend/Hostile...)
7 | // "baseAffilation" : "", //Affiliation it belongs to (Friend/Hostile...)
8 | // "baseDimension" : "", //Dimension it belongs to (Air/Ground...)
9 | // "baseGeometry" : {g:"",bbox:{}}, //Geometry is a combination of dimension and affiliation (AirFriend/GroundHostile...)
10 | // "civilian" : false, //Is it Civilian
11 | // "condition" : "", //What condition is it in
12 | context: "", //Context of the symbol (Reality/Exercise...)
13 | dimension: "", //Dimension it is shown as (Air/Ground...)
14 | dimensionUnknown: false, //Is the dimension unknown
15 | echelon: "", //What echelon (Platoon/Company...)
16 | faker: false, //Is it a Faker
17 | fenintDummy: false, //Is it a feint/dummy
18 | // "fill" : this.fill, //Standard says it should be filled
19 | // "frame" : this.frame, //Standard says it should be framed
20 | functionid: "", //Part of SIDC referring to the icon.
21 | // "headquarters" : false, //Is it a Headquarters
22 | // "installation" : false, //Is it an Instalation
23 | joker: false, //Is it a Joker
24 | // "mobility" : "", //What mobility (Tracked/Sled)
25 | notpresent: "", //Is it Anticipated or Pending
26 | numberSIDC: false, //Is the SIDC number based
27 | // "space" : false, //Is it in Space
28 | // "taskForce" : false //Is it a task force
29 | graphic: false
30 | };
31 | var mapping = {};
32 | mapping.context = ["Reality", "Exercise", "Simulation"];
33 | mapping.status = [
34 | "Present",
35 | "Planned",
36 | "FullyCapable",
37 | "Damaged",
38 | "Destroyed",
39 | "FullToCapacity"
40 | ];
41 | mapping.affiliation = ["Hostile", "Friend", "Neutral", "Unknown"];
42 | mapping.dimension = ["Air", "Ground", "Sea", "Subsurface"];
43 |
44 | properties.context = mapping.context[0];
45 |
46 | if (this.monoColor != "") {
47 | properties.fill = false;
48 | }
49 | this.SIDC = String(this.SIDC).replace(/\*/g, "-").replace(/ /g, "");
50 |
51 | properties.numberSIDC = !isNaN(this.SIDC);
52 | if (properties.numberSIDC) {
53 | //This is for new number based SIDCs
54 |
55 | if (typeof ms._getNumberProperties === "function") {
56 | properties = ms._getNumberPropertiesGraphic.call(
57 | this,
58 | properties,
59 | mapping
60 | );
61 | } else {
62 | console.warn(
63 | "ms._getNumberPropertiesGraphic() is not present, you will need to load functionality for letter based SIDCs"
64 | );
65 | }
66 | } else {
67 | //This would be old letter based SIDCs
68 |
69 | if (typeof ms._getLetterProperties === "function") {
70 | properties = ms._getLetterPropertiesGraphic.call(
71 | this,
72 | properties,
73 | mapping
74 | );
75 | } else {
76 | console.warn(
77 | "ms._getLetterPropertiesGraphic() is not present, you will need to load functionality for letter based SIDCs"
78 | );
79 | }
80 | }
81 |
82 | return properties;
83 | };
84 |
--------------------------------------------------------------------------------
/src/graphicslayer.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | function GraphicsLayer(data) {
4 | this.data = data;
5 | for (var i = 0; i < this.data.features.length; i++) {
6 | var feature = this.data.features[i];
7 |
8 | feature.graphic = new ms.Graphic(feature);
9 | feature.geometry = feature.graphic.geometry;
10 |
11 | if (feature.geometry && feature.geometry.type == "Point") {
12 | var properties = feature.properties;
13 | properties.size = properties.size || 30; //TODO set default size value from setting
14 | if (properties.sidc.charAt(0) != "X") {
15 | //Skip SitaWare custom graphics for now
16 | feature.symbol = new ms.Symbol(properties);
17 | }
18 | }
19 | }
20 | }
21 |
22 | GraphicsLayer.prototype.asCesium = require("./graphicslayer/ascesium.js");
23 |
24 | GraphicsLayer.prototype.asOpenLayers = require("./graphicslayer/asopenlayers.js");
25 |
26 | module.exports = GraphicsLayer;
27 |
--------------------------------------------------------------------------------
/src/graphicslayer/ascesium.js:
--------------------------------------------------------------------------------
1 | function asCesium() {
2 | var ratio = window.devicePixelRatio || 1;
3 | var entities = new Cesium.EntityCollection();
4 |
5 | for (var i = 0; i < this.data.features.length; i++) {
6 | var feature = this.data.features[i];
7 |
8 | if (feature.geometry.type == "Point") {
9 | console.info("point");
10 | var properties = feature.properties;
11 | if (properties.sidc.charAt(0) != "X") {
12 | //TODO handle sitaware custom graphics
13 | var milsymbol = feature.symbol;
14 | var ctx = milsymbol.asCanvas(ratio);
15 | var entity = {
16 | position: Cesium.Cartesian3.fromDegrees(
17 | feature.geometry.coordinates[0],
18 | feature.geometry.coordinates[1]
19 | ), //Cesium.Cartesian3.fromArray( feature.geometry.coordinates ),
20 | billboard: {
21 | horizontalOrigin: Cesium.HorizontalOrigin.LEFT, // default
22 | verticalOrigin: Cesium.VerticalOrigin.TOP,
23 | image: ctx,
24 | imageSubRegion: new Cesium.BoundingRectangle(
25 | 0,
26 | 0,
27 | ctx.width + 2,
28 | ctx.height + 2
29 | ),
30 | height: milsymbol.getSize().height,
31 | width: milsymbol.getSize().width,
32 | pixelOffset: new Cesium.Cartesian2(
33 | -milsymbol.getAnchor().x,
34 | -milsymbol.getAnchor().y
35 | ) // default: (0, 0)
36 | }
37 | };
38 | entities.add(entity);
39 | }
40 | }
41 |
42 | if (
43 | feature.graphic.isConverted() &&
44 | (feature.geometry.type == "LineString" ||
45 | feature.geometry.type == "MultiLineString")
46 | ) {
47 | //console.log('line')
48 | var lineparts;
49 | if (feature.geometry.type == "LineString") {
50 | lineparts = [feature.geometry.coordinates]; // Make linestring to a sort of multiline
51 | } else {
52 | lineparts = feature.geometry.coordinates;
53 | }
54 |
55 | for (var key in lineparts) {
56 | var coordinates = lineparts[key];
57 | var positions = [];
58 | for (var c in coordinates) {
59 | positions.push(
60 | Cesium.Cartesian3.fromDegrees(
61 | coordinates[c][0],
62 | coordinates[c][1],
63 | coordinates[c][2]
64 | )
65 | );
66 | }
67 |
68 | entity = new Cesium.Entity({
69 | polyline: new Cesium.PolylineGraphics({
70 | positions: positions,
71 | material: Cesium.Color.BLACK,
72 | width: 1.5
73 | })
74 | });
75 |
76 | entities.add(entity);
77 | }
78 | }
79 |
80 | if (feature.graphic.isConverted() && feature.geometry.type == "Polygon") {
81 | coordinates = feature.geometry.coordinates[0];
82 | positions = [];
83 | for (c in coordinates) {
84 | positions.push(
85 | Cesium.Cartesian3.fromDegrees(
86 | coordinates[c][0],
87 | coordinates[c][1],
88 | coordinates[c][2]
89 | )
90 | );
91 | }
92 |
93 | /*var entity = new Cesium.Entity({
94 | polygon: new Cesium.PolygonGraphics({
95 | hierarchy: new Cesium.PolygonHierarchy(positions),
96 | fill: false,
97 | outline: true,
98 | outlineColor: Cesium.Color.BLACK,
99 | outlineWidth: 3
100 | })
101 | });*/
102 |
103 | entity = new Cesium.Entity({
104 | polyline: new Cesium.PolylineGraphics({
105 | positions: positions,
106 | material: Cesium.Color.BLACK,
107 | width: 1.5
108 | })
109 | });
110 |
111 | entities.add(entity);
112 | }
113 | }
114 |
115 | return entities;
116 | }
117 |
118 | module.exports = asCesium;
119 |
--------------------------------------------------------------------------------
/src/graphicslayer/asopenlayers.js:
--------------------------------------------------------------------------------
1 | function asOpenLayers(crs) {
2 | crs = crs || "EPSG:3857";
3 | //var ua = window.navigator.userAgent;
4 | //var isIE = ( ua.indexOf('MSIE ') > 0 || ua.indexOf('Trident/') > 0 || ua.indexOf('Edge/') > 0) ? true : false;
5 | var ratio = window.devicePixelRatio || 1;
6 | var geoJSON = new ol.format.GeoJSON();
7 | var features = [];
8 |
9 | for (var i = 0; i < this.data.features.length; i++) {
10 | var feature = this.data.features[i];
11 | var olFeature = geoJSON.readFeature(feature, {
12 | featureProjection: ol.proj.get(crs)
13 | });
14 |
15 | if (
16 | olFeature.getGeometry() &&
17 | olFeature.getGeometry().getType() == "Point"
18 | ) {
19 | var properties = olFeature.getProperties();
20 | if (properties.sidc.charAt(0) != "X") {
21 | //TODO handle sitaware custom graphics
22 | var milsymbol = this.data.features[i].symbol;
23 | //var image = isIE ? mysymbol.asCanvas() : mysymbol.toDataURL();
24 | olFeature.setStyle(
25 | new ol.style.Style({
26 | image: new ol.style.Icon({
27 | scale: 1 / ratio,
28 | anchor: [
29 | milsymbol.getAnchor().x * ratio,
30 | milsymbol.getAnchor().y * ratio
31 | ],
32 | anchorXUnits: "pixels",
33 | anchorYUnits: "pixels",
34 | imgSize: [
35 | Math.floor(milsymbol.getSize().width * ratio),
36 | Math.floor(milsymbol.getSize().height * ratio)
37 | ],
38 | img: milsymbol.asCanvas(ratio)
39 | })
40 | })
41 | );
42 | }
43 | }
44 |
45 | if (
46 | feature.graphic.isConverted() &&
47 | (olFeature.getGeometry().getType() == "LineString" ||
48 | olFeature.getGeometry().getType() == "MultiLineString")
49 | ) {
50 | var styles = [
51 | new ol.style.Style({
52 | stroke: new ol.style.Stroke({
53 | lineCap: "butt",
54 | color: "#000000",
55 | width: 2
56 | })
57 | })
58 | ];
59 | if (feature.graphic.annotations) {
60 | var labelgeom = geoJSON
61 | .readFeature(feature.graphic.annotations[0].geometry, {
62 | featureProjection: ol.proj.get(crs)
63 | })
64 | .getGeometry();
65 | styles.push(
66 | new ol.style.Style({
67 | text: new ol.style.Text({
68 | fill: new ol.style.Fill({ color: "black" }),
69 | font: "bold 16px sans-serif",
70 | stroke: new ol.style.Stroke({
71 | color: "rgb(239, 239, 239)", // off-white
72 | width: 4
73 | }),
74 | text: feature.graphic.annotations[0].properties.text
75 | }),
76 | geometry: labelgeom
77 | })
78 | );
79 | }
80 | olFeature.setStyle(styles);
81 | }
82 |
83 | if (
84 | feature.graphic.isConverted() &&
85 | olFeature.getGeometry().getType() == "Polygon"
86 | ) {
87 | style = new ol.style.Style({
88 | stroke: new ol.style.Stroke({
89 | lineCap: "butt",
90 | color: "#000000",
91 | width: 2
92 | }),
93 | fill: new ol.style.Fill({ color: "rgba(0,0,0,0)" }),
94 | text: new ol.style.Text({
95 | fill: new ol.style.Fill({ color: "black" }),
96 | font: "bold 16px sans-serif",
97 | stroke: new ol.style.Stroke({
98 | color: "rgb(239, 239, 239)", // off-white
99 | width: 4
100 | }),
101 | text: feature.graphic.annotations
102 | ? feature.graphic.annotations[0].properties.text
103 | : ""
104 | })
105 | });
106 | olFeature.setStyle(style);
107 | }
108 |
109 | features.push(olFeature);
110 | }
111 |
112 | return features;
113 | }
114 |
115 | module.exports = asOpenLayers;
116 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /* ***************************************************************************************
2 | Creating the base of milgraphics by importing milsymbol
3 | *************************************************************************************** */
4 | var ms = require("milsymbol");
5 |
6 | ms.addSIDCgraphics = require("./ms/addsidcgraphics.js");
7 |
8 | ms.format = require("./format.js");
9 | ms.geometry = require("./geometry.js");
10 | ms.geometryConverter = require("./geometryconverter.js");
11 |
12 | ms.Graphic = require("./graphic.js");
13 |
14 | ms.GraphicsLayer = require("./graphicslayer.js");
15 |
16 | /* ***************************************************************************************
17 | Letter based SIDC
18 | *************************************************************************************** */
19 | ms._getLetterPropertiesGraphic = require("./letter-sidc/properties.js");
20 |
21 | ms._getLetterSIDCgraphic = require("./letter-sidc/getgraphic.js");
22 | ms.addSIDCgraphics(require("./letter-sidc/tactical-2525.js"), "letter");
23 | ms.addSIDCgraphics(require("./letter-sidc/tactical-app6.js"), "letter");
24 | /* ***************************************************************************************
25 | Number based SIDC
26 | *************************************************************************************** */
27 | ms._getNumberPropertiesGraphic = require("./number-sidc/properties.js");
28 |
29 | /* ***************************************************************************************
30 | Export ms to the world
31 | *************************************************************************************** */
32 | module.exports = ms;
33 |
--------------------------------------------------------------------------------
/src/letter-sidc/getgraphic.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | module.exports = function(sidc, STD2525) {
4 | // We modify sidc directly in the called functions so we don't need to return anything.
5 | // Might change this later since it adds complexity to understand the code.
6 | for (var i in ms._letterSIDCgraphics) {
7 | if (!ms._letterSIDCgraphics.hasOwnProperty(i)) continue;
8 | ms._letterSIDCgraphics[i].call(this, sidc, STD2525);
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/src/letter-sidc/properties.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | module.exports = function(properties, mapping) {
4 | this.SIDC = this.SIDC.toUpperCase();
5 |
6 | var codingscheme = this.SIDC.charAt(0) != "" ? this.SIDC.charAt(0) : "-";
7 | var affiliation = this.SIDC.charAt(1) != "" ? this.SIDC.charAt(1) : "-";
8 | var battledimension = this.SIDC.charAt(2) != "" ? this.SIDC.charAt(2) : "-";
9 | var status = this.SIDC.charAt(3) != "" ? this.SIDC.charAt(3) : "-";
10 | var functionid = (properties.functionid = this.SIDC.substr(4, 6) != ""
11 | ? this.SIDC.substr(4, 6)
12 | : "------");
13 | var symbolmodifier11 = this.SIDC.charAt(10) != ""
14 | ? this.SIDC.charAt(10)
15 | : "-";
16 | var symbolmodifier12 = this.SIDC.charAt(11) != ""
17 | ? this.SIDC.charAt(11)
18 | : "-";
19 | var countrycode = this.SIDC.substr(12, 2) != ""
20 | ? this.SIDC.substr(12, 2)
21 | : "--";
22 | var orderofbattle = this.SIDC.charAt(14) != "" ? this.SIDC.charAt(14) : "-";
23 |
24 | if (["H", "S", "J", "K"].indexOf(affiliation) > -1)
25 | properties.affiliation = mapping.affiliation[0];
26 | if (["F", "A", "D", "M"].indexOf(affiliation) > -1)
27 | properties.affiliation = mapping.affiliation[1];
28 | if (["N", "L"].indexOf(affiliation) > -1)
29 | properties.affiliation = mapping.affiliation[2];
30 | if (["P", "U", "G", "W", "O"].indexOf(affiliation) > -1)
31 | properties.affiliation = mapping.affiliation[3];
32 |
33 | if (["P", "A"].indexOf(battledimension) > -1)
34 | properties.dimension = mapping.dimension[0];
35 | if (["G", "Z", "F", "X"].indexOf(battledimension) > -1)
36 | properties.dimension = mapping.dimension[1];
37 | if (["S"].indexOf(battledimension) > -1)
38 | properties.dimension = mapping.dimension[2];
39 | if (["U"].indexOf(battledimension) > -1)
40 | properties.dimension = mapping.dimension[3];
41 |
42 | //Planned/Anticipated/Suspect symbols should have a dashed outline
43 | if (status == "A") {
44 | properties.notpresent = ms._dashArrays.anticipated;
45 | }
46 | if (["P", "A", "S", "G", "M"].indexOf(affiliation) > -1) {
47 | properties.notpresent = ms._dashArrays.pending;
48 | }
49 |
50 | if (orderofbattle == "X") {
51 | properties.graphic = true;
52 | }
53 |
54 | // Army XML compability
55 | //sidc['CIRCLE----'] = ms.geometryConverter.circle;
56 |
57 | // Systematic SitaWare compatibility
58 | var genericSIDC =
59 | this.SIDC.substr(0, 1) +
60 | "-" +
61 | this.SIDC.substr(2, 1) +
62 | "-" +
63 | this.SIDC.substr(4, 6);
64 | if (["X---C-----", "X---I-----", "X---A-----"].indexOf(genericSIDC) != -1) {
65 | properties.graphic = true;
66 | }
67 |
68 | return properties;
69 | };
70 |
--------------------------------------------------------------------------------
/src/letter-sidc/tactical-app6.js:
--------------------------------------------------------------------------------
1 | // Tactical graphics in APP6-B
2 | module.exportS = function tacticalPoints(sidc, std2525) {
3 | //sidc['G---------'] = [];//2.X
4 | //sidc['G-T-------'] = [];//2.X.1
5 | //sidc['G-T-G-----'] = [];//2.X.1.1
6 | sidc["G-T-GB----"] = ms.geometryConverter["BLOCK"]; //2.X.1.1.1
7 | sidc["G-T-GH----"] = ms.geometryConverter["BYPASS"]; //2.X.1.1.2
8 | sidc["G-T-GY----"] = ms.geometryConverter["BYPASS"]; //2.X.1.1.3
9 | sidc["G-T-GC----"] = ms.geometryConverter["CANALIZE"]; //2.X.1.1.4
10 | sidc["G-T-GX----"] = ms.geometryConverter["CLEAR"]; //2.X.1.1.5
11 | //sidc['G-T-GJ----'] = [];//2.X.1.1.6
12 | //sidc['G-T-GK----'] = [];//2.X.1.1.7
13 | //sidc['G-T-GKF---'] = [];//2.X.1.1.7.1
14 | sidc["G-T-GL----"] = ms.geometryConverter["DELAY"]; //2.X.1.1.8
15 | //sidc['G-T-GLT---'] = [];//2.X.1.1.8.1
16 | //sidc['G-T-GT----'] = [];//2.X.1.1.10
17 | sidc["G-T-GF----"] = ms.geometryConverter["FIX"]; //2.X.1.1.11
18 | //sidc['G-T-GA----'] = [];//2.X.1.1.12
19 | //sidc['G-T-GAS---'] = [];//2.X.1.1.12.1
20 | sidc["G-T-GE----"] = ms.geometryConverter["ISOLATE"]; //2.X.1.1.14
21 | //sidc['G-T-GO----'] = [];//2.X.1.1.16
22 | //sidc['G-T-GP----'] = [];//2.X.1.1.17
23 | //sidc['G-T-GR----'] = [];//2.X.1.1.18
24 | //sidc['G-T-GQ----'] = [];//2.X.1.1.19
25 | //sidc['G-T-GM----'] = [];//2.X.1.1.20
26 | //sidc['G-T-GS----'] = [];//2.X.1.1.21
27 | //sidc['G-T-GSS---'] = [];//2.X.1.1.21.1
28 | //sidc['G-T-GSG---'] = [];//2.X.1.1.21.2
29 | //sidc['G-T-GSC---'] = [];//2.X.1.1.21.3
30 | //sidc['G-T-GZ----'] = [];//2.X.1.1.22
31 | //sidc['G-T-GW----'] = [];//2.X.1.1.23
32 | //sidc['G-T-GWP---'] = [];//2.X.1.1.23.1
33 | //sidc['G-C-------'] = [];//2.X.2
34 | //sidc['G-C-M-----'] = [];//2.X.2.1
35 | //sidc['G-C-MG----'] = [];//2.X.2.1.1
36 | //sidc['G-C-MGP---'] = [];//2.X.2.1.1.1
37 | //sidc['G-C-MGPF--'] = [];//2.X.2.1.1.1.1
38 | //sidc['G-C-MGL---'] = [];//2.X.2.1.1.2
39 | //sidc['G-C-MGLB--'] = [];//2.X.2.1.1.2.1
40 | //sidc['G-C-MGLBG-'] = [];//2.X.2.1.1.2.1.1
41 | //sidc['G-C-MGLBGF'] = [];//2.X.2.1.1.2.1.1.1
42 | //sidc['G-C-MGLBGO'] = [];//2.X.2.1.1.2.1.1.2
43 | //sidc['G-C-MGLBGK'] = [];//2.X.2.1.1.2.1.1.3
44 | //sidc['G-C-MGLBGS'] = [];//2.X.2.1.1.2.1.1.4
45 | //sidc['G-C-MGLBL-'] = [];//2.X.2.1.1.2.1.2
46 | //sidc['G-C-MGLBF-'] = [];//2.X.2.1.1.2.1.3
47 | //sidc['G-C-MGLBR-'] = [];//2.X.2.1.1.2.1.4
48 | //sidc['G-C-MGLF--'] = [];//2.X.2.1.1.2.2
49 | //sidc['G-C-MGLL--'] = [];//2.X.2.1.1.2.3
50 | //sidc['G-C-MGLP--'] = [];//2.X.2.1.1.2.4
51 | //sidc['G-C-MGLE--'] = [];//2.X.2.1.1.2.5
52 | //sidc['G-C-MGLEE-'] = [];//2.X.2.1.1.2.5.1
53 | //sidc['G-C-MGLEA-'] = [];//2.X.2.1.1.2.5.2
54 | //sidc['G-C-MGLET-'] = [];//2.X.2.1.1.2.5.3
55 | //sidc['G-C-MGLEO-'] = [];//2.X.2.1.1.2.5.4
56 | //sidc['G-C-MGA---'] = [];//2.X.2.1.1.3
57 | //sidc['G-C-MGAU--'] = [];//2.X.2.1.1.3.1
58 | //sidc['G-C-MGAUA-'] = [];//2.X.2.1.1.3.1.1
59 | //sidc['G-C-MGAUAF'] = [];//2.X.2.1.1.3.1.1.1
60 | //sidc['G-C-MGAUAP'] = [];//2.X.2.1.1.3.1.1.2
61 | //sidc['G-C-MGAUAE'] = [];//2.X.2.1.1.3.1.1.3
62 | //sidc['G-C-MGAUAS'] = [];//2.X.2.1.1.3.1.1.4
63 | //sidc['G-C-MGAUB-'] = [];//2.X.2.1.1.3.1.2
64 | //sidc['G-C-MGAUBO'] = [];//2.X.2.1.1.3.1.2.1
65 | //sidc['G-C-MGAUBM'] = [];//2.X.2.1.1.3.1.2.2
66 | //sidc['G-C-MGAUBR'] = [];//2.X.2.1.1.3.1.2.3
67 | //sidc['G-C-MGAS--'] = [];//2.X.2.1.1.3.2
68 | //sidc['G-C-MGASD-'] = [];//2.X.2.1.1.3.2.1
69 | //sidc['G-C-MGASE-'] = [];//2.X.2.1.1.3.2.2
70 | //sidc['G-C-MGASL-'] = [];//2.X.2.1.1.3.2.3
71 | //sidc['G-C-MGASP-'] = [];//2.X.2.1.1.3.2.4
72 | //sidc['G-C-MGASS-'] = [];//2.X.2.1.1.3.2.5
73 | //sidc['G-C-MGASM-'] = [];//2.X.2.1.1.3.2.6
74 | //sidc['G-C-MGASG-'] = [];//2.X.2.1.1.3.2.7
75 | //sidc['G-C-MGASF-'] = [];//2.X.2.1.1.3.2.8
76 | //sidc['G-C-MGAST-'] = [];//2.X.2.1.1.3.2.9
77 | //sidc['G-C-MA----'] = [];//2.X.2.1.2
78 | //sidc['G-C-MAA---'] = [];//2.X.2.1.2.1
79 | //sidc['G-C-MAL---'] = [];//2.X.2.1.2.2
80 | //sidc['G-C-MALC--'] = [];//2.X.2.1.2.2.1
81 | //sidc['G-C-MALM--'] = [];//2.X.2.1.2.2.2
82 | //sidc['G-C-MALS--'] = [];//2.X.2.1.2.2.3
83 | //sidc['G-C-MALU--'] = [];//2.X.2.1.2.2.4
84 | //sidc['G-C-MALL--'] = [];//2.X.2.1.2.2.5
85 | //sidc['G-C-MALIN-'] = [];//2.X.2.1.2.2.6
86 | //sidc['G-C-MALIF-'] = [];//2.X.2.1.2.2.7
87 | //sidc['G-C-MAV---'] = [];//2.X.2.1.2.3
88 | //sidc['G-C-MAVR--'] = [];//2.X.2.1.2.3.1
89 | //sidc['G-C-MAVF--'] = [];//2.X.2.1.2.3.2
90 | //sidc['G-C-MAVH--'] = [];//2.X.2.1.2.3.3
91 | //sidc['G-C-MAVM--'] = [];//2.X.2.1.2.3.4
92 | //sidc['G-C-MAVML-'] = [];//2.X.2.1.2.3.4.1
93 | //sidc['G-C-MAVMH-'] = [];//2.X.2.1.2.3.4.2
94 | //sidc['G-C-MAVW--'] = [];//2.X.2.1.2.3.5
95 | //sidc['G-C-MD----'] = [];//2.X.2.1.3
96 | //sidc['G-C-MDD---'] = [];//2.X.2.1.3.1
97 | //sidc['G-C-MDA---'] = [];//2.X.2.1.3.2
98 | //sidc['G-C-MDF---'] = [];//2.X.2.1.3.3
99 | //sidc['G-C-MDM---'] = [];//2.X.2.1.3.4
100 | //sidc['G-C-MDY---'] = [];//2.X.2.1.3.5
101 | //sidc['G-C-MM----'] = [];//2.X.2.1.4
102 | //sidc['G-C-MMP---'] = [];//2.X.2.1.4.1
103 | //sidc['G-C-MMPB--'] = [];//2.X.2.1.4.1.2
104 | //sidc['G-C-MMPBO-'] = [];//2.X.2.1.4.1.2.1
105 | //sidc['G-C-MMPBP-'] = [];//2.X.2.1.4.1.2.2
106 | //sidc['G-C-MMPBL-'] = [];//2.X.2.1.4.1.2.3
107 | //sidc['G-C-*'] = [];//2.X.2.1.4.1.3
108 | //sidc['G-C-MMPSF-'] = [];//2.X.2.1.4.1.3.1
109 | //sidc['G-C-MMPSE-'] = [];//2.X.2.1.4.1.3.2
110 | //sidc['G-C-MMD---'] = [];//2.X.2.1.4.2
111 | //sidc['G-C-MMDF--'] = [];//2.X.2.1.4.2.1
112 | //sidc['G-C-MMDFA-'] = [];//2.X.2.1.4.2.1.1
113 | //sidc['G-C-MMDFP-'] = [];//2.X.2.1.4.2.1.2
114 | //sidc['G-C-MMDP--'] = [];//2.X.2.1.4.2.2
115 | //sidc['G-C-MMA---'] = [];//2.X.2.1.4.3
116 | //sidc['G-C-MMAE--'] = [];//2.X.2.1.4.3.1
117 | //sidc['G-C-MO----'] = [];//2.X.2.1.5
118 | //sidc['G-C-MOP---'] = [];//2.X.2.1.5.1
119 | //sidc['G-C-MOL---'] = [];//2.X.2.1.5.2
120 | //sidc['G-C-MOLA--'] = [];//2.X.2.1.5.2.1
121 | //sidc['G-C-MOLAF-'] = [];//2.X.2.1.5.2.1.1
122 | //sidc['G-C-MOLAA-'] = [];//2.X.2.1.5.2.1.2
123 | //sidc['G-C-MOLAH-'] = [];//2.X.2.1.5.2.1.3
124 | sidc["G-C-MOLAS-"] = ms.geometryConverter["SUPPORTING ATTACK"]; //2.X.2.1.5.2.1.4
125 | sidc["G-C-MOLAM-"] = ms.geometryConverter["MAIN ATTACK"]; //2.X.2.1.5.2.1.5
126 | //sidc['G-C-MOLAO-'] = [];//2.X.2.1.5.2.1.6
127 | //sidc['G-C-MOLAE-'] = [];//2.X.2.1.5.2.1.7
128 | //sidc['G-C-MOLAT-'] = [];//2.X.2.1.5.2.1.8
129 | //sidc['G-C-MOLD--'] = [];//2.X.2.1.5.2.2
130 | //sidc['G-C-MOLDF-'] = [];//2.X.2.1.5.2.2.1
131 | //sidc['G-C-MOLDY-'] = [];//2.X.2.1.5.2.2.2
132 | //sidc['G-C-MOLDE-'] = [];//2.X.2.1.5.2.2.3
133 | //sidc['G-C-MOLDT-'] = [];//2.X.2.1.5.2.2.4
134 | //sidc['G-C-MOLDG-'] = [];//2.X.2.1.5.2.2.5
135 | //sidc['G-C-MOLDR-'] = [];//2.X.2.1.5.2.2.6
136 | //sidc['G-C-MOLDS-'] = [];//2.X.2.1.5.2.2.7
137 | //sidc['G-C-MOLDM-'] = [];//2.X.2.1.5.2.2.8
138 | //sidc['G-C-MOLDO-'] = [];//2.X.2.1.5.2.2.9
139 | //sidc['G-C-MOLF--'] = [];//2.X.2.1.5.2.3
140 | //sidc['G-C-MOLI--'] = [];//2.X.2.1.5.2.4
141 | //sidc['G-C-MOLL--'] = [];//2.X.2.1.5.2.5
142 | //sidc['G-C-MOLT--'] = [];//2.X.2.1.5.2.6
143 | //sidc['G-C-MOLC--'] = [];//2.X.2.1.5.2.7
144 | //sidc['G-C-MOLP--'] = [];//2.X.2.1.5.2.8
145 | //sidc['G-C-MOLR--'] = [];//2.X.2.1.5.2.9
146 | //sidc['G-C-MOO---'] = [];//2.X.2.1.5.3
147 | //sidc['G-C-MOOA--'] = [];//2.X.2.1.5.3.1
148 | //sidc['G-C-MOOT--'] = [];//2.X.2.1.5.3.2
149 | //sidc['G-C-MOOTF-'] = [];//2.X.2.1.5.3.2.1
150 | //sidc['G-C-MOOTC-'] = [];//2.X.2.1.5.3.2.2
151 | //sidc['G-C-MOOTP-'] = [];//2.X.2.1.5.3.2.3
152 | //sidc['G-C-MOOP--'] = [];//2.X.2.1.5.3.3
153 | //sidc['G-C-MOOS--'] = [];//2.X.2.1.5.3.4
154 | //sidc['G-C-MOOJ--'] = [];//2.X.2.1.5.3.5
155 | //sidc['G-C-MOOX--'] = [];//2.X.2.1.5.3.6
156 | //sidc['G-C-MOOR--'] = [];//2.X.2.1.5.3.7
157 | //sidc['G-C-MS----'] = [];//2.X.2.1.6
158 | //sidc['G-C-MSG---'] = [];//2.X.2.1.6.1
159 | //sidc['G-C-MSGE--'] = [];//2.X.2.1.6.1.1
160 | //sidc['G-C-MSGEF-'] = [];//2.X.2.1.6.1.1.1
161 | //sidc['G-C-MSGEY-'] = [];//2.X.2.1.6.1.1.2
162 | sidc["G-C-MSGA--"] = ms.geometryConverter["AMBUSH"]; //2.X.2.1.6.1.2
163 | //sidc['G-C-MSL---'] = [];//2.X.2.1.6.2
164 | //sidc['G-C-MSLA--'] = [];//2.X.2.1.6.2.1
165 | //sidc['G-C-MSLB--'] = [];//2.X.2.1.6.2.2
166 | //sidc['G-C-MSLH--'] = [];//2.X.2.1.6.2.3
167 | //sidc['G-C-MSLR--'] = [];//2.X.2.1.6.2.4
168 | //sidc['G-C-MSA---'] = [];//2.X.2.1.6.3
169 | //sidc['G-C-MSAO--'] = [];//2.X.2.1.6.3.1
170 | sidc["G-C-MSAN--"] = ms.geometryConverter["NAMED AREA OF INTEREST"]; //2.X.2.1.6.3.2
171 | sidc["G-C-MSAT--"] = ms.geometryConverter["TARGETED AREA OF INTEREST"]; //2.X.2.1.6.3.3
172 | //sidc['G-C-B-----'] = [];//2.X.2.2
173 | //sidc['G-C-BO----'] = [];//2.X.2.2.1
174 | //sidc['G-C-BOG---'] = [];//2.X.2.2.1.1
175 | //sidc['G-C-BOGB--'] = [];//2.X.2.2.1.1.1
176 | //sidc['G-C-BOGL--'] = [];//2.X.2.2.1.1.2
177 | //sidc['G-C-BOGZ--'] = [];//2.X.2.2.1.1.3
178 | //sidc['G-C-BOA---'] = [];//2.X.2.2.1.2
179 | //sidc['G-C-BOAT--'] = [];//2.X.2.2.1.3
180 | //sidc['G-C-BOATO-'] = [];//2.X.2.2.1.3.1
181 | //sidc['G-C-BOATM-'] = [];//2.X.2.2.1.3.2
182 | //sidc['G-C-BOATW-'] = [];//2.X.2.2.1.3.4
183 | //sidc['G-C-BOAM--'] = [];//2.X.2.2.1.5
184 | //sidc['G-C-BOAMW-'] = [];//2.X.2.2.1.5.7
185 | //sidc['G-C-BOAI--'] = [];//2.X.2.2.1.6
186 | //sidc['G-C-BOAIL-'] = [];//2.X.2.2.1.6.3
187 | //sidc['G-C-BOAIG-'] = [];//2.X.2.2.1.6.4
188 | //sidc['G-C-BOAIM-'] = [];//2.X.2.2.1.6.9
189 | //sidc['G-C-BOAV--'] = [];//2.X.2.2.1.7
190 | //sidc['G-C-BOAE--'] = [];//2.X.2.2.1.8
191 | //sidc['G-C-BOAEB-'] = [];//2.X.2.2.1.8.1
192 | //sidc['G-C-BOAEF-'] = [];//2.X.2.2.1.8.2
193 | //sidc['G-C-BOAET-'] = [];//2.X.2.2.1.8.3
194 | //sidc['G-C-BOAED-'] = [];//2.X.2.2.1.8.4
195 | //sidc['G-C-BOAF--'] = [];//2.X.2.2.1.9
196 | //sidc['G-C-BOAFR-'] = [];//2.X.2.2.1.9.1
197 | //sidc['G-C-BOAU--'] = [];//2.X.2.2.1.10
198 | //sidc['G-C-BOAR--'] = [];//2.X.2.2.1.11
199 | //sidc['G-C-BOARP-'] = [];//2.X.2.2.1.11.1
200 | //sidc['G-C-BOARE-'] = [];//2.X.2.2.1.11.2
201 | //sidc['G-C-BOARS-'] = [];//2.X.2.2.1.11.3
202 | //sidc['G-C-BOARC-'] = [];//2.X.2.2.1.11.4
203 | //sidc['G-C-BOAP--'] = [];//2.X.2.2.1.12
204 | //sidc['G-C-BOAW--'] = [];//2.X.2.2.1.13
205 | //sidc['G-C-BOAWU-'] = [];//2.X.2.2.1.13.1
206 | //sidc['G-C-BOAWS-'] = [];//2.X.2.2.1.13.2
207 | //sidc['G-C-BOAWD-'] = [];//2.X.2.2.1.13.3
208 | //sidc['G-C-BOAWA-'] = [];//2.X.2.2.1.13.4
209 | //sidc['G-C-BOAWL-'] = [];//2.X.2.2.1.13.5
210 | //sidc['G-C-BOAWH-'] = [];//2.X.2.2.1.13.6
211 | //sidc['G-C-BOAWC-'] = [];//2.X.2.2.1.13.7
212 | //sidc['G-C-BOAWB-'] = [];//2.X.2.2.1.13.8
213 | //sidc['G-C-BOAWR-'] = [];//2.X.2.2.1.13.9
214 | //sidc['G-C-BY----'] = [];//2.X.2.2.2
215 | //sidc['G-C-BYO---'] = [];//2.X.2.2.2.1
216 | //sidc['G-C-BYOE--'] = [];//2.X.2.2.2.1.1
217 | //sidc['G-C-BYOD--'] = [];//2.X.2.2.2.1.2
218 | //sidc['G-C-BYOI--'] = [];//2.X.2.2.2.1.3
219 | //sidc['G-C-BYC---'] = [];//2.X.2.2.2.2
220 | //sidc['G-C-BYCA--'] = [];//2.X.2.2.2.2.1
221 | //sidc['G-C-BYCB--'] = [];//2.X.2.2.2.2.2
222 | //sidc['G-C-BYCF--'] = [];//2.X.2.2.2.2.3
223 | //sidc['G-C-BYCE--'] = [];//2.X.2.2.2.2.4
224 | //sidc['G-C-BYCD--'] = [];//2.X.2.2.2.2.5
225 | //sidc['G-C-BYCL--'] = [];//2.X.2.2.2.2.6
226 | //sidc['G-C-BYCR--'] = [];//2.X.2.2.2.2.7
227 | //sidc['G-C-BS----'] = [];//2.X.2.2.3
228 | //sidc['G-C-BSL---'] = [];//2.X.2.2.3.3
229 | //sidc['G-C-BSW---'] = [];//2.X.2.2.3.4
230 | //sidc['G-C-BSP---'] = [];//2.X.2.2.3.5
231 | //sidc['G-C-BW----'] = [];//2.X.2.2.4
232 | //sidc['G-C-BWM---'] = [];//2.X.2.2.4.1
233 | //sidc['G-C-BWA---'] = [];//2.X.2.2.4.7
234 | //sidc['G-C-BWC---'] = [];//2.X.2.2.4.8
235 | //sidc['G-C-BWH---'] = [];//2.X.2.2.4.9
236 | //sidc['G-C-BWK---'] = [];//2.X.2.2.4.10
237 | //sidc['G-C-BWD---'] = [];//2.X.2.2.4.11
238 | //sidc['G-C-BWR---'] = [];//2.X.2.2.4.12
239 | //sidc['G-C-F-----'] = [];//2.X.2.3
240 | //sidc['G-C-FS----'] = [];//2.X.2.3.1
241 | //sidc['G-C-FST---'] = [];//2.X.2.3.1.1
242 | //sidc['G-C-FSTC--'] = [];//2.X.2.3.1.1.2
243 | //sidc['G-C-FL----'] = [];//2.X.2.3.2
244 | //sidc['G-C-FLC---'] = [];//2.X.2.3.2.1
245 | //sidc['G-C-FLF---'] = [];//2.X.2.3.2.2
246 | //sidc['G-C-FLT---'] = [];//2.X.2.3.2.3
247 | //sidc['G-C-FLTP--'] = [];//2.X.2.3.2.3.1
248 | //sidc['G-C-FLK---'] = [];//2.X.2.3.2.4
249 | //sidc['G-C-FLKP--'] = [];//2.X.2.3.2.4.1
250 | //sidc['G-C-FLKS--'] = [];//2.X.2.3.2.4.2
251 | //sidc['G-C-FLKT--'] = [];//2.X.2.3.2.4.3
252 | //sidc['G-C-FLN---'] = [];//2.X.2.3.2.5
253 | //sidc['G-C-FLR---'] = [];//2.X.2.3.2.6
254 | //sidc['G-C-FA----'] = [];//2.X.2.3.3
255 | sidc["G-C-FAS---"] = ms.geometryConverter["FIRE SUPPORT AREA"]; //2.X.2.3.3.1
256 | sidc["G-C-FAC---"] = ms.geometryConverter["AIRSPACE COORDINATION AREA"]; //2.X.2.3.3.2
257 | //sidc['G-C-FAT---'] = [];//2.X.2.3.3.3
258 | //sidc['G-C-FAR---'] = [];//2.X.2.3.3.4
259 | //sidc['G-C-FARS--'] = [];//2.X.2.3.3.4.1
260 | //sidc['G-C-FARU--'] = [];//2.X.2.3.3.4.2
261 | //sidc['G-C-FAB---'] = [];//2.X.2.3.3.5
262 | sidc["G-C-FAI---"] = ms.geometryConverter["FREE FIRE AREA"]; //2.X.2.3.3.6
263 | //sidc['G-C-FAZ---'] = [];//2.X.2.3.3.7
264 | //sidc['G-C-FAZT--'] = [];//2.X.2.3.3.7.1
265 | //sidc['G-C-FAZU--'] = [];//2.X.2.3.3.7.2
266 | //sidc['G-C-FAN---'] = [];//2.X.2.3.3.8
267 | //sidc['G-C-FAD---'] = [];//2.X.2.3.3.10
268 | //sidc['G-C-FAP---'] = [];//2.X.2.3.3.11
269 | //sidc['G-C-FATA--'] = [];//2.X.2.3.3.12
270 | //sidc['*-*-*'] = [];//G
271 | //sidc['G-C-SP----'] = [];//2.X.2.4.1
272 | //sidc['G-C-SPQ---'] = [];//2.X.2.4.1.14
273 | //sidc['G-C-SPM---'] = [];//2.X.2.4.1.15
274 | //sidc['G-C-SL----'] = [];//2.X.2.4.2
275 | //sidc['G-C-SLC---'] = [];//2.X.2.4.2.1
276 | //sidc['G-C-SLCM--'] = [];//2.X.2.4.2.1.1
277 | //sidc['G-C-SLCH--'] = [];//2.X.2.4.2.1.2
278 | //sidc['G-C-SLR---'] = [];//2.X.2.4.2.2
279 | //sidc['G-C-SLRM--'] = [];//2.X.2.4.2.2.1
280 | //sidc['G-C-SLRA--'] = [];//2.X.2.4.2.2.2
281 | //sidc['G-C-SLRO--'] = [];//2.X.2.4.2.2.3
282 | //sidc['G-C-SLRT--'] = [];//2.X.2.4.2.2.4
283 | //sidc['G-C-SLRW--'] = [];//2.X.2.4.2.2.5
284 | //sidc['G-C-SA----'] = [];//2.X.2.4.3
285 | //sidc['G-C-SAD---'] = [];//2.X.2.4.3.1
286 | //sidc['G-C-SAP---'] = [];//2.X.2.4.3.2
287 | //sidc['G-C-SAR---'] = [];//2.X.2.4.3.3
288 | //sidc['G-C-SAH---'] = [];//2.X.2.4.3.4
289 | //sidc['G-C-SAT---'] = [];//2.X.2.4.3.5
290 | //sidc['G-C-SATB--'] = [];//2.X.2.4.3.5.1
291 | //sidc['G-C-SATD--'] = [];//2.X.2.4.3.5.2
292 | //sidc['G-C-SATR--'] = [];//2.X.2.4.3.5.3
293 | //sidc['G-C-SARR--'] = [];//2.X.2.4.3.6
294 | //sidc['G-C-O-----'] = [];//2.X.2.5
295 | //sidc['G-C-OXE---'] = [];//2.X.2.5.1.1
296 | //sidc['G-C-OXU---'] = [];//2.X.2.5.1.2
297 | //sidc['G-C-OXW---'] = [];//2.X.2.5.1.3
298 | //sidc['G-C-OXST--'] = [];//2.X.2.5.1.8
299 | //sidc['G-C-OXA---'] = [];//2.X.2.5.1.10
300 | //sidc['G-C-OL----'] = [];//2.X.2.5.3
301 | //sidc['*-*-*'] = [];//G
302 | //sidc['*-*-*'] = [];//G
303 | //sidc['*-*-*'] = [];//G
304 | //sidc['*-*-*'] = [];//G
305 | //sidc['G-O-------'] = [];//2.X.3
306 | //sidc['G-O-V-----'] = [];//2.X.3.1
307 | //sidc['G-O-L-----'] = [];//2.X.3.2
308 | //sidc['G-O-P-----'] = [];//2.X.3.3
309 | //sidc['G-O-PJ----'] = [];//2.X.3.3.13
310 | //sidc['G-O-I-----'] = [];//2.X.3.4
311 | };
312 |
--------------------------------------------------------------------------------
/src/ms/addsidcgraphics.js:
--------------------------------------------------------------------------------
1 | var addSIDCgraphics = function(parts, type) {
2 | if (typeof parts === "function") {
3 | if (typeof this["_" + type + "SIDCgraphics"] === "undefined") {
4 | this["_" + type + "SIDCgraphics"] = [];
5 | }
6 | this["_" + type + "SIDCgraphics"] = this[
7 | "_" + type + "SIDCgraphics"
8 | ].concat(parts);
9 | }
10 | return this;
11 | };
12 |
13 | module.exports = addSIDCgraphics;
14 |
--------------------------------------------------------------------------------
/src/number-sidc/properties.js:
--------------------------------------------------------------------------------
1 | var ms = require("milsymbol");
2 |
3 | module.exports = function(properties, mapping) {
4 | var version = this.SIDC.substr(0, 2);
5 | var standardIdentity1 = this.SIDC.substr(2, 1);
6 | var standardIdentity2 = this.SIDC.substr(3, 1);
7 | var symbolSet = this.SIDC.substr(4, 2);
8 | var status = this.SIDC.substr(6, 1);
9 | var headquartersTaskForceDummy = this.SIDC.substr(7, 1);
10 | var echelonMobility = this.SIDC.substr(8, 2);
11 |
12 | var affiliationMapping = {
13 | "0": "Unknown",
14 | "1": "Unknown",
15 | "2": "Friend",
16 | "3": "Friend",
17 | "4": "Neutral",
18 | "5": "Hostile",
19 | "6": "Hostile"
20 | };
21 |
22 | var dimensionMapping = {
23 | "00": "Sea",
24 | "01": "Air",
25 | "02": "Air",
26 | "05": "Air",
27 | "06": "Air",
28 | "10": "Ground",
29 | "11": "Ground",
30 | "12": "Ground",
31 | "15": "Ground",
32 | "20": "Ground",
33 | "30": "Sea",
34 | "35": "Subsurface",
35 | "36": "Subsurface",
36 | "39": "Subsurface",
37 | "40": "Ground",
38 | "50": "Air",
39 | "51": "Air",
40 | "52": "Ground",
41 | "53": "Sea",
42 | "54": "Subsurface",
43 | "60": "Ground"
44 | };
45 |
46 | var functionid = (properties.functionid = this.SIDC.substr(10, 10));
47 |
48 | properties.context = mapping.context[parseInt(this.SIDC.substr(2, 1))];
49 | properties.affiliation = affiliationMapping[standardIdentity2];
50 | properties.dimension = dimensionMapping[symbolSet];
51 |
52 | //Planned/Anticipated/Suspect symbols should have a dashed outline
53 | if (status == "1") properties.notpresent = ms._dashArrays.anticipated;
54 | if (
55 | standardIdentity2 == "0" ||
56 | standardIdentity2 == "2" ||
57 | standardIdentity2 == "5"
58 | )
59 | properties.notpresent = ms._dashArrays.pending;
60 |
61 | if (echelonMobility >= 70 && echelonMobility < 80) {
62 | properties.leadership = mapping.echelonMobility[echelonMobility];
63 | }
64 |
65 | return properties;
66 | };
67 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | var CustomVarLibraryNamePlugin = require("webpack-custom-var-library-name-plugin");
3 |
4 | module.exports = {
5 | entry: "./src/index.js",
6 | output: {
7 | filename: "milgraphics.js",
8 | path: path.resolve(__dirname, "dist"),
9 | library: "milgraphics",
10 | libraryTarget: "umd",
11 | umdNamedDefine: true
12 | },
13 | plugins: [
14 | new CustomVarLibraryNamePlugin({
15 | name: "ms"
16 | })
17 | ]
18 | };
19 |
--------------------------------------------------------------------------------