source: josm/trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java@ 1728

Last change on this file since 1728 was 1728, checked in by stoecker, 15 years ago

fixed #2804 - move mode not working

  • Property svn:eol-style set to native
File size: 54.0 KB
Line 
1/* License: GPL. Copyright 2007 by Immanuel Scholz and others */
2package org.openstreetmap.josm.data.osm.visitor;
3
4/* To enable debugging or profiling remove the double / signs */
5
6import static org.openstreetmap.josm.tools.I18n.marktr;
7import static org.openstreetmap.josm.tools.I18n.tr;
8
9import java.awt.BasicStroke;
10import java.awt.Color;
11import java.awt.Font;
12import java.awt.Graphics2D;
13import java.awt.Image;
14import java.awt.Point;
15import java.awt.Polygon;
16import java.awt.Stroke;
17import java.awt.geom.GeneralPath;
18import java.util.ArrayList;
19import java.util.Arrays;
20import java.util.Collection;
21import java.util.Iterator;
22import java.util.LinkedList;
23
24import javax.swing.ImageIcon;
25
26import org.openstreetmap.josm.Main;
27import org.openstreetmap.josm.data.coor.EastNorth;
28import org.openstreetmap.josm.data.coor.LatLon;
29import org.openstreetmap.josm.data.osm.DataSet;
30import org.openstreetmap.josm.data.osm.Node;
31import org.openstreetmap.josm.data.osm.OsmPrimitive;
32import org.openstreetmap.josm.data.osm.Relation;
33import org.openstreetmap.josm.data.osm.RelationMember;
34import org.openstreetmap.josm.data.osm.Way;
35import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
36import org.openstreetmap.josm.gui.mappaint.ElemStyle;
37import org.openstreetmap.josm.gui.mappaint.ElemStyles;
38import org.openstreetmap.josm.gui.mappaint.IconElemStyle;
39import org.openstreetmap.josm.gui.mappaint.LineElemStyle;
40import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
41import org.openstreetmap.josm.tools.ImageProvider;
42
43public class MapPaintVisitor extends SimplePaintVisitor {
44 protected boolean useRealWidth;
45 protected boolean zoomLevelDisplay;
46 protected int fillAreas;
47 protected boolean drawMultipolygon;
48 protected boolean drawRestriction;
49 protected boolean leftHandTraffic;
50 //protected boolean restrictionDebug;
51 protected int showNames;
52 protected int showIcons;
53 protected int useStrokes;
54 protected int fillAlpha;
55 protected Color untaggedColor;
56 protected Color textColor;
57 protected float[] currentDashed = new float[0];
58 protected Color currentDashedColor;
59 protected int currentWidth = 0;
60 protected Stroke currentStroke = null;
61 protected Font orderFont;
62 protected ElemStyles.StyleSet styles;
63 protected double circum;
64 protected double dist;
65 protected Collection<String> regionalNameOrder;
66 protected Boolean selectedCall;
67 protected Boolean useStyleCache;
68 private static int paintid = 0;
69 private static int viewid = 0;
70 private EastNorth minEN;
71 private EastNorth maxEN;
72
73 //protected int profilerVisibleNodes;
74 //protected int profilerVisibleWays;
75 //protected int profilerVisibleAreas;
76 //protected int profilerSegments;
77 //protected int profilerVisibleSegments;
78 //protected boolean profilerOmitDraw;
79
80 protected boolean isZoomOk(ElemStyle e) {
81 if (!zoomLevelDisplay) /* show everything if the user wishes so */
82 return true;
83
84 if(e == null) /* the default for things that don't have a rule (show, if scale is smaller than 1500m) */
85 return (circum < 1500);
86
87 return !(circum >= e.maxScale || circum < e.minScale);
88 }
89
90 public ElemStyle getPrimitiveStyle(OsmPrimitive osm) {
91 if(!useStyleCache)
92 return (styles != null) ? styles.get(osm) : null;
93
94 if(osm.mappaintStyle == null && styles != null) {
95 osm.mappaintStyle = styles.get(osm);
96 if(osm instanceof Way)
97 ((Way)osm).isMappaintArea = styles.isArea(osm);
98 }
99 return osm.mappaintStyle;
100 }
101
102 public IconElemStyle getPrimitiveNodeStyle(OsmPrimitive osm) {
103 if(!useStyleCache)
104 return (styles != null) ? styles.getIcon(osm) : null;
105
106 if(osm.mappaintStyle == null && styles != null)
107 osm.mappaintStyle = styles.getIcon(osm);
108
109 return (IconElemStyle)osm.mappaintStyle;
110 }
111
112 public boolean isPrimitiveArea(Way osm) {
113 if(!useStyleCache)
114 return styles.isArea(osm);
115
116 if(osm.mappaintStyle == null && styles != null) {
117 osm.mappaintStyle = styles.get(osm);
118 osm.isMappaintArea = styles.isArea(osm);
119 }
120 return osm.isMappaintArea;
121 }
122
123 /**
124 * Draw a small rectangle.
125 * White if selected (as always) or red otherwise.
126 *
127 * @param n The node to draw.
128 */
129 public void visit(Node n) {
130 /* check, if the node is visible at all */
131 if((n.getEastNorth().east() > maxEN.east() ) ||
132 (n.getEastNorth().north() > maxEN.north()) ||
133 (n.getEastNorth().east() < minEN.east() ) ||
134 (n.getEastNorth().north() < minEN.north()))
135 {
136 n.mappaintVisibleCode = viewid;
137 return;
138 }
139 n.mappaintVisibleCode = 0;
140
141 IconElemStyle nodeStyle = (IconElemStyle)getPrimitiveStyle(n);
142
143 //if(profilerOmitDraw)
144 // return;
145
146 if (nodeStyle != null && isZoomOk(nodeStyle) && showIcons > dist)
147 drawNode(n, nodeStyle.icon, nodeStyle.annotate, n.selected);
148 else if (n.highlighted)
149 drawNode(n, highlightColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
150 else if (n.selected)
151 drawNode(n, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
152 else if (n.isTagged())
153 drawNode(n, nodeColor, taggedNodeSize, taggedNodeRadius, fillUnselectedNode);
154 else
155 drawNode(n, nodeColor, unselectedNodeSize, unselectedNodeRadius, fillUnselectedNode);
156 }
157
158 /**
159 * Draw a line for all segments, according to tags.
160 * @param w The way to draw.
161 */
162 public void visit(Way w) {
163 if(w.nodes.size() < 2)
164 {
165 w.mappaintVisibleCode = viewid;
166 return;
167 }
168
169 /* check, if the way is visible at all */
170 double minx = 10000;
171 double maxx = -10000;
172 double miny = 10000;
173 double maxy = -10000;
174
175 for (Node n : w.nodes)
176 {
177 if(n.getEastNorth().east() > maxx) maxx = n.getEastNorth().east();
178 if(n.getEastNorth().north() > maxy) maxy = n.getEastNorth().north();
179 if(n.getEastNorth().east() < minx) minx = n.getEastNorth().east();
180 if(n.getEastNorth().north() < miny) miny = n.getEastNorth().north();
181 }
182
183 if ((minx > maxEN.east()) ||
184 (miny > maxEN.north()) ||
185 (maxx < minEN.east()) ||
186 (maxy < minEN.north()))
187 {
188 w.mappaintVisibleCode = viewid;
189 return;
190 }
191
192 ElemStyle wayStyle = getPrimitiveStyle(w);
193
194 if(!isZoomOk(wayStyle))
195 {
196 w.mappaintVisibleCode = viewid;
197 return;
198 }
199
200 w.mappaintVisibleCode = 0;
201 if(fillAreas > dist)
202 w.clearErrors();
203
204 if(wayStyle==null)
205 {
206 /* way without style */
207 //profilerVisibleWays++;
208 //if(!profilerOmitDraw)
209 drawWay(w, null, untaggedColor, w.selected);
210 }
211 else if(wayStyle instanceof LineElemStyle)
212 {
213 /* way with line style */
214 //profilerVisibleWays++;
215 //if(!profilerOmitDraw)
216 drawWay(w, (LineElemStyle)wayStyle, untaggedColor, w.selected);
217 }
218 else if (wayStyle instanceof AreaElemStyle)
219 {
220 AreaElemStyle areaStyle = (AreaElemStyle) wayStyle;
221 /* way with area style */
222 //if(!profilerOmitDraw)
223 //{
224 if (fillAreas > dist)
225 {
226 // profilerVisibleAreas++;
227 drawArea(w, w.selected ? selectedColor : areaStyle.color);
228 if(!w.isClosed())
229 w.putError(tr("Area style way is not closed."), true);
230 }
231 drawWay(w, areaStyle.line, areaStyle.color, w.selected);
232 //}
233 }
234 }
235
236 public void drawWay(Way w, LineElemStyle l, Color color, Boolean selected) {
237 /* show direction arrows, if draw.segment.relevant_directions_only is not set,
238 the way is tagged with a direction key
239 (even if the tag is negated as in oneway=false) or the way is selected */
240 boolean showDirection = w.selected || ((!useRealWidth) && (showDirectionArrow
241 && (!showRelevantDirectionsOnly || w.hasDirectionKeys())));
242 /* head only takes over control if the option is true,
243 the direction should be shown at all and not only because it's selected */
244 boolean showOnlyHeadArrowOnly = showDirection && !w.selected && showHeadArrowOnly;
245 int width = defaultSegmentWidth;
246 int realWidth = 0; /* the real width of the element in meters */
247 float dashed[] = new float[0];
248 Color dashedColor = null;
249 Node lastN;
250
251 if(l != null)
252 {
253 if (l.color != null) color = l.color;
254 width = l.width;
255 realWidth = l.realWidth;
256 dashed = l.dashed;
257 dashedColor = l.dashedColor;
258 }
259 if(selected)
260 color = selectedColor;
261 if (realWidth > 0 && useRealWidth && !showDirection)
262 {
263 int tmpWidth = (int) (100 / (float) (circum / realWidth));
264 if (tmpWidth > width) width = tmpWidth;
265
266 /* if we have a "width" tag, try use it */
267 /* (this might be slow and could be improved by caching the value in the Way, on the other hand only used if "real width" is enabled) */
268 String widthTag = w.get("width");
269 if(widthTag == null) {
270 widthTag = w.get("est_width");
271 }
272 if(widthTag != null) {
273 try {
274 width = Integer.parseInt(widthTag);
275 }
276 catch(NumberFormatException nfe) {
277 }
278 }
279 }
280
281 if(w.highlighted)
282 color = highlightColor;
283 else if(w.selected)
284 color = selectedColor;
285
286 /* draw overlays under the way */
287 if(l != null && l.overlays != null)
288 {
289 for(LineElemStyle s : l.overlays)
290 {
291 if(!s.over)
292 {
293 lastN = null;
294 for(Node n : w.nodes)
295 {
296 if(lastN != null)
297 {
298 drawSeg(lastN, n, s.color != null && !w.selected ? s.color : color,
299 false, s.getWidth(width), s.dashed, s.dashedColor);
300 }
301 lastN = n;
302 }
303 }
304 }
305 }
306
307 /* draw the way */
308 lastN = null;
309 Iterator<Node> it = w.nodes.iterator();
310 while (it.hasNext())
311 {
312 Node n = it.next();
313 if(lastN != null)
314 drawSeg(lastN, n, color,
315 showOnlyHeadArrowOnly ? !it.hasNext() : showDirection, width, dashed, dashedColor);
316 lastN = n;
317 }
318
319 /* draw overlays above the way */
320 if(l != null && l.overlays != null)
321 {
322 for(LineElemStyle s : l.overlays)
323 {
324 if(s.over)
325 {
326 lastN = null;
327 for(Node n : w.nodes)
328 {
329 if(lastN != null)
330 {
331 drawSeg(lastN, n, s.color != null && !w.selected ? s.color : color,
332 false, s.getWidth(width), s.dashed, s.dashedColor);
333 }
334 lastN = n;
335 }
336 }
337 }
338 }
339
340 if(showOrderNumber)
341 {
342 int orderNumber = 0;
343 lastN = null;
344 for(Node n : w.nodes)
345 {
346 if(lastN != null)
347 {
348 orderNumber++;
349 drawOrderNumber(lastN, n, orderNumber);
350 }
351 lastN = n;
352 }
353 }
354 displaySegments();
355 }
356
357 public Collection<Way> joinWays(Collection<Way> join, OsmPrimitive errs)
358 {
359 Collection<Way> res = new LinkedList<Way>();
360 Object[] joinArray = join.toArray();
361 int left = join.size();
362 while(left != 0)
363 {
364 Way w = null;
365 Boolean selected = false;
366 ArrayList<Node> n = null;
367 Boolean joined = true;
368 while(joined && left != 0)
369 {
370 joined = false;
371 for(int i = 0; i < joinArray.length && left != 0; ++i)
372 {
373 if(joinArray[i] != null)
374 {
375 Way c = (Way)joinArray[i];
376 if(w == null)
377 { w = c; selected = w.selected; joinArray[i] = null; --left; }
378 else
379 {
380 int mode = 0;
381 int cl = c.nodes.size()-1;
382 int nl;
383 if(n == null)
384 {
385 nl = w.nodes.size()-1;
386 if(w.nodes.get(nl) == c.nodes.get(0)) mode = 21;
387 else if(w.nodes.get(nl) == c.nodes.get(cl)) mode = 22;
388 else if(w.nodes.get(0) == c.nodes.get(0)) mode = 11;
389 else if(w.nodes.get(0) == c.nodes.get(cl)) mode = 12;
390 }
391 else
392 {
393 nl = n.size()-1;
394 if(n.get(nl) == c.nodes.get(0)) mode = 21;
395 else if(n.get(0) == c.nodes.get(cl)) mode = 12;
396 else if(n.get(0) == c.nodes.get(0)) mode = 11;
397 else if(n.get(nl) == c.nodes.get(cl)) mode = 22;
398 }
399 if(mode != 0)
400 {
401 joinArray[i] = null;
402 joined = true;
403 if(c.selected) selected = true;
404 --left;
405 if(n == null) n = new ArrayList<Node>(w.nodes);
406 n.remove((mode == 21 || mode == 22) ? nl : 0);
407 if(mode == 21)
408 n.addAll(c.nodes);
409 else if(mode == 12)
410 n.addAll(0, c.nodes);
411 else if(mode == 22)
412 {
413 for(Node node : c.nodes)
414 n.add(nl, node);
415 }
416 else /* mode == 11 */
417 {
418 for(Node node : c.nodes)
419 n.add(0, node);
420 }
421 }
422 }
423 }
424 } /* for(i = ... */
425 } /* while(joined) */
426 if(n != null)
427 {
428 w = new Way(w);
429 w.nodes.clear();
430 w.nodes.addAll(n);
431 w.selected = selected;
432 }
433 if(!w.isClosed())
434 {
435 if(errs != null)
436 {
437 errs.putError(tr("multipolygon way ''{0}'' is not closed.",
438 w.getName()), true);
439 }
440 }
441 res.add(w);
442 } /* while(left != 0) */
443
444 return res;
445 }
446
447 public void drawSelectedMember(OsmPrimitive osm, ElemStyle style, Boolean area,
448 Boolean areaselected)
449 {
450 if(osm instanceof Way)
451 {
452 if(style instanceof AreaElemStyle)
453 {
454 Way way = (Way)osm;
455 AreaElemStyle areaStyle = (AreaElemStyle)style;
456 drawWay(way, areaStyle.line, selectedColor, true);
457 if(area)
458 drawArea(way, areaselected ? selectedColor : areaStyle.color);
459 }
460 else
461 {
462 drawWay((Way)osm, (LineElemStyle)style, selectedColor, true);
463 }
464 }
465 else if(osm instanceof Node)
466 {
467 if(style != null && isZoomOk(style))
468 drawNode((Node)osm, ((IconElemStyle)style).icon,
469 ((IconElemStyle)style).annotate, true);
470 else
471 drawNode((Node)osm, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
472 }
473 osm.mappaintDrawnCode = paintid;
474 }
475
476 public void visit(Relation r) {
477
478 r.mappaintVisibleCode = 0;
479
480 /* TODO: is it possible to do this like the nodes/ways code? */
481 //if(profilerOmitDraw)
482 // return;
483
484 if(selectedCall)
485 {
486 for (RelationMember m : r.members)
487 {
488 if (m.member != null && !m.member.incomplete && !m.member.deleted
489 && m.member instanceof Node)
490 {
491 drawSelectedMember(m.member, styles != null ? getPrimitiveStyle(m.member) : null, true, true);
492 }
493 }
494 return;
495 }
496 else if (drawMultipolygon && r.keys != null && "multipolygon".equals(r.keys.get("type")))
497 {
498 if(drawMultipolygon(r))
499 return;
500 }
501 else if (drawRestriction && r.keys != null && "restriction".equals(r.keys.get("type")))
502 {
503 drawRestriction(r);
504 }
505
506 if(r.selected) /* draw ways*/
507 {
508 for (RelationMember m : r.members)
509 {
510 if (m.member != null && !m.member.incomplete && !m.member.deleted
511 && m.member instanceof Way) /* nodes drawn on second call */
512 {
513 drawSelectedMember(m.member, styles != null ? getPrimitiveStyle(m.member)
514 : null, true, true);
515 }
516 }
517 }
518 }
519
520 /* this current experimental implementation will only work for standard restrictions:
521 from(Way) / via(Node) / to(Way) */
522 public void drawRestriction(Relation r) {
523 //if(restrictionDebug)
524 // System.out.println("Restriction: " + r.keys.get("name") + " restriction " + r.keys.get("restriction"));
525
526 r.clearErrors();
527
528 Way fromWay = null;
529 Way toWay = null;
530 OsmPrimitive via = null;
531
532 /* find the "from", "via" and "to" elements */
533 for (RelationMember m : r.members)
534 {
535 //if(restrictionDebug)
536 // System.out.println("member " + m.member + " selected " + r.selected);
537
538 if(m.member == null)
539 r.putError(tr("Empty member in relation."), true);
540 else if(m.member.deleted)
541 r.putError(tr("Deleted member ''{0}'' in relation.",
542 m.member.getName()), true);
543 else if(m.member.incomplete)
544 {
545 return;
546 }
547 else
548 {
549 if(m.member instanceof Way)
550 {
551 Way w = (Way) m.member;
552 if(w.nodes.size() < 2)
553 {
554 r.putError(tr("Way ''{0}'' with less than two points.",
555 w.getName()), true);
556 }
557 else if("from".equals(m.role)) {
558 if(fromWay != null)
559 r.putError(tr("More than one \"from\" way found."), true);
560 else {
561 fromWay = w;
562 }
563 } else if("to".equals(m.role)) {
564 if(toWay != null)
565 r.putError(tr("More than one \"to\" way found."), true);
566 else {
567 toWay = w;
568 }
569 } else if("via".equals(m.role)) {
570 if(via != null)
571 r.putError(tr("More than one \"via\" found."), true);
572 else
573 via = w;
574 }
575 else
576 r.putError(tr("Unknown role ''{0}''.", m.role), true);
577 }
578 else if(m.member instanceof Node)
579 {
580 Node n = (Node) m.member;
581 if("via".equals(m.role))
582 {
583 if(via != null)
584 r.putError(tr("More than one \"via\" found."), true);
585 else
586 via = n;
587 }
588 else
589 r.putError(tr("Unknown role ''{0}''.", m.role), true);
590 }
591 else
592 r.putError(tr("Unknown member type for ''{0}''.", m.member.getName()), true);
593 }
594 }
595
596 if (fromWay == null) {
597 r.putError(tr("No \"from\" way found."), true);
598 return;
599 }
600 if (toWay == null) {
601 r.putError(tr("No \"to\" way found."), true);
602 return;
603 }
604 if (via == null) {
605 r.putError(tr("No \"via\" node or way found."), true);
606 return;
607 }
608
609 Node viaNode;
610 if(via instanceof Node)
611 {
612 viaNode = (Node) via;
613 if(!fromWay.isFirstLastNode(viaNode)) {
614 r.putError(tr("The \"from\" way doesn't start or end at a \"via\" node."), true);
615 return;
616 }
617 if(!toWay.isFirstLastNode(viaNode))
618 r.putError(tr("The \"to\" way doesn't start or end at a \"via\" node."), true);
619 }
620 else
621 {
622 Way viaWay = (Way) via;
623 Node firstNode = viaWay.firstNode();
624 Node lastNode = viaWay.lastNode();
625 if(fromWay.isFirstLastNode(firstNode))
626 viaNode = firstNode;
627 else if(fromWay.isFirstLastNode(lastNode))
628 viaNode = firstNode;
629 else {
630 r.putError(tr("The \"from\" way doesn't start or end at the \"via\" way."), true);
631 return;
632 }
633 if(!toWay.isFirstLastNode(viaNode == firstNode ? lastNode : firstNode))
634 r.putError(tr("The \"to\" way doesn't start or end at the \"via\" way."), true);
635 }
636
637 /* find the "direct" nodes before the via node */
638 Node fromNode = null;
639 if(fromWay.firstNode() == via) {
640 //System.out.println("From way heading away from via");
641 fromNode = fromWay.nodes.get(1);
642 } else {
643 //System.out.println("From way heading towards via");
644 fromNode = fromWay.nodes.get(fromWay.nodes.size()-2);
645 }
646
647 Point pFrom = nc.getPoint(fromNode);
648 Point pVia = nc.getPoint(viaNode);
649
650 //if(restrictionDebug) {
651 /* find the "direct" node after the via node */
652 // Node toNode = null;
653 // if(toWay.firstNode() == via) {
654 // System.out.println("To way heading away from via");
655 // toNode = toWay.nodes.get(1);
656 // } else {
657 // System.out.println("To way heading towards via");
658 // toNode = toWay.nodes.get(toWay.nodes.size()-2);
659 // }
660 // Point pTo = nc.getPoint(toNode);
661
662 // /* debug output of interesting nodes */
663 // System.out.println("From: " + fromNode);
664 // drawNode(fromNode, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
665 // System.out.println("Via: " + via);
666 // drawNode(via, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
667 // System.out.println("To: " + toNode);
668 // drawNode(toNode, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode);
669 // System.out.println("From X: " + pFrom.x + " Y " + pFrom.y);
670 // System.out.println("Via X: " + pVia.x + " Y " + pVia.y);
671 // System.out.println("To X: " + pTo.x + " Y " + pTo.y);
672 //}
673
674 /* starting from via, go back the "from" way a few pixels
675 (calculate the vector vx/vy with the specified length and the direction
676 away from the "via" node along the first segment of the "from" way)
677 */
678 double distanceFromVia=14;
679 double dx = (pFrom.x >= pVia.x) ? (pFrom.x - pVia.x) : (pVia.x - pFrom.x);
680 double dy = (pFrom.y >= pVia.y) ? (pFrom.y - pVia.y) : (pVia.y - pFrom.y);
681
682 double fromAngle;
683 if(dx == 0.0) {
684 fromAngle = Math.PI/2;
685 } else {
686 fromAngle = Math.atan(dy / dx);
687 }
688 double fromAngleDeg = Math.toDegrees(fromAngle);
689
690 double vx = distanceFromVia * Math.cos(fromAngle);
691 double vy = distanceFromVia * Math.sin(fromAngle);
692
693 if(pFrom.x < pVia.x) vx = -vx;
694 if(pFrom.y < pVia.y) vy = -vy;
695
696 //if(restrictionDebug)
697 // System.out.println("vx " + vx + " vy " + vy);
698
699 /* go a few pixels away from the way (in a right angle)
700 (calculate the vx2/vy2 vector with the specified length and the direction
701 90degrees away from the first segment of the "from" way)
702 */
703 double distanceFromWay=10;
704 double vx2 = 0;
705 double vy2 = 0;
706 double iconAngle = 0;
707
708 if(pFrom.x >= pVia.x && pFrom.y >= pVia.y) {
709 if(!leftHandTraffic) {
710 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg - 90));
711 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg - 90));
712 } else {
713 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg + 90));
714 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg + 90));
715 }
716 iconAngle = 270+fromAngleDeg;
717 }
718 if(pFrom.x < pVia.x && pFrom.y >= pVia.y) {
719 if(!leftHandTraffic) {
720 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg));
721 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg));
722 } else {
723 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg + 180));
724 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg + 180));
725 }
726 iconAngle = 90-fromAngleDeg;
727 }
728 if(pFrom.x < pVia.x && pFrom.y < pVia.y) {
729 if(!leftHandTraffic) {
730 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg + 90));
731 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg + 90));
732 } else {
733 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg - 90));
734 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg - 90));
735 }
736 iconAngle = 90+fromAngleDeg;
737 }
738 if(pFrom.x >= pVia.x && pFrom.y < pVia.y) {
739 if(!leftHandTraffic) {
740 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg + 180));
741 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg + 180));
742 } else {
743 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg));
744 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg));
745 }
746 iconAngle = 270-fromAngleDeg;
747 }
748
749 IconElemStyle nodeStyle = getPrimitiveNodeStyle(r);
750
751 if (nodeStyle == null) {
752 r.putError(tr("Style for restriction {0} not found.", r.keys.get("restriction")), true);
753 return;
754 }
755
756 /* rotate icon with direction last node in from to */
757 //if(restrictionDebug)
758 // System.out.println("Deg1 " + fromAngleDeg + " Deg2 " + (fromAngleDeg + 180) + " Icon " + iconAngle);
759 ImageIcon rotatedIcon = ImageProvider.createRotatedImage(null /*icon2*/, nodeStyle.icon, iconAngle);
760
761 /* scale down icon to 16*16 pixels */
762 ImageIcon smallIcon = new ImageIcon(rotatedIcon.getImage().getScaledInstance(16 , 16, Image.SCALE_SMOOTH));
763 int w = smallIcon.getIconWidth(), h=smallIcon.getIconHeight();
764 smallIcon.paintIcon ( Main.map.mapView, g, (int)(pVia.x+vx+vx2)-w/2, (int)(pVia.y+vy+vy2)-h/2 );
765
766 if (r.selected)
767 {
768 g.setColor ( selectedColor );
769 g.drawRect ((int)(pVia.x+vx+vx2)-w/2-2,(int)(pVia.y+vy+vy2)-h/2-2, w+4, h+4);
770 }
771 }
772
773 public Boolean drawMultipolygon(Relation r) {
774 Collection<Way> inner = new LinkedList<Way>();
775 Collection<Way> outer = new LinkedList<Way>();
776 Collection<Way> innerclosed = new LinkedList<Way>();
777 Collection<Way> outerclosed = new LinkedList<Way>();
778 Boolean incomplete = false;
779 Boolean drawn = false;
780
781 r.clearErrors();
782
783 for (RelationMember m : r.members)
784 {
785 if(m.member == null)
786 r.putError(tr("Empty member in relation."), true);
787 else if(m.member.deleted)
788 r.putError(tr("Deleted member ''{0}'' in relation.",
789 m.member.getName()), true);
790 else if(m.member.incomplete)
791 incomplete = true;
792 else
793 {
794 if(m.member instanceof Way)
795 {
796 Way w = (Way) m.member;
797 if(w.nodes.size() < 2)
798 {
799 r.putError(tr("Way ''{0}'' with less than two points.",
800 w.getName()), true);
801 }
802 else if("inner".equals(m.role))
803 inner.add(w);
804 else if("outer".equals(m.role))
805 outer.add(w);
806 else
807 {
808 r.putError(tr("No useful role ''{0}'' for Way ''{1}''.",
809 m.role == null ? "" : m.role, w.getName()), true);
810 if(m.role == null || m.role.length() == 0)
811 outer.add(w);
812 else if(r.selected)
813 drawSelectedMember(m.member, styles != null
814 ? getPrimitiveStyle(m.member) : null, true, true);
815 }
816 }
817 else
818 {
819 r.putError(tr("Non-Way ''{0}'' in multipolygon.",
820 m.member.getName()), true);
821 }
822 }
823 }
824
825 ElemStyle wayStyle = styles != null ? getPrimitiveStyle(r) : null;
826 if(styles != null && (wayStyle == null || !(wayStyle instanceof AreaElemStyle)))
827 {
828 for (Way w : outer)
829 {
830 if(wayStyle == null)
831 wayStyle = styles.getArea(w);
832 }
833 r.mappaintStyle = wayStyle;
834 }
835
836 if(wayStyle != null && wayStyle instanceof AreaElemStyle)
837 {
838 Boolean zoomok = isZoomOk(wayStyle);
839 Boolean visible = false;
840 Collection<Way> join = new LinkedList<Way>();
841
842 drawn = true;
843 for (Way w : outer)
844 {
845 if(w.isClosed()) outerclosed.add(w);
846 else join.add(w);
847 }
848 if(join.size() != 0)
849 {
850 for(Way w : joinWays(join, incomplete ? null : r))
851 outerclosed.add(w);
852 }
853
854 join.clear();
855 for (Way w : inner)
856 {
857 if(w.isClosed()) innerclosed.add(w);
858 else join.add(w);
859 }
860 if(join.size() != 0)
861 {
862 for(Way w : joinWays(join, incomplete ? null : r))
863 innerclosed.add(w);
864 }
865
866 if(outerclosed.size() == 0)
867 {
868 r.putError(tr("No outer way for multipolygon ''{0}''.",
869 r.getName()), true);
870 visible = true; /* prevent killing remaining ways */
871 }
872 else if(zoomok)
873 {
874 class PolyData {
875 public Polygon poly = new Polygon();
876 public Way way;
877 private Point p = null;
878 private Collection<Polygon> inner = null;
879 PolyData(Way w)
880 {
881 way = w;
882 for (Node n : w.nodes)
883 {
884 p = nc.getPoint(n);
885 poly.addPoint(p.x,p.y);
886 }
887 }
888 public int contains(Polygon p)
889 {
890 int contains = p.npoints;
891 for(int i = 0; i < p.npoints; ++i)
892 {
893 if(poly.contains(p.xpoints[i],p.ypoints[i]))
894 --contains;
895 }
896 if(contains == 0) return 1;
897 if(contains == p.npoints) return 0;
898 return 2;
899 }
900 public void addInner(Polygon p)
901 {
902 if(inner == null)
903 inner = new ArrayList<Polygon>();
904 inner.add(p);
905 }
906 public boolean isClosed()
907 {
908 return (poly.npoints >= 3
909 && poly.xpoints[0] == poly.xpoints[poly.npoints-1]
910 && poly.ypoints[0] == poly.ypoints[poly.npoints-1]);
911 }
912 public Polygon get()
913 {
914 if(inner != null)
915 {
916 for (Polygon pp : inner)
917 {
918 for(int i = 0; i < pp.npoints; ++i)
919 poly.addPoint(pp.xpoints[i],pp.ypoints[i]);
920 poly.addPoint(p.x,p.y);
921 }
922 inner = null;
923 }
924 return poly;
925 }
926 }
927 LinkedList<PolyData> poly = new LinkedList<PolyData>();
928 for (Way w : outerclosed)
929 {
930 poly.add(new PolyData(w));
931 }
932 for (Way wInner : innerclosed)
933 {
934 Polygon polygon = new Polygon();
935
936 for (Node n : wInner.nodes)
937 {
938 Point pInner = nc.getPoint(n);
939 polygon.addPoint(pInner.x,pInner.y);
940 }
941 if(!wInner.isClosed())
942 {
943 Point pInner = nc.getPoint(wInner.nodes.get(0));
944 polygon.addPoint(pInner.x,pInner.y);
945 }
946 PolyData o = null;
947 for (PolyData pd : poly)
948 {
949 Integer c = pd.contains(polygon);
950 if(c >= 1)
951 {
952 if(c > 1 && pd.way.isClosed())
953 {
954 r.putError(tr("Intersection between ways ''{0}'' and ''{1}''.",
955 pd.way.getName(), wInner.getName()), true);
956 }
957 if(o == null || o.contains(pd.poly) > 0)
958 o = pd;
959 }
960 }
961 if(o == null)
962 {
963 if(!incomplete)
964 {
965 r.putError(tr("Inner way ''{0}'' is outside.",
966 wInner.getName()), true);
967 }
968 o = poly.get(0);
969 }
970 o.addInner(polygon);
971 }
972 AreaElemStyle areaStyle = (AreaElemStyle)wayStyle;
973 for (PolyData pd : poly)
974 {
975 Polygon p = pd.get();
976 if(isPolygonVisible(p))
977 {
978 drawAreaPolygon(p, (pd.way.selected || r.selected) ? selectedColor
979 : areaStyle.color);
980 visible = true;
981 }
982 }
983 }
984 if(!visible) /* nothing visible, so disable relation and all its ways */
985 {
986 r.mappaintVisibleCode = viewid;
987 for (Way wInner : inner)
988 wInner.mappaintVisibleCode = viewid;
989 for (Way wOuter : outer)
990 wOuter.mappaintVisibleCode = viewid;
991 return drawn;
992 }
993 for (Way wInner : inner)
994 {
995 ElemStyle innerStyle = getPrimitiveStyle(wInner);
996 if(innerStyle == null)
997 {
998 if(zoomok && (wInner.mappaintDrawnCode != paintid
999 || outer.size() == 0))
1000 {
1001 drawWay(wInner, ((AreaElemStyle)wayStyle).line,
1002 ((AreaElemStyle)wayStyle).color, wInner.selected
1003 || r.selected);
1004 }
1005 wInner.mappaintDrawnCode = paintid;
1006 }
1007 else
1008 {
1009 if(r.selected)
1010 {
1011 drawSelectedMember(wInner, innerStyle,
1012 !wayStyle.equals(innerStyle), wInner.selected);
1013 }
1014 if(wayStyle.equals(innerStyle))
1015 {
1016 r.putError(tr("Style for inner way ''{0}'' equals multipolygon.",
1017 wInner.getName()), false);
1018 if(!r.selected)
1019 wInner.mappaintDrawnAreaCode = paintid;
1020 }
1021 }
1022 }
1023 for (Way wOuter : outer)
1024 {
1025 ElemStyle outerStyle = getPrimitiveStyle(wOuter);
1026 if(outerStyle == null)
1027 {
1028 if(zoomok)
1029 {
1030 drawWay(wOuter, ((AreaElemStyle)wayStyle).line,
1031 ((AreaElemStyle)wayStyle).color, wOuter.selected
1032 || r.selected);
1033 }
1034 wOuter.mappaintDrawnCode = paintid;
1035 }
1036 else
1037 {
1038 if(outerStyle instanceof AreaElemStyle
1039 && !wayStyle.equals(outerStyle))
1040 {
1041 r.putError(tr("Style for outer way ''{0}'' mismatches.",
1042 wOuter.getName()), true);
1043 }
1044 if(r.selected)
1045 {
1046 drawSelectedMember(wOuter, outerStyle, false, false);
1047 }
1048 else if(outerStyle instanceof AreaElemStyle)
1049 wOuter.mappaintDrawnAreaCode = paintid;
1050 }
1051 }
1052 }
1053 return drawn;
1054 }
1055
1056 protected Polygon getPolygon(Way w)
1057 {
1058 Polygon polygon = new Polygon();
1059
1060 for (Node n : w.nodes)
1061 {
1062 Point p = nc.getPoint(n);
1063 polygon.addPoint(p.x,p.y);
1064 }
1065 return polygon;
1066 }
1067
1068 protected void drawArea(Way w, Color color)
1069 {
1070 Polygon polygon = getPolygon(w);
1071
1072 /* set the opacity (alpha) level of the filled polygon */
1073 g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
1074 g.fillPolygon(polygon);
1075 }
1076
1077 protected void drawAreaPolygon(Polygon polygon, Color color)
1078 {
1079 /* set the opacity (alpha) level of the filled polygon */
1080 g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
1081 g.fillPolygon(polygon);
1082 }
1083
1084 protected void drawNode(Node n, ImageIcon icon, boolean annotate, Boolean selected) {
1085 Point p = nc.getPoint(n);
1086 if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth()) || (p.y > nc.getHeight())) return;
1087
1088 //profilerVisibleNodes++;
1089
1090 int w = icon.getIconWidth(), h=icon.getIconHeight();
1091 icon.paintIcon ( Main.map.mapView, g, p.x-w/2, p.y-h/2 );
1092 if(showNames > dist)
1093 {
1094 String name = getNodeName(n);
1095 if (name!=null && annotate)
1096 {
1097 g.setColor(textColor);
1098 Font defaultFont = g.getFont();
1099 g.setFont (orderFont);
1100 g.drawString (name, p.x+w/2+2, p.y+h/2+2);
1101 g.setFont(defaultFont);
1102 }
1103 }
1104 if (selected)
1105 {
1106 g.setColor ( selectedColor );
1107 g.drawRect (p.x-w/2-2, p.y-h/2-2, w+4, h+4);
1108 }
1109 }
1110
1111 protected String getNodeName(Node n) {
1112 String name = null;
1113 if (n.keys != null) {
1114 for (String rn : regionalNameOrder) {
1115 name = n.keys.get(rn);
1116 if (name != null) break;
1117 }
1118 }
1119 return name;
1120 }
1121
1122 private void drawSeg(Node n1, Node n2, Color col, boolean showDirection, int width, float dashed[], Color dashedColor) {
1123 //profilerSegments++;
1124 if (col != currentColor || width != currentWidth || !Arrays.equals(dashed,currentDashed) || dashedColor != currentDashedColor) {
1125 displaySegments(col, width, dashed, dashedColor);
1126 }
1127 Point p1 = nc.getPoint(n1);
1128 Point p2 = nc.getPoint(n2);
1129
1130 if (!isSegmentVisible(p1, p2)) {
1131 return;
1132 }
1133 //profilerVisibleSegments++;
1134 currentPath.moveTo(p1.x, p1.y);
1135 currentPath.lineTo(p2.x, p2.y);
1136
1137 if (showDirection) {
1138 double t = Math.atan2(p2.y-p1.y, p2.x-p1.x) + Math.PI;
1139 currentPath.lineTo((int)(p2.x + 10*Math.cos(t-PHI)), (int)(p2.y + 10*Math.sin(t-PHI)));
1140 currentPath.moveTo((int)(p2.x + 10*Math.cos(t+PHI)), (int)(p2.y + 10*Math.sin(t+PHI)));
1141 currentPath.lineTo(p2.x, p2.y);
1142 }
1143 }
1144
1145 protected void displaySegments() {
1146 displaySegments(null, 0, new float[0], null);
1147 }
1148
1149 protected void displaySegments(Color newColor, int newWidth, float newDash[], Color newDashedColor) {
1150 if (currentPath != null) {
1151 Graphics2D g2d = (Graphics2D)g;
1152 g2d.setColor(inactive ? inactiveColor : currentColor);
1153 if (currentStroke == null && useStrokes > dist) {
1154 if (currentDashed.length > 0) {
1155 try {
1156 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,0,currentDashed,0));
1157 } catch (IllegalArgumentException e) {
1158 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
1159 }
1160 }
1161 else
1162 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
1163 }
1164 g2d.draw(currentPath);
1165
1166 if(currentDashedColor != null) {
1167 g2d.setColor(currentDashedColor);
1168 if (currentStroke == null && useStrokes > dist) {
1169 if (currentDashed.length > 0) {
1170 float[] currentDashedOffset = new float[currentDashed.length];
1171 System.arraycopy(currentDashed, 1, currentDashedOffset, 0, currentDashed.length - 1);
1172 currentDashedOffset[currentDashed.length-1] = currentDashed[0];
1173 float offset = currentDashedOffset[0];
1174 try {
1175 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,0,currentDashedOffset,offset));
1176 } catch (IllegalArgumentException e) {
1177 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
1178 }
1179 }
1180 else
1181 g2d.setStroke(new BasicStroke(currentWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
1182 }
1183 g2d.draw(currentPath);
1184 }
1185
1186 if(useStrokes > dist)
1187 g2d.setStroke(new BasicStroke(1));
1188
1189 currentPath = new GeneralPath();
1190 currentColor = newColor;
1191 currentWidth = newWidth;
1192 currentDashed = newDash;
1193 currentDashedColor = newDashedColor;
1194 currentStroke = null;
1195 }
1196 }
1197
1198 /**
1199 * Draw the node as small rectangle with the given color.
1200 *
1201 * @param n The node to draw.
1202 * @param color The color of the node.
1203 */
1204 public void drawNode(Node n, Color color, int size, int radius, boolean fill) {
1205 if (isZoomOk(null) && size > 1) {
1206 Point p = nc.getPoint(n);
1207 if ((p.x < 0) || (p.y < 0) || (p.x > nc.getWidth())
1208 || (p.y > nc.getHeight()))
1209 return;
1210
1211 //profilerVisibleNodes++;
1212
1213 g.setColor(color);
1214 if (fill) {
1215 g.fillRect(p.x - radius, p.y - radius, size, size);
1216 g.drawRect(p.x - radius, p.y - radius, size, size);
1217 } else
1218 g.drawRect(p.x - radius, p.y - radius, size, size);
1219
1220 if(showNames > dist)
1221 {
1222 String name = getNodeName(n);
1223 if (name!=null /* && annotate */)
1224 {
1225 g.setColor(textColor);
1226 Font defaultFont = g.getFont();
1227 g.setFont (orderFont);
1228 g.drawString (name, p.x+radius+2, p.y+radius+2);
1229 g.setFont(defaultFont);
1230 }
1231 }
1232 }
1233 }
1234
1235 public void getColors()
1236 {
1237 super.getColors();
1238 untaggedColor = Main.pref.getColor(marktr("untagged"),Color.GRAY);
1239 textColor = Main.pref.getColor (marktr("text"), Color.WHITE);
1240 }
1241
1242 /* Shows areas before non-areas */
1243 public void visitAll(DataSet data, Boolean virtual) {
1244
1245 //boolean profiler = Main.pref.getBoolean("mappaint.profiler",false);
1246 //profilerOmitDraw = Main.pref.getBoolean("mappaint.profiler.omitdraw",false);
1247
1248 useStyleCache = Main.pref.getBoolean("mappaint.cache",true);
1249 fillAreas = Main.pref.getInteger("mappaint.fillareas", 10000000);
1250 fillAlpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50))));
1251 showNames = Main.pref.getInteger("mappaint.shownames", 10000000);
1252 showIcons = Main.pref.getInteger("mappaint.showicons", 10000000);
1253 useStrokes = Main.pref.getInteger("mappaint.strokes", 10000000);
1254 LatLon ll1 = nc.getLatLon(0,0);
1255 LatLon ll2 = nc.getLatLon(100,0);
1256 dist = ll1.greatCircleDistance(ll2);
1257
1258 //long profilerStart = java.lang.System.currentTimeMillis();
1259 //long profilerLast = profilerStart;
1260 //int profilerN;
1261 //if(profiler)
1262 // System.out.println("Mappaint Profiler (" +
1263 // (useStyleCache ? "cache=true, " : "cache=false, ") +
1264 // "fillareas " + fillAreas + ", " +
1265 // "fillalpha=" + fillAlpha + "%, " +
1266 // "dist=" + (int)dist + "m)");
1267
1268 getSettings(virtual);
1269 useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth",false);
1270 zoomLevelDisplay = Main.pref.getBoolean("mappaint.zoomLevelDisplay",false);
1271 circum = Main.map.mapView.getDist100Pixel();
1272 styles = MapPaintStyles.getStyles().getStyleSet();
1273 drawMultipolygon = Main.pref.getBoolean("mappaint.multipolygon",true);
1274 drawRestriction = Main.pref.getBoolean("mappaint.restriction",true);
1275 //restrictionDebug = Main.pref.getBoolean("mappaint.restriction.debug",false);
1276 leftHandTraffic = Main.pref.getBoolean("mappaint.lefthandtraffic",false);
1277 orderFont = new Font(Main.pref.get("mappaint.font","Helvetica"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8));
1278 String[] names = {"name:"+Main.getLanguageCode(), "name", "int_name", "ref", "operator", "brand","addr:housenumber"};
1279 regionalNameOrder = Main.pref.getCollection("mappaint.nameOrder", Arrays.asList(names));
1280 minEN = nc.getEastNorth(0,nc.getHeight()-1);
1281 maxEN = nc.getEastNorth(nc.getWidth()-1,0);
1282
1283
1284 selectedCall = false;
1285 ++paintid;
1286 viewid = nc.getViewID();
1287
1288 //profilerVisibleNodes = 0;
1289 //profilerVisibleWays = 0;
1290 //profilerVisibleAreas = 0;
1291 //profilerSegments = 0;
1292 //profilerVisibleSegments = 0;
1293
1294 //if(profiler)
1295 //{
1296 // System.out.format("Prepare : %5dms\n", (java.lang.System.currentTimeMillis()-profilerLast));
1297 // profilerLast = java.lang.System.currentTimeMillis();
1298 //}
1299
1300 if (fillAreas > dist && styles != null && styles.hasAreas()) {
1301 Collection<Way> noAreaWays = new LinkedList<Way>();
1302
1303 /*** RELATIONS ***/
1304 // profilerN = 0;
1305 for (final Relation osm : data.relations)
1306 {
1307 if(!osm.deleted && !osm.incomplete && osm.mappaintVisibleCode != viewid)
1308 {
1309 osm.visit(this);
1310 // profilerN++;
1311 }
1312 }
1313
1314 // if(profiler)
1315 // {
1316 // System.out.format("Relations: %5dms, calls=%7d\n", (java.lang.System.currentTimeMillis()-profilerLast), profilerN);
1317 // profilerLast = java.lang.System.currentTimeMillis();
1318 // }
1319
1320 /*** AREAS ***/
1321 // profilerN = 0;
1322 for (final Way osm : data.ways)
1323 {
1324 if (!osm.incomplete && !osm.deleted
1325 && osm.mappaintVisibleCode != viewid && osm.mappaintDrawnCode != paintid)
1326 {
1327 if(isPrimitiveArea(osm) && osm.mappaintDrawnAreaCode != paintid)
1328 {
1329 osm.visit(this);
1330 // profilerN++;
1331 } else
1332 noAreaWays.add(osm);
1333 }
1334 }
1335
1336 // if(profiler)
1337 // {
1338 // System.out.format("Areas : %5dms, calls=%7d, visible=%d\n",
1339 // (java.lang.System.currentTimeMillis()-profilerLast), profilerN, profilerVisibleAreas);
1340 // profilerLast = java.lang.System.currentTimeMillis();
1341 // }
1342
1343 /*** WAYS ***/
1344 // profilerN = 0;
1345 fillAreas = 0;
1346 for (final OsmPrimitive osm : noAreaWays)
1347 {
1348 osm.visit(this);
1349 // profilerN++;
1350 }
1351
1352 // if(profiler)
1353 // {
1354 // System.out.format("Ways : %5dms, calls=%7d, visible=%d\n",
1355 // (java.lang.System.currentTimeMillis()-profilerLast), profilerN, profilerVisibleWays);
1356 // profilerLast = java.lang.System.currentTimeMillis();
1357 // }
1358 }
1359 else
1360 {
1361 /*** WAYS (filling disabled) ***/
1362 // profilerN = 0;
1363 for (final OsmPrimitive osm : data.ways)
1364 if (!osm.incomplete && !osm.deleted && !osm.selected
1365 && osm.mappaintVisibleCode != viewid )
1366 {
1367 osm.visit(this);
1368 // profilerN++;
1369 }
1370
1371 // if(profiler)
1372 // {
1373 // System.out.format("Ways : %5dms, calls=%7d, visible=%d\n",
1374 // (java.lang.System.currentTimeMillis()-profilerLast), profilerN, profilerVisibleWays);
1375 // profilerLast = java.lang.System.currentTimeMillis();
1376 // }
1377 }
1378
1379 /*** SELECTED ***/
1380 selectedCall = true;
1381 //profilerN = 0;
1382 for (final OsmPrimitive osm : data.getSelected()) {
1383 if (!osm.incomplete && !osm.deleted && !(osm instanceof Node)
1384 && osm.mappaintVisibleCode != viewid && osm.mappaintDrawnCode != paintid)
1385 {
1386 osm.visit(this);
1387 // profilerN++;
1388 }
1389 }
1390
1391 //if(profiler)
1392 //{
1393 // System.out.format("Selected : %5dms, calls=%7d\n", (java.lang.System.currentTimeMillis()-profilerLast), profilerN);
1394 // profilerLast = java.lang.System.currentTimeMillis();
1395 //}
1396
1397 /*** DISPLAY CACHED SEGMENTS (WAYS) NOW ***/
1398 displaySegments();
1399
1400 /*** NODES ***/
1401 //profilerN = 0;
1402 for (final OsmPrimitive osm : data.nodes)
1403 if (!osm.incomplete && !osm.deleted
1404 && osm.mappaintVisibleCode != viewid && osm.mappaintDrawnCode != paintid)
1405 {
1406 osm.visit(this);
1407 // profilerN++;
1408 }
1409
1410 //if(profiler)
1411 //{
1412 // System.out.format("Nodes : %5dms, calls=%7d, visible=%d\n",
1413 // (java.lang.System.currentTimeMillis()-profilerLast), profilerN, profilerVisibleNodes);
1414 // profilerLast = java.lang.System.currentTimeMillis();
1415 //}
1416
1417 /*** VIRTUAL ***/
1418 if (virtualNodeSize != 0)
1419 {
1420 // profilerN = 0;
1421 currentColor = nodeColor;
1422 for (final OsmPrimitive osm : data.ways)
1423 if (!osm.incomplete && !osm.deleted
1424 && osm.mappaintVisibleCode != viewid )
1425 {
1426 /* TODO: move this into the SimplePaint code? */
1427 // if(!profilerOmitDraw)
1428 visitVirtual((Way)osm);
1429 // profilerN++;
1430 }
1431
1432 // if(profiler)
1433 // {
1434 // System.out.format("Virtual : %5dms, calls=%7d\n", (java.lang.System.currentTimeMillis()-profilerLast), profilerN);
1435 // profilerLast = java.lang.System.currentTimeMillis();
1436 // }
1437
1438 displaySegments(null);
1439 }
1440
1441 //if(profiler)
1442 //{
1443 // System.out.format("Segments : calls=%7d, visible=%d\n", profilerSegments, profilerVisibleSegments);
1444 // System.out.format("All : %5dms\n", (profilerLast-profilerStart));
1445 //}
1446 }
1447
1448 /**
1449 * Draw a number of the order of the two consecutive nodes within the
1450 * parents way
1451 */
1452 protected void drawOrderNumber(Node n1, Node n2, int orderNumber) {
1453 Point p1 = nc.getPoint(n1);
1454 Point p2 = nc.getPoint(n2);
1455 drawOrderNumber(p1, p2, orderNumber);
1456 }
1457}
Note: See TracBrowser for help on using the repository browser.