Changeset 36132 in osm for applications/editors/josm/plugins/addrinterpolation/src
- Timestamp:
- 2023-09-07T16:52:05+02:00 (16 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/addrinterpolation/src/org/openstreetmap/josm/plugins/AddrInterpolation/AddrInterpolationDialog.java
r35978 r36132 55 55 import org.openstreetmap.josm.data.osm.Relation; 56 56 import org.openstreetmap.josm.data.osm.RelationMember; 57 import org.openstreetmap.josm.data.osm.Tagged; 57 58 import org.openstreetmap.josm.data.osm.Way; 58 59 import org.openstreetmap.josm.gui.MainApplication; 59 60 import org.openstreetmap.josm.gui.widgets.UrlLabel; 60 61 import org.openstreetmap.josm.tools.ImageProvider; 62 import org.openstreetmap.josm.tools.Logging; 61 63 62 64 /** … … 65 67 public class AddrInterpolationDialog extends JDialog implements ActionListener { 66 68 67 private Way selectedStreet = null;68 private Way addrInterpolationWay = null;69 private Relation associatedStreetRelation = null;70 private ArrayList<Node> houseNumberNodes = null; // Additional nodes with addr:housenumber69 private Way selectedStreet; 70 private Way addrInterpolationWay; 71 private Relation associatedStreetRelation; 72 private ArrayList<Node> houseNumberNodes; // Additional nodes with addr:housenumber 71 73 72 74 private static String lastIncrement = ""; 73 private static int lastAccuracyIndex = 0;75 private static int lastAccuracyIndex; 74 76 private static String lastCity = ""; 75 77 private static String lastState = ""; … … 77 79 private static String lastCountry = ""; 78 80 private static String lastFullAddress = ""; 79 private static boolean lastConvertToHousenumber = false;81 private static boolean lastConvertToHousenumber; 80 82 81 83 // Edit controls 82 private EscapeDialog dialog = null;83 private JRadioButton streetNameButton = null;84 private JRadioButton streetRelationButton = null;85 private JTextField startTextField = null;86 private JTextField endTextField = null;87 private JTextField incrementTextField = null;88 private JTextField cityTextField = null;89 private JTextField stateTextField = null;90 private JTextField postCodeTextField = null;91 private JTextField countryTextField = null;92 private JTextField fullTextField = null;93 private Checkbox cbConvertToHouseNumbers = null;94 95 private boolean relationChanged = false; // Whether to re-trigger data changed for relation84 private EscapeDialog dialog; 85 private JRadioButton streetNameButton; 86 private JRadioButton streetRelationButton; 87 private JTextField startTextField; 88 private JTextField endTextField; 89 private JTextField incrementTextField; 90 private JTextField cityTextField; 91 private JTextField stateTextField; 92 private JTextField postCodeTextField; 93 private JTextField countryTextField; 94 private JTextField fullTextField; 95 private Checkbox cbConvertToHouseNumbers; 96 97 private boolean relationChanged; // Whether to re-trigger data changed for relation 96 98 // Track whether interpolation method is known so that auto detect doesn't override a previous choice. 97 private boolean interpolationMethodSet = false;99 private boolean interpolationMethodSet; 98 100 99 101 // NOTE: The following 2 arrays must match in number of elements and position … … 101 103 String[] addrInterpolationTags = {"odd", "even", "all", "alphabetic", "Numeric"}; 102 104 String[] addrInterpolationStrings = {tr("Odd"), tr("Even"), tr("All"), tr("Alphabetic"), tr("Numeric") }; // Translatable names for display 103 private final int NumericIndex= 4;104 private JComboBox<String> addrInterpolationList = null;105 private static final int NUMERIC_INDEX = 4; 106 private JComboBox<String> addrInterpolationList; 105 107 106 108 // NOTE: The following 2 arrays must match in number of elements and position 107 109 String[] addrInclusionTags = {"actual", "estimate", "potential" }; // Tag values for map 108 110 String[] addrInclusionStrings = {tr("Actual"), tr("Estimate"), tr("Potential") }; // Translatable names for display 109 private JComboBox<String> addrInclusionList = null;111 private JComboBox<String> addrInclusionList; 110 112 111 113 // For tracking edit changes as group for undo 112 private Collection<Command> commandGroup = null; 113 private Relation editedRelation = null; 114 114 private Collection<Command> commandGroup; 115 private Relation editedRelation; 116 117 /** 118 * Create a new address interpolation dialog with a specified name 119 * @param name The name to show in the title bar 120 */ 115 121 public AddrInterpolationDialog(String name) { 116 122 117 if (! FindAndSaveSelections()) {123 if (!findAndSaveSelections()) { 118 124 return; 119 125 } 120 126 121 JPanel editControlsPane = CreateEditControls(); 122 123 ShowDialog(editControlsPane, name); 124 } 125 126 private void ShowDialog(JPanel editControlsPane, String name) { 127 JPanel editControlsPane = createEditControls(); 128 129 showDialog(editControlsPane, name); 130 } 131 132 /** 133 * Show the dialog 134 * @param editControlsPane The controls to show 135 * @param name The name of the dialog 136 */ 137 private void showDialog(JPanel editControlsPane, String name) { 127 138 dialog = new EscapeDialog(MainApplication.getMainFrame(), name, true); 128 139 … … 144 155 145 156 dialog.setVisible(true); 146 147 lastIncrement = incrementTextField.getText(); 148 lastCity = cityTextField.getText(); 149 lastState = stateTextField.getText(); 150 lastPostCode = postCodeTextField.getText(); 151 lastCountry = countryTextField.getText(); 152 lastFullAddress = fullTextField.getText(); 153 lastConvertToHousenumber = cbConvertToHouseNumbers.getState(); 154 155 } 156 157 // Create edit control items and return JPanel on which they reside 158 private JPanel CreateEditControls() { 157 updateFields(this); 158 } 159 160 private static void updateFields(AddrInterpolationDialog dialog) { 161 lastIncrement = dialog.incrementTextField.getText(); 162 lastCity = dialog.cityTextField.getText(); 163 lastState = dialog.stateTextField.getText(); 164 lastPostCode = dialog.postCodeTextField.getText(); 165 lastCountry = dialog.countryTextField.getText(); 166 lastFullAddress = dialog.fullTextField.getText(); 167 lastConvertToHousenumber = dialog.cbConvertToHouseNumbers.getState(); 168 } 169 170 /** 171 * Create edit control items and return JPanel on which they reside 172 * @return the edit controls 173 */ 174 private JPanel createEditControls() { 159 175 160 176 JPanel editControlsPane = new JPanel(); … … 167 183 168 184 String streetName = selectedStreet.get("name"); 169 String streetRelation = FindRelation();170 if ( streetRelation.equals("")) {185 String streetRelation = findRelation(); 186 if ("".equals(streetRelation)) { 171 187 streetRelation = " (Create new)"; 172 188 } … … 213 229 214 230 // Preload any values already set in map 215 GetExistingMapKeys();231 getExistingMapKeys(); 216 232 217 233 218 234 JLabel[] textLabels = {startLabel, endLabel, numberingLabel, incrementLabel, inclusionLabel}; 219 235 Component[] editFields = {startTextField, endTextField, addrInterpolationList, incrementTextField, addrInclusionList}; 220 AddEditControlRows(textLabels, editFields, editControlsPane);236 addEditControlRows(textLabels, editFields, editControlsPane); 221 237 222 238 cbConvertToHouseNumbers = new Checkbox(tr("Convert way to individual house numbers."), null, lastConvertToHousenumber); … … 231 247 } 232 248 233 JPanel optionPanel = CreateOptionalFields();249 JPanel optionPanel = createOptionalFields(); 234 250 c.gridx = 0; 235 251 c.gridwidth = 2; // # of columns to span … … 242 258 @Override 243 259 public void keyPressed(KeyEvent e) { 244 if (e.getKeyCode() == KeyEvent.VK_ENTER) { 245 if (ValidateAndSave()) { 246 dialog.dispose(); 247 } 260 if (e.getKeyCode() == KeyEvent.VK_ENTER && validateAndSave()) { 261 dialog.dispose(); 248 262 } 249 263 } … … 261 275 @Override 262 276 public void focusGained(FocusEvent fe) { 263 if (!interpolationMethodSet) { 264 if (AutoDetectInterpolationMethod()) { 265 interpolationMethodSet = true; // Don't auto detect over a previous choice 266 } 277 if (!interpolationMethodSet && autoDetectInterpolationMethod()) { 278 interpolationMethodSet = true; // Don't auto detect over a previous choice 267 279 } 268 280 } … … 271 283 // Watch when Interpolation Method combo box is changed so that 272 284 // Numeric increment box can be enabled or disabled. 273 addrInterpolationList.addActionListener(new ActionListener() { 274 @Override 275 public void actionPerformed(ActionEvent e) { 276 int selectedIndex = addrInterpolationList.getSelectedIndex(); 277 incrementTextField.setEnabled(selectedIndex == NumericIndex); // Enable or disable numeric field 278 } 285 addrInterpolationList.addActionListener(e -> { 286 int selectedIndex = addrInterpolationList.getSelectedIndex(); 287 incrementTextField.setEnabled(selectedIndex == NUMERIC_INDEX); // Enable or disable numeric field 279 288 }); 280 289 281 290 editControlsPane.add(cbConvertToHouseNumbers, c); 282 291 283 if ( houseNumberNodes.size() > 0) {292 if (!houseNumberNodes.isEmpty()) { 284 293 JLabel houseNumberNodeNote = new JLabel(tr("Will associate {0} additional house number nodes", 285 294 houseNumberNodes.size())); … … 318 327 // combo box gets focus. 319 328 // Return true if a method was detected 320 private boolean AutoDetectInterpolationMethod() { 321 322 String startValueString = ReadTextField(startTextField); 323 String endValueString = ReadTextField(endTextField); 329 private boolean autoDetectInterpolationMethod() { 330 String startValueString = readTextField(startTextField); 331 String endValueString = readTextField(endTextField); 324 332 if ((startValueString == null) || (endValueString == null)) { 325 333 // Not all values entered yet … … 336 344 if (isEven(startValue)) { 337 345 if (isEven(endValue)) { 338 SelectInterpolationMethod("even");346 selectInterpolationMethod("even"); 339 347 } else { 340 SelectInterpolationMethod("all");348 selectInterpolationMethod("all"); 341 349 } 342 350 } else { 343 351 if (!isEven(endValue)) { 344 SelectInterpolationMethod("odd");352 selectInterpolationMethod("odd"); 345 353 } else { 346 SelectInterpolationMethod("all");354 selectInterpolationMethod("all"); 347 355 } 348 356 } … … 352 360 char endingChar = endValueString.charAt(endValueString.length()-1); 353 361 354 if (! IsNumeric("" + startingChar) && !IsNumeric("" + endingChar)) {362 if (!isNumeric("" + startingChar) && !isNumeric("" + endingChar)) { 355 363 // Both end with alpha 356 SelectInterpolationMethod("alphabetic");364 selectInterpolationMethod("alphabetic"); 357 365 return true; 358 366 } 359 367 360 if ( IsNumeric("" + startingChar) && !IsNumeric("" + endingChar)) {368 if (isNumeric("" + startingChar) && !isNumeric("" + endingChar)) { 361 369 endingChar = Character.toUpperCase(endingChar); 362 370 if ((endingChar >= 'A') && (endingChar <= 'Z')) { 363 371 // First is a number, last is Latin alpha 364 SelectInterpolationMethod("alphabetic");372 selectInterpolationMethod("alphabetic"); 365 373 return true; 366 374 } … … 373 381 } 374 382 375 // Set Interpolation Method combo box to method specified by 'currentMethod' (an OSM key value) 376 private void SelectInterpolationMethod(String currentMethod) { 383 /** 384 * Set Interpolation Method combo box to method specified by 'currentMethod' (an OSM key value) 385 * @param currentMethod The current interpolation method (number or key values) 386 */ 387 private void selectInterpolationMethod(String currentMethod) { 377 388 int currentIndex = 0; 378 389 if (isLong(currentMethod)) { … … 394 405 } 395 406 396 // Set Inclusion Method combo box to method specified by 'currentMethod' (an OSM key value) 397 private void SelectInclusion(String currentMethod) { 407 /** 408 * Set Inclusion Method combo box to method specified by 'currentMethod' (an OSM key value) 409 * @param currentMethod The key to use 410 */ 411 private void selectInclusion(String currentMethod) { 398 412 int currentIndex = 0; 399 413 // Must scan OSM key values because combo box is already loaded with translated strings … … 407 421 } 408 422 409 // Create optional control fields in a group box 410 private JPanel CreateOptionalFields() { 423 /** 424 * Create optional control fields in a group box 425 * @return a panel with optional fields 426 */ 427 private JPanel createOptionalFields() { 411 428 412 429 JPanel editControlsPane = new JPanel(); … … 450 467 451 468 Component[] optionalEditFields = {cityTextField, stateTextField, postCodeTextField, countryTextField, fullTextField}; 452 AddEditControlRows(optionalTextLabels, optionalEditFields, editControlsPane);469 addEditControlRows(optionalTextLabels, optionalEditFields, editControlsPane); 453 470 454 471 JPanel optionPanel = new JPanel(new BorderLayout()); … … 463 480 } 464 481 465 // Populate dialog for any possible existing settings if editing an existing Address interpolation way 466 private void GetExistingMapKeys() { 482 /** 483 * Populate dialog for any possible existing settings if editing an existing Address interpolation way 484 */ 485 private void getExistingMapKeys() { 467 486 468 487 // Check all nodes for optional addressing data 469 488 // Address interpolation nodes will overwrite these value if they contain optional data 470 489 for (Node node : houseNumberNodes) { 471 CheckNodeForAddressTags(node);490 checkNodeForAddressTags(node); 472 491 } 473 492 … … 476 495 if (currentMethod != null) { 477 496 478 SelectInterpolationMethod(currentMethod);497 selectInterpolationMethod(currentMethod); 479 498 interpolationMethodSet = true; // Don't auto detect over a previous choice 480 499 } … … 482 501 String currentInclusion = addrInterpolationWay.get("addr:inclusion"); 483 502 if (currentInclusion != null) { 484 SelectInclusion(currentInclusion);503 selectInclusion(currentInclusion); 485 504 } 486 505 … … 498 517 endTextField.setText(value); 499 518 } 500 CheckNodeForAddressTags(firstNode); 501 CheckNodeForAddressTags(lastNode); 502 } 503 } 504 505 // Check for any existing address data. If found, 506 // overwrite any previous data 507 private void CheckNodeForAddressTags(Node checkNode) { 508 519 checkNodeForAddressTags(firstNode); 520 checkNodeForAddressTags(lastNode); 521 } 522 } 523 524 /** 525 * Check for any existing address data. 526 * If found, overwrite any previous data 527 * @param checkNode The node to look for possible existing values 528 */ 529 private static void checkNodeForAddressTags(Tagged checkNode) { 509 530 // Interrogate possible existing optional values 510 531 String value = checkNode.get("addr:city"); … … 530 551 } 531 552 532 // Look for a possible 'associatedStreet' type of relation for selected street 533 // Returns relation description, or an empty string 534 private String FindRelation() { 535 String relationDescription = null; 536 DataSet currentDataSet = MainApplication.getLayerManager().getEditDataSet(); 553 /** 554 * Look for a possible 'associatedStreet' type of relation for selected street 555 * @return relation description, or an empty string 556 */ 557 private String findRelation() { 558 final DataSet currentDataSet = MainApplication.getLayerManager().getEditDataSet(); 537 559 if (currentDataSet != null) { 538 560 for (Relation relation : currentDataSet.getRelations()) { 539 540 String relationType = relation.get("type"); 541 if (relationType != null) { 542 if (relationType.equals("associatedStreet")) { 543 for (RelationMember relationMember : relation.getMembers()) { 544 if (relationMember.isWay()) { 545 Way way = (Way) relationMember.getMember(); 546 // System.out.println("Name: " + way.get("name") ); 547 if (way == selectedStreet) { 548 associatedStreetRelation = relation; 549 relationDescription = Long.toString(way.getId()); 550 551 String streetName = ""; 552 if (relation.getKeys().containsKey("name")) { 553 streetName = relation.get("name"); 554 } else { 555 // Relation is unnamed - use street name 556 streetName = selectedStreet.get("name"); 557 } 558 relationDescription += " (" + streetName + ")"; 559 return relationDescription; 561 if ("associatedStreet".equals(relation.get("type"))) { 562 for (RelationMember relationMember : relation.getMembers()) { 563 if (relationMember.isWay()) { 564 final StringBuilder relationDescription = new StringBuilder(); 565 Way way = (Way) relationMember.getMember(); 566 // System.out.println("Name: " + way.get("name") ); 567 if (way == selectedStreet) { 568 associatedStreetRelation = relation; 569 relationDescription.append(way.getId()).append('('); 570 571 if (relation.getKeys().containsKey("name")) { 572 relationDescription.append(relation.get("name")); 573 } else { 574 // Relation is unnamed - use street name 575 relationDescription.append(selectedStreet.get("name")); 560 576 } 577 relationDescription.append(')'); 578 return relationDescription.toString(); 561 579 } 562 580 } … … 565 583 } 566 584 } 567 568 585 return ""; 569 586 } 570 587 571 // We can proceed only if there is both a named way (the 'street') and 572 // one un-named way (the address interpolation way ) selected. 573 // The plugin menu item is enabled after a single way is selected to display a more meaningful 574 // message (a new user may not realize that they need to select both the street and 575 // address interpolation way first). 576 // Also, selected street and working address interpolation ways are saved. 577 private boolean FindAndSaveSelections() { 588 /** We can proceed only if there is both a named way (the 'street') and 589 * one un-named way (the address interpolation way ) selected. 590 * The plugin menu item is enabled after a single way is selected to display a more meaningful 591 * message (a new user may not realize that they need to select both the street and 592 * address interpolation way first). 593 * Also, selected street and working address interpolation ways are saved. 594 * @return {@code true} if 595 */ 596 private boolean findAndSaveSelections() { 578 597 579 598 boolean isValid = false; … … 583 602 DataSet currentDataSet = MainApplication.getLayerManager().getEditDataSet(); 584 603 if (currentDataSet != null) { 585 for (OsmPrimitive osm : currentDataSet.getSelectedWays()) { 586 Way way = (Way) osm; 604 for (Way way : currentDataSet.getSelectedWays()) { 587 605 if (way.getKeys().containsKey("name")) { 588 606 namedWayCount++; … … 599 617 houseNumberNodes = new ArrayList<>(); 600 618 // Check selected nodes 601 for (OsmPrimitive osm : currentDataSet.getSelectedNodes()) { 602 Node node = (Node) osm; 619 for (Node node : currentDataSet.getSelectedNodes()) { 603 620 if (node.getKeys().containsKey("addr:housenumber")) { 604 621 houseNumberNodes.add(node); … … 606 623 } 607 624 608 if (addrInterpolationWay != null) { 609 // Check nodes in middle of address interpolation way 610 if (addrInterpolationWay.getNodesCount() > 2) { 611 for (int i = 1; i < (addrInterpolationWay.getNodesCount()-2); i++) { 612 Node testNode = addrInterpolationWay.getNode(i); 613 if (testNode.getKeys().containsKey("addr:housenumber")) { 614 houseNumberNodes.add(testNode); 615 } 625 // Check nodes in middle of address interpolation way 626 if (addrInterpolationWay != null && addrInterpolationWay.getNodesCount() > 2) { 627 for (int i = 1; i < (addrInterpolationWay.getNodesCount()-2); i++) { 628 Node testNode = addrInterpolationWay.getNode(i); 629 if (testNode.getKeys().containsKey("addr:housenumber")) { 630 houseNumberNodes.add(testNode); 616 631 } 617 632 } … … 630 645 if (unNamedWayCount != 1) { 631 646 // Allow for street + house number nodes only to be selected (no address interpolation way). 632 if ( houseNumberNodes.size() > 0) {647 if (!houseNumberNodes.isEmpty()) { 633 648 isValid = true; 634 649 } else { … … 655 670 * @param container container 656 671 */ 657 private void AddEditControlRows(JLabel[] labels,658 Component[] editFields,659 Container container) {672 private static void addEditControlRows(JLabel[] labels, 673 Component[] editFields, 674 Container container) { 660 675 GridBagConstraints c = new GridBagConstraints(); 661 676 c.anchor = GridBagConstraints.EAST; … … 680 695 public void actionPerformed(ActionEvent e) { 681 696 if ("ok".equals(e.getActionCommand())) { 682 if ( ValidateAndSave()) {697 if (validateAndSave()) { 683 698 dialog.dispose(); 684 699 } … … 688 703 } 689 704 690 // For Alpha interpolation, return base string 691 // For example: "22A" -> "22" 692 // For example: "A" -> "" 693 // Input string must not be empty 694 private String BaseAlpha(String strValue) { 705 /** 706 * For Alpha interpolation, return base string 707 * For example: "22A" -> "22" 708 * For example: "A" -> "" 709 * Input string must not be empty 710 * @param strValue The value to get the base string of 711 * @return the base string, or an empty string 712 */ 713 private static String baseAlpha(String strValue) { 695 714 if (strValue.length() > 0) { 696 return strValue.substring(0, strValue.length() -1);715 return strValue.substring(0, strValue.length() - 1); 697 716 } else { 698 717 return ""; … … 700 719 } 701 720 702 private char LastChar(String strValue) { 721 /** 722 * Get the last char of a string 723 * @param strValue The string to get the last char of 724 * @return The last char, or {@code 0}. 725 */ 726 private static char lastChar(String strValue) { 703 727 if (strValue.length() > 0) { 704 return strValue.charAt(strValue.length() -1);728 return strValue.charAt(strValue.length() - 1); 705 729 } else { 706 730 return 0; … … 708 732 } 709 733 710 // Test for valid positive long int 711 private boolean isLong(String input) { 734 /** 735 * Test for valid positive long int 736 * @param input The input string 737 * @return {@code true} if the input is a positive long 738 */ 739 private static boolean isLong(String input) { 712 740 try { 713 Long val = Long.parseLong(input);741 long val = Long.parseLong(input); 714 742 return (val > 0); 715 } catch (Exception e) { 743 } catch (NumberFormatException e) { 744 Logging.trace(e); 716 745 return false; 717 746 } 718 747 } 719 748 720 private boolean isEven(Long input) { 749 /** 750 * Check if a number is even 751 * @param input The input number 752 * @return {@code true} if the number is even 753 */ 754 private static boolean isEven(long input) { 721 755 return ((input % 2) == 0); 722 756 } 723 757 724 private static Pattern p = Pattern.compile("^[0-9]+$"); 725 private static boolean IsNumeric(String s) { 726 return p.matcher(s).matches(); 727 } 728 729 private void InterpolateAlphaSection(int startNodeIndex, int endNodeIndex, String endValueString, 730 char startingChar, char endingChar) { 731 732 733 String baseAlpha = BaseAlpha(endValueString); 758 private static final Pattern PATTERN_NUMERIC = Pattern.compile("^[0-9]+$"); 759 760 /** 761 * Check if a string is numeric 762 * @param s The string to check 763 * @return {@code true} if it is a numeric string 764 */ 765 private static boolean isNumeric(String s) { 766 return PATTERN_NUMERIC.matcher(s).matches(); 767 } 768 769 770 private void interpolateAlphaSection(int startNodeIndex, int endNodeIndex, String endValueString, 771 char startingChar, char endingChar) { 772 773 774 String baseAlpha = baseAlpha(endValueString); 734 775 int nSegments = endNodeIndex - startNodeIndex; 735 776 736 777 double[] segmentLengths = new double[nSegments]; 737 778 // Total length of address interpolation way section 738 double totalLength = CalculateSegmentLengths(startNodeIndex, endNodeIndex, segmentLengths);779 double totalLength = calculateSegmentLengths(startNodeIndex, endNodeIndex, segmentLengths); 739 780 740 781 … … 784 825 } 785 826 786 private void CreateAlphaInterpolation(String startValueString, String endValueString) {787 char startingChar = LastChar(startValueString);788 char endingChar = LastChar(endValueString);827 private void createAlphaInterpolation(String startValueString, String endValueString) { 828 char startingChar = lastChar(startValueString); 829 char endingChar = lastChar(endValueString); 789 830 790 831 if (isLong(startValueString)) { … … 798 839 Node testNode = addrInterpolationWay.getNode(i); 799 840 String endNodeNumber = testNode.get("addr:housenumber"); 800 if (endNodeNumber != null) { 801 // This is a potential anchor node 802 if (endNodeNumber != "") { 803 char anchorChar = LastChar(endNodeNumber); 804 if ((anchorChar > startingChar) && (anchorChar < endingChar)) { 805 // Lies within the expected range 806 InterpolateAlphaSection(startIndex, i, endNodeNumber, startingChar, anchorChar); 807 808 // For next interpolation section 809 startingChar = anchorChar; 810 startValueString = endNodeNumber; 811 startIndex = i; 812 } 813 } 814 841 // This is a potential anchor node 842 if (endNodeNumber != null && !"".equals(endNodeNumber)) { 843 char anchorChar = lastChar(endNodeNumber); 844 if ((anchorChar > startingChar) && (anchorChar < endingChar)) { 845 // Lies within the expected range 846 interpolateAlphaSection(startIndex, i, endNodeNumber, startingChar, anchorChar); 847 848 // For next interpolation section 849 startingChar = anchorChar; 850 startValueString = endNodeNumber; 851 startIndex = i; 852 } 815 853 } 816 854 } 817 855 818 856 // End nodes do not actually contain housenumber value yet (command has not executed), so use user-entered value 819 InterpolateAlphaSection(startIndex, addrInterpolationWay.getNodesCount()-1, endValueString, startingChar, endingChar);820 } 821 822 private double CalculateSegmentLengths(int startNodeIndex, int endNodeIndex, double[] segmentLengths) {857 interpolateAlphaSection(startIndex, addrInterpolationWay.getNodesCount()-1, endValueString, startingChar, endingChar); 858 } 859 860 private double calculateSegmentLengths(int startNodeIndex, int endNodeIndex, double[] segmentLengths) { 823 861 Node fromNode = addrInterpolationWay.getNode(startNodeIndex); 824 862 double totalLength = 0.0; … … 834 872 } 835 873 836 private void InterpolateNumericSection(int startNodeIndex, int endNodeIndex,837 long startingAddr, long endingAddr,838 long increment) {874 private void interpolateNumericSection(int startNodeIndex, int endNodeIndex, 875 long startingAddr, long endingAddr, 876 long increment) { 839 877 840 878 int nSegments = endNodeIndex - startNodeIndex; … … 843 881 844 882 // Total length of address interpolation way section 845 double totalLength = CalculateSegmentLengths(startNodeIndex, endNodeIndex, segmentLengths);883 double totalLength = calculateSegmentLengths(startNodeIndex, endNodeIndex, segmentLengths); 846 884 847 885 int nHouses = (int) ((endingAddr - startingAddr) / increment) -1; … … 885 923 } 886 924 887 private void CreateNumericInterpolation(String startValueString, String endValueString, long increment) {925 private void createNumericInterpolation(String startValueString, String endValueString, long increment) { 888 926 889 927 long startingAddr = Long.parseLong(startValueString); … … 895 933 Node testNode = addrInterpolationWay.getNode(i); 896 934 String strEndNodeNumber = testNode.get("addr:housenumber"); 897 if (strEndNodeNumber != null) { 898 // This is a potential anchor node 899 if (isLong(strEndNodeNumber)) { 900 901 long anchorAddrNumber = Long.parseLong(strEndNodeNumber); 902 if ((anchorAddrNumber > startingAddr) && (anchorAddrNumber < endingAddr)) { 903 // Lies within the expected range 904 InterpolateNumericSection(startIndex, i, startingAddr, anchorAddrNumber, increment); 905 906 // For next interpolation section 907 startingAddr = anchorAddrNumber; 908 startValueString = strEndNodeNumber; 909 startIndex = i; 910 } 911 } 912 935 // This is a potential anchor node 936 if (strEndNodeNumber != null && isLong(strEndNodeNumber)) { 937 long anchorAddrNumber = Long.parseLong(strEndNodeNumber); 938 if ((anchorAddrNumber > startingAddr) && (anchorAddrNumber < endingAddr)) { 939 // Lies within the expected range 940 interpolateNumericSection(startIndex, i, startingAddr, anchorAddrNumber, increment); 941 942 // For next interpolation section 943 startingAddr = anchorAddrNumber; 944 startValueString = strEndNodeNumber; 945 startIndex = i; 946 } 913 947 } 914 948 } 915 949 916 950 // End nodes do not actually contain housenumber value yet (command has not executed), so use user-entered value 917 InterpolateNumericSection(startIndex, addrInterpolationWay.getNodesCount()-1, startingAddr, endingAddr, increment);951 interpolateNumericSection(startIndex, addrInterpolationWay.getNodesCount()-1, startingAddr, endingAddr, increment); 918 952 } 919 953 920 954 // Called if user has checked "Convert to House Numbers" checkbox. 921 private void ConvertWayToHousenumbers(String selectedMethod, String startValueString, String endValueString,922 String incrementString) {955 private void convertWayToHousenumbers(String selectedMethod, String startValueString, String endValueString, 956 String incrementString) { 923 957 // - Use nodes labeled with 'same type' as interim anchors in the middle of the way to identify unequal spacing. 924 958 // - Ignore nodes of different type; for example '25b' is ignored in sequence 5..15 925 959 926 960 // Calculate required number of house numbers to create 927 if ( selectedMethod.equals("alphabetic")) {928 929 CreateAlphaInterpolation(startValueString, endValueString);961 if ("alphabetic".equals(selectedMethod)) { 962 963 createAlphaInterpolation(startValueString, endValueString); 930 964 931 965 } else { 932 966 long increment = 1; 933 if ( selectedMethod.equals("odd") || selectedMethod.equals("even")) {967 if ("odd".equals(selectedMethod) || "even".equals(selectedMethod)) { 934 968 increment = 2; 935 } else if ( selectedMethod.equals("Numeric")) {969 } else if ("Numeric".equals(selectedMethod)) { 936 970 increment = Long.parseLong(incrementString); 937 971 } 938 CreateNumericInterpolation(startValueString, endValueString, increment);939 } 940 941 RemoveAddressInterpolationWay();942 943 } 944 945 private void RemoveAddressInterpolationWay() {972 createNumericInterpolation(startValueString, endValueString, increment); 973 } 974 975 removeAddressInterpolationWay(); 976 977 } 978 979 private void removeAddressInterpolationWay() { 946 980 947 981 // Remove way - nodes of the way remain 948 commandGroup.add( new DeleteCommand(addrInterpolationWay));982 commandGroup.add(DeleteCommand.delete(Collections.singleton(addrInterpolationWay))); 949 983 950 984 // Remove untagged nodes … … 952 986 Node testNode = addrInterpolationWay.getNode(i); 953 987 if (!testNode.hasKeys()) { 954 commandGroup.add( new DeleteCommand(testNode));988 commandGroup.add(DeleteCommand.delete(Collections.singleton(testNode))); 955 989 } 956 990 } … … 959 993 } 960 994 961 private boolean ValidateAndSave() {962 963 String startValueString = ReadTextField(startTextField);964 String endValueString = ReadTextField(endTextField);965 String incrementString = ReadTextField(incrementTextField);966 String city = ReadTextField(cityTextField);967 String state = ReadTextField(stateTextField);968 String postCode = ReadTextField(postCodeTextField);969 String country = ReadTextField(countryTextField);970 String fullAddress = ReadTextField(fullTextField);971 972 String selectedMethod = GetInterpolationMethod();995 private boolean validateAndSave() { 996 997 String startValueString = readTextField(startTextField); 998 String endValueString = readTextField(endTextField); 999 String incrementString = readTextField(incrementTextField); 1000 String city = readTextField(cityTextField); 1001 String state = readTextField(stateTextField); 1002 String postCode = readTextField(postCodeTextField); 1003 String country = readTextField(countryTextField); 1004 String fullAddress = readTextField(fullTextField); 1005 1006 String selectedMethod = getInterpolationMethod(); 973 1007 if (addrInterpolationWay != null) { 974 1008 Long startAddr = 0L, endAddr = 0L; 975 if (! selectedMethod.equals("alphabetic")) {1009 if (!"alphabetic".equals(selectedMethod)) { 976 1010 Long[] addrArray = {startAddr, endAddr}; 977 if (! ValidAddressNumbers(startValueString, endValueString, addrArray)) {1011 if (!validAddressNumbers(startValueString, endValueString, addrArray)) { 978 1012 return false; 979 1013 } … … 983 1017 984 1018 String errorMessage = ""; 985 if (selectedMethod.equals("odd")) { 986 if (isEven(startAddr) || isEven(endAddr)) { 987 errorMessage = tr("Expected odd numbers for addresses"); 988 } 989 990 } else if (selectedMethod.equals("even")) { 991 if (!isEven(startAddr) || !isEven(endAddr)) { 992 errorMessage = tr("Expected even numbers for addresses"); 993 } 994 } else if (selectedMethod.equals("all")) { 995 996 } else if (selectedMethod.equals("alphabetic")) { 997 errorMessage = ValidateAlphaAddress(startValueString, endValueString); 998 999 } else if (selectedMethod.equals("Numeric")) { 1000 1001 if (!ValidNumericIncrementString(incrementString, startAddr, endAddr)) { 1002 errorMessage = tr("Expected valid number for increment"); 1003 } 1004 } 1005 if (!errorMessage.equals("")) { 1019 switch (selectedMethod) { 1020 case "odd": 1021 if (isEven(startAddr) || isEven(endAddr)) { 1022 errorMessage = tr("Expected odd numbers for addresses"); 1023 } 1024 break; 1025 case "even": 1026 if (!isEven(startAddr) || !isEven(endAddr)) { 1027 errorMessage = tr("Expected even numbers for addresses"); 1028 } 1029 break; 1030 case "alphabetic": 1031 errorMessage = validateAlphaAddress(startValueString, endValueString); 1032 break; 1033 case "Numeric": 1034 if (!validNumericIncrementString(incrementString, startAddr, endAddr)) { 1035 errorMessage = tr("Expected valid number for increment"); 1036 } 1037 break; 1038 case "all": 1039 default: 1040 // Fall through 1041 } 1042 if (!"".equals(errorMessage)) { 1006 1043 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), errorMessage, tr("Error"), JOptionPane.ERROR_MESSAGE); 1007 1044 return false; … … 1009 1046 } 1010 1047 1011 if (country != null) { 1012 if (country.length() != 2) { 1013 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 1014 tr("Country code must be 2 letters"), tr("Error"), JOptionPane.ERROR_MESSAGE); 1015 return false; 1016 } 1048 if (country != null && country.length() != 2) { 1049 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 1050 tr("Country code must be 2 letters"), tr("Error"), JOptionPane.ERROR_MESSAGE); 1051 return false; 1017 1052 } 1018 1053 … … 1034 1069 1035 1070 String interpolationTagValue = selectedMethod; 1036 if ( selectedMethod.equals("Numeric")) {1071 if ("Numeric".equals(selectedMethod)) { 1037 1072 // The interpolation method is the number for 'Numeric' case 1038 1073 interpolationTagValue = incrementString; … … 1042 1077 // Convert way to house numbers is checked. 1043 1078 // Create individual nodes and delete interpolation way 1044 ConvertWayToHousenumbers(selectedMethod, startValueString, endValueString, incrementString);1079 convertWayToHousenumbers(selectedMethod, startValueString, endValueString, incrementString); 1045 1080 } else { 1046 1081 // Address interpolation way will remain 1047 1082 commandGroup.add(new ChangePropertyCommand(addrInterpolationWay, "addr:interpolation", interpolationTagValue)); 1048 commandGroup.add(new ChangePropertyCommand(addrInterpolationWay, "addr:inclusion", GetInclusionMethod()));1083 commandGroup.add(new ChangePropertyCommand(addrInterpolationWay, "addr:inclusion", getInclusionMethod())); 1049 1084 } 1050 1085 … … 1061 1096 // Relation button was selected 1062 1097 if (associatedStreetRelation == null) { 1063 CreateRelation(currentDataSet, streetName);1098 createRelation(currentDataSet, streetName); 1064 1099 // relationChanged = true; (not changed since it was created) 1065 1100 } … … 1068 1103 1069 1104 if (addrInterpolationWay != null) { 1070 AddToRelation(associatedStreetRelation, addrInterpolationWay, "house");1105 addToRelation(associatedStreetRelation, addrInterpolationWay, "house"); 1071 1106 } 1072 1107 } … … 1077 1112 1078 1113 if (streetRelationButton.isSelected()) { 1079 AddToRelation(associatedStreetRelation, node, "house");1114 addToRelation(associatedStreetRelation, node, "house"); 1080 1115 } 1081 1116 Map<String, String> tags = new HashMap<>(); … … 1105 1140 } 1106 1141 1107 private boolean ValidNumericIncrementString(String incrementString, long startingAddr, long endingAddr) {1142 private static boolean validNumericIncrementString(String incrementString, long startingAddr, long endingAddr) { 1108 1143 1109 1144 if (!isLong(incrementString)) { … … 1115 1150 } 1116 1151 1117 if (((endingAddr - startingAddr) % testIncrement) != 0) { 1118 return false; 1119 } 1120 return true; 1152 return ((endingAddr - startingAddr) % testIncrement) == 0; 1121 1153 } 1122 1154 1123 1155 // Create Associated Street relation, add street, and add to list of commands to perform 1124 private void CreateRelation(DataSet currentDataSet, String streetName) {1156 private void createRelation(DataSet currentDataSet, String streetName) { 1125 1157 associatedStreetRelation = new Relation(); 1126 1158 associatedStreetRelation.put("name", streetName); … … 1133 1165 // Read from dialog text box, removing leading and trailing spaces 1134 1166 // Return the string, or null for a zero length string 1135 private String ReadTextField(JTextField field) {1167 private static String readTextField(JTextField field) { 1136 1168 String value = field.getText(); 1137 1169 if (value != null) { 1138 1170 value = value.trim(); 1139 if ( value.equals("")) {1171 if ("".equals(value)) { 1140 1172 value = null; 1141 1173 } … … 1146 1178 // Test if relation contains specified member 1147 1179 // If not already present, it is added 1148 private void AddToRelation(Relation relation, OsmPrimitive testMember, String role) {1180 private void addToRelation(Relation relation, OsmPrimitive testMember, String role) { 1149 1181 boolean isFound = false; 1150 1182 for (RelationMember relationMember : relation.getMembers()) { … … 1168 1200 // Last character of ending must be greater than starting 1169 1201 // Return empty error message if OK 1170 private String ValidateAlphaAddress(String startValueString,1171 String endValueString) {1202 private static String validateAlphaAddress(String startValueString, 1203 String endValueString) { 1172 1204 String errorMessage = ""; 1173 1205 1174 if ( startValueString.equals("") || endValueString.equals("")) {1206 if ("".equals(startValueString) || "".equals(endValueString)) { 1175 1207 errorMessage = tr("Please enter valid number for starting and ending address"); 1176 1208 } else { 1177 char startingChar = LastChar(startValueString);1178 char endingChar = LastChar(endValueString);1209 char startingChar = lastChar(startValueString); 1210 char endingChar = lastChar(endValueString); 1179 1211 1180 1212 1181 1213 boolean isOk = false; 1182 if ( IsNumeric("" + startingChar) && !IsNumeric("" + endingChar)) {1214 if (isNumeric("" + startingChar) && !isNumeric("" + endingChar)) { 1183 1215 endingChar = Character.toUpperCase(endingChar); 1184 1216 if ((endingChar >= 'A') && (endingChar <= 'Z')) { … … 1186 1218 isOk = true; 1187 1219 } 1188 } else if (! IsNumeric("" + startingChar) && !IsNumeric("" + endingChar)) {1220 } else if (!isNumeric("" + startingChar) && !isNumeric("" + endingChar)) { 1189 1221 // Both are alpha 1190 1222 isOk = true; … … 1198 1230 1199 1231 // Get number portion of first item: may or may not have letter suffix 1200 String numStart = BaseAlpha(startValueString);1201 if ( IsNumeric(startValueString)) {1232 String numStart = baseAlpha(startValueString); 1233 if (isNumeric(startValueString)) { 1202 1234 numStart = startValueString; 1203 1235 } 1204 1236 1205 String numEnd = BaseAlpha(endValueString);1237 String numEnd = baseAlpha(endValueString); 1206 1238 if (!numStart.equals(numEnd)) { 1207 1239 errorMessage = tr("Starting and ending numbers must be the same for alphabetic addresses"); … … 1219 1251 1220 1252 // Convert string addresses to numeric, with error check 1221 private boolean ValidAddressNumbers(String startValueString,1222 String endValueString, Long[] addrArray) {1253 private static boolean validAddressNumbers(String startValueString, 1254 String endValueString, Long[] addrArray) { 1223 1255 String errorMessage = ""; 1224 1256 … … 1229 1261 errorMessage = tr("Please enter valid number for ending address"); 1230 1262 } 1231 if ( errorMessage.equals("")) {1263 if ("".equals(errorMessage)) { 1232 1264 addrArray[0] = Long.parseLong(startValueString); 1233 1265 addrArray[1] = Long.parseLong(endValueString); … … 1238 1270 } 1239 1271 1240 if ( errorMessage.equals("")) {1272 if ("".equals(errorMessage)) { 1241 1273 return true; 1242 1274 … … 1247 1279 } 1248 1280 1249 private String GetInterpolationMethod() {1281 private String getInterpolationMethod() { 1250 1282 int selectedIndex = addrInterpolationList.getSelectedIndex(); 1251 1283 return addrInterpolationTags[selectedIndex]; 1252 1284 } 1253 1285 1254 private String GetInclusionMethod() {1286 private String getInclusionMethod() { 1255 1287 int selectedIndex = addrInclusionList.getSelectedIndex(); 1256 1288 lastAccuracyIndex = selectedIndex;
Note:
See TracChangeset
for help on using the changeset viewer.