| | 392 | |
| | 393 | protected JCheckBoxMenuItem getShowDownloadedAreaMenuItem() { |
| | 394 | JPopupMenu menu = this.sourceButton.getPopupMenu(); |
| | 395 | boolean afterSeparator = false; |
| | 396 | for (Component c: menu.getComponents()) { |
| | 397 | if (JPopupMenu.Separator.class.isInstance(c)) { |
| | 398 | assertFalse("More than one separator before target item", afterSeparator); |
| | 399 | afterSeparator = true; |
| | 400 | } else if (((JMenuItem) c).getText().equals(tr("Show downloaded area"))) { |
| | 401 | assertTrue("Separator not found before target item", afterSeparator); |
| | 402 | assertTrue("Target item doesn't appear to be a JCheckBoxMenuItem", JCheckBoxMenuItem.class.isInstance(c)); |
| | 403 | return (JCheckBoxMenuItem) c; |
| | 404 | } |
| | 405 | } |
| | 406 | fail("'Show downloaded area' menu item not found"); |
| | 407 | return null; |
| | 408 | } |
| | 409 | |
| | 410 | /** |
| | 411 | * test downloaded area is shown shaded |
| | 412 | * @throws Exception if any error occurs |
| | 413 | */ |
| | 414 | @Test |
| | 415 | public void testShowDownloadedArea() throws Exception { |
| | 416 | Main.pref.put("slippy_map_chooser.mapstyle", "Green Tiles"); |
| | 417 | Main.pref.putBoolean("slippy_map_chooser.show_downloaded_area", false); |
| | 418 | |
| | 419 | DataSet dataSet = new DataSet(); |
| | 420 | dataSet.addDataSource(new DataSource(new Bounds(51.725, -0.0209, 51.746, 0.0162), "Somewhere")); |
| | 421 | |
| | 422 | OsmDataLayer dataLayer = new OsmDataLayer( |
| | 423 | dataSet, |
| | 424 | "Test Layer 123", |
| | 425 | null |
| | 426 | ); |
| | 427 | MainApplication.getLayerManager().addLayer(dataLayer); |
| | 428 | MainApplication.getLayerManager().setActiveLayer(dataLayer); |
| | 429 | |
| | 430 | MapView mapView = MainApplication.getMap().mapView; |
| | 431 | GuiHelper.runInEDTAndWaitWithException(() -> { |
| | 432 | mapView.setVisible(true); |
| | 433 | mapView.addNotify(); |
| | 434 | mapView.doLayout(); |
| | 435 | mapView.setBounds(0, 0, 500, 500); |
| | 436 | }); |
| | 437 | |
| | 438 | this.setUpMiniMap(); |
| | 439 | |
| | 440 | // assert "show downloaded areas" checkbox is unchecked |
| | 441 | assertFalse(this.getShowDownloadedAreaMenuItem().isSelected()); |
| | 442 | |
| | 443 | // we won't end up with exactly this viewport as it doesn't *precisely* match the aspect ratio |
| | 444 | mapView.zoomTo(new Bounds(51.732, -0.0269, 51.753, 0.0102)); |
| | 445 | |
| | 446 | // an initial paint operation is required to trigger the tile fetches |
| | 447 | this.paintSlippyMap(); |
| | 448 | |
| | 449 | Awaitility.await().atMost(1000, MILLISECONDS).until(this.slippyMapTasksFinished); |
| | 450 | |
| | 451 | this.paintSlippyMap(); |
| | 452 | |
| | 453 | Map<Integer, String> paletteMap = ImmutableMap.<Integer, String>builder() |
| | 454 | .put(0xff00ff00, "g") // green |
| | 455 | .put(0xff000000, "b") // black |
| | 456 | .put(0xff8ad16b, "v") // viewport marker inner (pink+green mix) |
| | 457 | .put(0xff00df00, "d") // (shaded green) |
| | 458 | .put(0xff8ac46b, "q") // (shaded pink+green mix) |
| | 459 | .build(); |
| | 460 | |
| | 461 | // assert downloaded areas are not drawn |
| | 462 | ImagePatternMatching.rowMatch( |
| | 463 | paintedSlippyMap, |
| | 464 | paintedSlippyMap.getHeight()/2, |
| | 465 | paletteMap, |
| | 466 | "^g+bv+bg+$", |
| | 467 | true |
| | 468 | ); |
| | 469 | ImagePatternMatching.columnMatch( |
| | 470 | paintedSlippyMap, |
| | 471 | paintedSlippyMap.getWidth()/2, |
| | 472 | paletteMap, |
| | 473 | "^g+bv+bg+$", |
| | 474 | true |
| | 475 | ); |
| | 476 | |
| | 477 | // enable "show downloaded areas" |
| | 478 | GuiHelper.runInEDTAndWaitWithException(() -> this.getShowDownloadedAreaMenuItem().doClick()); |
| | 479 | assertTrue(this.getShowDownloadedAreaMenuItem().isSelected()); |
| | 480 | |
| | 481 | // assert downloaded areas are drawn |
| | 482 | this.paintSlippyMap(); |
| | 483 | |
| | 484 | ImagePatternMatching.rowMatch( |
| | 485 | paintedSlippyMap, |
| | 486 | paintedSlippyMap.getHeight()/2, |
| | 487 | paletteMap, |
| | 488 | "^d+bq+v+bg+d+$", |
| | 489 | true |
| | 490 | ); |
| | 491 | ImagePatternMatching.columnMatch( |
| | 492 | paintedSlippyMap, |
| | 493 | paintedSlippyMap.getWidth()/2, |
| | 494 | paletteMap, |
| | 495 | "^d+bq+v+bg+d+$", |
| | 496 | true |
| | 497 | ); |
| | 498 | |
| | 499 | // also assert the leftmost column doesn't (yet) have any downloaded area marks (i.e. fully shaded) |
| | 500 | ImagePatternMatching.columnMatch( |
| | 501 | paintedSlippyMap, |
| | 502 | 0, |
| | 503 | paletteMap, |
| | 504 | "^d+$", |
| | 505 | true |
| | 506 | ); |
| | 507 | |
| | 508 | // add another downloaded area, going off the left of the widget |
| | 509 | dataSet.addDataSource(new DataSource(new Bounds(51.745, -1., 51.765, 0.0162), "Somewhere else")); |
| | 510 | // and redraw |
| | 511 | this.paintSlippyMap(); |
| | 512 | |
| | 513 | // the middle row should be as before |
| | 514 | ImagePatternMatching.rowMatch( |
| | 515 | paintedSlippyMap, |
| | 516 | paintedSlippyMap.getHeight()/2, |
| | 517 | paletteMap, |
| | 518 | "^d+bq+v+bg+d+$", |
| | 519 | true |
| | 520 | ); |
| | 521 | // the middle column should have its unshaded region extended beyond the viewport marker |
| | 522 | ImagePatternMatching.columnMatch( |
| | 523 | paintedSlippyMap, |
| | 524 | paintedSlippyMap.getWidth()/2, |
| | 525 | paletteMap, |
| | 526 | "^d+g+bv+bg+d+$", |
| | 527 | true |
| | 528 | ); |
| | 529 | // but the leftmost column should now have an unshaded mark |
| | 530 | ImagePatternMatching.columnMatch( |
| | 531 | paintedSlippyMap, |
| | 532 | 0, |
| | 533 | paletteMap, |
| | 534 | "^d+g+d+$", |
| | 535 | true |
| | 536 | ); |
| | 537 | // and the rightmost column should be untouched |
| | 538 | ImagePatternMatching.columnMatch( |
| | 539 | paintedSlippyMap, |
| | 540 | paintedSlippyMap.getWidth()-1, |
| | 541 | paletteMap, |
| | 542 | "^d+$", |
| | 543 | true |
| | 544 | ); |
| | 545 | |
| | 546 | // and now if we pan to the left (in EastNorth units) |
| | 547 | mapView.zoomTo(mapView.getCenter().add(-5000., 0.)); |
| | 548 | // and redraw |
| | 549 | this.paintSlippyMap(); |
| | 550 | |
| | 551 | // the middle row should have its unshaded region outside the viewport marker |
| | 552 | ImagePatternMatching.rowMatch( |
| | 553 | paintedSlippyMap, |
| | 554 | paintedSlippyMap.getHeight()/2, |
| | 555 | paletteMap, |
| | 556 | "^d+bq+bd+g+d*$", |
| | 557 | true |
| | 558 | ); |
| | 559 | // the middle column should have a shaded region inside the viewport marker |
| | 560 | ImagePatternMatching.columnMatch( |
| | 561 | paintedSlippyMap, |
| | 562 | paintedSlippyMap.getWidth()/2, |
| | 563 | paletteMap, |
| | 564 | "^d+g+bv+q+bd+$", |
| | 565 | true |
| | 566 | ); |
| | 567 | } |
| | 568 | |
| | 569 | /** |
| | 570 | * test display of downloaded area follows active layer switching |
| | 571 | * @throws Exception if any error occurs |
| | 572 | */ |
| | 573 | @Test |
| | 574 | public void testShowDownloadedAreaLayerSwitching() throws Exception { |
| | 575 | Main.pref.put("slippy_map_chooser.mapstyle", "Green Tiles"); |
| | 576 | Main.pref.putBoolean("slippy_map_chooser.show_downloaded_area", true); |
| | 577 | |
| | 578 | DataSet dataSetA = new DataSet(); |
| | 579 | // dataSetA has a long thin horizontal downloaded area (extending off the left & right of the map) |
| | 580 | dataSetA.addDataSource(new DataSource(new Bounds(-18., -61.02, -15., -60.98), "Elsewhere")); |
| | 581 | |
| | 582 | OsmDataLayer dataLayerA = new OsmDataLayer( |
| | 583 | dataSetA, |
| | 584 | "Test Layer A", |
| | 585 | null |
| | 586 | ); |
| | 587 | MainApplication.getLayerManager().addLayer(dataLayerA); |
| | 588 | |
| | 589 | DataSet dataSetB = new DataSet(); |
| | 590 | // dataSetB has a long thin vertical downloaded area (extending off the top & bottom of the map) |
| | 591 | dataSetB.addDataSource(new DataSource(new Bounds(-16.38, -62., -16.34, -60.), "Nowhere")); |
| | 592 | |
| | 593 | OsmDataLayer dataLayerB = new OsmDataLayer( |
| | 594 | dataSetB, |
| | 595 | "Test Layer B", |
| | 596 | null |
| | 597 | ); |
| | 598 | MainApplication.getLayerManager().addLayer(dataLayerB); |
| | 599 | |
| | 600 | MainApplication.getLayerManager().setActiveLayer(dataLayerB); |
| | 601 | |
| | 602 | MapView mapView = MainApplication.getMap().mapView; |
| | 603 | GuiHelper.runInEDTAndWaitWithException(() -> { |
| | 604 | mapView.setVisible(true); |
| | 605 | mapView.addNotify(); |
| | 606 | mapView.doLayout(); |
| | 607 | mapView.setBounds(0, 0, 400, 400); |
| | 608 | }); |
| | 609 | |
| | 610 | this.setUpMiniMap(); |
| | 611 | |
| | 612 | // assert "show downloaded areas" checkbox is checked |
| | 613 | assertTrue(this.getShowDownloadedAreaMenuItem().isSelected()); |
| | 614 | |
| | 615 | // again, we won't end up with exactly this viewport as it doesn't *precisely* match the aspect ratio |
| | 616 | mapView.zoomTo(new Bounds(-16.423, -61.076, -16.299, -60.932)); |
| | 617 | |
| | 618 | // an initial paint operation is required to trigger the tile fetches |
| | 619 | this.paintSlippyMap(); |
| | 620 | |
| | 621 | Awaitility.await().atMost(1000, MILLISECONDS).until(this.slippyMapTasksFinished); |
| | 622 | |
| | 623 | this.paintSlippyMap(); |
| | 624 | |
| | 625 | Map<Integer, String> paletteMap = ImmutableMap.<Integer, String>builder() |
| | 626 | .put(0xff00ff00, "g") // green |
| | 627 | .put(0xff000000, "b") // black |
| | 628 | .put(0xff8ad16b, "v") // viewport marker inner (pink+green mix) |
| | 629 | .put(0xff00df00, "d") // (shaded green) |
| | 630 | .put(0xff8ac46b, "q") // (shaded pink+green mix) |
| | 631 | .build(); |
| | 632 | |
| | 633 | // the middle row should be entirely unshaded |
| | 634 | ImagePatternMatching.rowMatch( |
| | 635 | paintedSlippyMap, |
| | 636 | paintedSlippyMap.getHeight()/2, |
| | 637 | paletteMap, |
| | 638 | "^g+bv+bg+$", |
| | 639 | true |
| | 640 | ); |
| | 641 | // the middle column should have an unshaded band within the viewport marker |
| | 642 | Matcher centerMatcher = ImagePatternMatching.columnMatch( |
| | 643 | paintedSlippyMap, |
| | 644 | paintedSlippyMap.getWidth()/2, |
| | 645 | paletteMap, |
| | 646 | "^(d+bq+)(v+)(q+bd+)$", |
| | 647 | true |
| | 648 | ); |
| | 649 | // the leftmost and rightmost columns should have an unshaded band |
| | 650 | Matcher leftMatcher = ImagePatternMatching.columnMatch( |
| | 651 | paintedSlippyMap, |
| | 652 | 0, |
| | 653 | paletteMap, |
| | 654 | "^(d+)(g+)(d+)$", |
| | 655 | true |
| | 656 | ); |
| | 657 | Matcher rightMatcher = ImagePatternMatching.columnMatch( |
| | 658 | paintedSlippyMap, |
| | 659 | paintedSlippyMap.getWidth()-1, |
| | 660 | paletteMap, |
| | 661 | "^(d+)(g+)(d+)$", |
| | 662 | true |
| | 663 | ); |
| | 664 | // the three columns should have the unshaded band in the same place |
| | 665 | assertEquals(centerMatcher.group(1).length(), leftMatcher.group(1).length()); |
| | 666 | assertEquals(centerMatcher.group(1).length(), rightMatcher.group(1).length()); |
| | 667 | assertEquals(centerMatcher.group(2).length(), leftMatcher.group(2).length()); |
| | 668 | assertEquals(centerMatcher.group(2).length(), rightMatcher.group(2).length()); |
| | 669 | |
| | 670 | // switch active layer |
| | 671 | MainApplication.getLayerManager().setActiveLayer(dataLayerA); |
| | 672 | this.paintSlippyMap(); |
| | 673 | |
| | 674 | // the middle column should be entirely unshaded |
| | 675 | ImagePatternMatching.columnMatch( |
| | 676 | paintedSlippyMap, |
| | 677 | paintedSlippyMap.getWidth()/2, |
| | 678 | paletteMap, |
| | 679 | "^g+bv+bg+$", |
| | 680 | true |
| | 681 | ); |
| | 682 | // the middle row should have an unshaded band within the viewport marker |
| | 683 | centerMatcher = ImagePatternMatching.rowMatch( |
| | 684 | paintedSlippyMap, |
| | 685 | paintedSlippyMap.getHeight()/2, |
| | 686 | paletteMap, |
| | 687 | "^(d+bq+)(v+)(q+bd+)$", |
| | 688 | true |
| | 689 | ); |
| | 690 | // the topmost and bottommost rows should have an unshaded band |
| | 691 | Matcher topMatcher = ImagePatternMatching.rowMatch( |
| | 692 | paintedSlippyMap, |
| | 693 | 0, |
| | 694 | paletteMap, |
| | 695 | "^(d+)(g+)(d+)$", |
| | 696 | true |
| | 697 | ); |
| | 698 | Matcher BottomMatcher = ImagePatternMatching.rowMatch( |
| | 699 | paintedSlippyMap, |
| | 700 | paintedSlippyMap.getHeight()-1, |
| | 701 | paletteMap, |
| | 702 | "^(d+)(g+)(d+)$", |
| | 703 | true |
| | 704 | ); |
| | 705 | // the three rows should have the unshaded band in the same place |
| | 706 | assertEquals(centerMatcher.group(1).length(), topMatcher.group(1).length()); |
| | 707 | assertEquals(centerMatcher.group(1).length(), BottomMatcher.group(1).length()); |
| | 708 | assertEquals(centerMatcher.group(2).length(), topMatcher.group(2).length()); |
| | 709 | assertEquals(centerMatcher.group(2).length(), BottomMatcher.group(2).length()); |
| | 710 | |
| | 711 | // deleting dataLayerA should hopefully switch our active layer back to dataLayerB |
| | 712 | MainApplication.getLayerManager().removeLayer(dataLayerA); |
| | 713 | this.paintSlippyMap(); |
| | 714 | |
| | 715 | // now we're really just repeating the same assertions we made originally when dataLayerB was active |
| | 716 | // the middle row should be entirely unshaded |
| | 717 | ImagePatternMatching.rowMatch( |
| | 718 | paintedSlippyMap, |
| | 719 | paintedSlippyMap.getHeight()/2, |
| | 720 | paletteMap, |
| | 721 | "^g+bv+bg+$", |
| | 722 | true |
| | 723 | ); |
| | 724 | // the middle column should have an unshaded band within the viewport marker |
| | 725 | centerMatcher = ImagePatternMatching.columnMatch( |
| | 726 | paintedSlippyMap, |
| | 727 | paintedSlippyMap.getWidth()/2, |
| | 728 | paletteMap, |
| | 729 | "^(d+bq+)(v+)(q+bd+)$", |
| | 730 | true |
| | 731 | ); |
| | 732 | // the leftmost and rightmost columns should have an unshaded band |
| | 733 | leftMatcher = ImagePatternMatching.columnMatch( |
| | 734 | paintedSlippyMap, |
| | 735 | 0, |
| | 736 | paletteMap, |
| | 737 | "^(d+)(g+)(d+)$", |
| | 738 | true |
| | 739 | ); |
| | 740 | rightMatcher = ImagePatternMatching.columnMatch( |
| | 741 | paintedSlippyMap, |
| | 742 | paintedSlippyMap.getWidth()-1, |
| | 743 | paletteMap, |
| | 744 | "^(d+)(g+)(d+)$", |
| | 745 | true |
| | 746 | ); |
| | 747 | // the three columns should have the unshaded band in the same place |
| | 748 | assertEquals(centerMatcher.group(1).length(), leftMatcher.group(1).length()); |
| | 749 | assertEquals(centerMatcher.group(1).length(), rightMatcher.group(1).length()); |
| | 750 | assertEquals(centerMatcher.group(2).length(), leftMatcher.group(2).length()); |
| | 751 | assertEquals(centerMatcher.group(2).length(), rightMatcher.group(2).length()); |
| | 752 | |
| | 753 | // but now if we expand its downloaded area to cover most of the southern hemisphere... |
| | 754 | dataSetB.addDataSource(new DataSource(new Bounds(-75., -100., 0., 100.), "Everywhere")); |
| | 755 | this.paintSlippyMap(); |
| | 756 | |
| | 757 | // we should see it all as unshaded. |
| | 758 | ImagePatternMatching.rowMatch( |
| | 759 | paintedSlippyMap, |
| | 760 | 0, |
| | 761 | paletteMap, |
| | 762 | "^g+$", |
| | 763 | true |
| | 764 | ); |
| | 765 | ImagePatternMatching.rowMatch( |
| | 766 | paintedSlippyMap, |
| | 767 | paintedSlippyMap.getHeight()/2, |
| | 768 | paletteMap, |
| | 769 | "^g+bv+bg+$", |
| | 770 | true |
| | 771 | ); |
| | 772 | ImagePatternMatching.rowMatch( |
| | 773 | paintedSlippyMap, |
| | 774 | paintedSlippyMap.getHeight()-1, |
| | 775 | paletteMap, |
| | 776 | "^g+$", |
| | 777 | true |
| | 778 | ); |
| | 779 | ImagePatternMatching.columnMatch( |
| | 780 | paintedSlippyMap, |
| | 781 | 0, |
| | 782 | paletteMap, |
| | 783 | "^g+$", |
| | 784 | true |
| | 785 | ); |
| | 786 | ImagePatternMatching.columnMatch( |
| | 787 | paintedSlippyMap, |
| | 788 | paintedSlippyMap.getWidth()/2, |
| | 789 | paletteMap, |
| | 790 | "^g+bv+bg+$", |
| | 791 | true |
| | 792 | ); |
| | 793 | ImagePatternMatching.columnMatch( |
| | 794 | paintedSlippyMap, |
| | 795 | paintedSlippyMap.getWidth()-1, |
| | 796 | paletteMap, |
| | 797 | "^g+$", |
| | 798 | true |
| | 799 | ); |
| | 800 | } |