source: josm/trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java@ 16913

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

fix #19698 - Refactoring: make private fields final

  • Property svn:eol-style set to native
File size: 6.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection;
3
4import static org.junit.Assert.assertTrue;
5
6import java.security.SecureRandom;
7import java.util.Arrays;
8import java.util.Collection;
9import java.util.HashSet;
10import java.util.Random;
11
12import org.junit.Assert;
13import org.junit.Test;
14import org.openstreetmap.josm.data.Bounds;
15import org.openstreetmap.josm.data.coor.EastNorth;
16import org.openstreetmap.josm.data.coor.LatLon;
17
18/**
19 * Unit tests for class {@link Projection}.
20 */
21public class ProjectionTest {
22
23 private static final Random rand = new SecureRandom();
24
25 boolean error;
26 String text;
27
28 /**
29 * Tests that projections are numerically stable in their definition bounds (round trip error < 1e-5)
30 */
31 @Test
32 public void testProjections() {
33 error = false;
34 text = "";
35
36 testProjection(Projections.getProjectionByCode("EPSG:4326")); // WGS 84
37 testProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
38 testProjection(Projections.getProjectionByCode("EPSG:3301")); // Lambert EST
39
40 for (int i = 0; i <= 3; ++i) {
41 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(27561+i))); // Lambert 4 Zones France
42 }
43
44 for (int i = 0; i <= 4; ++i) {
45 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(2176+i))); // PUWG Poland
46 }
47
48 testProjection(Projections.getProjectionByCode("EPSG:21781")); // Swiss grid
49
50 for (int i = 0; i <= 60; ++i) {
51 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(32601+i))); // UTM North
52 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(32701+i))); // UTM South
53 }
54
55 for (String c : Arrays.asList("2969", "2970", "2972", "2973")) {
56 testProjection(Projections.getProjectionByCode("EPSG:"+c)); // UTM France DOM
57 }
58
59 for (int i = 0; i <= 8; ++i) {
60 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(3942+i))); // Lambert CC9 Zones France
61 }
62
63 for (int i = 0; i <= 17; ++i) {
64 testProjection(Projections.getProjectionByCode("EPSG:"+Integer.toString(102421+i))); // WGS_1984_ARC_System Zones
65 }
66
67 testProjection(Projections.getProjectionByCode("EPSG:102016")); // North Pole
68 testProjection(Projections.getProjectionByCode("EPSG:102019")); // South Pole
69
70 if (error) {
71 System.err.println(text);
72 Assert.fail();
73 }
74 }
75
76 private void testProjection(Projection p) {
77 if (p != null) {
78 double maxErrLat = 0, maxErrLon = 0;
79 Bounds b = p.getWorldBoundsLatLon();
80
81 text += String.format("*** %s %s%n", p.toString(), p.toCode());
82 for (int num = 0; num < 1000; ++num) {
83
84 LatLon ll0 = random(b);
85 LatLon ll = ll0;
86
87 for (int i = 0; i < 10; ++i) {
88 EastNorth en = p.latlon2eastNorth(ll);
89 ll = p.eastNorth2latlon(en);
90 }
91 maxErrLat = Math.max(maxErrLat, Math.abs(ll0.lat() - ll.lat()));
92 maxErrLon = Math.max(maxErrLon, Math.abs(ll0.lon() - ll.lon()));
93 }
94
95 String mark = "";
96 if (maxErrLat + maxErrLon > 1e-5) {
97 mark = "--FAILED-- ";
98 error = true;
99 }
100 text += String.format("%s errorLat: %s errorLon: %s%n", mark, maxErrLat, maxErrLon);
101 }
102 }
103
104 private LatLon random(Bounds b) {
105 for (int i = 0; i < 20; i++) {
106 double lat = rand.nextDouble() * (b.getMax().lat() - b.getMin().lat()) + b.getMin().lat();
107 double lon = rand.nextDouble() * (b.getMax().lon() - b.getMin().lon()) + b.getMin().lon();
108 LatLon result = new LatLon(lat, lon);
109 if (result.isValid()) return result;
110 }
111 throw new RuntimeException();
112 }
113
114 boolean error2;
115 String text2;
116 Collection<String> projIds;
117
118 /**
119 * Tests that projections are numerically stable in their definition bounds (round trip error &lt; epsilon)
120 */
121 @Test
122 public void testProjs() {
123 error2 = false;
124 text2 = "";
125
126 projIds = new HashSet<>(Projections.getAllBaseProjectionIds());
127
128 final double EPS = 1e-6;
129 testProj("lonlat", EPS, "");
130 testProj("lcc", EPS, "+lat_0=34");
131 testProj("lcc", EPS, "+lat_1=87 +lat_2=83.6 +lat_0=85.43");
132 testProj("somerc", EPS, "+lat_0=47");
133 testProj("tmerc", 1e-5, "+bounds=-2.5,-89,2.5,89");
134 testProj("tmerc", 2e-3, "");
135 testProj("sterea", EPS, "+lat_0=52");
136 testProj("aea", EPS, "+lat_1=27.5 +lat_2=35 +lat_0=18");
137 testProj("stere", 1e-5, "+lat_0=-90 +lat_ts=-70");
138 testProj("stere", 1e-5, "+lat_0=90 +lat_ts=90");
139 testProj("omerc", EPS, "+lat_0=4 +lonc=115 +alpha=53 +no_uoff +gamma=53.130 +bounds=112,4,116,7");
140 testProj("cass", 1e-3, "+lat_0=11 +bounds=-1.0,-89,1.0,89");
141 testProj("laea", 3e-3, "+lat_0=34");
142 testProj("merc", 1e-5, "");
143 testProj("sinu", 1e-4, "");
144 testProj("aeqd", 1e-5, "+lon_0=0dE +lat_0=90dN");
145 testProj("aeqd", 1e-5, "+lon_0=0dE +lat_0=90dS");
146 testProj("eqc", 1e-5, "");
147
148 if (error2) {
149 System.err.println(text2);
150 Assert.fail();
151 }
152 assertTrue("missing test: "+projIds, projIds.isEmpty());
153 }
154
155 private void testProj(String id, double eps, String prefAdd) {
156 final int NUM_IT = 1000;
157 projIds.remove(id);
158 String pref = String.format("+proj=%s +ellps=WGS84 +nadgrids=null "+prefAdd, id);
159 CustomProjection p = new CustomProjection();
160 try {
161 p.update(pref);
162 } catch (ProjectionConfigurationException ex) {
163 throw new RuntimeException(ex);
164 }
165 Bounds b = p.getWorldBoundsLatLon();
166 double maxDist = 0;
167 LatLon maxLatLon = null;
168 for (int i = 0; i < NUM_IT; i++) {
169 LatLon ll1 = random(b);
170 EastNorth en = p.latlon2eastNorth(ll1);
171 LatLon ll2 = p.eastNorth2latlon(en);
172 assertTrue(p.toCode() + " at " + ll1 + " is " + ll2, ll2.isValid());
173 double dist = ll1.greatCircleDistance(ll2);
174 if (dist > eps) {
175 error2 = true;
176 if (dist > maxDist) {
177 maxDist = dist;
178 maxLatLon = ll1;
179 }
180 }
181 }
182 if (maxDist > 0) {
183 text2 += id + ": dist " + maxDist + " at " + maxLatLon + "\n";
184 }
185 }
186
187 /**
188 * Checks that Swedish projections have their axis defined correctly.
189 */
190 @Test
191 public void testSwedishProjections() {
192 for (int code = 3006; code <= 3018; code++) {
193 assertTrue(Projections.getProjectionByCode("EPSG:"+code).switchXY());
194 }
195 }
196}
Note: See TracBrowser for help on using the repository browser.