/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2002-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.referencing.factory.epsg; import java.util.Map; import java.util.HashMap; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.awt.geom.Point2D; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.ProjectedCRS; import org.apache.sis.math.Statistics; import org.apache.sis.referencing.CRS; import org.apache.sis.geometry.DirectPosition2D; import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.factory.GeodeticAuthorityFactory; import static org.junit.Assert.*; import static java.lang.StrictMath.*; import static org.apache.sis.util.collection.Containers.hashMapCapacity; /** * A thread which will perform many coordinate transformations between different pairs of CRS. * The results are compared with previous results for consistency. * <p> * The {@link StressTest} class starts many instances of this class in order to test concurrency. * * @author Jody Garnett (Refractions) * @author Martin Desruisseaux (Geomatys) * @version 3.17 * * @since 2.4 */ final strictfp class ClientThread extends Thread { /** * The tolerance (in decimal degrees) between the results of transformation * to geographic coordinates. */ private static final double ANGLE_TOLERANCE = 1E-12; /** * The squared value of the maximal distance (in metres) allowed between a point * in UTM 84 and its transform in UTM 72, or conversely. */ private static final double UTM_TOLERANCE = 20 * 20; /** * Thread identifier. */ final int id; /** * The result of the {@link #testGeographicToRandom()} method. * Keys are EPSG code of the source CRS. Values are the transformed coordinates. */ final Map<Integer, Point2D.Double> result; /** * The first exception that occurred, or {@code null} if everything was successful. */ Throwable exception; /** * The code of the CRS that caused the exception, or {@code null} if none. */ String badCode; /** * Test metrics. */ final Statistics statistics; /** * Random number generator. */ private final Random random; /** * The factory to test. */ private final GeodeticAuthorityFactory factory; /** * Used in order to wait until every threads are ready to process. */ private final CountDownLatch lock; /** * Creates a client thread for the given factory to test. * * @param id Thread identifier. * @param factory The factory to test. */ public ClientThread(final int id, final GeodeticAuthorityFactory factory, final CountDownLatch lock) { super("ClientThread" + (id < 10 ? " 0" : " ") + id); this.id = id; this.factory = factory; this.random = new Random(179702531L + id); this.statistics = new Statistics(null); this.lock = lock; this.result = createEmptyResultMap(); } /** * Creates an initially empty map which will hold the result of * {@link #testGeographicToRandom()}. */ static Map<Integer, Point2D.Double> createEmptyResultMap() { return new HashMap<>(hashMapCapacity(CODES.length)); } /** * Gets random CRS and apply a map projection from that CRS to WGS84 for each of them. */ @Override public void run() { final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.normalizedGeographic(); final DirectPosition2D sourcePt = new DirectPosition2D(104800, 273914); // Random coordinate final DirectPosition2D targetPt = new DirectPosition2D(); final DirectPosition2D coordUTM = new DirectPosition2D(); /* * Wait until every threads are ready to process. */ try { lock.await(); } catch (InterruptedException e) { // Consider that as a failure. exception = e; return; } for (int i=0; i<StressTest.ITERATIONS; i++) { /* * Test the transformations from a random CRS to WGS84. This test uses a * fixed coordinates so we can verify that every thread produce the same * result for the same source CRS. */ final int crsCode = CODES[random.nextInt(CODES.length)]; String code = String.valueOf(crsCode); long startTime = System.nanoTime(); try { /* * Random CRS --> WGS84 * The result will be saved for comparison with the results from other threads. */ final CoordinateReferenceSystem targetCRS = factory.createCoordinateReferenceSystem(code); MathTransform transform = CRS.findOperation(sourceCRS, targetCRS, null).getMathTransform(); assertSame(targetPt, transform.inverse().transform(sourcePt, targetPt)); statistics.accept(System.nanoTime() - startTime); assertFalse("x=NaN", Double.isNaN(targetPt.x)); assertFalse("y=NaN", Double.isNaN(targetPt.y)); assertConsistent(result, crsCode, targetPt); /* * UTM 72 --> UTM 84 (or conversely) * The distance should be small. */ int zone = random.nextInt(60) + 1; if (random.nextBoolean()) { zone += 100; // Switch from zone North to zone South. } final ProjectedCRS sourceUTM = factory.createProjectedCRS(code = String.valueOf(32200 + zone)); final ProjectedCRS targetUTM = factory.createProjectedCRS(code = String.valueOf(32600 + zone)); transform = CRS.findOperation(sourceUTM, targetUTM, null).getMathTransform(); if (random.nextBoolean()) { transform = transform.inverse(); } assertFalse("Expected at datum shift.", transform.isIdentity()); final double x = coordUTM.x = random.nextDouble() * 300000 + 100000; final double y = coordUTM.y = random.nextDouble() * 5000000 + 2500000; assertSame(coordUTM, transform.transform(coordUTM, coordUTM)); final double distSq = coordUTM.distanceSq(x, y); if (!(distSq <= UTM_TOLERANCE)) { // Use '!' for catching NaN. fail("UTM tolerance error: " + sqrt(distSq)); } } catch (Throwable e) { exception = e; badCode = code; break; } } } /** * Asserts that the given result of a coordinate transformation is consistent with previous * result. */ static void assertConsistent(final Map<Integer, Point2D.Double> result, final Integer code, final Point2D.Double point) { final Point2D.Double previous = result.put(code, new Point2D.Double(point.x, point.y)); if (previous != null) { assertEquals("x", previous.x, point.x, ANGLE_TOLERANCE); assertEquals("y", previous.y, point.y, ANGLE_TOLERANCE); } } /** * A selection of CRS codes for UTM and NAD zones. */ static final int[] CODES = { 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032, 2033, 2034, 2035, 2040, 2041, 2042, 2043, 2058, 2059, 2060, 2061, 2063, 2064, 2067, 2077, 2078, 2079, 2080, 2084, 2085, 2086, 2089, 2090, 2095, 2133, 2134, 2135, 2138, 2156, 2158, 2161, 2162, 2188, 2189, 2190, 2195, 2201, 2202, 2203, 2204, 2205, 2215, 2216, 2217, 2219, 2220, 2222, 2223, 2224, 2225, 2226, 2227, 2228, 2229, 2230, 2231, 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247, 2248, 2249, 2250, 2251, 2252, 2253, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2261, 2262, 2263, 2264, 2265, 2266, 2267, 2268, 2269, 2270, 2271, 2272, 2273, 2274, 2275, 2276, 2277, 2278, 2279, 2280, 2281, 2282, 2283, 2284, 2285, 2286, 2287, 2288, 2289, 2291, 2312, 2313, 2315, 2316, 2736, 2737, 2759, 2760, 2761, 2762, 2763, 2764, 2765, 2766, 2767, 2768, 2769, 2770, 2771, 2772, 2773, 2774, 2775, 2776, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 2788, 2789, 2790, 2791, 2792, 2793, 2794, 2795, 2796, 2797, 2798, 2799, 2800, 2801, 2802, 2803, 2804, 2805, 2806, 2807, 2808, 2809, 2810, 2811, 2812, 2813, 2814, 2815, 2816, 2817, 2818, 2819, 2820, 2821, 2822, 2823, 2824, 2825, 2826, 2827, 2828, 2829, 2830, 2831, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2840, 2841, 2842, 2843, 2844, 2845, 2846, 2847, 2848, 2849, 2850, 2851, 2852, 2853, 2854, 2855, 2856, 2857, 2858, 2859, 2860, 2861, 2862, 2863, 2864, 2865, 2866, 2867, 2868, 2869, 2870, 2871, 2872, 2873, 2874, 2875, 2876, 2877, 2878, 2879, 2880, 2881, 2882, 2883, 2884, 2885, 2886, 2887, 2888, 2889, 2890, 2891, 2892, 2893, 2894, 2895, 2896, 2897, 2898, 2899, 2900, 2901, 2902, 2903, 2904, 2905, 2906, 2907, 2908, 2909, 2910, 2911, 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919, 2920, 2921, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2933, 2936, 2942, 2943, 2944, 2945, 2946, 2947, 2948, 2949, 2950, 2951, 2952, 2953, 2954, 2955, 2956, 2957, 2958, 2959, 2960, 2961, 2962, 2964, 2965, 2966, 2967, 2968, 2969, 2970, 2971, 2972, 2973, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2983, 2987, 2988, 2989, 2991, 2992, 2993, 2994, 2995, 2996, 2997, 2998, 2999, 3005, 3036, 3037, 3054, 3055, 3056, 3060, 3061, 3062, 3063, 3064, 3065, 3148, 3149, 3439, 3440, 3920, 4152, 4267, 4268, 4269, 4608, 4609, 4617, 20135, 20136, 20137, 20138, 20437, 20438, 20439, 20538, 20539, 20822, 20823, 20824, 20934, 20935, 20936, 21035, 21036, 21037, 21095, 21096, 21097, 21148, 21149, 21150, 21817, 21818, 22032, 22033, 22234, 22235, 22236, 22332, 22523, 22524, 23028, 23029, 23030, 23031, 23032, 23033, 23034, 23035, 23036, 23037, 23038, 23239, 23240, 23846, 23847, 23848, 23849, 23850, 23851, 23852, 23853, 23886, 23887, 23888, 23889, 23890, 23891, 23892, 23893, 23894, 23946, 23947, 23948, 24047, 24048, 24305, 24306, 24311, 24312, 24313, 24342, 24343, 24344, 24345, 24346, 24347, 24547, 24548, 24718, 24719, 24720, 24818, 24819, 24820, 24821, 24877, 24878, 24879, 24880, 24882, 25231, 25828, 25829, 25830, 25831, 25832, 25833, 25834, 25835, 25836, 25837, 25838, 25932, 26237, 26331, 26332, 26432, 26632, 26692, 26703, 26704, 26705, 26706, 26707, 26708, 26709, 26710, 26711, 26712, 26713, 26714, 26715, 26716, 26717, 26718, 26719, 26720, 26721, 26722, 26729, 26730, 26731, 26732, 26733, 26734, 26735, 26736, 26737, 26738, 26739, 26740, 26741, 26742, 26743, 26744, 26745, 26746, 26747, 26748, 26749, 26750, 26751, 26752, 26753, 26754, 26755, 26756, 26757, 26758, 26759, 26760, 26766, 26767, 26768, 26769, 26770, 26771, 26772, 26773, 26774, 26775, 26776, 26777, 26778, 26779, 26780, 26781, 26782, 26783, 26784, 26785, 26786, 26787, 26791, 26792, 26793, 26794, 26795, 26796, 26797, 26798, 26801, 26802, 26803, 26811, 26812, 26813, 26903, 26904, 26905, 26906, 26907, 26908, 26909, 26910, 26911, 26912, 26913, 26914, 26915, 26916, 26917, 26918, 26919, 26920, 26921, 26922, 26923, 26929, 26930, 26931, 26932, 26933, 26934, 26935, 26936, 26937, 26938, 26939, 26940, 26941, 26942, 26943, 26944, 26945, 26946, 26948, 26949, 26950, 26951, 26952, 26953, 26954, 26955, 26956, 26957, 26958, 26959, 26960, 26961, 26962, 26963, 26964, 26965, 26966, 26967, 26968, 26969, 26970, 26971, 26972, 26973, 26974, 26975, 26976, 26977, 26978, 26979, 26980, 26981, 26982, 26983, 26984, 26985, 26986, 26987, 26988, 26989, 26990, 26991, 26992, 26993, 26994, 26995, 26996, 26997, 26998, 27038, 27039, 27040, 27120, 27258, 27259, 27260, 27429, 28232, 29168, 29169, 29170, 29171, 29172, 29187, 29188, 29189, 29190, 29191, 29192, 29193, 29194, 29195, 29220, 29221, 29333, 29738, 29739, 29849, 29850, 30339, 30340, 30729, 30730, 30731, 30732, 31028, 31121, 31528, 31529, 31838, 31839, 31986, 31987, 31988, 31989, 31990, 31991, 31992, 31993, 31994, 31995, 31996, 31997, 31998, 31999, 32000, 32001, 32002, 32003, 32005, 32006, 32007, 32008, 32009, 32010, 32011, 32012, 32013, 32014, 32015, 32016, 32017, 32018, 32019, 32020, 32021, 32022, 32023, 32024, 32025, 32026, 32027, 32028, 32029, 32030, 32031, 32033, 32034, 32035, 32036, 32037, 32038, 32039, 32040, 32041, 32042, 32043, 32044, 32045, 32046, 32047, 32048, 32049, 32050, 32051, 32052, 32053, 32054, 32055, 32056, 32057, 32058, 32061, 32062, 32064, 32065, 32066, 32067, 32074, 32075, 32076, 32077, 32081, 32082, 32083, 32084, 32085, 32086, 32098, 32100, 32104, 32107, 32108, 32109, 32110, 32111, 32112, 32113, 32114, 32115, 32116, 32117, 32118, 32119, 32120, 32121, 32122, 32123, 32124, 32125, 32126, 32127, 32128, 32129, 32130, 32133, 32134, 32135, 32136, 32137, 32138, 32139, 32140, 32141, 32142, 32143, 32144, 32145, 32146, 32147, 32148, 32149, 32150, 32151, 32152, 32153, 32154, 32155, 32156, 32157, 32158, 32161, 32180, 32181, 32182, 32183, 32184, 32185, 32186, 32187, 32188, 32189, 32190, 32191, 32192, 32193, 32194, 32195, 32196, 32197, 32198, 32201, 32202, 32203, 32204, 32205, 32206, 32207, 32208, 32209, 32210, 32211, 32212, 32213, 32214, 32215, 32216, 32217, 32218, 32219, 32220, 32221, 32222, 32223, 32224, 32225, 32226, 32227, 32228, 32229, 32230, 32231, 32232, 32233, 32234, 32235, 32236, 32237, 32238, 32239, 32240, 32241, 32242, 32243, 32244, 32245, 32246, 32247, 32248, 32249, 32250, 32251, 32252, 32253, 32254, 32255, 32256, 32257, 32258, 32259, 32260, 32301, 32302, 32303, 32304, 32305, 32306, 32307, 32308, 32309, 32310, 32311, 32312, 32313, 32314, 32315, 32316, 32317, 32318, 32319, 32320, 32321, 32322, 32323, 32324, 32325, 32326, 32327, 32328, 32329, 32330, 32331, 32332, 32333, 32334, 32335, 32336, 32337, 32338, 32339, 32340, 32341, 32342, 32343, 32344, 32345, 32346, 32347, 32348, 32349, 32350, 32351, 32352, 32353, 32354, 32355, 32356, 32357, 32358, 32359, 32360, 32401, 32402, 32403, 32404, 32405, 32406, 32407, 32408, 32409, 32410, 32411, 32412, 32413, 32414, 32415, 32416, 32417, 32418, 32419, 32420, 32421, 32422, 32423, 32424, 32425, 32426, 32427, 32428, 32429, 32430, 32431, 32432, 32433, 32434, 32435, 32436, 32437, 32438, 32439, 32440, 32441, 32442, 32443, 32444, 32445, 32446, 32447, 32448, 32449, 32450, 32451, 32452, 32453, 32454, 32455, 32456, 32457, 32458, 32459, 32460, 32501, 32502, 32503, 32504, 32505, 32506, 32507, 32508, 32509, 32510, 32511, 32512, 32513, 32514, 32515, 32516, 32517, 32518, 32519, 32520, 32521, 32522, 32523, 32524, 32525, 32526, 32527, 32528, 32529, 32530, 32531, 32532, 32533, 32534, 32535, 32536, 32537, 32538, 32539, 32540, 32541, 32542, 32543, 32544, 32545, 32546, 32547, 32548, 32549, 32550, 32551, 32552, 32553, 32554, 32555, 32556, 32557, 32558, 32559, 32560, 32601, 32602, 32603, 32604, 32605, 32606, 32607, 32608, 32609, 32610, 32611, 32612, 32613, 32614, 32615, 32616, 32617, 32618, 32619, 32620, 32621, 32622, 32623, 32624, 32625, 32626, 32627, 32628, 32629, 32630, 32631, 32632, 32633, 32634, 32635, 32636, 32637, 32638, 32639, 32640, 32641, 32642, 32643, 32644, 32645, 32646, 32647, 32648, 32649, 32650, 32651, 32652, 32653, 32654, 32655, 32656, 32657, 32658, 32659, 32660, 32701, 32702, 32703, 32704, 32705, 32706, 32707, 32708, 32709, 32710, 32711, 32712, 32713, 32714, 32715, 32716, 32717, 32718, 32719, 32720, 32721, 32722, 32723, 32724, 32725, 32726, 32727, 32728, 32729, 32730, 32731, 32732, 32733, 32734, 32735, 32736, 32737, 32738, 32739, 32740, 32741, 32742, 32743, 32744, 32745, 32746, 32747, 32748, 32749, 32750, 32751, 32752, 32753, 32754, 32755, 32756, 32757, 32758, 32759, 32760 }; }