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

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

fixed #2232

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