Changeset 1295 in josm
- Timestamp:
- 2009-01-18T17:27:32+01:00 (16 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java
r1289 r1295 9 9 import java.awt.Font; 10 10 import java.awt.Graphics2D; 11 import java.awt.Image; 11 12 import java.awt.Point; 12 13 import java.awt.Polygon; … … 37 38 import org.openstreetmap.josm.gui.mappaint.LineElemStyle; 38 39 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles; 40 import org.openstreetmap.josm.tools.ImageProvider; 39 41 40 42 public class MapPaintVisitor extends SimplePaintVisitor { … … 43 45 protected int fillAreas; 44 46 protected boolean drawMultipolygon; 47 protected boolean drawRestriction; 48 protected boolean restrictionDebug; 45 49 protected int showNames; 46 50 protected int showIcons; … … 474 478 { 475 479 if (m.member != null && !m.member.incomplete && !m.member.deleted 476 && m.member instanceof Node) 480 && (drawRestriction || m.member instanceof Node)) 477 481 { 478 482 drawSelectedMember(m.member, styles != null ? styles.get(m.member) : null, true, true); … … 485 489 { 486 490 drawMultipolygon(r); 491 return; 492 } 493 494 if (drawRestriction && r.keys != null && "restriction".equals(r.keys.get("type"))) 495 { 496 drawRestriction(r); 487 497 return; 488 498 } … … 490 500 if(r.selected) 491 501 drawSelectedRelation(r); 502 } 503 504 505 // this current experimental implementation will only work for standard restrictions: 506 // from(Way) / via(Node) / to(Way) 507 public void drawRestriction(Relation r) { 508 if(restrictionDebug) 509 System.out.println("Restriction: " + r.keys.get("name") + " restriction " + r.keys.get("restriction")); 510 511 r.clearErrors(); 512 513 Way fromWay = null; 514 Way toWay = null; 515 Node via = null; 516 517 // find the "from", "via" and "to" elements 518 for (RelationMember m : r.members) 519 { 520 if(restrictionDebug) 521 System.out.println("member " + m.member + " selected " + r.selected); 522 523 if(m.member == null) 524 r.putError(tr("Empty member in relation."), true); 525 else if(m.member.deleted) 526 r.putError(tr("Deleted member ''{0}'' in relation.", 527 m.member.getName()), true); 528 else if(m.member.incomplete) 529 { 530 // TODO: What to do with incomplete members? 531 //incomplete = true; 532 r.putError(tr("incomplete member {0}" + " with role {1}", m.member, m.role), true); 533 } 534 else 535 { 536 if(m.member instanceof Way) 537 { 538 Way w = (Way) m.member; 539 ElemStyle style = getPrimitiveStyle(w); 540 //if(r.selected) { 541 // drawWay(w, null /*(LineElemStyle)style*/, selectedColor, true); 542 // w.mappaintDrawnCode = paintid; 543 //} 544 if(w.nodes.size() < 2) 545 { 546 r.putError(tr("Way ''{0}'' with less than two points.", 547 w.getName()), true); 548 } 549 else if("from".equals(m.role)) { 550 if(fromWay != null) 551 r.putError(tr("more than one from way found - ignored."), true); 552 else { 553 fromWay = w; 554 } 555 } else if("to".equals(m.role)) { 556 if(toWay != null) 557 r.putError(tr("more than one to way found - ignored."), true); 558 else { 559 toWay = w; 560 } 561 } 562 else 563 r.putError(tr("unknown role {0} - ignored", m.role), true); 564 } 565 else if(m.member instanceof Node) 566 { 567 Node n = (Node) m.member; 568 if("via".equals(m.role)) 569 if(via != null) 570 System.out.println("more than one via found - ignored"); 571 else { 572 via = n; 573 } 574 else 575 r.putError(tr("unknown role {0} - ignored", m.role), true); 576 } 577 else 578 r.putError(tr("unknown instanceof member - ignored"), true); 579 } 580 } 581 582 if (fromWay == null) { 583 r.putError(tr("no from way found"), true); 584 return; 585 } 586 if (toWay == null) { 587 r.putError(tr("no to way found"), true); 588 return; 589 } 590 if (via == null) { 591 r.putError(tr("no via node found"), true); 592 return; 593 } 594 595 // check if "from" way starts or ends at via 596 if(fromWay.nodes.get(0) != via && fromWay.nodes.get(fromWay.nodes.size()-1) != via) { 597 r.putError(tr("from way doesn't start or end at a via node"), true); 598 return; 599 } 600 // check if "to" way starts or ends at via 601 /*if(toWay.nodes.get(0) != via && toWay.nodes.get(toWay.nodes.size()-1) != via) { 602 r.putError(tr("to way doesn't start or end at a via node"), true); 603 //return; 604 }*/ 605 606 // find the "direct" nodes before the via node 607 Node fromNode = null; 608 try 609 { 610 if(fromWay.nodes.get(0) == via) { 611 //System.out.println("From way heading away from via"); 612 fromNode = fromWay.nodes.get(1); 613 } else { 614 //System.out.println("From way heading towards via"); 615 fromNode = fromWay.nodes.get(fromWay.nodes.size()-2); 616 } 617 } catch (IndexOutOfBoundsException ioobe) { 618 System.out.println("from must contain at least 2 nodes"); 619 } 620 621 // find the "direct" node after the via node 622 Node toNode = null; 623 try 624 { 625 if(toWay.nodes.get(0) == via) { 626 if(restrictionDebug) 627 System.out.println("To way heading away from via"); 628 toNode = toWay.nodes.get(1); 629 } else { 630 if(restrictionDebug) 631 System.out.println("To way heading towards via"); 632 toNode = toWay.nodes.get(toWay.nodes.size()-2); 633 } 634 } catch (IndexOutOfBoundsException ioobe) { 635 System.out.println("to must contain at least 2 nodes"); 636 } 637 638 Point pFrom = nc.getPoint(fromNode.eastNorth); 639 Point pVia = nc.getPoint(via.eastNorth); 640 641 if(restrictionDebug) { 642 Point pTo = nc.getPoint(toNode.eastNorth); 643 644 // debug output of interesting nodes 645 System.out.println("From: " + fromNode); 646 drawNode(fromNode, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode); 647 System.out.println("Via: " + via); 648 drawNode(via, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode); 649 System.out.println("To: " + toNode); 650 drawNode(toNode, selectedColor, selectedNodeSize, selectedNodeRadius, fillSelectedNode); 651 System.out.println("From X: " + pFrom.x + " Y " + pFrom.y); 652 System.out.println("Via X: " + pVia.x + " Y " + pVia.y); 653 System.out.println("To X: " + pTo.x + " Y " + pTo.y); 654 } 655 656 // starting from via, go back the "from" way a few pixels 657 // (calculate the vector vx/vy with the specified length and the direction away from the "via" node along the first segment of the "from" way) 658 double distanceFromVia=14; 659 double dx = (pFrom.x >= pVia.x) ? (pFrom.x - pVia.x) : (pVia.x - pFrom.x); 660 double dy = (pFrom.y >= pVia.y) ? (pFrom.y - pVia.y) : (pVia.y - pFrom.y); 661 662 if(dx == 0.0) { 663 System.out.println("dx " + dx); 664 return; 665 } 666 double fromAngle = Math.atan(dy / dx); 667 double fromAngleDeg = Math.toDegrees(fromAngle); 668 669 double vx = distanceFromVia * Math.cos(fromAngle); 670 double vy = distanceFromVia * Math.sin(fromAngle); 671 672 if(pFrom.x < pVia.x) vx = -vx; 673 if(pFrom.y < pVia.y) vy = -vy; 674 675 if(restrictionDebug) 676 System.out.println("vx " + vx + " vy " + vy); 677 678 // go a few pixels away from the way (in a right angle) 679 // (calculate the vx2/vy2 vector with the specified length and the direction 90degrees away from the first segment of the "from" way) 680 double distanceFromWay=8; 681 double vx2 = 0; 682 double vy2 = 0; 683 double iconAngle = 0; 684 685 if(pFrom.x >= pVia.x && pFrom.y >= pVia.y) { 686 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg - 90)); 687 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg - 90)); 688 iconAngle = 270+fromAngleDeg; 689 } 690 if(pFrom.x < pVia.x && pFrom.y >= pVia.y) { 691 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg)); 692 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg)); 693 iconAngle = 90-fromAngleDeg; 694 } 695 if(pFrom.x < pVia.x && pFrom.y < pVia.y) { 696 vx2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg + 90)); 697 vy2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg + 90)); 698 iconAngle = 90+fromAngleDeg; 699 } 700 if(pFrom.x >= pVia.x && pFrom.y < pVia.y) { 701 vx2 = distanceFromWay * Math.sin(Math.toRadians(fromAngleDeg+180)); 702 vy2 = distanceFromWay * Math.cos(Math.toRadians(fromAngleDeg+180)); 703 iconAngle = 270-fromAngleDeg; 704 } 705 706 IconElemStyle nodeStyle = (IconElemStyle)getPrimitiveStyle(r); 707 708 if (nodeStyle == null) { 709 r.putError(tr("Style for restriction {0} not found", r.keys.get("restriction")), true); 710 return; 711 } 712 713 // rotate icon with direction last node in from to 714 if(restrictionDebug) 715 System.out.println("Deg1 " + fromAngleDeg + " Deg2 " + (fromAngleDeg + 180) + " Icon " + iconAngle); 716 ImageIcon rotatedIcon = ImageProvider.createRotatedImage(null /*icon2*/, nodeStyle.icon, iconAngle); 717 718 // scale down icon to 16*16 pixels 719 ImageIcon smallIcon = new ImageIcon(rotatedIcon.getImage().getScaledInstance(16 , 16, Image.SCALE_SMOOTH)); 720 int w = smallIcon.getIconWidth(), h=smallIcon.getIconHeight(); 721 smallIcon.paintIcon ( Main.map.mapView, g, (int)(pVia.x+vx+vx2)-w/2, (int)(pVia.y+vy+vy2)-h/2 ); 722 723 if (r.selected) 724 { 725 g.setColor ( selectedColor ); 726 g.drawRect ((int)(pVia.x+vx+vx2)-w/2-2,(int)(pVia.y+vy+vy2)-h/2-2, w+4, h+4); 727 } 492 728 } 493 729 … … 955 1191 styles = MapPaintStyles.getStyles().getStyleSet(); 956 1192 drawMultipolygon = Main.pref.getBoolean("mappaint.multipolygon",true); 1193 drawRestriction = Main.pref.getBoolean("mappaint.restriction",false); 1194 restrictionDebug = Main.pref.getBoolean("mappaint.restriction.debug",false); 957 1195 orderFont = new Font(Main.pref.get("mappaint.font","Helvetica"), Font.PLAIN, Main.pref.getInteger("mappaint.fontsize", 8)); 958 1196 String currentLocale = Locale.getDefault().getLanguage(); -
trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
r1240 r1295 120 120 { 121 121 return (osm.keys == null) ? null : 122 ((osm instanceof Node) ? getNode(osm.keys) : get(osm.keys)); 122 ((osm instanceof Node || osm instanceof Relation) ? getNode(osm.keys) : get(osm.keys)); 123 123 } 124 124 -
trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
r1169 r1295 2 2 package org.openstreetmap.josm.tools; 3 3 4 import java.awt.Component; 4 5 import java.awt.Cursor; 5 6 import java.awt.Graphics; 7 import java.awt.Graphics2D; 6 8 import java.awt.GraphicsConfiguration; 7 9 import java.awt.GraphicsEnvironment; 8 10 import java.awt.Image; 9 11 import java.awt.Point; 12 import java.awt.RenderingHints; 10 13 import java.awt.Toolkit; 11 14 import java.awt.Transparency; … … 224 227 } 225 228 } 229 230 /* from: http://www.jidesoft.com/blog/2008/02/29/rotate-an-icon-in-java/ 231 * License: "feel free to use" 232 */ 233 final static double DEGREE_90 = 90.0 * Math.PI / 180.0; 234 235 /** 236 * Creates a rotated version of the input image. 237 * 238 * @param c The component to get properties useful for painting, e.g. the foreground 239 * or background color. 240 * @param icon the image to be rotated. 241 * @param rotatedAngle the rotated angle, in degree, clockwise. It could be any double but we 242 * will mod it with 360 before using it. 243 * 244 * @return the image after rotating. 245 */ 246 public static ImageIcon createRotatedImage(Component c, Icon icon, double rotatedAngle) { 247 // convert rotatedAngle to a value from 0 to 360 248 double originalAngle = rotatedAngle % 360; 249 if (rotatedAngle != 0 && originalAngle == 0) { 250 originalAngle = 360.0; 251 } 252 253 // convert originalAngle to a value from 0 to 90 254 double angle = originalAngle % 90; 255 if (originalAngle != 0.0 && angle == 0.0) { 256 angle = 90.0; 257 } 258 259 double radian = Math.toRadians(angle); 260 261 int iw = icon.getIconWidth(); 262 int ih = icon.getIconHeight(); 263 int w; 264 int h; 265 266 if ((originalAngle >= 0 && originalAngle <= 90) || (originalAngle > 180 && originalAngle <= 270)) { 267 w = (int) (iw * Math.sin(DEGREE_90 - radian) + ih * Math.sin(radian)); 268 h = (int) (iw * Math.sin(radian) + ih * Math.sin(DEGREE_90 - radian)); 269 } 270 else { 271 w = (int) (ih * Math.sin(DEGREE_90 - radian) + iw * Math.sin(radian)); 272 h = (int) (ih * Math.sin(radian) + iw * Math.sin(DEGREE_90 - radian)); 273 } 274 BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 275 Graphics g = image.getGraphics(); 276 Graphics2D g2d = (Graphics2D) g.create(); 277 278 // calculate the center of the icon. 279 int cx = iw / 2; 280 int cy = ih / 2; 281 282 // move the graphics center point to the center of the icon. 283 g2d.translate(w/2, h/2); 284 285 // rotate the graphics about the center point of the icon 286 g2d.rotate(Math.toRadians(originalAngle)); 287 288 g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); 289 icon.paintIcon(c, g2d, -cx, -cy); 290 291 g2d.dispose(); 292 return new ImageIcon(image); 293 } 226 294 } -
trunk/styles/standard/elemstyles.xml
r1269 r1295 47 47 <rules name="standard"> 48 48 49 <rule> 50 <condition k="restriction" v="no_left_turn"/> 51 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/no_left_turn.png"/> 52 <scale_min>1</scale_min> 53 <scale_max>40000</scale_max> 54 </rule> 55 <rule> 56 <condition k="restriction" v="no_right_turn"/> 57 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/no_right_turn.png"/> 58 <scale_min>1</scale_min> 59 <scale_max>40000</scale_max> 60 </rule> 61 <rule> 62 <condition k="restriction" v="no_straight_on"/> 63 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/no_straight_on.png"/> 64 <scale_min>1</scale_min> 65 <scale_max>40000</scale_max> 66 </rule> 67 <rule> 68 <condition k="restriction" v="no_u_turn"/> 69 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/no_u_turn.png"/> 70 <scale_min>1</scale_min> 71 <scale_max>40000</scale_max> 72 </rule> 73 <rule> 74 <condition k="restriction" v="only_left_turn"/> 75 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/only_left_turn.png"/> 76 <scale_min>1</scale_min> 77 <scale_max>40000</scale_max> 78 </rule> 79 <rule> 80 <condition k="restriction" v="only_right_turn"/> 81 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/only_right_turn.png"/> 82 <scale_min>1</scale_min> 83 <scale_max>40000</scale_max> 84 </rule> 85 <rule> 86 <condition k="restriction" v="only_straight_on"/> 87 <icon annotate="true" src="vehicle/restrictions/turn_restrictions/only_straight_on.png"/> 88 <scale_min>1</scale_min> 89 <scale_max>40000</scale_max> 90 </rule> 91 92 49 93 <!-- mark some specials that should be fixed - they are already the default and therefore shouldn't be tagged --> 50 94 <rule>
Note:
See TracChangeset
for help on using the changeset viewer.