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

Last change on this file since 1862 was 1862, checked in by jttt, 15 years ago

Way refactoring - added method that will in future replace public field nodes

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