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

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

some cleanups

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