source: osm/applications/editors/josm/plugins/reltoolbox/src/relcontext/relationfix/BoundaryFixer.java

Last change on this file was 36217, checked in by GerdP, 18 months ago

fix #23521: fix some memory leaks

  • dispose dialogs
  • either avoid to create clones of ways or relations or use setNodes(null) / setMembers(null)
  • replaces most ChangeCommand instances by better specialized alternatives
  • add some comments
  • fix some checkstyle / sonar issues
File size: 4.2 KB
RevLine 
[32395]1// License: GPL. For details, see LICENSE file.
[28693]2package relcontext.relationfix;
3
[28703]4import static org.openstreetmap.josm.tools.I18n.tr;
5
[36217]6import java.util.ArrayList;
7import java.util.List;
8
9import org.openstreetmap.josm.command.ChangeMembersCommand;
[28693]10import org.openstreetmap.josm.command.Command;
[36103]11import org.openstreetmap.josm.data.osm.DataSet;
[28693]12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.RelationMember;
[33708]16import org.openstreetmap.josm.gui.MainApplication;
[36103]17import org.openstreetmap.josm.tools.Utils;
[28693]18
19/**
[36102]20 * Fix multipolygon boundaries
21 * @see <a href="https://wiki.openstreetmap.org/wiki/Relation:boundary">osmwiki:Relation:boundary</a>
[28693]22 */
23public class BoundaryFixer extends MultipolygonFixer {
24
[30738]25 public BoundaryFixer() {
26 super("boundary", "multipolygon");
27 }
[28703]28
[30738]29 /**
30 * For boundary relations both "boundary" and "multipolygon" types are applicable, but
31 * it should also have key boundary=administrative to be fully boundary.
[36102]32 * @see <a href="https://wiki.openstreetmap.org/wiki/Relation:boundary">osmwiki:Relation:boundary</a>
[30738]33 */
34 @Override
35 public boolean isFixerApplicable(Relation rel) {
36 return super.isFixerApplicable(rel) && "administrative".equals(rel.get("boundary"));
37 }
[28703]38
[30738]39 @Override
40 public boolean isRelationGood(Relation rel) {
[32395]41 for (RelationMember m : rel.getMembers()) {
[36217]42 if (m.getType() == OsmPrimitiveType.RELATION && !"subarea".equals(m.getRole())) {
[28762]43 setWarningMessage(tr("Relation without ''subarea'' role found"));
[28693]44 return false;
[28703]45 }
[36217]46 if (m.getType() == OsmPrimitiveType.NODE && !("label".equals(m.getRole()) || "admin_centre".equals(m.getRole()))) {
[28762]47 setWarningMessage(tr("Node without ''label'' or ''admin_centre'' role found"));
[28693]48 return false;
[28703]49 }
[36217]50 if (m.getType() == OsmPrimitiveType.WAY && !("outer".equals(m.getRole()) || "inner".equals(m.getRole()))) {
[28762]51 setWarningMessage(tr("Way without ''inner'' or ''outer'' role found"));
[30738]52 return false;
[28703]53 }
[28693]54 }
[30738]55 clearWarningMessage();
56 return true;
57 }
[28693]58
[30738]59 @Override
60 public Command fixRelation(Relation rel) {
[36217]61 List<RelationMember> members = fixMultipolygonRoles(rel.getMembers());
62 if (members.isEmpty()) {
63 members = rel.getMembers();
[30738]64 }
[36217]65 members = fixBoundaryRoles(members);
66 if (!members.equals(rel.getMembers())) {
[36103]67 final DataSet ds = Utils.firstNonNull(rel.getDataSet(), MainApplication.getLayerManager().getEditDataSet());
[36217]68 return new ChangeMembersCommand(ds, rel, members);
[36103]69 }
70 return null;
[30738]71 }
[28693]72
[36217]73 /**
74 * Possibly change roles of non-way members.
75 * @param origMembers original list of relation members
76 * @return either the original and unmodified list or a new one with at least one new item
77 */
78 private static List<RelationMember> fixBoundaryRoles(List<RelationMember> origMembers) {
79 List<RelationMember> members = origMembers;
80 for (int i = 0; i < members.size(); i++) {
81 RelationMember m = members.get(i);
[28693]82 String role = null;
[32395]83 if (m.isRelation()) {
[28693]84 role = "subarea";
[36217]85 } else if (m.isNode() && !m.getMember().isIncomplete()) {
[32395]86 Node n = (Node) m.getMember();
[36217]87 if (n.hasKey("place")) {
88 String place = n.get("place");
89 if ("state".equals(place) || "country".equals(place) ||
90 "county".equals(place) || "region".equals(place)) {
91 role = "label";
[32395]92 } else {
[36217]93 role = "admin_centre";
[32395]94 }
[36217]95 } else {
96 role = "label";
[28693]97 }
98 }
[32395]99 if (role != null && !role.equals(m.getRole())) {
[36217]100 if (members == origMembers) {
101 members = new ArrayList<>(origMembers); // don't modify original list
102 }
103 members.set(i, new RelationMember(role, m.getMember()));
[28693]104 }
105 }
[36217]106 return members;
[28693]107 }
108}
Note: See TracBrowser for help on using the repository browser.