source: osm/applications/editors/josm/plugins/seachart/src/render/Signals.java@ 30894

Last change on this file since 30894 was 30894, checked in by malcolmh, 10 years ago

Add SeaChart plugin

File size: 26.4 KB
Line 
1/* Copyright 2014 Malcolm Herring
2 *
3 * This is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License.
6 *
7 * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
8 */
9
10package render;
11
12import java.awt.Color;
13import java.awt.Font;
14import java.awt.geom.*;
15import java.util.ArrayList;
16import java.util.EnumMap;
17
18import s57.S57att.*;
19import s57.S57obj.*;
20import s57.S57val.*;
21import s57.S57map.*;
22import symbols.Beacons;
23import symbols.Topmarks;
24import symbols.Symbols.*;
25
26public class Signals {
27
28 static final EnumMap<ColCOL, Color> lightColours = new EnumMap<ColCOL, Color>(ColCOL.class);
29 static {
30 lightColours.put(ColCOL.COL_WHT, new Color(0xffff00));
31 lightColours.put(ColCOL.COL_RED, new Color(0xff0000));
32 lightColours.put(ColCOL.COL_GRN, new Color(0x00ff00));
33 lightColours.put(ColCOL.COL_BLU, new Color(0x0000ff));
34 lightColours.put(ColCOL.COL_YEL, new Color(0xffff00));
35 lightColours.put(ColCOL.COL_AMB, new Color(0xffc200));
36 lightColours.put(ColCOL.COL_VIO, new Color(0xee82ee));
37 lightColours.put(ColCOL.COL_ORG, Color.orange);
38 lightColours.put(ColCOL.COL_MAG, Color.magenta);
39 }
40
41 static final EnumMap<ColCOL, String> lightLetters = new EnumMap<ColCOL, String>(ColCOL.class);
42 static {
43 lightLetters.put(ColCOL.COL_WHT, "W");
44 lightLetters.put(ColCOL.COL_RED, "R");
45 lightLetters.put(ColCOL.COL_GRN, "G");
46 lightLetters.put(ColCOL.COL_BLU, "Bu");
47 lightLetters.put(ColCOL.COL_YEL, "Y");
48 lightLetters.put(ColCOL.COL_AMB, "Am");
49 lightLetters.put(ColCOL.COL_VIO, "Vi");
50 lightLetters.put(ColCOL.COL_ORG, "Or");
51 }
52
53 static final EnumMap<LitCHR, String> lightCharacters = new EnumMap<LitCHR, String>(LitCHR.class);
54 static {
55 lightCharacters.put(LitCHR.CHR_F, "W");
56 lightCharacters.put(LitCHR.CHR_FL, "Fl");
57 lightCharacters.put(LitCHR.CHR_LFL, "LFl");
58 lightCharacters.put(LitCHR.CHR_Q, "Q");
59 lightCharacters.put(LitCHR.CHR_VQ, "VQ");
60 lightCharacters.put(LitCHR.CHR_UQ, "UQ");
61 lightCharacters.put(LitCHR.CHR_ISO, "Iso");
62 lightCharacters.put(LitCHR.CHR_OC, "Oc");
63 lightCharacters.put(LitCHR.CHR_IQ, "IQ");
64 lightCharacters.put(LitCHR.CHR_IVQ, "IVQ");
65 lightCharacters.put(LitCHR.CHR_IUQ, "IUQ");
66 lightCharacters.put(LitCHR.CHR_MO, "Mo");
67 lightCharacters.put(LitCHR.CHR_FFL, "FFl");
68 lightCharacters.put(LitCHR.CHR_FLLFL, "FlLFl");
69 lightCharacters.put(LitCHR.CHR_OCFL, "OcFl");
70 lightCharacters.put(LitCHR.CHR_FLFL, "FLFl");
71 lightCharacters.put(LitCHR.CHR_ALOC, "Al.Oc");
72 lightCharacters.put(LitCHR.CHR_ALLFL, "Al.LFl");
73 lightCharacters.put(LitCHR.CHR_ALFL, "Al.Fl");
74 lightCharacters.put(LitCHR.CHR_ALGR, "Al.Gr");
75 lightCharacters.put(LitCHR.CHR_QLFL, "Q+LFl");
76 lightCharacters.put(LitCHR.CHR_VQLFL, "VQ+LFl");
77 lightCharacters.put(LitCHR.CHR_UQLFL, "UQ+LFl");
78 lightCharacters.put(LitCHR.CHR_AL, "Al");
79 lightCharacters.put(LitCHR.CHR_ALFFL, "Al.FFl");
80 }
81
82 public static void addSignals(Feature feature) {
83 if (feature.objs.containsKey(Obj.FOGSIG)) fogSignals(feature);
84 if (feature.objs.containsKey(Obj.RTPBCN)) radarStations(feature);
85 if (feature.objs.containsKey(Obj.RADSTA)) radarStations(feature);
86 if (feature.objs.containsKey(Obj.RDOSTA)) radioStations(feature);
87 if (feature.objs.containsKey(Obj.LIGHTS)) lights(feature);
88 }
89
90 static final EnumMap<CatFOG, String> fogSignals = new EnumMap<CatFOG, String>(CatFOG.class);
91 static {
92 fogSignals.put(CatFOG.FOG_EXPL, "Explos");
93 fogSignals.put(CatFOG.FOG_DIA, "Dia");
94 fogSignals.put(CatFOG.FOG_SIRN, "Siren");
95 fogSignals.put(CatFOG.FOG_NAUT, "Horn");
96 fogSignals.put(CatFOG.FOG_REED, "Horn");
97 fogSignals.put(CatFOG.FOG_TYPH, "Horn");
98 fogSignals.put(CatFOG.FOG_BELL, "Bell");
99 fogSignals.put(CatFOG.FOG_WHIS, "Whis");
100 fogSignals.put(CatFOG.FOG_GONG, "Gong");
101 fogSignals.put(CatFOG.FOG_HORN, "Horn");
102 }
103
104 public static void fogSignals(Feature feature) {
105 Renderer.symbol(feature, Beacons.FogSignal);
106 AttMap atts = feature.objs.get(Obj.FOGSIG).get(0);
107 String str = "";
108 if (atts.containsKey(Att.CATFOG)) {
109 str += fogSignals.get(atts.get(Att.CATFOG).val);
110 }
111 if (atts.containsKey(Att.SIGGRP)) {
112 str += "(" + atts.get(Att.SIGGRP).val + ")";
113 } else {
114 str += " ";
115 }
116 if (atts.containsKey(Att.SIGPER)) {
117 str += atts.get(Att.SIGPER).val + "s";
118 }
119 if (atts.containsKey(Att.VALMXR)) {
120 str += atts.get(Att.VALMXR).val + "M";
121 }
122 if ((Renderer.zoom >= 15) && !str.isEmpty()) {
123 Renderer.labelText(feature, str, new Font("Arial", Font.PLAIN, 40),Color.black, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-60, -30)));
124 }
125 }
126
127 public static void radarStations(Feature feature) {
128 Renderer.symbol(feature, Beacons.RadarStation);
129 String bstr = "";
130 CatRTB cat = (CatRTB) Rules.getAttVal(feature, Obj.RTPBCN, 0, Att.CATRTB);
131 String wal = (String) Rules.getAttVal(feature, Obj.RTPBCN, 0, Att.RADWAL);
132 switch (cat) {
133 case RTB_RAMK:
134 bstr += " Ramark";
135 break;
136 case RTB_RACN:
137 bstr += " Racon";
138 String astr = (String) Rules.getAttVal(feature, Obj.RTPBCN, 0, Att.SIGGRP);
139 if (!astr.isEmpty()) {
140 bstr += "(" + astr + ")";
141 }
142 Double per = (Double) Rules.getAttVal(feature, Obj.RTPBCN, 0, Att.SIGPER);
143 Double mxr = (Double) Rules.getAttVal(feature, Obj.RTPBCN, 0, Att.VALMXR);
144 if ((per != 0) || (mxr != 0)) {
145 bstr += (astr.isEmpty() ? " " : "");
146 bstr += (per != 0) ? per.toString() + "s" : "";
147 bstr += (mxr != 0) ? mxr.toString() + "M" : "";
148 }
149 break;
150 default:
151 break;
152 }
153 if (wal!= null) {
154 switch (wal) {
155 case "0.03-X":
156 bstr += "(3cm)";
157 break;
158 case "0.10-S":
159 bstr += "(10cm)";
160 break;
161 }
162 }
163 if ((Renderer.zoom >= 15) && !bstr.isEmpty()) {
164 Renderer.labelText(feature, bstr, new Font("Arial", Font.PLAIN, 40), Rules.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -70)));
165 }
166 }
167
168 public static void radioStations(Feature feature) {
169 Renderer.symbol(feature, Beacons.RadarStation);
170 ArrayList<CatROS> cats = (ArrayList<CatROS>)Rules.getAttVal(feature, Obj.RDOSTA, 0, Att.CATROS);
171 boolean vais = false;
172 String bstr = "";
173 for (CatROS ros : cats) {
174 switch (ros) {
175 case ROS_OMNI:
176 bstr += " RC";
177 break;
178 case ROS_DIRL:
179 bstr += " RD";
180 break;
181 case ROS_ROTP:
182 bstr += " RW";
183 break;
184 case ROS_CNSL:
185 bstr += " Consol";
186 break;
187 case ROS_RDF:
188 bstr += " RG";
189 break;
190 case ROS_QTA:
191 bstr += " R";
192 break;
193 case ROS_AERO:
194 bstr += " AeroRC";
195 break;
196 case ROS_DECA:
197 bstr += " Decca";
198 break;
199 case ROS_LORN:
200 bstr += " Loran";
201 break;
202 case ROS_DGPS:
203 bstr += " DGPS";
204 break;
205 case ROS_TORN:
206 bstr += " Toran";
207 break;
208 case ROS_OMGA:
209 bstr += " Omega";
210 break;
211 case ROS_SYLD:
212 bstr += " Syledis";
213 break;
214 case ROS_CHKA:
215 bstr += " Chiaka";
216 break;
217 case ROS_PCOM:
218 case ROS_COMB:
219 case ROS_FACS:
220 case ROS_TIME:
221 break;
222 case ROS_PAIS:
223 case ROS_SAIS:
224 bstr += " AIS";
225 break;
226 case ROS_VAIS:
227 vais = true;
228 break;
229 case ROS_VANC:
230 vais = true;
231 Renderer.symbol(feature, Topmarks.TopNorth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
232 break;
233 case ROS_VASC:
234 vais = true;
235 Renderer.symbol(feature, Topmarks.TopSouth, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
236 break;
237 case ROS_VAEC:
238 vais = true;
239 Renderer.symbol(feature, Topmarks.TopEast, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
240 break;
241 case ROS_VAWC:
242 vais = true;
243 Renderer.symbol(feature, Topmarks.TopWest, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
244 break;
245 case ROS_VAPL:
246 vais = true;
247 Renderer.symbol(feature, Topmarks.TopCan, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
248 break;
249 case ROS_VASL:
250 vais = true;
251 Renderer.symbol(feature, Topmarks.TopCone, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
252 break;
253 case ROS_VAID:
254 vais = true;
255 Renderer.symbol(feature, Topmarks.TopIsol, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
256 break;
257 case ROS_VASW:
258 vais = true;
259 Renderer.symbol(feature, Topmarks.TopSphere, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
260 break;
261 case ROS_VASP:
262 vais = true;
263 Renderer.symbol(feature, Topmarks.TopX, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
264 break;
265 case ROS_VAWK:
266 vais = true;
267 Renderer.symbol(feature, Topmarks.TopCross, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, -25)));
268 break;
269 default:
270 break;
271 }
272 }
273 if (Renderer.zoom >= 15) {
274 if (vais) {
275 Renderer.labelText(feature, "V-AIS", new Font("Arial", Font.PLAIN, 40), Rules.Msymb, new Delta(Handle.BC, AffineTransform.getTranslateInstance(0, 70)));
276 }
277 if (!bstr.isEmpty()) {
278 Renderer.labelText(feature, bstr, new Font("Arial", Font.PLAIN, 40), Rules.Msymb, new Delta(Handle.TR, AffineTransform.getTranslateInstance(-30, -110)));
279 }
280 }
281 }
282
283 public static void lights(Feature feature) {
284 Enum<ColCOL> col = null;
285 Enum<ColCOL> tcol = null;
286 ObjTab objs = feature.objs.get(Obj.LIGHTS);
287 for (AttMap atts : objs.values()) {
288 if (atts.containsKey(Att.COLOUR)) {
289 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
290 if (cols.size() == 1) {
291 tcol = cols.get(0);
292 if (col == null) {
293 col = tcol;
294 } else if (tcol != col) {
295 col = ColCOL.COL_MAG;
296 break;
297 }
298 } else {
299 col = ColCOL.COL_MAG;
300 break;
301 }
302 }
303 }
304 Renderer.symbol(feature, Beacons.LightFlare, new Scheme(lightColours.get(col)), new Delta(Handle.BC, AffineTransform.getRotateInstance(Math.toRadians(120))));
305 if (objs.get(1) != null) {
306 for (AttMap atts : objs.values()) {
307 Enum<ColCOL> col1 = null;
308 Enum<ColCOL> col2 = null;
309 double radius = 0.2;
310 double s1 = 0;
311 double s2 = 0;
312 boolean dir = false;
313 if (atts.containsKey(Att.COLOUR)) {
314 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
315 col1 = cols.get(0);
316 if (cols.size() > 1) col2 = cols.get(1);
317 } else {
318 continue;
319 }
320 if (atts.containsKey(Att.RADIUS)) {
321 radius = (Double) atts.get(Att.RADIUS).val;
322 }
323 if (atts.containsKey(Att.SECTR1)) {
324 s1 = (Double) atts.get(Att.SECTR1).val;
325 } else {
326 continue;
327 }
328 if (atts.containsKey(Att.SECTR2)) {
329 s2 = (Double) atts.get(Att.SECTR2).val;
330 } else {
331 continue;
332 }
333 if (atts.containsKey(Att.CATLIT)) {
334 ArrayList<CatLIT> cats = (ArrayList<CatLIT>) atts.get(Att.CATLIT).val;
335 if (cats.contains(CatLIT.LIT_DIR)) {
336 dir = true;
337 }
338 }
339 String str = "";
340 if (atts.containsKey(Att.LITCHR)) {
341 str += lightCharacters.get(atts.get(Att.LITCHR).val);
342 }
343 if (atts.containsKey(Att.SIGGRP)) {
344 str += "(" + atts.get(Att.SIGGRP).val + ")";
345 } else if (!str.isEmpty()) {
346 str += ".";
347 }
348 if (atts.containsKey(Att.COLOUR)) {
349 ArrayList<Enum<ColCOL>> cols = (ArrayList<Enum<ColCOL>>) atts.get(Att.COLOUR).val;
350 str += lightLetters.get(cols.get(0));
351 if (cols.size() > 1)
352 str += lightLetters.get(cols.get(1));
353 }
354 if (dir && atts.containsKey(Att.ORIENT)) {
355 double orient = (Double)atts.get(Att.ORIENT).val;
356 str += " " + orient + "°";
357 s1 = (orient - 4 + 360) % 360;
358 s2 = (orient + 4) % 360;
359 double n1 = 360;
360 double n2 = 360;
361 for (AttMap sect : objs.values()) {
362 if (sect != atts) {
363
364 }
365 }
366 }
367 Renderer.lightSector(feature, lightColours.get(col1), lightColours.get(col2), radius, s1, s2, dir, str);
368 }
369 }
370 }
371
372 /*
373void renderSector(Item_t *item, int s, char *text, char *style, double offset, int dy) {
374 Obj_t *sector;
375 double start, end;
376 Att_t *att;
377 XY_t p0, p1;
378 double r0, r1;
379 double b0, b1, span;
380 char *col;
381 XY_t pos = findCentroid(item);
382 if ((sector = getObj(item, LIGHTS, s)) != NULL) {
383 strcpy(string1, (att = getAtt(sector, LITRAD)) != NULL ? att->val.val.a : "0.2");
384 if (((att = getAtt(sector, CATLIT)) != NULL) && (testAtt(att, LIT_DIR)) && ((att = getAtt(sector, ORIENT)) != NULL)) {
385 b0 = fmod(540.0 - att->val.val.f, 360.0);
386 if ((att = getAtt(sector, COLOUR)) != NULL) {
387 col = light_colours[att->val.val.l->val];
388 r0 = atof(string1);
389 p0 = radial(pos, r0, b0);
390 printf("<path d=\"M %g,%g L %g,%g\" style=\"fill:none;stroke:#808080;stroke-width:%g;stroke-dasharray:%g\"/>\n",
391 pos.x, pos.y, p0.x, p0.y, (4 * symbolScale[zoom]), (20 * symbolScale[zoom]));
392 start = fmod(b0 + 2.0, 360.0);
393 end = fmod(360.0 + b0 - 2.0, 360.0);
394 Obj_t *adj;
395 for (int i = s-1; i <= s+1; i++) {
396 if (i == s) continue;
397 if ((adj = getObj(item, LIGHTS, i)) == NULL) continue;
398 Att_t *att;
399 if (((att = getAtt(adj, CATLIT)) != NULL) && (testAtt(att, LIT_DIR)) && ((att = getAtt(adj, ORIENT)) != NULL)) {
400 b1 = fmod(540.0 - att->val.val.f, 360.0);
401 if (fabs(b0 - b1) > 180.0) {
402 if (b0 < b1) b0 += 360.0;
403 else b1 += 360.0;
404 }
405 if (fabs(b0 - b1) < 4.0) {
406 if (b1 > b0) start = fmod((720.0 + b0 + b1) / 2.0, 360.0);
407 else end = fmod((720.0 + b0 + b1) / 2.0, 360.0);
408 }
409 }
410 }
411 p0 = radial(pos, r0, start);
412 p1 = radial(pos, r0, end);
413 printf("<path id=\"%d\" d=\"M %g,%g A %g,%g,0,0,1,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g\"/>\n",
414 ++ref, p0.x, p0.y, r0*mile, r0*mile, p1.x, p1.y, col, (20 * symbolScale[zoom]));
415 if (att->val.val.l->next != NULL) {
416 char *col = light_colours[att->val.val.l->next->val];
417 r1 = r0 - (20 * symbolScale[zoom]/mile);
418 p0 = radial(pos, r1, start);
419 p1 = radial(pos, r1, end);
420 printf("<path d=\"M %g,%g A %g,%g,0,0,1,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g\"/>\n",
421 p0.x, p0.y, r1*mile, r1*mile, p1.x, p1.y, col, (20 * symbolScale[zoom]));
422 }
423 }
424 } else if ((att = getAtt(sector, SECTR1)) != NULL) {
425 start = fmod(540.0 - att->val.val.f, 360.0);
426 if ((att = getAtt(sector, SECTR2)) != NULL) {
427 end = fmod(540.0 - att->val.val.f, 360.0);
428 start += start < end ? 360.0 : 0.0;
429 if ((att = getAtt(sector, COLOUR)) != NULL) {
430 char *ttok, *etok;
431 char *radstr = strdup(string1);
432 int arc = 0;
433 col = light_colours[att->val.val.l->val];
434 r0 = 0.0;
435 b0 = b1 = start;
436 for (char *tpl = strtok_r(radstr, ";", &ttok); tpl != NULL; tpl = strtok_r(NULL, ";", &ttok)) {
437 p0 = radial(pos, r0, b0);
438 span = 0.0;
439 char *ele = strtok_r(tpl, ":", &etok);
440 if ((*tpl == ':') && (r0 == 0.0)) {
441 r1 = 0.2;
442 } else if (*tpl != ':') {
443 r1 = atof(tpl);
444 ele = strtok_r(NULL, ":", &etok);
445 }
446 while (ele != NULL) {
447 if (isalpha(*ele)) {
448 if (strcmp(ele, "suppress") == 0) arc = 2;
449 else if (strcmp(ele, "dashed") == 0) arc = 1;
450 else arc = 0;
451 } else {
452 span = atof(ele);
453 }
454 ele = strtok_r(NULL, ":", &etok);
455 }
456 if (span == 0.0) {
457 char *back = (ttok != NULL) ? strstr(ttok, "-") : NULL;
458 if (back != NULL) {
459 span = b0 - end + atof(back);
460 } else {
461 span = b0 - end;
462 }
463 }
464 if (r1 != r0) {
465 p1 = radial(pos, r1, b0);
466 if (!((start == 180.0) && (end == 180.0)))
467 printf("<path d=\"M %g,%g L %g,%g\" style=\"fill:none;stroke:#808080;stroke-width:%g;stroke-dasharray:%g\"/>\n",
468 p0.x, p0.y, p1.x, p1.y, (4 * symbolScale[zoom]), (20 * symbolScale[zoom]));
469 r0 = r1;
470 p0 = p1;
471 }
472 if (span < 0.0) {
473 b1 = end - span;
474 b1 = b1 > b0 ? b0 : b1;
475 b0 = b1;
476 b1 = end;
477 p0 = radial(pos, r0, b0);
478 } else {
479 b1 = b0 - span;
480 b1 = b1 < end ? end : b1;
481 }
482 p1 = radial(pos, r1, b1);
483 if ((b0 == 180.0) && (b1 == 180.0)) {
484 span = 360.0;
485 p1 = radial(pos, r1, b1+0.01);
486 }
487 if (arc == 0) {
488 if (p0.x < p1.x)
489 printf("<path id=\"%d\" d=\"M %g,%g A %g,%g,0,%d,1,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g\"/>\n",
490 ++ref, p0.x, p0.y, r1*mile, r1*mile, span>180.0, p1.x, p1.y, col, (20 * symbolScale[zoom]));
491 else
492 printf("<path id=\"%d\" d=\"M %g,%g A %g,%g,0,%d,0,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g\"/>\n",
493 ++ref, p1.x, p1.y, r1*mile, r1*mile, span>180.0, p0.x, p0.y, col, (20 * symbolScale[zoom]));
494 if (text != NULL) {
495 double chord = sqrt(pow((p0.x - p1.x), 2) + pow((p0.y - p1.y), 2));
496 if ((chord > (strlen(text) * textScale[zoom] * 50)) || ((b0 == 180.0) && (b1 == 180.0)))
497 drawLineText(item, text, style, offset, dy, ref);
498 }
499 } else if (arc == 1) {
500 printf("<path d=\"M %g,%g A %g,%g,0,%d,1,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g;stroke-opacity:0.5;stroke-dasharray:%g\"/>\n",
501 p0.x, p0.y, r1*mile, r1*mile, span>180.0, p1.x, p1.y, col, (10 * symbolScale[zoom]), (30 * symbolScale[zoom]));
502 }
503 if ((arc == 0) && (att->val.val.l->next != NULL)) {
504 char *col = light_colours[att->val.val.l->next->val];
505 double r2 = r1 - (20 * symbolScale[zoom]/mile);
506 XY_t p2 = radial(pos, r2, b0);
507 XY_t p3 = radial(pos, r2, b1);
508 printf("<path d=\"M %g,%g A %g,%g,0,%d,1,%g,%g\" style=\"fill:none;stroke:%s;stroke-width:%g\"/>\n",
509 p2.x, p2.y, r1*mile, r1*mile, span>180.0, p3.x, p3.y, col, (20 * symbolScale[zoom]));
510 }
511 b0 = b1;
512 if (b0 == end) break;
513 }
514 if (!((start == 180.0) && (end == 180.0)))
515 printf("<path d=\"M %g,%g L %g,%g\" style=\"fill:none;stroke:#808080;stroke-width:%g;stroke-dasharray:%g\"/>\n",
516 pos.x, pos.y, p1.x, p1.y, (4 * symbolScale[zoom]), (20 * symbolScale[zoom]));
517 free(radstr);
518 }
519 }
520 }
521 }
522}
523char *charString(Item_t *item, char *type, int idx) {
524 strcpy(string1, "");
525 Att_t *att = NULL;
526 Obj_t *obj = getObj(item, enumType(type), idx);
527 switch (enumType(type)) {
528 case LIGHTS:
529 {
530 int secmax = countObjects(item, "light");
531 if ((idx == 0) && (secmax > 0)) {
532 struct SECT {
533 struct SECT *next;
534 int dir;
535 LitCHR_t chr;
536 ColCOL_t col;
537 ColCOL_t alt;
538 char *grp;
539 double per;
540 double rng;
541 } *lights = NULL;
542 for (int i = secmax; i > 0; i--) {
543 struct SECT *tmp = calloc(1, sizeof(struct SECT));
544 tmp->next = lights;
545 lights = tmp;
546 obj = getObj(item, LIGHTS, i);
547 if ((att = getAtt(obj, CATLIT)) != NULL) {
548 lights->dir = testAtt(att, LIT_DIR);
549 }
550 if ((att = getAtt(obj, LITCHR)) != NULL) {
551 lights->chr = att->val.val.e;
552 switch (lights->chr) {
553 case CHR_AL:
554 lights->chr = CHR_F;
555 break;
556 case CHR_ALOC:
557 lights->chr = CHR_OC;
558 break;
559 case CHR_ALLFL:
560 lights->chr = CHR_LFL;
561 break;
562 case CHR_ALFL:
563 lights->chr = CHR_FL;
564 break;
565 case CHR_ALFFL:
566 lights->chr = CHR_FFL;
567 break;
568 default:
569 break;
570 }
571 }
572 if ((att = getAtt(obj, SIGGRP)) != NULL) {
573 lights->grp = att->val.val.a;
574 } else {
575 lights->grp = "";
576 }
577 if ((att = getAtt(obj, SIGPER)) != NULL) {
578 lights->per = att->val.val.f;
579 }
580 if ((att = getAtt(obj, VALNMR)) != NULL) {
581 lights->rng = att->val.val.f;
582 }
583 if ((att = getAtt(obj, COLOUR)) != NULL) {
584 lights->col = att->val.val.l->val;
585 if (att->val.val.l->next != NULL)
586 lights->alt = att->val.val.l->next->val;
587 }
588 }
589 struct COLRNG {
590 int col;
591 double rng;
592 } colrng[14];
593 while (lights != NULL) {
594 strcpy(string2, "");
595 bzero(colrng, 14*sizeof(struct COLRNG));
596 colrng[lights->col].col = 1;
597 colrng[lights->col].rng = lights->rng;
598 struct SECT *this = lights;
599 struct SECT *next = lights->next;
600 while (next != NULL) {
601 if ((this->dir == next->dir) && (this->chr == next->chr) &&
602 (strcmp(this->grp, next->grp) == 0) && (this->per == next->per)) {
603 colrng[next->col].col = 1;
604 if (next->rng > colrng[next->col].rng)
605 colrng[next->col].rng = next->rng;
606 struct SECT *tmp = lights;
607 while (tmp->next != next) tmp = tmp->next;
608 tmp->next = next->next;
609 free(next);
610 next = tmp->next;
611 } else {
612 next = next->next;
613 }
614 }
615 if (this->chr != CHR_UNKN) {
616 if (this->dir) strcpy(string2, "Dir.");
617 strcat(string2, light_characters[this->chr]);
618 if (strcmp(this->grp, "") != 0) {
619 if (this->grp[0] == '(')
620 sprintf(strchr(string2, 0), "%s", this->grp);
621 else
622 sprintf(strchr(string2, 0), "(%s)", this->grp);
623 } else {
624 if (strlen(string2) > 0) strcat(string2, ".");
625 }
626 int n = 0;
627 for (int i = 0; i < 14; i++) if (colrng[i].col) n++;
628 double max = 0.0;
629 for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng > max)) max = colrng[i].rng;
630 double min = max;
631 for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng > 0.0) && (colrng[i].rng < min)) min = colrng[i].rng;
632 if (min == max) {
633 for (int i = 0; i < 14; i++) if (colrng[i].col) strcat(string2, light_letters[i]);
634 } else {
635 for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng == max)) strcat(string2, light_letters[i]);
636 for (int i = 0; i < 14; i++) if (colrng[i].col && (colrng[i].rng < max) && (colrng[i].rng > min)) strcat(string2, light_letters[i]);
637 for (int i = 0; i < 14; i++) if (colrng[i].col && colrng[i].rng == min) strcat(string2, light_letters[i]);
638 }
639 strcat(string2, ".");
640 if (this->per > 0.0) sprintf(strchr(string2, 0), "%gs", this->per);
641 if (max > 0.0) {
642 sprintf(strchr(string2, 0), "%g", max);
643 if (min != max) {
644 if (n == 2) strcat(string2, "/");
645 else if (n > 2) strcat(string2, "-");
646 if (min < max) sprintf(strchr(string2, 0), "%g", min);
647 }
648 strcat(string2, "M");
649 }
650 if (strlen(string1) > 0) strcat(string1, "\n");
651 strcat(string1, string2);
652 }
653 lights = this->next;
654 free(this);
655 this = lights;
656 }
657 } else {
658 if ((att = getAtt(obj, CATLIT)) != NULL) {
659 if (testAtt(att, LIT_DIR))
660 strcat(string1, "Dir");
661 }
662 if ((att = getAtt(obj, MLTYLT)) != NULL)
663 sprintf(strchr(string1, 0), "%s", stringValue(att->val));
664 if ((att = getAtt(obj, LITCHR)) != NULL) {
665 char *chrstr = strdup(stringValue(att->val));
666 Att_t *grp = getAtt(obj, SIGGRP);
667 if (grp != NULL) {
668 char *strgrp = strdup(stringValue(grp->val));
669 char *grpstr = strtok(strgrp, "()");
670 switch (att->val.val.e) {
671 case CHR_QLFL:
672 sprintf(strchr(string1, 0), "Q(%s)+LFl", grpstr);
673 break;
674 case CHR_VQLFL:
675 sprintf(strchr(string1, 0), "VQ(%s)+LFl", grpstr);
676 break;
677 case CHR_UQLFL:
678 sprintf(strchr(string1, 0), "UQ(%s)+LFl", grpstr);
679 break;
680 default:
681 sprintf(strchr(string1, 0), "%s(%s)", chrstr, grpstr);
682 break;
683 }
684 free(strgrp);
685 } else {
686 sprintf(strchr(string1, 0), "%s", chrstr);
687 }
688 free(chrstr);
689 }
690 if ((att = getAtt(obj, COLOUR)) != NULL) {
691 int n = countValues(att);
692 if (!((n == 1) && (idx == 0) && (testAtt(att, COL_WHT)))) {
693 if ((strlen(string1) > 0) && ((string1[strlen(string1)-1] != ')')))
694 strcat(string1, ".");
695 Lst_t *lst = att->val.val.l;
696 while (lst != NULL) {
697 strcat(string1, light_letters[lst->val]);
698 lst = lst->next;
699 }
700 }
701 }
702 if ((idx == 0) && (att = getAtt(obj, CATLIT)) != NULL) {
703 if (testAtt(att, LIT_VERT))
704 strcat(string1, "(vert)");
705 if (testAtt(att, LIT_HORI))
706 strcat(string1, "(hor)");
707 }
708 if ((strlen(string1) > 0) &&
709 ((getAtt(obj, SIGPER) != NULL) ||
710 (getAtt(obj, HEIGHT) != NULL) ||
711 (getAtt(obj, VALMXR) != NULL)) &&
712 (string1[strlen(string1)-1] != ')'))
713 strcat(string1, ".");
714 if ((att = getAtt(obj, SIGPER)) != NULL)
715 sprintf(strchr(string1, 0), "%ss", stringValue(att->val));
716 if ((idx == 0) && (item->objs.obj != LITMIN)) {
717 if ((att = getAtt(obj, HEIGHT)) != NULL)
718 sprintf(strchr(string1, 0), "%sm", stringValue(att->val));
719 if ((att = getAtt(obj, VALNMR)) != NULL)
720 sprintf(strchr(string1, 0), "%sM", stringValue(att->val));
721 }
722 if ((idx == 0) && (att = getAtt(obj, CATLIT)) != NULL) {
723 if (testAtt(att, LIT_FRNT))
724 strcat(string1, "(Front)");
725 if (testAtt(att, LIT_REAR))
726 strcat(string1, "(Rear)");
727 if (testAtt(att, LIT_UPPR))
728 strcat(string1, "(Upper)");
729 if (testAtt(att, LIT_LOWR))
730 strcat(string1, "(Lower)");
731 }
732 }
733 }
734 break;
735 default: break;
736 }
737 return string1;
738}
739*/
740
741}
Note: See TracBrowser for help on using the repository browser.