source: josm/trunk/test/unit/org/openstreetmap/josm/actions/JoinAreasActionTest.java@ 11741

Last change on this file since 11741 was 11741, checked in by Don-vip, 7 years ago

fix java warnings

  • Property svn:eol-style set to native
File size: 8.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertTrue;
6
7import java.io.FileInputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.util.Arrays;
11import java.util.Collection;
12import java.util.HashSet;
13import java.util.Objects;
14import java.util.Set;
15
16import org.junit.Rule;
17import org.junit.Test;
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.TestUtils;
20import org.openstreetmap.josm.actions.search.SearchAction;
21import org.openstreetmap.josm.data.osm.DataSet;
22import org.openstreetmap.josm.data.osm.Node;
23import org.openstreetmap.josm.data.osm.OsmPrimitive;
24import org.openstreetmap.josm.data.osm.Relation;
25import org.openstreetmap.josm.data.osm.RelationMember;
26import org.openstreetmap.josm.data.osm.Way;
27import org.openstreetmap.josm.gui.layer.Layer;
28import org.openstreetmap.josm.gui.layer.OsmDataLayer;
29import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
30import org.openstreetmap.josm.io.IllegalDataException;
31import org.openstreetmap.josm.io.OsmReader;
32import org.openstreetmap.josm.testutils.JOSMTestRules;
33import org.openstreetmap.josm.tools.MultiMap;
34import org.openstreetmap.josm.tools.Utils;
35
36import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37
38/**
39 * Unit tests of {@link JoinAreasAction} class.
40 */
41public class JoinAreasActionTest {
42
43 /**
44 * Setup test.
45 */
46 @Rule
47 @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
48 public JOSMTestRules test = new JOSMTestRules().commands();
49
50 /**
51 * Non-regression test for bug #10511.
52 * @throws IOException if any I/O error occurs
53 * @throws IllegalDataException if OSM parsing fails
54 */
55 @Test
56 public void testTicket10511() throws IOException, IllegalDataException {
57 try (InputStream is = TestUtils.getRegressionDataStream(10511, "10511_mini.osm")) {
58 DataSet ds = OsmReader.parseDataSet(is, null);
59 Layer layer = new OsmDataLayer(ds, null, null);
60 Main.getLayerManager().addLayer(layer);
61 try {
62 new JoinAreasAction().join(ds.getWays());
63 } finally {
64 // Ensure we clean the place before leaving, even if test fails.
65 Main.getLayerManager().removeLayer(layer);
66 }
67 }
68 }
69
70 /**
71 * Non-regression test for bug #11992.
72 * @throws IOException if any I/O error occurs
73 * @throws IllegalDataException if OSM parsing fails
74 */
75 @Test
76 public void testTicket11992() throws IOException, IllegalDataException {
77 try (InputStream is = TestUtils.getRegressionDataStream(11992, "shapes.osm")) {
78 DataSet ds = OsmReader.parseDataSet(is, null);
79 assertEquals(10, ds.getWays().size());
80 Layer layer = new OsmDataLayer(ds, null, null);
81 Main.getLayerManager().addLayer(layer);
82 for (String ref : new String[]{"A", "B", "C", "D", "E"}) {
83 System.out.print("Joining ways " + ref);
84 Collection<OsmPrimitive> found = SearchAction.searchAndReturn("type:way ref="+ref, SearchAction.SearchMode.replace);
85 assertEquals(2, found.size());
86
87 Main.main.menu.joinAreas.join(Utils.filteredCollection(found, Way.class));
88
89 Collection<OsmPrimitive> found2 = SearchAction.searchAndReturn("type:relation ref="+ref, SearchAction.SearchMode.replace);
90 assertEquals(1, found2.size());
91 System.out.println(" ==> OK");
92 }
93 }
94 }
95
96 /**
97 * Non-regression test which checks example files in data_nodist
98 * @throws Exception if an error occurs
99 */
100 @Test
101 @SuppressWarnings({ "rawtypes", "unchecked" })
102 public void testExamples() throws Exception {
103 DataSet dsToJoin, dsExpected;
104 try (InputStream is = new FileInputStream("data_nodist/Join_Areas_Tests.osm")) {
105 dsToJoin = OsmReader.parseDataSet(is, NullProgressMonitor.INSTANCE);
106 }
107 try (InputStream is = new FileInputStream("data_nodist/Join_Areas_Tests_joined.osm")) {
108 dsExpected = OsmReader.parseDataSet(is, NullProgressMonitor.INSTANCE);
109 }
110 Collection<OsmPrimitive> testPrims = dsToJoin.getPrimitives(osm -> osm.get("test") != null);
111 MultiMap<String, OsmPrimitive> tests = new MultiMap<>();
112 for (OsmPrimitive testPrim : testPrims) {
113 tests.put(testPrim.get("test"), testPrim);
114 }
115 for (String test : tests.keySet()) {
116 Collection<OsmPrimitive> primitives = tests.get(test);
117 for (OsmPrimitive osm : primitives) {
118 assertTrue(test + "; expected way, but got: " + osm, osm instanceof Way);
119 }
120 new JoinAreasAction().join((Collection) primitives);
121 Collection<OsmPrimitive> joinedCol = dsToJoin.getPrimitives(osm -> !osm.isDeleted() && Objects.equals(osm.get("test"), test));
122 assertEquals("in test " + test + ":", 1, joinedCol.size());
123 Collection<OsmPrimitive> expectedCol = dsExpected.getPrimitives(osm -> !osm.isDeleted() && Objects.equals(osm.get("test"), test));
124 assertEquals("in test " + test + ":", 1, expectedCol.size());
125 OsmPrimitive osmJoined = joinedCol.iterator().next();
126 OsmPrimitive osmExpected = expectedCol.iterator().next();
127 assertTrue("difference in test " + test, isSemanticallyEqual(osmExpected, osmJoined));
128 }
129 }
130
131 /**
132 * Check if 2 primitives are semantically equal as result of a join areas
133 * operation.
134 * @param osm1 first primitive
135 * @param osm2 second primitive
136 * @return true if both primitives are semantically equal
137 */
138 private boolean isSemanticallyEqual(OsmPrimitive osm1, OsmPrimitive osm2) {
139 if (osm1 instanceof Node && osm2 instanceof Node)
140 return isSemanticallyEqualNode((Node) osm1, (Node) osm2);
141 if (osm1 instanceof Way && osm2 instanceof Way)
142 return isSemanticallyEqualWay((Way) osm1, (Way) osm2);
143 if (osm1 instanceof Relation && osm2 instanceof Relation)
144 return isSemanticallyEqualRelation((Relation) osm1, (Relation) osm2);
145 return false;
146 }
147
148 private boolean isSemanticallyEqualRelation(Relation r1, Relation r2) {
149 if (!r1.getKeys().equals(r2.getKeys())) return false;
150 if (r1.getMembersCount() != r2.getMembersCount()) return false;
151 Set<RelationMember> matchCandidates = new HashSet<>(r2.getMembers());
152 for (RelationMember rm : r1.getMembers()) {
153 RelationMember matched = null;
154 for (RelationMember cand : matchCandidates) {
155 if (!rm.getRole().equals(cand.getRole())) continue;
156 if (!isSemanticallyEqual(rm.getMember(), cand.getMember())) continue;
157 matched = cand;
158 break;
159 }
160 if (matched == null) return false;
161 matchCandidates.remove(matched);
162 }
163 return true;
164 }
165
166 private boolean isSemanticallyEqualWay(Way w1, Way w2) {
167 if (!w1.isClosed() || !w2.isClosed()) throw new UnsupportedOperationException();
168 if (!w1.getKeys().equals(w2.getKeys())) return false;
169 if (w1.getNodesCount() != w2.getNodesCount()) return false;
170 int n = w1.getNodesCount() - 1;
171 for (int dir : Arrays.asList(1, -1)) {
172 for (int i = 0; i < n; i++) {
173 boolean different = false;
174 for (int j = 0; j < n; j++) {
175 Node n1 = w1.getNode(j);
176 Node n2 = w2.getNode(Utils.mod(i + dir*j, n));
177 if (!isSemanticallyEqualNode(n1, n2)) {
178 different = true;
179 break;
180 }
181 }
182 if (!different)
183 return true;
184 }
185 }
186 return false;
187 }
188
189 private boolean isSemanticallyEqualNode(Node n1, Node n2) {
190 return n1.hasEqualSemanticAttributes(n2);
191 }
192}
Note: See TracBrowser for help on using the repository browser.