aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoward Butler <howard@hobu.co>2016-08-21 23:34:02 -0500
committerGitHub <noreply@github.com>2016-08-21 23:34:02 -0500
commitc33ab589cf13d3e774cf0f842b221a8e44e21672 (patch)
tree164c39355073fa4b78262ae69c99df3b7f589ea6
parentedd1521df96ea5750b59f507fc4e8b9f8dbf3282 (diff)
parent4965b57742667280a0d1b25fb92607df1527ced8 (diff)
downloadPROJ-c33ab589cf13d3e774cf0f842b221a8e44e21672.tar.gz
PROJ-c33ab589cf13d3e774cf0f842b221a8e44e21672.zip
Merge pull request #386 from micahcochran/py-gigs-test4
Add GIGS tests.
-rw-r--r--.travis.yml18
-rw-r--r--test/gigs/5101.1-jhs.json63
-rw-r--r--test/gigs/5101.2-jhs.json32
-rw-r--r--test/gigs/5101.3-jhs.json33
-rw-r--r--test/gigs/5101.4-jhs-etmerc.json31
-rw-r--r--test/gigs/5101.4-jhs.json33
-rw-r--r--test/gigs/5102.1.json29
-rw-r--r--test/gigs/5102.2.json29
-rw-r--r--test/gigs/5103.1.json29
-rw-r--r--test/gigs/5103.2.json21
-rw-r--r--test/gigs/5103.3.json20
-rw-r--r--test/gigs/5104.json30
-rw-r--r--test/gigs/5105.1.json26
-rw-r--r--test/gigs/5105.2.json23
-rw-r--r--test/gigs/5106.json35
-rw-r--r--test/gigs/5107.json26
-rw-r--r--test/gigs/5108.json26
-rw-r--r--test/gigs/5109.json23
-rw-r--r--test/gigs/5110.json12
-rw-r--r--test/gigs/5111.1.json45
-rw-r--r--test/gigs/5111.2.json44
-rw-r--r--test/gigs/5112.json15
-rw-r--r--test/gigs/5113.json12
-rw-r--r--test/gigs/5201.json39
-rw-r--r--test/gigs/5203.1.json25
-rw-r--r--test/gigs/5204.1.json25
-rw-r--r--test/gigs/5205.1.json25
-rw-r--r--test/gigs/5206.json54
-rw-r--r--test/gigs/5207.1.json30
-rw-r--r--test/gigs/5207.2.json47
-rw-r--r--test/gigs/5208.json25
-rw-r--r--test/gigs/TESTNOTES.md225
-rw-r--r--test/gigs/test_json.py528
33 files changed, 1678 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
index 286d640c..a476f875 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -98,6 +98,24 @@ install:
- make -j3
- make check
- ./src/proj -VC
+
+# install & run the working GIGS test
+ # create locations that pyproj understands
+ - python3 --version
+ - ln -s src include
+ - ln -s src/.libs lib
+ - mkdir share
+ - ln -s nad share/proj
+ - pwd
+ # install pyproj
+ - PROJ_DIR=`pwd` pip3 install -v --user pyproj
+
+ - cd test/gigs
+ # run test_json.py
+ - PROJ_LIB=../../nad python3 test_json.py --test conversion 5101.1-jhs.json 5101.4-jhs-etmerc.json 5105.2.json 5106.json 5108.json 5110.json 5111.1.json
+ - PROJ_LIB=../../nad python3 test_json.py 5101.2-jhs.json 5101.3-jhs.json 5102.1.json 5103.1.json 5103.2.json 5103.3.json 5107.json 5109.json 5112.json 5113.json 5201.json 5208.json
+ - cd ../..
+
- mv src/.libs/*.gc* src
script:
diff --git a/test/gigs/5101.1-jhs.json b/test/gigs/5101.1-jhs.json
new file mode 100644
index 00000000..95624c62
--- /dev/null
+++ b/test/gigs/5101.1-jhs.json
@@ -0,0 +1,63 @@
+{
+"coordinates": [
+ [[3, 80], [496813.178, 3358297.326]],
+ [[2.9999999, 60], [678711.584, 1134498.83]],
+ [[3, 49], [765648.501, -87944.74]],
+ [[3.0000001, 40], [826893.845, -1087710.121]],
+ [[3, 20], [923539.353, -3308151.625]],
+ [[3, 0], [957087.829, -5527462.686]],
+ [[3, -20], [923539.353, -7746773.748]],
+ [[3, -40], [826893.845, -9967215.251]],
+ [[3, -60], [678711.584, -12189424.202]],
+ [[3, -80], [496813.178, -14413222.698]],
+ [[-2, 80], [400000, 3354134.429]],
+ [[-2, 60], [400000, 1123956.966]],
+ [[-2, 49], [400000, -100000]],
+ [[-2, 40], [400000, -1099699.834]],
+ [[-2, 20], [400000, -3315978.565]],
+ [[-2, 0], [400000, -5527462.686]],
+ [[-2, -20], [400000, -7738946.807]],
+ [[-2, -40], [400000, -9955225.538]],
+ [[-2, -60], [400000, -12178882.338]],
+ [[-2, -80], [400000, -14409059.801]],
+ [[-5, 80], [341867.711, 3355633.571]],
+ [[-5, 60], [232704.966, 1127751.264]],
+ [[-5, 49], [180586.02, -95662.911]],
+ [[-5, 40], [143900.026, -1095387.991]],
+ [[-5, 20], [86073.28, -3313165.843]],
+ [[-5, 0], [66021.018, -5527462.686]],
+ [[-5, -20], [86073.28, -7741759.529]],
+ [[-5, -40], [143900.026, -9959537.381]],
+ [[-5, -60], [232704.966, -12182676.637]],
+ [[-5, -80], [341867.711, -14410558.943]],
+ [[-7.5559037, 49.7661327], [0, 0]],
+ [[-5, 0], [66021.018, -5527462.686]],
+ [[-4, 0], [177404.277, -5527462.686]],
+ [[-3, 0], [288719.208, -5527462.686]],
+ [[-2, 0], [400000.0, -5527462.686]],
+ [[-1, 0], [511280.792, -5527462.686]],
+ [[0, 0], [622595.723, -5527462.686]],
+ [[1, 0], [733978.982, -5527462.686]],
+ [[2, 0], [845464.865, -5527462.686]],
+ [[3, 0], [957087.829, -5527462.686]],
+ [[4, 0], [1068882.539, -5527462.686]],
+ [[5, 0], [1180883.933, -5527462.686]],
+ [[6, 0], [1293127.266, -5527462.686]],
+ [[7, 0], [1405648.179, -5527462.686]],
+ [[8, 0], [1518482.747, -5527462.686]],
+ [[-5, 60], [232704.966, 1127751.264]],
+ [[-4, 60], [288455.816, 1125643.213]],
+ [[-3, 60], [344223.662, 1124378.512]],
+ [[-2, 60], [400000, 1123956.966]],
+ [[-1, 60], [455776.338, 1124378.512]],
+ [[0, 60], [511544.184, 1125643.213]],
+ [[1, 60], [567295.034, 1127751.264]],
+ [[2, 60], [623020.357, 1130702.987]],
+ [[3, 60], [678711.584, 1134498.83]], [[4.0, 60.0], [734360.093, 1139139.367]], [[5.0, 60.0], [789957.197, 1144625.296]], [[6.0, 60.0], [845494.132, 1150957.434]], [[7.0, 60.0], [900962.042, 1158136.713]], [[8.0, 60.0],
+ [956351.967, 1166164.18]]
+],
+"description": "Test 5101 (part 1), Transverse Mercator, v2-0_2011-06-28, recommended JHS formula",
+"projections": ["+init=epsg:4326", "+proj=etmerc +lat_0=49 +lon_0=-2 +k_0=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=WGS84 +units=m +no_def"],
+"tests": [{"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5101.2-jhs.json b/test/gigs/5101.2-jhs.json
new file mode 100644
index 00000000..c03929ab
--- /dev/null
+++ b/test/gigs/5101.2-jhs.json
@@ -0,0 +1,32 @@
+{
+"coordinates": [
+ [[-2.0, 80.0], [403186.945, 8885748.708]],
+ [[-2.0, 60.0], [221288.77, 6661953.041]],
+ [[-2.0, 40.0], [73106.698, 4439746.917]],
+ [[-2.0, 20.0], [-23538.687, 2219308.238]],
+ [[-2.0, 0.0], [-57087.12, 0.0]],
+ [[-2.0, -20.0], [-23538.687, -2219308.238]],
+ [[-2.0, -40.0], [73106.698, -4439746.917]],
+ [[-2.0, -60.0], [221288.77, -6661953.041]],
+ [[-2.0, -80.0], [403186.945, -8885748.708]],
+ [[-5.0, 60.0], [54506.435, 6678411.623]],
+ [[-4.0, 60.0], [110043.299, 6672079.494]],
+ [[-3.0, 60.0], [165640.332, 6666593.572]],
+ [[-2.0, 60.0], [221288.77, 6661953.041]],
+ [[-1.0, 60.0], [276979.926, 6658157.202]],
+ [[0.0, 60.0], [332705.179, 6655205.484]],
+ [[1.0, 60.0], [388455.958, 6653097.435]],
+ [[2.0, 60.0], [444223.733, 6651832.735]],
+ [[3.0, 60.0], [500000.0, 6651411.19]],
+ [[4.0, 60.0], [555776.267, 6651832.735]],
+ [[5.0, 60.0], [611544.042, 6653097.435]],
+ [[6.0, 60.0], [667294.821, 6655205.484]],
+ [[7.0, 60.0], [723020.074, 6658157.202]],
+ [[8.0, 60.0], [778711.23, 6661953.041]]
+ ],
+"description": "Test 5101 (part 2), Transverse Mercator, v2-0_2011-06-28, recommended JHS formula",
+"projections": ["+init=epsg:4326", "+init=epsg:32631"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5101.3-jhs.json b/test/gigs/5101.3-jhs.json
new file mode 100644
index 00000000..e7cc2dc3
--- /dev/null
+++ b/test/gigs/5101.3-jhs.json
@@ -0,0 +1,33 @@
+{
+"coordinates": [
+ [[146, 80], [596813.055, 18885748.71]],
+ [[146, 60], [778711.23, 16661953.04]],
+ [[146, 40], [926893.302, 14439746.92]],
+ [[146, 20], [1023538.687, 12219308.24]],
+ [[146, 0], [1057087.12, 10000000.0]],
+ [[146, -20], [1023538.687, 7780691.762]],
+ [[146, -40], [926893.302, 5560253.083]],
+ [[146, -60], [778711.23, 3338046.96]],
+ [[146, -80], [596813.055, 1114251.292]],
+ [[136, -60], [221288.77, 3338046.96]],
+ [[137, -60], [276979.926, 3341842.798]],
+ [[138, -60], [332705.179, 3344794.516]],
+ [[139, -60], [388455.958, 3346902.565]],
+ [[140, -60], [444223.733, 3348167.265]],
+ [[141, -60], [500000.0, 3348588.81]],
+ [[142, -60], [555776.267, 3348167.265]],
+ [[143, -60], [611544.042, 3346902.565]],
+ [[144, -60], [667294.821, 3344794.516]],
+ [[145, -60], [723020.074, 3341842.798]],
+ [[146, -60], [778711.23, 3338046.96]],
+ [[147, -60], [834359.668, 3333406.428]],
+ [[148, -60], [889956.701, 3327920.506]],
+ [[149, -60], [945493.565, 3321588.377]]
+ ],
+"description": "Test 5101 (part 3), Transverse Mercator, v2-0_2011-06-28, recommended JHS formula",
+"projections": ["+init=epsg:4283", "+init=epsg:28354"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5101.4-jhs-etmerc.json b/test/gigs/5101.4-jhs-etmerc.json
new file mode 100644
index 00000000..1775f750
--- /dev/null
+++ b/test/gigs/5101.4-jhs-etmerc.json
@@ -0,0 +1,31 @@
+{
+"coordinates": [
+ [[-63.9993433, 80.0002644], [5422500.0, 18889800.0]],
+ [[-63.9998472, 60.0001191], [5276900.0, 16662800.0]],
+ [[-63.9997361, 40.0003081], [5158399.999, 14439199.99]],
+ [[-64.0004605, 19.9996448], [5081100.0, 12219300.0]],
+ [[-63.9996186, 0.0003092], [5054400.005, 10002000.0]],
+ [[-64.0004675, -19.9999283], [5081100.017, 7784599.993]],
+ [[-63.9997001, -39.9996924], [5158400.0, 5564800.0]],
+ [[-63.9998814, -60.0004008], [5276899.994, 3341099.995]],
+ [[-63.9991006, -79.9996521], [5422500.0, 1114200.0]],
+ [[-70.0002089, -40.000215], [4645300.113, 5524200.123]],
+ [[-69.0001441, -40.0002935], [4730900.0, 5533400.0]],
+ [[-67.9995333, -39.9996136], [4816500.043, 5541700.028]],
+ [[-66.9998073, -39.9999313], [4902000.0, 5548900.0]],
+ [[-65.9996522, -39.9995894], [4987500.009, 5555200.001]],
+ [[-64.9992796, -40.000411], [5073000.0, 5560400.0]],
+ [[-63.9997, -39.9996925], [5158400.01, 5564799.987]],
+ [[-62.9999842, -40.0002087], [5243800.0, 5568100.0]],
+ [[-62.0000778, -40.0001803], [5329199.995, 5570500.009]],
+ [[-61.0000574, -39.9996182], [5414600.0, 5572000.0]],
+ [[-60.0, -40.0003306], [5500000.0, 5572399.996]],
+ [[-58.9999426, -39.9996182], [5585400.0, 5572000.0]],
+ [[-57.9999222, -40.0001803], [5670800.005, 5570500.009]],
+ [[-57.0000158, -40.0002087], [5756200.0, 5568100.0]]
+ ],
+"description": "Test 5101 (part 4), Transverse Mercator, v2-0_2011-06-28, recommended JHS formula",
+"projections": ["+init=epsg:4190",
+ "+proj=etmerc +lat_0=-90 +lon_0=-60 +k=1 +x_0=5500000 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"],
+"tests": [{"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"}, {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5101.4-jhs.json b/test/gigs/5101.4-jhs.json
new file mode 100644
index 00000000..81648735
--- /dev/null
+++ b/test/gigs/5101.4-jhs.json
@@ -0,0 +1,33 @@
+{
+"coordinates": [
+ [[-63.9993433, 80.0002644], [5422500.0, 18889800.0]],
+ [[-63.9998472, 60.0001191], [5276900.0, 16662800.0]],
+ [[-63.9997361, 40.0003081], [5158399.999, 14439199.99]],
+ [[-64.0004605, 19.9996448], [5081100.0, 12219300.0]],
+ [[-63.9996186, 0.0003092], [5054400.005, 10002000.0]],
+ [[-64.0004675, -19.9999283], [5081100.017, 7784599.993]],
+ [[-63.9997001, -39.9996924], [5158400.0, 5564800.0]],
+ [[-63.9998814, -60.0004008], [5276899.994, 3341099.995]],
+ [[-63.9991006, -79.9996521], [5422500.0, 1114200.0]],
+ [[-70.0002089, -40.000215], [4645300.113, 5524200.123]],
+ [[-69.0001441, -40.0002935], [4730900.0, 5533400.0]],
+ [[-67.9995333, -39.9996136], [4816500.043, 5541700.028]],
+ [[-66.9998073, -39.9999313], [4902000.0, 5548900.0]],
+ [[-65.9996522, -39.9995894], [4987500.009, 5555200.001]],
+ [[-64.9992796, -40.000411], [5073000.0, 5560400.0]],
+ [[-63.9997, -39.9996925], [5158400.01, 5564799.987]],
+ [[-62.9999842, -40.0002087], [5243800.0, 5568100.0]],
+ [[-62.0000778, -40.0001803], [5329199.995, 5570500.009]],
+ [[-61.0000574, -39.9996182], [5414600.0, 5572000.0]],
+ [[-60, -40.0003306], [5500000.0, 5572399.996]],
+ [[-58.9999426, -39.9996182], [5585400.0, 5572000.0]],
+ [[-57.9999222, -40.0001803], [5670800.005, 5570500.009]],
+ [[-57.0000158, -40.0002087], [5756200.0, 5568100.0]]
+ ],
+"description": "Test 5101 (part 4), Transverse Mercator, v2-0_2011-06-28, recommended JHS formula",
+"projections": ["+init=epsg:4190", "+init=epsg:22175"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5102.1.json b/test/gigs/5102.1.json
new file mode 100644
index 00000000..28f74538
--- /dev/null
+++ b/test/gigs/5102.1.json
@@ -0,0 +1,29 @@
+{
+"coordinates": [
+ [[5, 58], [760722.92, 3457368.68]],
+ [[5, 57], [764566.844, 3343948.93]],
+ [[5, 56], [768396.683, 3230944.812]],
+ [[5, 55], [772213.973, 3118310.947]],
+ [[5, 54], [776020.189, 3006003.839]],
+ [[5, 53], [779816.748, 2893981.68]],
+ [[4, 51], [717027.292, 2668695.784]],
+ [[4, 50], [719385.249, 2557252.841]],
+ [[4, 49], [721740.43, 2445941.161]],
+ [[4, 46.8], [726915.752, 2201342.519]],
+ [[3, 53], [644764.905, 2891124.195]],
+ [[4, 53], [712299.916, 2892123.369]],
+ [[5, 53], [779816.748, 2893981.68]],
+ [[6, 53], [847304.473, 2896698.827]],
+ [[7, 53], [914752.168, 2900274.371]],
+ [[8, 53], [982148.913, 2904707.734]],
+ [[9, 53], [1049483.8, 2909998.196]],
+ [[10, 53], [1116745.929, 2916144.902]],
+ [[11, 53], [1183924.412, 2923146.858]]
+ ],
+"description": "Test 5102, Lambert Conic Conformal (1SP), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4230", "+init=epsg:2192"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5102.2.json b/test/gigs/5102.2.json
new file mode 100644
index 00000000..3916733a
--- /dev/null
+++ b/test/gigs/5102.2.json
@@ -0,0 +1,29 @@
+{
+"coordinates": [
+ [[2.9586342556, 64.4444444444], [760724.023, 3457334.864]],
+ [[2.9586342556, 63.3333333333], [764567.882, 3343917.044]],
+ [[2.9586342556, 62.2222222222], [768397.648, 3230915.06]],
+ [[2.9586342556, 61.1111111111], [772214.859, 3118283.535]],
+ [[2.9586342556, 60], [776020.989, 3005978.979]],
+ [[2.9586342556, 58.8888888889], [779817.454, 2893959.584]],
+ [[1.8475231444, 56.6666666667], [717027.602, 2668679.866]],
+ [[1.8475231444, 55.5555555556], [719385.487, 2557240.347]],
+ [[1.8475231444, 54.4444444444], [721740.59, 2445932.319]],
+ [[1.8475231444, 52], [726915.726, 2201342.51838845]],
+ [[0.7364120333, 58.8888888889], [644765.081, 2891102.088]],
+ [[1.8475231444, 58.8888888889], [712300.356, 2892101.266]],
+ [[2.9586342556, 58.8888888889], [779817.454, 2893959.584]],
+ [[4.0697453667, 58.8888888889], [847305.444, 2896676.742]],
+ [[5.1808564778, 58.8888888889], [914753.403, 2900252.301]],
+ [[6.2919675889, 58.8888888889], [982150.413, 2904685.68]],
+ [[7.4030787, 58.8888888889], [1049485.565, 2909976.163]],
+ [[8.5141898111, 58.8888888889], [1116747.958, 2916122.894]],
+ [[9.6253009222, 58.8888888889], [1183926.705, 2923124.876]]
+ ],
+"description": "Test 5102 (part 2), Lambert Conic Conformal (1SP), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4807", "+init=epsg:27572"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5103.1.json b/test/gigs/5103.1.json
new file mode 100644
index 00000000..e2fdf9a1
--- /dev/null
+++ b/test/gigs/5103.1.json
@@ -0,0 +1,29 @@
+{
+"coordinates": [
+ [[5, 58], [187742.7, 969521.653]],
+ [[5, 57], [188698.877, 857277.135]],
+ [[5, 56], [189652.853, 745291.184]],
+ [[5, 55], [190604.967, 633523.672]],
+ [[5, 54], [191555.55, 521935.9]],
+ [[5, 53], [192504.921, 410490.433]],
+ [[5.3876389, 52.1561606], [219843.841, 316827.604]],
+ [[4, 51], [124202.936, 187756.876]],
+ [[4, 50], [123652.406, 76521.628]],
+ [[4, 49], [123101.889, -34711.068]],
+ [[3.3137281, 47.9752611], [71254.553, -148236.592]],
+ [[3, 53], [58108.966, 411155.591]],
+ [[4, 53], [125304.704, 410370.504]],
+ [[5, 53], [192504.921, 410490.433]],
+ [[6, 53], [259697.429, 411515.356]],
+ [[7, 53], [326870.04, 413445.087]],
+ [[8, 53], [394010.571, 416279.276]],
+ [[9, 53], [461106.844, 420017.408]],
+ [[10, 53], [528146.69, 424658.807]],
+ [[11, 53], [595117.95, 430202.63]]
+],
+
+"description": "Test 5103 (part 1), Lambert Conic Conformal (2SP), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4313", "+init=epsg:31370"],
+"tests": [ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5103.2.json b/test/gigs/5103.2.json
new file mode 100644
index 00000000..c882393c
--- /dev/null
+++ b/test/gigs/5103.2.json
@@ -0,0 +1,21 @@
+{
+"coordinates": [
+ [[-110, 49], [2003937.27, 6452491.7]],
+ [[-110, 47], [2016621.93, 5717728.61]],
+ [[-110, 45], [2029255.57, 4985920.56]],
+ [[-110, 43], [2041855.08, 4256089.74]],
+ [[-110, 41], [2054436.57, 3527302.73]],
+ [[-110, 41], [2054436.57, 3527302.73]],
+ [[-108, 41], [2606245.52, 3543182.55]],
+ [[-106, 41], [3157542.86, 3571757.39]],
+ [[-104, 41], [3708036.57, 3613012.12]],
+ [[-102, 41], [4257435.06, 3666924.89]]
+ ],
+"description": "Test 5103 (part 2), Lambert Conic Conformal (2SP), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4152", "+init=epsg:2921"],
+
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5103.3.json b/test/gigs/5103.3.json
new file mode 100644
index 00000000..9a388af2
--- /dev/null
+++ b/test/gigs/5103.3.json
@@ -0,0 +1,20 @@
+{
+"coordinates": [
+ [[-110, 49], [2003933.27, 6452478.8]],
+ [[-110, 47], [2016617.9, 5717717.18]],
+ [[-110, 45], [2029251.51, 4985910.59]],
+ [[-110, 43], [2041851.0, 4256081.23]],
+ [[-110, 41], [2054432.46, 3527295.67]],
+ [[-110, 41], [2054432.46, 3527295.67]],
+ [[-108, 41], [2606240.3, 3543175.46]],
+ [[-106, 41], [3157536.54, 3571750.25]],
+ [[-104, 41], [3708029.16, 3613004.9]],
+ [[-102, 41], [4257426.54, 3666917.56]]
+ ],
+"description": "Test 5103 (part 3), Lambert Conic Conformal (2SP), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4152", "+init=epsg:3568"],
+"tests": [
+ {"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5104.json b/test/gigs/5104.json
new file mode 100644
index 00000000..973f832f
--- /dev/null
+++ b/test/gigs/5104.json
@@ -0,0 +1,30 @@
+{
+"coordinates": [
+ [[5, 58], [132023.27, 1114054.87]],
+ [[5, 57], [131405.466, 1002468.081]],
+ [[5, 56], [130792.264, 890981.281]],
+ [[5, 55], [130183.56, 779577.7]],
+ [[5, 54], [129579.26, 668240.58]],
+ [[5, 53], [128979.26, 556953.19]],
+ [[5.38763888888889, 52.1561605555556], [155000, 463000]],
+ [[4, 51], [57605.946, 335312.662]],
+ [[4, 50], [55502.306, 224086.514]],
+ [[4.0, 49.0], [53412.76, 112842.73]],
+ [[3.31372805555556, 47.9752611111111], [0, 0]],
+ [[3, 53], [-5253.06, 559535.55]],
+ [[4, 53], [61856.78, 557779.12]],
+ [[5, 53], [128979.26, 556953.19]],
+ [[6, 53], [196105.28, 557057.74]],
+ [[7, 53], [263225.72, 558092.77]],
+ [[8, 53], [330331.46, 560058.31]],
+ [[9, 53], [397413.385, 562954.436]],
+ [[10, 53], [464462.35, 566781.24]],
+ [[11, 53], [531469.2, 571538.84]]
+],
+"description": "Test 5104, Oblique stereographic, v2-0_2011-06-28.",
+"projections": ["+init=epsg:4289", "+init=epsg:28992"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5105.1.json b/test/gigs/5105.1.json
new file mode 100644
index 00000000..48b5a2fe
--- /dev/null
+++ b/test/gigs/5105.1.json
@@ -0,0 +1,26 @@
+{
+"coordinates": [
+ [[117, 12], [807919.14, 1329535.33]],
+ [[117, 10], [808784.98, 1107678.47]],
+ [[117, 9], [809334.18, 996918.21]],
+ [[117, 8], [809939.3, 886240.18]],
+ [[116.8465522, 6.8784583], [793704.63, 762081.05]],
+ [[117, 6], [811253.3, 665041.27]],
+ [[117, 5], [811930.35, 554475.63]],
+ [[117, 4], [812599.58, 443902.71]],
+ [[115, 4], [590521.15, 442890.86]],
+ [[117, 3], [813245.13, 333300.13]],
+ [[117, 2], [813851.07, 222645.51]],
+ [[117.0, 1.0], [814401.38, 111916.45]],
+ [[109.6858208, -0.0001733], [0, 0]],
+ [[123, 6], [1475669.28, 673118.57]],
+ [[122, 6], [1364854.86, 671146.25]],
+ [[121, 6], [1254086.17, 669446.25]], [[120.0, 6.0], [1143352.6, 668002.07]], [[119.0, 6.0], [1032643.31, 666797.35]], [[118.0, 6.0], [921947.29, 665815.82]], [[117.0, 6.0], [811253.3, 665041.27]], [[116.0, 6.0], [700549.97, 664457.59]], [[115.0, 6.0], [589825.71, 664048.72]],
+ [[114, 6], [479068.802, 663798.63]]
+],
+"description": "Test 5105 (part 1), Oblique Mercator (variant B), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4742",
+ "+proj=somerc +lat_0=4 +lonc=115 +alpha=53.31580995 +k=0.99984 +x_0=0 +y_0=0 +no_uoff +gamma=53.13010236111111 +ellps=GRS80 +units=m +no_defs"],
+"tests": [{"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5105.2.json b/test/gigs/5105.2.json
new file mode 100644
index 00000000..d811108d
--- /dev/null
+++ b/test/gigs/5105.2.json
@@ -0,0 +1,23 @@
+{
+"coordinates": [
+ [[16, 48.5], [424714.235, 355124.6]],
+ [[17.2, 48.0], [512056.188, 296756.716]],
+ [[17.582650555556, 47.636134722222], [539847.765, 255701.086]],
+ [[19.048571666667, 47.144393611111], [650000, 200000]],
+ [[19.223429444445, 46.875668333333], [663329.053, 170142.318]],
+ [[20.135740555556, 46.370301111111], [733651.455, 114532.099]],
+ [[21.4, 45.7], [833148.855, 42191.482]],
+ [[22.3, 49.3], [886565.935, 444656.613]],
+ [[21.294198611111, 48.489974722222], [815999.993, 351999.998]],
+ [[19.223429444445, 46.875668333333], [663329.053, 170142.318]],
+ [[17.619153611111, 46.068746388889], [539403.958, 81440.103]],
+ [[16.36, 45.5], [439836.709, 20816.456]]
+],
+
+"description": "Test 5105 (part 2), Oblique Mercator (variant B), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4237", "+init=epsg:23700"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5106.json b/test/gigs/5106.json
new file mode 100644
index 00000000..cc741478
--- /dev/null
+++ b/test/gigs/5106.json
@@ -0,0 +1,35 @@
+{
+"coordinates": [
+ [[117, 12], [807919.144, 1329535.334]],
+ [[117, 10], [808784.981, 1107678.473]],
+ [[117, 9], [809334.177, 996918.212]],
+ [[117, 8], [809939.302, 886240.183]],
+ [[116.8465522222222222224906494, 6.878458333333333334122825262], [793704.631, 762081.047]],
+ [[117, 6], [811253.303, 665041.265]],
+ [[117, 5], [811930.345, 554475.627]],
+ [[117, 4], [812599.582, 443902.706]],
+ [[115, 4], [590521.147, 442890.861]],
+ [[117, 3], [813245.133, 333300.13]],
+ [[117, 2], [813851.067, 222645.511]],
+ [[117, 1], [814401.375, 111916.452]],
+ [[109.6858208333333333333530706, -0.0001733333333333333330866171056], [0, 0]],
+ [[123, 6], [1475669.281, 673118.573]],
+ [[122, 6], [1364854.862, 671146.254]],
+ [[121, 6], [1254086.173, 669446.249]],
+ [[120, 6], [1143352.598, 668002.074]],
+ [[119, 6], [1032643.312, 666797.354]],
+ [[118, 6], [921947.286, 665815.815]],
+ [[117, 6], [811253.303, 665041.265]],
+ [[116, 6], [700549.965, 664457.586]],
+ [[115, 6], [589825.706, 664048.715]],
+ [[114, 6], [479068.802, 663798.63]]
+],
+
+"description": "Test 5106, Hotine Oblique Mercator (variant A), v2-0_2011-06-28.",
+
+"projections": ["+init=epsg:4742", "+init=epsg:3376"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5107.json b/test/gigs/5107.json
new file mode 100644
index 00000000..58440028
--- /dev/null
+++ b/test/gigs/5107.json
@@ -0,0 +1,26 @@
+{
+"projections": [
+ "+init=epsg:4674",
+ "+proj=poly +lat_0=0 +lon_0=-54 +x_0=5000000 +y_0=10000000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs "
+],
+"tests": [
+ {"type": "conversion", "tolerances": [5.555555555555555e-07, 0.05]},
+ {"type": "roundtrip", "times": 1000, "tolerances": [5.555555555555556e-08, 0.006]}
+ ],
+"coordinates": [
+ [[-54, 0], [5000000.0, 10000000.0]],
+ [[-45, 6], [5996378.70981775, 10671650.0559245]],
+ [[-45, 0], [6001875.41713946, 10000000.0]],
+ [[-45, -6], [5996378.70981775, 9328349.94407546]],
+ [[-41, -13], [6409689.58687533, 8526306.26193173]],
+ [[-38, -20], [6671808.91962898, 7707735.72987798]],
+ [[-37, -24], [6725584.49172815, 7240461.99578364]],
+ [[-36, -30], [6729619.73995286, 6543762.57643596]],
+ [[-57, -30], [4710574.22343996, 6676097.81116979]],
+ [[-54, -29.3674766667], [5000000.0, 6750000.0]],
+ [[-47, -27.5], [5691318.14688622, 6937461.05067494]],
+ [[-37, -24], [6725584.49172815, 7240461.99578364]],
+ [[-30, 22.5], [7458947.7013321, 7313327.31691123]]
+],
+"description": "Test 5107, American Polyconic, v2-0_2011-06-28."
+}
diff --git a/test/gigs/5108.json b/test/gigs/5108.json
new file mode 100644
index 00000000..2ff48e23
--- /dev/null
+++ b/test/gigs/5108.json
@@ -0,0 +1,26 @@
+{
+"coordinates": [
+ [[106, 10], [267186.017, 881108.902]],
+ [[106, 9], [268006.024, 770398.186]],
+ [[106, 8], [268740.351, 659692.254]],
+ [[106, 7], [269388.786, 548990.588]],
+ [[106, 6], [269951.141, 438292.666]],
+ [[106, 5], [270427.255, 327597.962]],
+ [[106, 4], [270816.99, 216905.945]],
+ [[106, 3], [271120.234, 106216.081]],
+ [[103.561065778024, 2.04246768119792], [0, 0]],
+ [[103.640259839629, 1.8277648438075], [8813.252, -23740.095]],
+ [[106, 1], [271466.923, -115159.332]],
+ [[109, 5], [603116.703, 329668.599]],
+ [[108, 5], [492221.308, 328807.336]],
+ [[107, 5], [381324.74, 328117.472]],
+ [[106, 5], [270427.255, 327597.962]],
+ [[105, 5], [159529.111, 327248.012]],
+ [[104, 5], [48630.563, 327067.097]]
+],
+
+"description": "Test 5108, Cassini-Soldner, v2-0_2011-06-28.",
+"projections": ["+init=epsg:4742", "+init=epsg:3377"],
+"tests": [{"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5109.json b/test/gigs/5109.json
new file mode 100644
index 00000000..62614164
--- /dev/null
+++ b/test/gigs/5109.json
@@ -0,0 +1,23 @@
+{
+"coordinates": [
+ [[132, 0], [0, 0]],
+ [[132, -27], [0, -2926820.89]],
+ [[140, 0], [966973.98, -30285.6]],
+ [[140, -20], [832799.36, -2170181.93]],
+ [[140, -40], [693250.21, -4395794.49]],
+ [[140, -60], [567313.29, -6404311.16]],
+ [[140, -80], [486878.674, -7687130.029]],
+ [[120, -60], [-850274.75, -6426505.13]],
+ [[130, -60], [-141915.26, -6387653.78]],
+ [[140, -60], [567313.29, -6404311.16]],
+ [[150, -60], [1273067.747, -6476375.276]],
+ [[160, -60], [1971026.26, -6603404.82]],
+ [[170, -60], [2656914.716, -6784621.89]]
+],
+"description": "Test 5109, Albers Equal Area, v2-0_2011-06-28.",
+"projections": ["+init=epsg:4283", "+init=epsg:3577"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5110.json b/test/gigs/5110.json
new file mode 100644
index 00000000..e9812ecf
--- /dev/null
+++ b/test/gigs/5110.json
@@ -0,0 +1,12 @@
+{
+"coordinates": [
+ [[5, 70], [4127824.65822105, 5214090.649]],
+ [[5, 60], [4041548.13, 4109791.66]],
+ [[5, 50], [3962799.45, 2999718.853]],
+ [[5, 40], [3892127.02, 1892578.962]],
+ [[5, 30], [3830117.9, 796781.677]],
+ [[10, 52], [4321000.0, 3210000.0]], [[0.0, 50.0], [3606514.43, 3036305.967]], [[3.0, 50.0], [3819948.288, 3011432.894]], [[5.0, 50.0], [3962799.451, 2999718.853]], [[8.0, 50.0], [4177612.521, 2989464.315]], [[10.0, 50.0], [4321000.0, 2987510.567]]], "description": "Test 5110, Lambert Azimuthal Equal Area, v2-0_2011-06-28.",
+"projections": ["+init=epsg:4258", "+init=epsg:3035"],
+"tests": [{"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5111.1.json b/test/gigs/5111.1.json
new file mode 100644
index 00000000..25ca8572
--- /dev/null
+++ b/test/gigs/5111.1.json
@@ -0,0 +1,45 @@
+{
+"coordinates": [
+ [[100.0876483, 77.6534822], [2800000.0, 15000000.0]],
+ [[100.0876483, 73.1442856], [2800000.0, 13000000.0]],
+ [[100.0876483, 67.0518325], [2800000.0, 11000000.0]],
+ [[100.0876483, 58.9140458], [2800000.0, 9000000.0]],
+ [[100.0876483, 48.2638981], [2800000.0, 7000000.0]],
+ [[100.0876483, 34.8029044], [2800000.0, 5000000.0]],
+ [[100.0876483, 18.7048581], [2800000.0, 3000000.0]],
+ [[100.0876483, 0.9071392], [2800000.0, 1000000.0]],
+ [[110.0, 0.0], [3900000.0, 900000.0]],
+ [[100.0876483, -0.9071392], [2800000.0, 800000.0]],
+ [[100.0876483, -1.8140483], [2800000.0, 700000.0]],
+ [[100.0876483, -2.0], [2800000.0, 679490.65]],
+ [[100.0876483, -3.6262553], [2800000.0, 500000.0]],
+ [[100.0876483, -4.531095], [2800000.0, 400000.0]],
+ [[100.0876483, -5.4347892], [2800000.0, 300000.0]],
+ [[100.0876483, -6.3371111], [2800000.0, 200000.0]],
+ [[100.0876483, -7.2378372], [2800000.0, 100000.0]],
+ [[74.8562083, -8.136745], [0.0, 0.0]],
+ [[-71.0, -2.0], [23764105.84, 679490.65]],
+ [[-90.0, -2.0], [21655625.33, 679490.65]],
+ [[-120.0, -2.0], [18326445.58, 679490.65]],
+ [[-150.0, -2.0], [14997265.83, 679490.65]],
+ [[180.0, -2.0], [11668086.08, 679490.65]],
+ [[150.0, -2.0], [8338906.33, 679490.65]],
+ [[120.0, -2.0], [5009726.58, 679490.65]],
+ [[110.0, -2.0], [3900000.0, 679490.65]],
+ [[106.8077194, -2.0], [3545744.14, 679490.65]],
+ [[100.0876483, -2.0], [2800000.0, 679490.65]],
+ [[90.0, -2.0], [1680546.83, 679490.65]],
+ [[60.0, -2.0], [-1648632.92, 679490.65]],
+ [[30.0, -2.0], [-4977812.67, 679490.65]],
+ [[0.0, -2.0], [-8306992.42, 679490.65]],
+ [[-30.0, -2.0], [-11636172.17, 679490.65]],
+ [[-60.0, -2.0], [-14965351.92, 679490.65]],
+ [[-69.0, -2.0], [-15964105.84, 679490.65]]
+],
+"description": "Test 5111 (part 1), Mercator (variant A), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4211", "+init=epsg:3001"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5111.2.json b/test/gigs/5111.2.json
new file mode 100644
index 00000000..03d43f41
--- /dev/null
+++ b/test/gigs/5111.2.json
@@ -0,0 +1,44 @@
+{
+"coordinates": [
+ [[-6.7200711, 77.6534822], [2800000.0, 15000000.0]],
+ [[-6.7200711, 73.1442856], [2800000.0, 13000000.0]],
+ [[-6.7200711, 67.0518325], [2800000.0, 11000000.0]],
+ [[-6.7200711, 58.9140458], [2800000.0, 9000000.0]],
+ [[-6.7200711, 48.2638981], [2800000.0, 7000000.0]],
+ [[-6.7200711, 34.8029044], [2800000.0, 5000000.0]],
+ [[-6.7200711, 18.7048581], [2800000.0, 3000000.0]],
+ [[-6.7200711, 0.9071392], [2800000.0, 1000000.0]],
+ [[3.1922806, 0.0], [3900000.0, 900000.0]],
+ [[-6.7200711, 0.9071392], [2800000.0, 800000.0]],
+ [[-6.7200711, 1.8140483], [2800000.0, 700000.0]],
+ [[-6.7200711, 2.0], [2800000.0, 679490.65]],
+ [[-6.7200711, 3.6262553], [2800000.0, 500000.0]],
+ [[-6.7200711, 4.531095], [2800000.0, 400000.0]],
+ [[-6.7200711, 5.4347892], [2800000.0, 300000.0]],
+ [[-6.7200711, 6.3371111], [2800000.0, 200000.0]],
+ [[-6.7200711, 7.2378372], [2800000.0, 100000.0]],
+ [[-31.9515111, 8.136745], [0.0, 0.0]],
+ [[-177.8077194, 2.0], [23764105.84, 679490.65]],
+ [[163.1922806, 2.0], [21655625.33, 679490.65]],
+ [[133.1922806, 2.0], [18326445.58, 679490.65]],
+ [[103.1922806, 2.0], [14997265.83, 679490.65]],
+ [[73.1922806, 2.0], [11668086.08, 679490.65]],
+ [[43.1922806, 2.0], [8338906.33, 679490.65]],
+ [[13.1922806, 2.0], [5009726.58, 679490.65]],
+ [[3.1922806, 2.0], [3900000.0, 679490.65]],
+ [[0.0, 2.0], [3545744.14, 679490.65]],
+ [[-6.7200711, 2.0], [2800000.0, 679490.65]],
+ [[-16.8077194, 2.0], [1680546.83, 679490.65]],
+ [[-46.8077194, 2.0], [-1648632.92, 679490.65]],
+ [[-76.8077194, 2.0], [-4977812.67, 679490.65]],
+ [[-106.8077194, 2.0], [-8306992.42, 679490.65]],
+ [[-136.8077194, 2.0], [-11636172.17, 679490.65]],
+ [[-166.8077194, 2.0], [-14965351.92, 679490.65]],
+ [[-175.8077194, 2.0], [-15964105.84, 679490.65]]
+],
+"description": "Test 5111 (part 2), Mercator (variant A), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4813",
+ "+proj=merc +lon_0=110 +k=0.997 +x_0=3900000 +y_0=900000 +ellps=bessel +units=m +no_defs"],
+"tests": [ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"} ]
+}
diff --git a/test/gigs/5112.json b/test/gigs/5112.json
new file mode 100644
index 00000000..2b652933
--- /dev/null
+++ b/test/gigs/5112.json
@@ -0,0 +1,15 @@
+{
+"coordinates": [
+ [[51.0, 42.0], [0.0, 3819897.85]],
+ [[51.0, 0.0], [0.0, 0.0]],
+ [[57.0, 0.0], [497112.88, 0.0]],
+ [[54.0, 20.5], [248556.44, 1724781.5]],
+ [[67.0, -41.0], [1325634.35, -3709687.25]]
+ ],
+"description": "Test 5112, Mercator (variant B), v2-0_2011-06-28.",
+"projections": ["+init=epsg:4284", "+init=epsg:3388"],
+"tests": [
+ {"tolerances": [5.555555555555555e-07, 0.05], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}
+ ]
+}
diff --git a/test/gigs/5113.json b/test/gigs/5113.json
new file mode 100644
index 00000000..945e4c44
--- /dev/null
+++ b/test/gigs/5113.json
@@ -0,0 +1,12 @@
+{
+"description": "Test 5113, Transverse Mercator (South Oriented), v2-0_2011-06-28.",
+"coordinates": [ [[22.5, 0.0], [-166998.44, 0.0]],
+ [[21.5, -25.0], [-50475.46, 2766147.25]],
+ [[20.5, -30.0], [48243.45, 3320218.65]],
+ [[19.5, -35.0], [136937.65, 3875621.18]],
+ [[19.5, -35.0], [136937.65, 3875621.18]]
+ ],
+"projections": ["+init=epsg:4148", "+init=epsg:2049"],
+"tests": [{"tolerances": [2.7777777777777776e-07, 0.03], "type": "conversion"},
+ {"times": 1000, "tolerances": [5.555555555555556e-08, 0.006], "type": "roundtrip"}]
+}
diff --git a/test/gigs/5201.json b/test/gigs/5201.json
new file mode 100644
index 00000000..e1ffdd77
--- /dev/null
+++ b/test/gigs/5201.json
@@ -0,0 +1,39 @@
+{
+"description" : "Test 5201, Geographic Geocentric conversions, v2.0_2011-09-28. (EPSG 4979 - WGS84 3d has been replaced with EPSG code 4326 WGS84 2d).",
+"projections" : [ "+init=epsg:4978", "+init=epsg:4326" ],
+
+"coordinates": [
+ [ [-962479.5924, 555687.8517, 6260738.6526], [150, 80, 1214.137] ],
+ [ [-962297.0059, 555582.4354, 6259542.961], [150, 80, 0] ],
+ [ [-1598248.169, 2768777.623, 5501278.468], [119.99524538, 60.00475191, 619.6317] ],
+ [ [-1598023.169, 2768387.912, 5500499.045], [119.99524470, 60.00475258, -280.3683] ],
+ [ [2764210.4054, 4787752.865, 3170468.5199], [60, 30, 189.569] ],
+ [ [2764128.3196, 4787610.6883, 3170373.7354], [60, 30, 0] ],
+ [ [6377934.396, -112, 434], [-0.00100615, 0.00392509, -202.5882] ],
+ [ [6374934.396, -112, 434], [-0.00100662, 0.00392695, -3202.5881] ],
+ [ [6367934.396, -112, 434], [-0.00100773, 0.00393129, -10202.5881] ],
+ [ [2764128.3196, -4787610.6883, -3170373.7354], [-60, -30, 0] ],
+ [ [2763900.3489, -4787215.8313, -3170110.4974], [-60, -30, -526.476] ],
+ [ [2763880.8633, -4787182.0813, -3170087.9974], [-60, -30, -571.476] ],
+ [ [-1598023.169, -2768611.912, -5499631.045], [-119.99323757, -59.99934884, -935.0995] ],
+ [ [-1597798.169, -2768222.201, -5498851.622], [-119.99323663, -59.99934874, -1835.0995] ],
+ [ [-962297.0059, -555582.4354, -6259542.961], [-150, -80, 0] ],
+ [ [-962150.945, -555498.1071, -6258586.4616], [-150, -80, -971.255] ],
+ [ [-961798.2951, -555294.5046, -6256277.0874], [-150, -80, -3316.255] ],
+ [ [-2187336.719, -112, 5971017.093], [-179.99706624, 70.00490733, -223.6178] ],
+ [ [-2904698.5551, -2904698.5551, 4862789.0377], [-135, 50, 0] ],
+ [ [371, -5783593.614, 2679326.11], [-89.99632465, 25.00366329, -274.7286] ],
+ [ [6378137, 0, 0], [0, 0, 0] ],
+ [ [-4087095.478, 2977467.559, -3875457.429], [143.92649252, -37.65282217, 737.7182] ],
+ [ [-4085919.959, 2976611.233, -3874335.274], [143.92649211, -37.65282206, -1099.2288] ],
+ [ [-4084000.165, 2975212.729, -3872502.631], [143.92649143, -37.65282187, -4099.2288] ],
+ [ [-4079520.647, 2971949.553, -3868226.465], [143.92648984, -37.65282143, -11099.2288] ],
+ [ [-2904698.5551, 2904698.5551, -4862789.0377], [135, -50, 0] ],
+ [ [-2187336.719, -112, -5970149.093], [-179.99706624, -70.00224647, -1039.2896] ]
+],
+
+"tests" : [
+ {"type": "conversion", "tolerances": [0.01, [8.333333333333333e-08, 8.333333333333333e-08, 0.01]]},
+ {"type": "roundtrip", "times":1000, "tolerances": [0.006, [5.555555555555556e-08, 5.555555555555556e-08, 0.006]] }
+]
+}
diff --git a/test/gigs/5203.1.json b/test/gigs/5203.1.json
new file mode 100644
index 00000000..658e7857
--- /dev/null
+++ b/test/gigs/5203.1.json
@@ -0,0 +1,25 @@
+{
+"description": "GIGS Test 5203 (part 1), Position Vector 7-parameter transformation, v2.0_2011-06-28. Geographic 2D domain (EPSG method code 9606).",
+"projections" : [ "+init=epsg:4277", "+init=epsg:4326" ],
+
+"coordinates" : [
+ [ [150.00567472, 79.99487333], [150.0, 80.0] ],
+ [ [120.0, 60.0], [119.99435889, 60.00569306] ],
+ [ [60.00446778, 29.99566778], [60.0, 30.0] ],
+ [ [0.0, 0.0], [-0.00089056, 0.00483333] ],
+ [ [-60.00357056, -30.00504639], [-60.0, -30.0] ],
+ [ [-120.0, -60.0], [-119.9918525, -59.99907361] ],
+ [ [-150.01693111, -79.99778139], [-150.0, -80.0] ],
+ [ [-180.0, 70.0], [-179.99637361, 70.005945] ],
+ [ [-135.00596333, 49.99458694], [-135.0, 50.0] ],
+ [ [-90.0, 25.0], [-89.99531139, 25.00445833] ],
+ [ [0.00089056, -0.00483333], [0.0, 0.0] ],
+ [ [143.9279419, -37.6532236], [143.92634806, -37.65235306] ],
+ [ [135.00291194, -49.99973028], [135.0, -50.0] ],
+ [ [180.0, -70.0], [-179.99660139, -70.002485] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/5204.1.json b/test/gigs/5204.1.json
new file mode 100644
index 00000000..06347e64
--- /dev/null
+++ b/test/gigs/5204.1.json
@@ -0,0 +1,25 @@
+{
+"description" : "GIGS Test 5204, Coordinate Frame 7-parameter transformation, v2.0_2011-06-28. Geographic 2D domain (EPSG method code 9607)",
+"projections" : [ "+init=epsg:4313", "+init=epsg:4326" ],
+
+"coordinates" : [
+ [ [149.99825389, 80.00155167], [150, 80] ],
+ [ [120, 60], [120.00197111, 59.99807333] ],
+ [ [59.99822194, 30.00134083], [60, 30] ],
+ [ [0, 0], [0.00098139, -0.00081028] ],
+ [ [-59.99991333, -29.99943917], [-60, -30] ],
+ [ [-120, -60], [-120.00150694, -59.999835] ],
+ [ [-149.99532167, -80.00054917], [-150, -80] ],
+ [ [-180, 70], [179.99939778, 69.99812806] ],
+ [ [-134.99891389, 50.00183], [-135, 50] ],
+ [ [-90, 25], [-90.00060583, 24.99862667] ],
+ [ [-0.00098139, 0.00081028], [0, 0] ],
+ [ [143.9279419, -37.6532236], [143.92857222, -37.65257083] ],
+ [ [134.99913472, -50.00096139], [135, -50] ],
+ [ [180, -70], [179.99888667, -69.99901667] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/5205.1.json b/test/gigs/5205.1.json
new file mode 100644
index 00000000..e0c41ff3
--- /dev/null
+++ b/test/gigs/5205.1.json
@@ -0,0 +1,25 @@
+{
+"description" : "GIGS Test 5205 (Part 1), Molodensky-Badekas 10-parameter transformation, v2.0_2011-06-28. Geographic 2D domain (EPSG method code 9636)",
+"projections" : [ "+init=epsg:4289", "+init=epsg:4326" ],
+
+"coordinates": [
+ [ [150.01814371, 79.99494639], [150, 80] ],
+ [ [120, 60], [119.99001559, 60.00441792] ],
+ [ [60.00535007, 29.99746103], [60, 30] ],
+ [ [0, 0], [-0.00007025, 0.0041133] ],
+ [ [-60.00473241, -30.0042486], [-60, -30] ],
+ [ [-120, -60], [-119.9922412, -60.00081456] ],
+ [ [-150.01209192, -79.99612229], [-150, -80] ],
+ [ [-180, 70], [179.99786174, 70.00666951] ],
+ [ [-135.00454845, 49.99357566], [-135, 50] ],
+ [ [-90, 25], [-89.99487454, 25.00457271] ],
+ [ [0.00007032, -0.00411349], [0, 0] ],
+ [ [143.9279419, -37.6532236], [143.92330599, -37.65282034] ],
+ [ [135.00641074, -49.99958243], [135, -50] ],
+ [ [180, -70], [179.99847886, -70.00362084] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/5206.json b/test/gigs/5206.json
new file mode 100644
index 00000000..d5a26252
--- /dev/null
+++ b/test/gigs/5206.json
@@ -0,0 +1,54 @@
+{
+"description" : "Test 5206, NADCON transformation, v2.0_2011-06-28. Out of transform grid area error tests have been removed.",
+"projections" : [ "+init=epsg:4267", "+init=epsg:4269" ],
+
+"coordinates": [
+ [ [-89.5177272, 29.9997978], [-89.5177778, 30.0000000] ],
+ [ [-90.5177778, 29.2833333], [-90.5178639, 29.2835592] ],
+ [ [-91.5176758, 28.2830864], [-91.5177778, 28.2833333] ],
+ [ [-92.5177778, 27.2833333], [-92.5178811, 27.2836106] ],
+ [ [-93.5176731, 26.2830225], [-93.5177778, 26.2833333] ],
+ [ [-94.5177778, 25], [-94.5178744, 25.0003486] ],
+ [ [-142.9972522, 70.0001631], [-143, 70] ],
+ [ [-142, 70.0000000], [-142.0026922, 69.9998422] ],
+ [ [-141.9973078, 70.0001578], [-142, 70] ],
+ [ [-140.9971981, 70.0001481], [-141, 70] ],
+ [ [-140, 70], [-140.0027922, 69.9998617] ],
+ [ [-138.9973075, 70.0001297], [-139, 70] ],
+ [ [-138, 70], [-138.0026767, 69.9998867] ],
+ [ [-134.9973733, 70.000055], [-135, 70] ],
+ [ [-130, 70], [-130.0025347, 70.0000511] ],
+ [ [-128.0009742, 69.9999053], [-128.0034722, 70] ],
+ [ [-179, 70], [-179.0035064, 69.9990142] ],
+ [ [-179.9964664, 70.0010089], [180, 70] ],
+ [ [180, 70], [179.9964664, 69.9989911] ],
+ [ [179, 70], [178.9964394, 69.9989678] ],
+ [ [-111.9991714, 49.9999556], [-112, 49.9999997] ],
+ [ [-112, 49.9999997], [-112.0008286, 50.0000439] ],
+ [ [-111.9991214, 49.0000033], [-112, 49] ],
+ [ [-112, 48], [-112.0008492, 47.9999606] ],
+ [ [-111.9991678, 47.0000569], [-112, 47] ],
+ [ [-112, 47], [-112.0008325, 46.9999431] ],
+ [ [-111.9991756, 46.0000733], [-112, 46] ],
+ [ [-112, 45], [-112.0008022, 44.9999197] ],
+ [ [-130.5177467, 51], [-130.5193953, 50.9997114] ],
+ [ [-130.5160981, 51.0002886], [-130.5177467, 51] ],
+ [ [-130.5161206, 50.0002897], [-130.5177467, 49.9999997] ],
+ [ [-130.5177467, 49.9999997], [-130.5193731, 49.9997097] ],
+ [ [-130.5161458, 49.0002717], [-130.5177467, 49] ],
+ [ [-130.5177467, 48.1166667], [-130.5193258, 48.1164106] ],
+ [ [-130.5161942, 47.0002378], [-130.5177467, 47] ],
+ [ [-130.5177467, 47], [-130.5192992, 46.9997622] ],
+ [ [-130.5162172, 46.0002222], [-130.5177467, 46] ],
+ [ [-130.5177467, 45], [-130.5192539, 44.9997925] ],
+ [ [-132.9984775, 48.1169867], [-133, 48.1166667] ],
+ [ [-131.4555556, 48.1166667], [-131.4571578, 48.1163964] ],
+ [ [-130.5161675, 48.1169228], [-130.5177467, 48.1166667] ],
+ [ [-128.4555556, 48.1166667], [-128.4570433, 48.1164319] ],
+ [ [-128.5444444, 48.1166667], [-128.5459361, 48.1164311] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/5207.1.json b/test/gigs/5207.1.json
new file mode 100644
index 00000000..aa4e0f07
--- /dev/null
+++ b/test/gigs/5207.1.json
@@ -0,0 +1,30 @@
+{
+"description" : "Test 5207, NTv2 transformation, v2.0_2011-06-28. Out of transform grid area error tests have been removed.",
+"projections" : [ "+init=epsg:4202", "+init=epsg:4283" ],
+
+"coordinates": [
+ [ [-115, -10.05], [-115.001251111111, -10.048637222222] ],
+ [ [-114.998744166667, -11.001359444445], [-115, -11] ],
+ [ [-115, -12], [-115.001261388889, -11.998644166667] ],
+ [ [-138.04, -9], [-138.041132777778, -8.998543333333] ],
+ [ [-138.043867222222, -9.001456666667], [-138.045, -9] ],
+ [ [-138.05, -9], [-138.051132777778, -8.998543333333] ],
+ [ [-138.048867222222, -9.001456666667], [-138.05, -9] ],
+ [ [-138.053867222222, -9.001456666667], [-138.055, -9] ],
+ [ [-138.06, -9], [-138.061132777778, -8.998543333333] ],
+ [ [-138.038730833333, -27.126476388889], [-138.04, -27.125] ],
+ [ [-138.045, -27.125], [-138.046268888889, -27.123523611111] ],
+ [ [-138.05, -27.125], [-138.051268888889, -27.123523611111] ],
+ [ [-138.048731111111, -27.126476388889], [-138.05, -27.125] ],
+ [ [-138.055, -27.125], [-138.056268888889, -27.123523333333] ],
+ [ [-138.058731111111, -27.126476666667], [-138.06, -27.125] ],
+ [ [-136.847222222222, -28.05], [-136.848525277778, -28.048526944445] ],
+ [ [-137.847222222222, -28.05], [-137.848505555556, -28.048531111111] ],
+ [ [-138.847222222222, -28.05], [-138.8484925, -28.048518888889] ],
+ [ [-139.847222222222, -28.05], [-139.848475277778, -28.048507222222] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08]}
+ ]
+}
diff --git a/test/gigs/5207.2.json b/test/gigs/5207.2.json
new file mode 100644
index 00000000..cf5c4cd6
--- /dev/null
+++ b/test/gigs/5207.2.json
@@ -0,0 +1,47 @@
+{
+"description" : "Test 5206, NADCON transformation, v2.0_2011-06-28. Out of transform grid area error tests have been removed.",
+"projections" : [ "+init=epsg:4267", "+init=epsg:4269" ],
+
+"coordinates": [
+ [ [-142, 70], [-142.002804722222, 69.999806944445] ],
+ [ [-141.997195277778, 70.000193055556], [-142, 70] ],
+ [ [-140.997219722222, 70.000179166667], [-141, 70] ],
+ [ [-140, 70], [-140.002795277778, 69.999828055556] ],
+ [ [-138.997199444444, 70.000160833333], [-139, 70] ],
+ [ [-138, 70], [-138.002957222222, 69.999875555556] ],
+ [ [-134.997081944444, 70.000046388889], [-135, 70] ],
+ [ [-130, 70], [-130.002737222222, 70.000053333333] ],
+ [ [-128.000734722222, 69.999866388889], [-128.003472222222, 70] ],
+ [ [-128, 70], [-128.002737777778, 70.000133611111] ],
+ [ [-125.997388333333, 69.999778055556], [-126, 70] ],
+ [ [-88.005575, 70], [-88.0056825, 70.000609444445] ],
+ [ [-88, 70], [-88.000107222222, 70.000609166667] ],
+ [ [-87.999893333333, 69.999390833333], [-88, 70] ],
+ [ [-87.6610917, 70], [-87.661171666667, 70.000603333333] ],
+ [ [-112.165693333333, 51.016955555556], [-112.166607777778, 51.017009444445] ],
+ [ [-111.999093888889, 50.999949166667], [-112, 51] ],
+ [ [-111.999095277778, 49.999959722222], [-112, 49.999999722222] ],
+ [ [-112, 49.999999722222], [-112.000904638889, 50.000039666667] ],
+ [ [-111.9991175, 49.000006388889], [-112, 49] ],
+ [ [-112, 48], [-112.0008525, 47.999988888889] ],
+ [ [-111.999174722222, 47.000009722222], [-112, 47] ],
+ [ [-112, 47], [-112.000825277778, 46.999990277778] ],
+ [ [-130.517746666667, 51], [-130.519401944444, 50.999771388889] ],
+ [ [-130.516091666667, 51.000228611111], [-130.517746666667, 51] ],
+ [ [-130.516041666667, 50.000246111111], [-130.517746666667, 49.999999722222] ],
+ [ [-130.517746666667, 49.999999722222], [-130.519451666667, 49.999753333333] ],
+ [ [-130.516067222222, 49.0002825], [-130.517746666667, 49] ],
+ [ [-130.517746666667, 48], [-130.519391111111, 47.999679444445] ],
+ [ [-130.516146944444, 47.000361111111], [-130.517746666667, 47] ],
+ [ [-130.517746666667, 47], [-130.519346388889, 46.999638611111] ],
+ [ [-132.998205277778, 48.117026388889], [-133, 48.116666666667] ],
+ [ [-131.455555555556, 48.116666666667], [-131.457260277778, 48.116333055556] ],
+ [ [-130.516098055556, 48.116982777778], [-130.517746666667, 48.116666666667] ],
+ [ [-128.455555555556, 48.116666666667], [-128.457086944444, 48.116392777778] ],
+ [ [-128.5444, 48.1167066], [-128.545936111111, 48.116431111111] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/5208.json b/test/gigs/5208.json
new file mode 100644
index 00000000..4242c175
--- /dev/null
+++ b/test/gigs/5208.json
@@ -0,0 +1,25 @@
+{
+"description": "Test 5208, Longitude Rotation, v2.0_2011-06-28.",
+"projections" : [ "+init=epsg:4275", "+init=epsg:4807" ],
+
+"coordinates": [
+ [ [5, 58], [2.66277083, 58] ],
+ [ [5, 56], [2.66277083, 56] ],
+ [ [5, 55], [2.66277083, 55] ],
+ [ [5, 53], [2.66277083, 53] ],
+ [ [4, 51], [1.66277083, 51] ],
+ [ [4, 49], [1.66277083, 49] ],
+ [ [2.33722917, 46.8], [0, 46.8] ],
+ [ [3, 53], [0.66277083, 53] ],
+ [ [4, 53], [1.66277083, 53] ],
+ [ [6, 53], [3.66277083, 53] ],
+ [ [7, 53], [4.66277083, 53] ],
+ [ [9, 53], [6.66277083, 53] ],
+ [ [10, 53], [7.66277083, 53] ],
+ [ [11, 53], [8.66277083, 53] ]
+],
+
+"tests" : [ {"type": "conversion", "tolerances": [2.7777777777777776e-07, 2.7777777777777776e-07]},
+ {"type": "roundtrip", "times":1000, "tolerances": [5.555555555555556e-08, 5.555555555555556e-08] }
+ ]
+}
diff --git a/test/gigs/TESTNOTES.md b/test/gigs/TESTNOTES.md
new file mode 100644
index 00000000..003872e8
--- /dev/null
+++ b/test/gigs/TESTNOTES.md
@@ -0,0 +1,225 @@
+## TEST JSON ###########################################################
+
+This is the testing framework that uses JSON formated files that tests
+PROJ.4 using Geospatial Integrity of Geoscience Sofware (GIGS) calculations.
+This could be used as a framework for testing projections from other
+sources.
+
+
+For more information about the Geospatial Integrity of Geoscience Software
+(GIGS) at
+http://www.iogp.org/Geomatics#2521115-gigs
+
+## Geospatial Integrity of Geoscience Software License #################
+
+The disclaimer and copyright **only** applies to JSON files that originate
+from GIGS tests, which is a reformatting material provided by the
+International Association of Oil & Gas Producers.
+
+**Disclaimer**
+
+Whilst every effort has been made to ensure the accuracy of the information contained in this publication,
+neither the OGP nor any of its members past present or future warrants its accuracy or will, regardless
+of its or their negligence, assume liability for any foreseeable or unforeseeable use made thereof, which
+liability is hereby excluded. Consequently, such use is at the recipient’s own risk on the basis that any use
+by the recipient constitutes agreement to the terms of this disclaimer. The recipient is obliged to inform
+any subsequent recipient of such terms.
+
+This document may provide guidance supplemental to the requirements of local legislation. Nothing
+herein, however, is intended to replace, amend, supersede or otherwise depart from such requirements. In
+the event of any conflict or contradiction between the provisions of this document and local legislation,
+applicable laws shall prevail.
+
+**Copyright notice**
+
+The contents of these pages are © The International Association of Oil & Gas Producers. Permission
+is given to reproduce this report in whole or in part provided (i) that the copyright of OGP and (ii)
+the source are acknowledged. All other rights are reserved.” Any other use requires the prior written
+permission of the OGP.
+
+These Terms and Conditions shall be governed by and construed in accordance with the laws of
+England and Wales. Disputes arising here from shall be exclusively subject to the jurisdiction of the
+courts of England and Wales.
+
+
+## INSTALLING ##########################################################
+
+ * Requires: Python 2.7 or 3.3+
+ * pyproj (optional but highly recommended), this speeds up tests, makes
+ results more precise but has the trade-off of making installation a
+ little more complicated.
+
+
+
+### Installing pyproj ##################################################
+
+ 1) Install `pip` (usually `pip3`) if not installed, should already be installed on new Python
+ versions (Python 3 >=3.4) or if using a virtual environment for python.
+ see https://pip.pypa.io/en/stable/installing/
+ * **Note**: if you have Python 2.x and 3.x installed, `pip3` is for Python 3.x.
+ `pip` could be an alias for either one.
+ 2) Upgrade `pip` (possibly not needed)
+ https://pip.pypa.io/en/stable/installing/#upgrading-pip
+ 3) Install pyproj
+ * requires a C/C++ compiler be usuable by python
+ * repository version requires Cython to be installed, releases do not require this
+
+```
+ $ pip install cython
+```
+
+ * install latest release
+ * set PROJ_DIR environment variable to an installed version of PROJ4
+ library. This should have the directories include/ lib/ &
+ share/proj/ underneath it.
+
+ * installing on Linux (default ./configure settings for PROJ.4)
+
+```
+ $ PROJ_DIR=/usr/local pip install pyproj
+```
+
+## Running Tests #######################################################
+
+When calling test_json.py it defaults to using pyproj driver.
+
+```
+ $ python test_json.py 5*.json
+```
+
+There is a driver to directly use cs2cs instead of installing pyproj, but
+it is much slower and not recommended.
+
+Here is how you run the cs2cs driver:
+
+```
+ $ python test_json.py -d cs2cs -e path/to/repo/bin/cs2cs 5201.json
+```
+
+
+## GIGS Test ###########################################################
+
+Tests that were meant to test for out of grid errors were removed from
+testing. PROJ.4 cs2cs provides coordinates seemingly without warnings
+or errors.
+
+### Drastic Tolerance Errors ###########################################
+
+These are errors that might indicate the wrong projection is being used,
+wrong parameters are being used in the projection, or problems with the
+projection itself. It could point to problems with the provided model.
+
+ * 5101 part 4 - Transverse Mercator
+ - EPSG code will need to be redefined to make sure that etmerc version
+ is used, should be done before next release (4.9.3 / 4.10.0 ?)
+ - Temporarily use test "5101.4-jhs-etmerc.json", perhaps remove file
+ when etmerc/tmerc aliasing issue has been fixed.
+ * 5102 part 2 - Lambert Conic Conformal (1SP)
+ - This one seems to have some problems.
+ * 5105 part 1 - Oblique Mercator (variant B)
+ - There are some drastically different answers.
+
+### Slight Tolerance Errors ############################################
+
+These tests have results with rounding errors that are slightly out of
+tolerance. This could be due to a lack of precision in the JSON file
+or due to the formula's precision. Most of these tests fail with some
+point in testing 1,000 round trip coordinate conversions. A few of these
+might require a little bit of tuning with cs2cs. There are some rather
+concerning differences between Python 2.7 and Python 3.4 in testing, which
+needs to be pinpointed.
+
+ * 5101 part 1 - Transverse Mercator
+ - roundtrip tests fail with very slight tolerance issues
+ * 5104 - Oblique stereographic
+ - roundtrip tests fail with very slight tolerance issues
+ * 5105 part 2 - Oblique Mercator (variant B)
+ - roundtrip tests fail with tolerance issues
+ * 5106 - Hotline Oblique Mercator (variant A)
+ - roundtrip tests fail with very slight tolerance issues
+ * 5108 - Cassini-Soldner
+ - roundtrip tests seem to accumulate errors
+ * 5110 - Lambert Azimuthal Equal Area
+ - roundtrip tests have some slight errors
+ * 5111 part 1 - Mercator (variant A)
+ - roundtrip tests fail with very slight tolerance issues
+ * 5111 part 2 - Mercator (variant A)
+ * 5203 part 1 - Position Vector 7-parameter transformation
+ - most seem to be rounding errors. Some results cross longitude
+ line 180/-180
+ * 5204 part 1 - Coordinate Frame 7-parameter transformation
+ - most seem to be rounding errors. Some results cross longitude
+ line 180/-180
+ * 5205 part 1 - Molodensky-Badekas 10-parameter transformation
+ - most seem to be rounding errors. Some results cross longitude
+ line 180/-180
+ * 5206 - NADCON transformation
+ * 5207 parts 1 & 2 - NTv2 transformation
+
+
+### Other Issues with Tests ############################################
+ * 5201 - Geographic Geocentric conversions
+ - EPSG code 4979, does not exist in PROJ.4 substituted EPGS code 4326.
+ - The test passes.
+ * 5206 and 5207 parts 1 & 2 - NADCON Transformation and NTv2 Transformation
+ - These tests have cases that are out of grid, which have been omitted.
+ The GIGS tests expectations, "[n]ote 1: This location is out of
+ transformation grid area - the attempted transformation should fail
+ and application notify user."
+
+
+## Passing Tests #######################################################
+ * 5101 part 2 - Transverse Mercator
+ * 5101 part 3 - Transverse Mercator
+ * 5102 part 1 - Lambert Conic Conformal (1SP)
+ * 5103 part 1 - Lambert Conic Conformal (2SP)
+ * 5103 part 2 - Lambert Conic Conformal (2SP)
+ * 5103 part 3 - Lambert Conic Conformal (2SP)
+ * 5107 - American Polyconic
+ * 5109 - Albers Equal Area
+ * 5112 - Mercator (variant B)
+ * 5113 - Transverse Mercator (South Oriented)
+ * 5208 - Longitude Rotation
+
+
+
+## Benchmarks ##########################################################
+
+Benchmarks were made using Micah Cochran's circa 2008 Desktop computer
+using LXLE Ubuntu Linux 14.04. The pattern "5*.json" was used for testing.
+
+This is the computer time used for the process, not the actual run time.
+ * pyproj driver testing 5 seconds
+ * cs2cs driver testing - using Python 2.7.6 - 4 min 36 seconds
+ * cs2cs driver testing - using Python 3.4.3 - 6 min 23 seconds
+
+
+
+## Random Notes #######################################################
+Roundtrip testing has been fixed, it now checks both resulting coordinates.
+
+Some tests in the 5100/5200 series have not been converted. The most of
+the 3d coordinate test in the 5200 series have not been converted.
+
+This is designed to use decimal degrees over Sexagesimal degree or degree
+minutes seconds, which is a decision that might need to be revisited.
+Decimal degrees were chosen because it was easier interface with the
+Python pyproj library. This might be the cause of some testing tolerance
+issues.
+
+pyproj and cs2cs drivers do not quite work the same. Different tests
+fail depending on the driver.
+
+Other drivers could be written to interface with other code.
+
+There could be some precision issues with cs2cs, perhaps some adjustment
+of the "-f format" parameter could help. This could be done based either
+on expected output or extra info from the JSON file.
+
+A TODO list is located source code.
+
+Conversion tests the output coordinate, causing 2 test results per
+coordinate pair.
+
+Roundtrip tests the input coordinate and the output coordinate of each
+ pair, causing 4 test results per coordinate pair.
diff --git a/test/gigs/test_json.py b/test/gigs/test_json.py
new file mode 100644
index 00000000..2c1f9f02
--- /dev/null
+++ b/test/gigs/test_json.py
@@ -0,0 +1,528 @@
+# This is a framework to test GIGS, Geospatial Integrity of geoscience
+# software. Which is published by International Association of Oil & Gas
+# Producers as a resources for how geospatial software should give consistent
+# and expected results.
+#
+# This could be expanded to be used with other testing frameworks.
+#
+# - See more at: http://www.iogp.org/Geomatics#2521115-gigs
+#
+
+#
+# == REQUIREMENTS ==
+# - Python 2.7 or 3.3+
+# - pyproj (optional but highly recommended) - read TESTNOTES.md
+
+# == TODO list ==
+# * Python 3 was not running all the test cases seemingly due to how it uses
+# an iterable version of zip. -- FIXED
+# * driver for proj4js (javascript)
+# - could be written using nodejs using subprocess
+# - could use PyExecJS (currently not advanced enough) or PyV8
+# * call cs2cs directly
+# - WORKING but 2 orders of magnitude slower than pyproj, and
+# potentially insecure shelling?
+
+
+import argparse
+import glob
+import json
+import logging
+import os
+import platform
+import sys
+import subprocess
+from tempfile import NamedTemporaryFile
+
+# only for debug
+# import pdb
+
+try:
+ import pyproj
+except ImportError as e_pyproj:
+ pass
+
+
+PY_MAJOR = sys.version_info[0]
+PY2 = (PY_MAJOR == 2)
+
+# Python 2/3 Compatibility code ########################################
+if PY_MAJOR >= 3:
+ # list-producing versions of the major Python iterating functions
+ # lzip acts like Python 2.x zip function.
+ # taken from Python-Future http://python-future.org/
+ # future.utils.lzip()
+
+ def lzip(*args, **kwargs):
+ return list(zip(*args, **kwargs))
+
+else:
+ from __builtin__ import zip as lzip
+########################################################################
+
+
+def list_count_matches(coords, ex_coords, tolerance):
+ """
+ counts coordinates in lists that match and don't match.
+ assumes that lists are the same length (they should be)
+
+ coords - coordinates
+ ex_cords - expected cooridnate
+ tolerance - difference allowed between the coordinates
+
+ returns tuple (matches, non_matches)
+ """
+ matches, non_matches = 0, 0
+ iter_ex_coords = iter(ex_coords)
+ for c in coords:
+ ex_coord = next(iter_ex_coords)
+ if match_func(c, ex_coord, tolerance):
+ matches = matches + 1
+ else:
+ non_matches = non_matches + 1
+
+ return (matches, non_matches)
+
+
+def match_func(cor, exc, tolerance):
+ """
+ Check if coordinate matches expected coordinate within a given tolerance.
+
+ cor - coordinate
+ exc - expected coordinate
+ tolerance - error rate
+ float coordinate elements will be checked based on this value
+ list/tuple coordinate elements will be checked based on the
+ corresponding values
+ return bool
+ """
+ if len(exc) == 3:
+ # coordinate triples
+ coord_diff = abs(cor[0] - exc[0]), abs(cor[1] - exc[1]), abs(cor[2] - exc[2])
+ if isinstance(tolerance, float):
+ matching = coord_diff < (tolerance, tolerance, tolerance)
+ elif isinstance(tolerance, (list, tuple)): # FIXME is list's length atleast 3?
+ matching = coord_diff < tuple(tolerance)
+ else:
+ # assume coordinate pairs
+ coord_diff = abs(cor[0] - exc[0]), abs(cor[1] - exc[1])
+ if isinstance(tolerance, float):
+ matching = coord_diff < (tolerance, tolerance)
+ elif isinstance(tolerance, (list, tuple)): # FIXME is list's length atleast 2?
+ matching = coord_diff < tuple(tolerance)
+
+ if matching is False:
+ logging.info('non-match, calculated coordinate: {c1}\n'
+ 'expected coordinate: {c2}\n difference:{res}\n'
+ 'tolerance: {tol}\n'
+ ''.format(c1=cor, c2=exc, res=coord_diff, tol=tolerance))
+
+ return matching
+
+
+# parse multiple tests and call TransformTest
+# TODO: needs some awareness of the driver, so driver_info function in
+# TranformTest classes can be called, could allow a dummy instance of
+# Driver and move all the initization code to another function? Or allow
+# dipatch function to check if everything is in order do a transform.
+# Not an elegant solution.
+class TransformRunner(object):
+ def __init__(self, fn_pattern, driver, **kwargs):
+ """
+ fn_pattern - file name or file name pattern (example "*.json")
+ driver - this is the type of driver to run
+ kwargs - parameters passed to the respective driver TransfromTest class
+ """
+ self.driver = driver
+ json_input = []
+ if os.path.isfile(fn_pattern):
+ with open(fn_pattern, 'rt') as fp:
+ logging.info("Reading json from file '{0}'".format(fn_pattern))
+ json_dict = json.load(fp, parse_int=float)
+ json_dict['filename'] = fn_pattern
+ json_input = [json_dict]
+ # is this a glob/fnmatch style pattern?
+ elif '*' in fn_pattern or '?' in fn_pattern:
+ filename_iter = glob.iglob(fn_pattern)
+ for filename in filename_iter:
+ with open(filename, 'rt') as fp:
+ logging.info("Reading json from file '{0}'".format(filename))
+ j_input = json.load(fp, parse_int=float)
+ if isinstance(j_input, dict):
+ j_input['filename'] = filename
+ json_input.append(j_input)
+ elif isinstance(j_input, list):
+ # FIXME could build a new list with the filename dict
+ logging.warning("json file is a list, not quite supported - FIXME")
+ json_input.extend(j_input)
+ else:
+ raise ValueError('json input in an unknown type')
+ else:
+ raise TypeError('filename_pattern must be a valid filename or pattern')
+
+ self.runs = json_input
+ self.kwargs = kwargs
+
+ def dispatch(self):
+ """
+ main loop to run all the tests
+ """
+ total_matches, total_no_matches, success_code = 0, 0, 0
+ for run in self.runs:
+ if self.driver == 'pyproj':
+ trantst = TransformTestPyProj(run, self.kwargs)
+ elif self.driver == 'cs2cs':
+ trantst = TransformTestCs2cs(run, self.kwargs)
+ else:
+ raise ValueError("driver {0} is not a valid test driver".format(self.driver))
+ matches, no_matches = trantst.dispatch()
+ total_matches += matches
+ total_no_matches += no_matches
+ success_code += no_matches
+
+ return total_matches, total_no_matches, success_code
+
+
+# parses and runs a single GIGS test case
+class TransformTestBase(object):
+ """
+ TransformTest common code for testing framework.
+ """
+ def __init__(self, json_dict, kwargs):
+ """
+ json_dict must dictonary from json
+ """
+ if not isinstance(json_dict, dict): # must be a json dictionary
+ raise TypeError("json_source must be a dictionary type not {0}"
+ "".format(type(json_dict)))
+
+ # require keys 'coordinates' and 'projections'
+ if 'coordinates' not in json_dict:
+ raise KeyError("TransformTest.__init__ requires 'coordinates' key"
+ " in json source input")
+
+ if 'projections' not in json_dict:
+ raise KeyError("TransformTest.__init__ requires 'projections' key"
+ " in json source input")
+
+ logging.info('Number of coordinate pairs to test: {0}'.format(
+ len(json_dict['coordinates'])))
+
+ self.run_test_args = kwargs.get('test')
+
+ # unpack coordinates
+ self.coords_left, self.coords_right = lzip(*json_dict['coordinates'])
+
+ self.testobj = json_dict
+
+ def runner_conversion(self, **kwargs):
+ """
+ tests a single conversion
+
+ return tuple (num_matches, num_no_matches)
+ """
+
+ # get tolerance, if not set tolerance to a precise value
+ tolerances = kwargs.get('tolerances', [0.0000000000001, 0.0000000000001])
+
+ test_right = self.transform(self.proj_left, self.proj_right, self.coords_left)
+ test_left = self.transform(self.proj_right, self.proj_left, self.coords_right)
+
+ results1 = list_count_matches(test_right, self.coords_right, tolerances[1])
+ results2 = list_count_matches(test_left, self.coords_left, tolerances[0])
+
+ return (results1[0] + results2[0], results1[1] + results2[1])
+
+ def runner_roundtrip(self, **kwargs):
+ """
+ rountrip test using pyproj.
+
+ times - number roundtrips to perform
+ tolerance - TODO explain the structure of why this is a list
+
+ return tuple (num_matches, num_no_matches)
+ """
+ times = None
+
+ # get variables
+ times = int(kwargs.get('times'))
+ tolerances = kwargs.get('tolerances', [0.0000000000001, 0.0000000000001])
+
+ # keep the transformations separate, so as to not cross contaminate the
+ # results.
+
+ # process roundtrip for the left coordinates - Test 1
+ test1_left = self.coords_left
+ for i in range(times):
+ test1_right = self.transform(self.proj_left, self.proj_right, test1_left)
+ test1_left = self.transform(self.proj_right, self.proj_left, test1_right)
+
+ # process roundtrip for the right coordinates - Test 2
+ test2_right = self.coords_right
+ for i in range(times):
+ test2_left = self.transform(self.proj_right, self.proj_left, test2_right)
+ test2_right = self.transform(self.proj_left, self.proj_right, test2_left)
+
+ results = (
+ list_count_matches(test1_right, self.coords_right, tolerances[1]),
+ list_count_matches(test1_left, self.coords_left, tolerances[0]),
+ list_count_matches(test2_right, self.coords_right, tolerances[1]),
+ list_count_matches(test2_left, self.coords_left, tolerances[0])
+ )
+
+ return tuple(sum(x) for x in lzip(*results))
+
+ # TODO: Untested. Not useful for GIGS.
+ def runner_onedirection(self, **kwargs):
+ """
+ Perform a conversion in only one direction, not both. Useful for
+ testing convergence of a coordinate system.
+
+ return tuple (num_matches, num_no_matches)
+ """
+ # get variables
+ direction = kwargs.get('direction')
+ # get tolerance, if not set tolerance to a precise value
+ tolerances = kwargs.get('tolerances', [0.0000000000001, 0.0000000000001])
+
+ if direction not in ('left-to-right', 'right-to-left'):
+ raise ValueError('direction must be left-to-right or right-to-left, not: {0}'.format(direction))
+
+ if direction == 'left-to-right':
+ test_dest_right = self.transform(self.proj_left, self.proj_right, self.coords_left)
+ results = list_count_matches(test_dest_right, self.coords_right, tolerances[1])
+ elif direction == 'right-to-left':
+ test_dest_left = self.transform(self.proj_right, self.proj_left, self.coords_right)
+ results = list_count_matches(test_dest_left, self.coords_left, tolerances[0])
+ else:
+ raise RuntimeError('Unexpected state of value direction "{0}" in runner_onedirection'.format(direction))
+
+ return results
+
+ # placeholder function
+ def transform(self, src_crs, dst_crs, coords):
+ pass
+
+ def dispatch(self):
+ """
+ main
+ """
+ matches, no_matches = 0, 0
+
+ # convert to tuple
+ run_tests = self.run_test_args,
+ if self.run_test_args is None:
+ run_tests = ('conversion', 'roundtrip')
+
+ logging.info('Testing: {0}'.format(self.testobj['description']))
+
+ for test in self.testobj['tests']:
+ m_res, nm_res = None, None
+ if test['type'] not in run_tests:
+ # skip test
+ continue
+
+ if test['type'] == 'conversion':
+ m_res, nm_res = self.runner_conversion(**test)
+ elif test['type'] == 'roundtrip':
+ m_res, nm_res = self.runner_roundtrip(**test)
+
+ if nm_res == 0:
+ logging.info(" {0}... All {1} match.".format(test['type'], m_res))
+ else:
+ logging.info(" {0}... matches: {1} doesn't match: {2}"
+ "".format(test['type'], m_res, nm_res))
+
+ matches += m_res
+ no_matches += nm_res
+
+ return matches, no_matches
+
+ # placeholder function -- TODO How should this be exposed?
+ def driver_info(self):
+ return "base class"
+
+
+class TransformTestPyProj(TransformTestBase):
+ """
+ TransformTest uses pyproj to run tests.
+ """
+ def __init__(self, json_dict, kwargs):
+ # call super class
+ TransformTestBase.__init__(self, json_dict, kwargs)
+
+ # setup projections
+ try:
+ self.proj_left = pyproj.Proj(json_dict['projections'][0], preserve_units=True)
+ except RuntimeError as e:
+ logging.error('pyproj raised a RuntimeError for projection string:'
+ ' "{0}"'.format(json_dict['projections'][0]))
+ raise RuntimeError(e)
+ try:
+ self.proj_right = pyproj.Proj(json_dict['projections'][1], preserve_units=True)
+ except RuntimeError as e:
+ logging.error('pyproj raised a RuntimeError for projection string:'
+ ' "{0}"'.format(json_dict['projections'][1]))
+ raise RuntimeError(e)
+
+ def transform(self, src_crs, dst_crs, coords):
+ return self.pyproj_transform_ex(src_crs, dst_crs, coords)
+
+ def driver_info(self):
+ return 'pyproj {0}\nproj4 {1}\n'.format(
+ pyproj.__version__, self.proj4_version())
+
+ # TODO: currently dead code, unneeded for the pyproj repo. version
+ # as of 2016-05-24.
+ def proj4_version():
+ """
+ Gives the proj.4 library's version number. (requires pyproj)
+ returns string, so proj.4 version 4.9.3 will return "4.9.3"
+ """
+ try:
+ return pyproj.proj_version_str
+ except AttributeError:
+ # for pyproj versions 1.9.5.1 and before, this will run
+ # Get PROJ4 version in a floating point number
+ proj4_ver_num = pyproj.Proj(proj='latlong').proj_version
+
+ # convert float into a version string (4.90 becomes '4.9.0')
+ return '.'.join(str(int(proj4_ver_num * 100)))
+
+ def pyproj_transform_ex(self, proj_src, proj_dst, coords):
+ """
+ wrapper for pyproj.transform to do all the zipping of the coordinates
+
+ returns coordinate list
+ """
+ # are these coordinate triples?
+ if len(coords[0]) == 3:
+ xi, yi, zi = lzip(*coords)
+ xo, yo, zo = pyproj.transform(proj_src, proj_dst, xi, yi, zi)
+ return lzip(xo, yo, zo)
+
+ # assume list of coordinate pairs
+ xi, yi = lzip(*coords)
+ xo, yo = pyproj.transform(proj_src, proj_dst, xi, yi)
+ return lzip(xo, yo)
+
+
+class TransformTestCs2cs(TransformTestBase):
+ def __init__(self, json_dict, kwargs):
+ # call super class
+ TransformTestBase.__init__(self, json_dict, kwargs)
+
+ # copy proj4 projection strings
+ self.proj_left, self.proj_right = json_dict['projections']
+
+ self.exe = kwargs.get('exe', 'cs2cs')
+
+ # when the exe is not the default, check if the file exists
+ if self.exe == 'cs2cs' or not os.path.isfile(self.exe):
+ raise RuntimeError('cannot find cs2cs executable file: {}'
+ ''.format(self.exe))
+
+ def transform(self, src_crs, dst_crs, coords):
+ # send points to a temporary file
+ # TODO Should this use with statement?
+ tmpfn = NamedTemporaryFile(mode='w+t', delete=False)
+ for point in coords:
+ # convert list of float values into a list of strings
+ point = [str(e) for e in point]
+ # print('POINT: {}'.format(point))
+ tmpfn.write(' '.join(point) + '\n')
+
+ tmpfn.flush()
+ command = "{exe} {proj_from} +to {proj_to} -f %.13f {filename}".format(
+ exe=self.exe, proj_from=src_crs, proj_to=dst_crs, filename=tmpfn.name)
+ tmpfn.close()
+
+ logging.debug('Running Popen on command "{0}"'.format(command))
+
+ if platform.system() == 'Windows':
+ shell = False
+ else:
+ # shell=True according to the subprocess documentation has some
+ # security implications
+ # Linux seems to need this
+ shell = True
+
+ # call cs2cs
+ outs = subprocess.check_output(command, shell=shell)
+
+ # delete temporary filename
+ os.unlink(tmpfn.name)
+
+ # print('RESULTS OUTS: {}\n'.format(outs))
+ # print('RESULTS ERRS: {}\n'.format(errs))
+
+ # outs
+ # print('RESULTS LINE: {}\n'.format([line.split() for line in outs]))
+ coords = []
+
+ # process output
+ for line in outs.splitlines():
+ # print("LINE: {}".format(line))
+ coord = []
+ for e in line.split():
+ coord.append(float(e))
+
+ coords.append(coord)
+
+ # print('COORDS: {}\n'.format(coords))
+ return coords
+
+ def driver_info(self):
+ shell = True # see transform() for info.
+ if platform.system() == 'Windows':
+ shell = False
+
+ outs = subprocess.check_output(self.exe, shell=shell)
+ return 'PROJ.4 version: ' + outs.splitlines()[0] + '\n'
+
+
+if __name__ == '__main__':
+ # logging.basicConfig(level=logging.DEBUG)
+ logging.basicConfig(level=logging.INFO)
+
+ parser = argparse.ArgumentParser(description='Test PROJ.4 using a JSON file.')
+ parser.add_argument('-e', '--exe',
+ help="executable with path default: 'cs2cs' (needed for cs2cs driver)")
+
+ parser.add_argument('-d', '--driver', default='pyproj',
+ help='driver to test')
+
+ parser.add_argument('-t', '--test',
+ help='only run these test types (valid values: conversion or roundtrip)')
+
+ # get json file names and/or glob patterns
+ parser.add_argument('testnames_pat_json', nargs=argparse.REMAINDER,
+ help='single filename or glob wildcard patern')
+
+ args = parser.parse_args()
+
+ # test that the arguments have sensible values
+ if args.driver not in ('cs2cs', 'pyproj'):
+ raise ValueError('driver "{}" is not a valid driver'.format(args.driver))
+
+ logging.info('Python {}'.format(sys.version))
+ logging.info('using driver: {}'.format(args.driver))
+
+ # there could be a version command for the TransformRunner TODO
+
+ match_results, nonmatch_results, success_code = 0, 0, 0
+ for test_name in args.testnames_pat_json:
+ tratst = TransformRunner(test_name, driver=args.driver, exe=args.exe,
+ test=args.test)
+ m_res, nm_res, success_cd = tratst.dispatch()
+ match_results += m_res
+ nonmatch_results += nm_res
+ success_code += success_cd
+
+ logging.info("----------------------------------------")
+ logging.info("TOTAL: matches: {0} non-matching: {1}"
+ "".format(match_results, nonmatch_results))
+
+ # exit status code is the number of non-matching results
+ # This should play nicely with Travis and similar testing.
+ sys.exit(success_code)