source: josm/trunk/test/unit/org/openstreetmap/josm/io/GeoJSONReaderTest.java@ 16933

Last change on this file since 16933 was 16933, checked in by simon04, 4 years ago

fix #19624 - Support reading line-delimited GeoJSON (RFC 7464; patch by taylor.smock)

  • Property svn:eol-style set to native
File size: 7.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.junit.Assert.assertEquals;
5import static org.junit.Assert.assertFalse;
6import static org.junit.Assert.assertNull;
7import static org.junit.Assert.assertTrue;
8import static org.junit.jupiter.api.Assertions.assertThrows;
9
10import java.io.ByteArrayInputStream;
11import java.io.InputStream;
12import java.nio.charset.StandardCharsets;
13import java.nio.file.Files;
14import java.nio.file.Paths;
15import java.util.ArrayList;
16import java.util.Collection;
17import java.util.List;
18import java.util.Optional;
19import java.util.stream.IntStream;
20
21import org.junit.Rule;
22import org.junit.Test;
23import org.openstreetmap.josm.TestUtils;
24import org.openstreetmap.josm.data.coor.LatLon;
25import org.openstreetmap.josm.data.osm.Node;
26import org.openstreetmap.josm.data.osm.OsmPrimitive;
27import org.openstreetmap.josm.data.osm.Way;
28import org.openstreetmap.josm.testutils.JOSMTestRules;
29
30/**
31 * Unit tests of {@link GeoJSONReader}.
32 */
33public class GeoJSONReaderTest {
34
35 /**
36 * Setup test.
37 */
38 @Rule
39 public JOSMTestRules rules = new JOSMTestRules();
40
41 /**
42 * Test reading a GeoJSON file.
43 * @throws Exception in case of error
44 */
45 @Test
46 public void testReadGeoJson() throws Exception {
47 try (InputStream in = Files.newInputStream(Paths.get(TestUtils.getTestDataRoot(), "geo.json"))) {
48 final List<OsmPrimitive> primitives = new ArrayList<>(new GeoJSONReader()
49 .doParseDataSet(in, null)
50 .getPrimitives(it -> true));
51
52 assertExpectedGeoPrimitives(primitives);
53 }
54 }
55
56 /**
57 * Tests reading a GeoJSON file that is line by line separated, per RFC 7464
58 * @throws Exception in case of an error
59 */
60 @Test
61 public void testReadLineByLineGeoJSON() throws Exception {
62 try (InputStream in = Files.newInputStream(Paths.get(TestUtils.getTestDataRoot(), "geoLineByLine.json"))) {
63 final List<OsmPrimitive> primitives = new ArrayList<>(new GeoJSONReader()
64 .doParseDataSet(in, null)
65 .getPrimitives(it -> true));
66
67 assertExpectedGeoPrimitives(primitives);
68 }
69 }
70
71 private void assertExpectedGeoPrimitives(Collection<OsmPrimitive> primitives) {
72 assertEquals(20, primitives.size());
73
74 final Node node1 = new Node(new LatLon(0.5, 102.0));
75 final Optional<OsmPrimitive> foundNode1 = primitives.stream()
76 .filter(it -> areEqualNodes(it, node1))
77 .findFirst();
78 assertTrue(foundNode1.isPresent());
79 assertEquals("valueA", foundNode1.get().get("propA"));
80
81 final Way way1 = new Way();
82 way1.addNode(new Node(new LatLon(0.5, 102.0)));
83 way1.addNode(new Node(new LatLon(1, 103)));
84 way1.addNode(new Node(new LatLon(0, 104)));
85 way1.addNode(new Node(new LatLon(1, 105)));
86 final Optional<OsmPrimitive> foundWay1 = primitives.stream()
87 .filter(it -> areEqualWays(it, way1))
88 .findFirst();
89 assertTrue(foundWay1.isPresent());
90 assertEquals("valueB", foundWay1.get().get("propB"));
91 assertEquals("0.0", foundWay1.get().get("propB2"));
92 assertEquals(foundNode1.get(), ((Way) foundWay1.get()).firstNode());
93 assertEquals("valueA", ((Way) foundWay1.get()).firstNode().get("propA"));
94
95 final Way way2 = new Way();
96 way2.addNode(new Node(new LatLon(40, 180)));
97 way2.addNode(new Node(new LatLon(50, 180)));
98 way2.addNode(new Node(new LatLon(50, 170)));
99 way2.addNode(new Node(new LatLon(40, 170)));
100 way2.addNode(new Node(new LatLon(40, 180)));
101 final Optional<OsmPrimitive> foundWay2 = primitives.stream()
102 .filter(it -> areEqualWays(it, way2))
103 .findFirst();
104 assertTrue(foundWay2.isPresent());
105 assertEquals(
106 ((Way) foundWay2.get()).getNode(0),
107 ((Way) foundWay2.get()).getNode(((Way) foundWay2.get()).getNodesCount() - 1)
108 );
109
110 final Way way3 = new Way();
111 way3.addNode(new Node(new LatLon(40, -170)));
112 way3.addNode(new Node(new LatLon(50, -170)));
113 way3.addNode(new Node(new LatLon(50, -180)));
114 way3.addNode(new Node(new LatLon(40, -180)));
115 way3.addNode(new Node(new LatLon(40, -170)));
116 final Optional<OsmPrimitive> foundWay3 = primitives.stream()
117 .filter(it -> areEqualWays(it, way3))
118 .findFirst();
119 assertTrue(foundWay3.isPresent());
120 assertEquals(
121 ((Way) foundWay3.get()).getNode(0),
122 ((Way) foundWay3.get()).getNode(((Way) foundWay3.get()).getNodesCount() - 1)
123 );
124
125 final Way way4 = new Way();
126 way4.addNode(new Node(new LatLon(0, 100)));
127 way4.addNode(new Node(new LatLon(0, 101)));
128 way4.addNode(new Node(new LatLon(1, 101)));
129 way4.addNode(new Node(new LatLon(1, 100)));
130 way4.addNode(new Node(new LatLon(0, 100)));
131 final Optional<OsmPrimitive> foundWay4 = primitives.stream()
132 .filter(it -> areEqualWays(it, way4))
133 .findFirst();
134 assertTrue(foundWay4.isPresent());
135 assertEquals(
136 ((Way) foundWay4.get()).getNode(0),
137 ((Way) foundWay4.get()).getNode(((Way) foundWay4.get()).getNodesCount() - 1)
138 );
139 assertEquals("valueD", foundWay4.get().get("propD"));
140 assertFalse(foundWay4.get().hasTag("propD2"));
141 assertEquals("true", foundWay4.get().get("propD3"));
142 assertFalse(foundWay4.get().hasKey("propD4"));
143 assertNull(foundWay4.get().get("propD4"));
144 }
145
146 /**
147 * Test reading a GeoJSON file with a named CRS.
148 * @throws Exception in case of error
149 */
150 @Test
151 public void testReadGeoJsonNamedCrs() throws Exception {
152 try (InputStream in = Files.newInputStream(Paths.get(TestUtils.getTestDataRoot(), "geocrs.json"))) {
153 final List<OsmPrimitive> primitives = new ArrayList<>(new GeoJSONReader()
154 .doParseDataSet(in, null)
155 .getPrimitives(it -> true));
156 assertEquals(24, primitives.size());
157 assertTrue(primitives.stream()
158 .anyMatch(it -> areEqualNodes(it, new Node(new LatLon(52.5840213, 13.1724145)))));
159 }
160 }
161
162 /**
163 * Test reading a JSON file which is not a proper GeoJSON (type missing).
164 */
165 public void testReadGeoJsonWithoutType() {
166 assertThrows(IllegalDataException.class, () ->
167 new GeoJSONReader().doParseDataSet(new ByteArrayInputStream("{}".getBytes(StandardCharsets.UTF_8)), null));
168 }
169
170 private static boolean areEqualNodes(final OsmPrimitive p1, final OsmPrimitive p2) {
171 return (p1 instanceof Node)
172 && (p2 instanceof Node)
173 && ((Node) p1).getCoor().equalsEpsilon(((Node) p2).getCoor());
174 }
175
176 private static boolean areEqualWays(final OsmPrimitive p1, final OsmPrimitive p2) {
177 if (
178 (!(p1 instanceof Way))
179 || (!(p2 instanceof Way))
180 || ((Way) p1).getNodes().size() != ((Way) p2).getNodes().size()
181 ) {
182 return false;
183 }
184 return IntStream.range(0, ((Way) p1).getNodes().size())
185 .allMatch(i -> areEqualNodes(((Way) p1).getNode(i), ((Way) p2).getNode(i)));
186 }
187}
Note: See TracBrowser for help on using the repository browser.