proj4rb 3.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +32 -15
  3. data/README.rdoc +82 -44
  4. data/Rakefile +27 -27
  5. data/lib/api/api.rb +117 -118
  6. data/lib/api/api_5_0.rb +337 -300
  7. data/lib/api/api_5_1.rb +6 -6
  8. data/lib/api/api_5_2.rb +4 -4
  9. data/lib/api/api_6_0.rb +118 -14
  10. data/lib/api/api_6_1.rb +4 -4
  11. data/lib/api/api_6_2.rb +9 -6
  12. data/lib/api/api_6_3.rb +6 -0
  13. data/lib/api/api_7_0.rb +69 -0
  14. data/lib/api/api_7_1.rb +73 -0
  15. data/lib/api/api_7_2.rb +14 -0
  16. data/lib/api/api_8_0.rb +6 -0
  17. data/lib/api/api_8_1.rb +24 -0
  18. data/lib/api/api_8_2.rb +6 -0
  19. data/lib/api/api_9_1.rb +7 -0
  20. data/lib/api/api_9_2.rb +9 -0
  21. data/lib/api/api_experimental.rb +201 -0
  22. data/lib/proj/area.rb +74 -32
  23. data/lib/proj/axis_info.rb +44 -0
  24. data/lib/proj/bounds.rb +13 -0
  25. data/lib/proj/context.rb +175 -28
  26. data/lib/proj/conversion.rb +91 -0
  27. data/lib/proj/coordinate.rb +281 -197
  28. data/lib/proj/coordinate_operation_mixin.rb +381 -0
  29. data/lib/proj/coordinate_system.rb +137 -0
  30. data/lib/proj/crs.rb +672 -204
  31. data/lib/proj/crs_info.rb +47 -0
  32. data/lib/proj/database.rb +305 -0
  33. data/lib/proj/datum.rb +32 -0
  34. data/lib/proj/datum_ensemble.rb +34 -0
  35. data/lib/proj/ellipsoid.rb +77 -41
  36. data/lib/proj/error.rb +62 -9
  37. data/lib/proj/file_api.rb +166 -0
  38. data/lib/proj/grid.rb +121 -0
  39. data/lib/proj/grid_cache.rb +64 -0
  40. data/lib/proj/grid_info.rb +19 -0
  41. data/lib/proj/network_api.rb +92 -0
  42. data/lib/proj/operation.rb +42 -42
  43. data/lib/proj/operation_factory_context.rb +137 -0
  44. data/lib/proj/parameter.rb +38 -0
  45. data/lib/proj/parameters.rb +107 -0
  46. data/lib/proj/pj_object.rb +670 -80
  47. data/lib/proj/pj_objects.rb +45 -0
  48. data/lib/proj/prime_meridian.rb +65 -39
  49. data/lib/proj/projection.rb +698 -207
  50. data/lib/proj/session.rb +47 -0
  51. data/lib/proj/strings.rb +32 -0
  52. data/lib/proj/transformation.rb +101 -60
  53. data/lib/proj/unit.rb +108 -53
  54. data/lib/proj.rb +114 -9
  55. data/proj4rb.gemspec +5 -5
  56. data/test/abstract_test.rb +23 -1
  57. data/test/context_test.rb +172 -82
  58. data/test/conversion_test.rb +368 -0
  59. data/test/coordinate_system_test.rb +144 -0
  60. data/test/crs_test.rb +770 -71
  61. data/test/database_test.rb +360 -0
  62. data/test/datum_ensemble_test.rb +65 -0
  63. data/test/datum_test.rb +55 -0
  64. data/test/ellipsoid_test.rb +64 -18
  65. data/test/file_api_test.rb +66 -0
  66. data/test/grid_cache_test.rb +72 -0
  67. data/test/grid_test.rb +141 -0
  68. data/test/network_api_test.rb +45 -0
  69. data/test/operation_factory_context_test.rb +201 -0
  70. data/test/parameters_test.rb +40 -0
  71. data/test/pj_object_test.rb +179 -0
  72. data/test/prime_meridian_test.rb +76 -0
  73. data/test/proj_test.rb +46 -4
  74. data/test/projection_test.rb +646 -222
  75. data/test/session_test.rb +78 -0
  76. data/test/transformation_test.rb +149 -7
  77. data/test/unit_test.rb +57 -28
  78. metadata +51 -13
  79. data/lib/api/api_4_9.rb +0 -31
  80. data/lib/proj/config.rb +0 -70
  81. data/lib/proj/point.rb +0 -72
  82. data/test/prime_meridians_test.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d2946731ccd3cf4e96e214fce1e8e3c7fc46313f5f1d1fcc119c84e9b88f26f
4
- data.tar.gz: 17ca8b08ed1b03be5d910ba77013b7028d88e45160b352764619799f7f156887
3
+ metadata.gz: dee29581eba9124621bcf04204e9d224e39bba0482caa174fc57014c49a37be7
4
+ data.tar.gz: 46529fe96f62f6a94cc26baf8f1a695e38ff9099b16c52c58b503380d8773594
5
5
  SHA512:
6
- metadata.gz: 6a23e8938aa5d6289dabe4b1f0e5ad2aa204281f6ff2f0073fcbc20b6d404bc6b265120cb0c22561ad68338248a16959fd36873777cdbe7ebae4cbf86258ad2f
7
- data.tar.gz: 78b42798c55214f7d73df85575b5d6a4a64283ab51583656a9441a725c369fde5a7b12c36944a8dd0a66c67bdf9ef6b48e189e34a3c6d280f11e0adca4116835
6
+ metadata.gz: 145525e768e261cc293be7ec9851c6e19590f40572de114262da5b4c94eb9baec8296131071eee3438de0df7a18e7ace0981f14c2b6b0079b37739d852879833
7
+ data.tar.gz: f79972d062f3ce4f3f03e8ba2d67b908a928407b5cec336cfc79c83dca745e310c06d339d78d506bf419eeec3a8bd6c3e543aba950c37f5537edfba625f9da84
data/ChangeLog CHANGED
@@ -1,71 +1,88 @@
1
- 3.0.0 (September 26, 2021)
1
+ 4.1.0 - March 12, 2023
2
+ ======================
3
+ * Fix YARD warnings
4
+ * Fix YARD types to match RBS types
5
+ * Don't use type as attribute or method name to avoid conflicts with RBS
6
+
7
+ 4.0.0 - March 12, 2023
8
+ ======================
9
+ * Support Proj 9
10
+ * Add support for missing APIs - the gem now provides almost 100% coverage
11
+ * Add support for Proj experimental APIs including the creation of projection conversions
12
+ * Add/updated support for a number of ISO 19111 classes, including PrimeMeridian, Ellipsoid,
13
+ Datum, DatumEnsemble, CoordinateOperation and Parameters
14
+ * Greatly improved documentation (https://rubydoc.info/github/cfis/proj4rb)
15
+ * Remove old Proj 4.9 support
16
+ * Note this release does have some API changes. These include the removal of Proj 4.9 Point and Coordinate classes, changes to the PrimeMeridian class and changes to the Ellipsoid class. These changes should not impact most users.
17
+
18
+ 3.0.0 - September 26, 2021
2
19
  =========================
3
20
  * Support Proj 8 which removes the old Proj API (Charlie Savage)
4
21
  * Support newer versions of FFI which remove support for returning strings from callbacks (Charlie Savage)
5
22
 
6
- 2.2.2 (January 10, 2020)
23
+ 2.2.2 - January 10, 2020
7
24
  =========================
8
- * Move proj_context_set_autoclose_database to api 6.2 (Jan Klimke)
25
+ * Move proj_context_set_autoclose_database to api 6.2 - Jan Klimke)
9
26
  * Improve search path generation code (Charlie Savage)
10
27
 
11
- 2.2.1 (January 8, 2020)
28
+ 2.2.1 - January 8, 2020
12
29
  =========================
13
30
  * Move proj_as_projjson from version 6.0 to 6.2 api (Charlie Savage)
14
31
  * Improve search path generation code (Charlie Savage)
15
32
 
16
- 2.2.0 (January 7, 2020)
33
+ 2.2.0 - January 7, 2020
17
34
  =========================
18
35
  * Fix broken gem - was not including all api files (Jan Klimke)
19
36
  * Add paths on MacOS when using Brew (Jan Klimke)
20
37
  * Various code cleanups (Charlie Savage)
21
38
 
22
- 2.1.0 (January 5, 2020)
39
+ 2.1.0 - January 5, 2020
23
40
  =========================
24
41
  * Set Ruby 2.4.1 to be the minimum allowed version (Samuel Williams)
25
42
  * Fix incorrect use of context, reduce warnings when running tests (Samuel Williams)
26
43
  * Fix `bundle exec rake test` (Samuel Williams)
27
44
  * Add 2.4.1 to the travis test matrix (Samuel Williams)
28
45
 
29
- 2.0.0 (December 30, 2019)
46
+ 2.0.0 - December 30, 2019
30
47
  =========================
31
- - Full rewrite to support API changes in Proj versions 5 and 6 (Charlie Savage)
48
+ - Full rewrite to support API changes in Proj versions 5 and 6 - Charlie Savage)
32
49
  - As part of rewrite switch bindings to use FFI versus a C extension (Charlie Savage)
33
50
  - Split Ruby code into multiple files based on classes (Charlie Savage)
34
51
  - Add in a bunch of new classes including Context, Crs, Coordinate, Ellipsoid, Prime Meridian and Transform (Charlie Savage)
35
52
  - Deprecate Projection and Point - these will stop working with Proj 7 since the use an older deprecated API (Charlie Savage)
36
53
 
37
- 1.0.0 (December 14, 2014)
54
+ 1.0.0 - December 14, 2014
38
55
  =========================
39
56
  - Calling this 1.0.0 since its a very stable gem (Charlie Savage)
40
57
 
41
- 0.4.3 (August 30, 2011)
58
+ 0.4.3 - August 30, 2011
42
59
  =========================
43
60
  - Remove reference to now private projects.h header
44
61
 
45
- 0.4.2 (August 15, 2011)
62
+ 0.4.2 - August 15, 2011
46
63
  =========================
47
64
  - Minor build tweak to support MSVC++
48
65
 
49
- 0.4.1 (July 30, 2011)
66
+ 0.4.1 - July 30, 2011
50
67
  =========================
51
68
  - Search first for binaries when using windows gems
52
69
  - Add # encoding to test files
53
70
  - Reformat tests files to use standard ruby 2 space indenting
54
71
 
55
- 0.4.0 (July 30, 2011)
72
+ 0.4.0 - July 30, 2011
56
73
  =========================
57
74
  - Update to compile on Ruby 1.9.* (Fabio Renzo Panettieri)
58
75
  - Add in gemspec file (Charlie Savage)
59
76
  - Add rake-compiler as development dependency, remove older MinGW build system (Charlie Savage)
60
77
  - Move to GitHub (Charlie Savage)
61
78
 
62
- 0.3.1 (December 23, 2009)
79
+ 0.3.1 - December 23, 2009
63
80
  =========================
64
81
  - Update extconf.conf file to be more flexible to make it easier to build
65
82
  on OS X when using MacPorts
66
83
  - Updated windows binary to link against proj4.7
67
84
 
68
- 0.3.0 (August 14, 2008)
85
+ 0.3.0 - August 14, 2008
69
86
  =========================
70
87
  - Removed Proj4::UV class which was previously deprecated
71
88
  - New build infrastructure for Windows (Charlie Savage)
data/README.rdoc CHANGED
@@ -3,7 +3,9 @@ This gem provides Ruby bindings for the Proj Library (https://proj.org). The Pro
3
3
  between a number of different coordinate systems and projections.
4
4
 
5
5
  == Documentation
6
- Besides this readme file, reference documentation is available at https://rubydoc.info/github/cfis/proj4rb.
6
+ Reference documentation is available at https://rubydoc.info/github/cfis/proj4rb.
7
+
8
+ Examples can be found in this README file as well as in the Examples file. In addition, the test suite has exapmles of calling almost every API so when in doubt take a look at them!
7
9
 
8
10
  == Installation
9
11
  First install the gem in the usual manner:
@@ -23,9 +25,9 @@ If you are using the old Proj4 namespace, then you can do this:
23
25
 
24
26
  require 'proj4'
25
27
 
26
- === Crs
27
- If you are using Proj 6, or newer, create a coordinate system. To create a coordinate system, you can use CRS codes,
28
- well-known text (WKT) strings or old-style Proj4 strings (which are deprecated).
28
+ === CRS
29
+ To create a coordinate system, you can use CRS codes, well-known text (WKT) strings
30
+ or old-style Proj strings (which are deprecated).
29
31
 
30
32
  crs1 = Proj::Crs.new('EPSG:4326')
31
33
 
@@ -64,14 +66,14 @@ After you have created two coordinate systems, you can then create a transformat
64
66
  convert coordinates from the "3-degree Gauss-Kruger zone 3" coordinate system to WGS84 (one version of lat-long)
65
67
  first create a transformation:
66
68
 
67
- crs_gk = Proj::Crs.new('epsg:31467')
68
- crs_wgs84 = Proj::Crs.new('epsg:4326')
69
+ crs_gk = Proj::Crs.new('EPSG:31467')
70
+ crs_wgs84 = Proj::Crs.new('EPSG:4326')
69
71
  transform = Proj::Transformation.new(crs_gk, crs_wgs84)
70
72
 
71
73
  Alternatively, or if you are using Proj 5, you can create a transformation without first
72
74
  creating Crs instances. Instead, pass the EPSG information directly to the transformation:
73
75
 
74
- transform = Proj::Transformation.new('epsg:31467', 'epsg:4326')
76
+ transform = Proj::Transformation.new('EPSG:31467', 'EPSG:4326')
75
77
 
76
78
  Once you've created the transformation, you can tranform coordinates using either
77
79
  the +forward+ or +inverse+ methods. The forward transformation looks like this:
@@ -94,6 +96,25 @@ While the inverse transformation looks like this:
94
96
  assert_in_delta(0, to.z, 0.01)
95
97
  assert_in_delta(0, to.t, 0.01)
96
98
 
99
+ === Coordinate Operations
100
+ Transformations are a type of Coordinate Operation. PROJ divides coordinate operations into three groups:
101
+
102
+ * Conversions
103
+ * Projections
104
+ * Transformations
105
+
106
+ Conversions are coordinate operations that do not exert a change in reference frame. The Ruby bindings support these via the Conversion class. See https://proj.org/operations/conversions/index.html for more information.
107
+
108
+ Projections are cartographic mappings of the sphere onto the plane. Technically projections are conversions (according to ISO standards), but PROJ distinguishes them from conversions. The Ruby bindings support these
109
+ via the Projection module which has methods to create many common projections. A list can be found at https://proj.org/operations/projections/index.html.
110
+
111
+ Transformations are coordinate operations that do cause a change in reference frames. The Ruby bindings support these via the Transformation class.
112
+
113
+ For more information see https://proj.org/operations/index.html
114
+
115
+ === Operation Factory
116
+ The OperationFactoryContext class can be used to build coordinate operations between two CRSes. This is done by first creating a factory and setting appropiate filters. These include spatial filters, accuracy filters, grid availability filters, etc. Once filters are set, then the factory can be queried for a list of possible conversions. For examples, please see the operation_factory_context_test.rb file.
117
+
97
118
  === Coordinate
98
119
  Notice the examples above transform Coordinate objects. A Coordinate consists
99
120
  of up to four double values to represent three directions plus time. In general
@@ -104,6 +125,21 @@ you will need to fill out at least the first two values:
104
125
 
105
126
  Lam is longitude and phi is latitude.
106
127
 
128
+ === Axis Order
129
+ By default tranformations accept coordinates expressed in the units and axis order of the source CRS and return transformed coordinates in the units and axis order of the target CRS.
130
+
131
+ For most geographic CRSes, the units will be in degrees. For geographic CRSes defined by the EPSG authority, the order of coordinates is latitude and then longitude.
132
+
133
+ For projected CRSes, the units will vary (metre, us-foot, etc.). For projected CRS defined by the EPSG authority, and with EAST / NORTH directions, the order might may be east and then north or north and then east.
134
+
135
+ If you prefer to work with a uniform axis order, regardless of the axis orders mandated by the source and target CRSes, then call the Context#normalize_for_visualization method:
136
+
137
+ normalized = transform.normalize_for_visualization
138
+
139
+ The normalized transformation will return output coordinates in longitude, latitude order for geographic CRSes and easting, northing for most projected CRSes.
140
+
141
+ For more information see https://proj.org/faq.html#why-is-the-axis-ordering-in-proj-not-consistent.
142
+
107
143
  === Context
108
144
  Contexts are used to support multi-threaded programs. The bindings expose this object via Context.current
109
145
  and store it using thread local storage. Use the context object to access error codes, set proj4
@@ -112,48 +148,50 @@ compatability settings, set the logging level and to install custom logging code
112
148
  Both Crs and Transformation objects take a context object in their constructors. If none is passed, they default
113
149
  to using Context.current
114
150
 
115
- === Projection
116
- If you are using Proj 4, then instead of using Coordinates, Crses and Tranformations you need to us Points and Projections.
117
- Those are deprecated classes but will continue to work with Proj version 7 and older. Please refer to the documentation
118
- for more information.
151
+ == Network Access
152
+ Proj supports downloading grid files on demand if network access is enabled (it is disabled by default). To enable network use the method Context#network_enabled=. To specify the url endpoint use Context#url=. Advanced users can replace Proj's networking code, which uses libcurl, with their own implementation. To do this see the NetworkApi class.
153
+
154
+ Downloaded grids are cached in a sqlite file named cache.db. To specify the location, size and other characteristics of the cache file refer to the GridCache class which is accessible via Context#cache. By default the cache size is 300MB. Caching is on by default but can be disabled via GridCache#enabled=.
119
155
 
120
156
  == Error handling
121
157
  When an error occurs, a Proj::Error instance will be thrown with the underlying message provided
122
158
  from the Proj library.
123
159
 
124
- == Finding Proj Files (LIB_PROJ)
160
+ == Finding Proj Library (PROJ_LIB_PATH)
161
+ proj4rb will search in a number of well-known locations for the libproj shared library. You
162
+ can override this by specifying the full path to the library using the PROJ_LIB_PATH
163
+ environmental variable.
164
+
165
+ == Finding Proj Files (PROJ_DATA)
125
166
  Starting with version 6, Proj stores its information (datums, ellipsoids, prime meridians, coordinate systems,
126
- units, etc) in a sqlite file called proj.db. If Proj cannot find its database, then the Ruby bindings will
127
- search for it in some well-known locations. Failing that, the Ruby bindings will raise an exception.
128
- In this case, set the environmental variable PROJ_LIB to point at the folder that contains the proj.db file.
129
- Note PROJ_LIB must be set by whatever launches your Ruby program. The Ruby program itself cannot set this
130
- variable and have it work correctly (at least not on windows).
131
-
132
- == Backwards Compatibility
133
- Proj versions 5 and 6 are *very* different than Proj version 4. Changes are documented at
134
- https://proj.org/development/migration.html. Note that the gem should gracefully degrade
135
- (as in newer functionality stops working but older functionality keeps working) depending on
136
- the version of Proj you are using.
137
-
138
- To ensure backwards compatiblity, the Ruby bindings still include the older Point and Projection
139
- classes. However, these classes are no longer documented in this Readme because the underlying API
140
- they rely on was removed in Proj 8. So please port your code! But take note of the changes in Proj 6 described below.
141
-
142
- Proj 5 introduced the Coordinate, Crs and Tranformation APIs. However, it wasn't until Proj 6 that additional
143
- metadata APIs were added, so the amount of information about each object is somewhat limited in Proj 5.
144
-
145
- Proj 6 makes a big change compared to previous releases that is not well documented (see
146
- https://github.com/OSGeo/PROJ/pull/1182). When creating tranformations with EPSG values Proj 6
147
- will assume EPSG axis order and units (typically lat-long degree for geodetic CRS). First,
148
- this means that lat-long should usually be specified in degrees and not radians (breaking change one).
149
- Second, the axis order is likely different than what your previous code assumed (breaking change two).
150
- Note if creating transformations with the deprecated "+init=epsg:XXXX" values, Proj 6 will assume the traditional
151
- axis order and units (long-lat radians for geodetic CRS).
152
-
153
- Bottom line - when porting your code to the new Proj 6 APIs generally:
154
-
155
- * Use degrees, not radians
156
- * Swap the order of the lat and long values
167
+ units, etc) in a sqlite file called proj.db. If Proj cannot find its database an exception will be
168
+ raised. In this case, you can set the environmental variable PROJ_DATA to point to the folder that
169
+ contains the proj.db file. Note PROJ_LIB must be set by whatever launches your Ruby program.
170
+ The Ruby program itself cannot set this variable and have it work correctly (at least not on windows).
171
+
172
+ For more information see https://proj.org/resource_files.html
173
+
174
+ == Class Hierarchy
175
+ The proj4rb class hierarchy is based on Proj's class hiearchy which, in turn, is derived from http://docs.opengeospatial.org/as/18-005r5/18-005r5.html. It is:
176
+
177
+ PjObject
178
+ CoordinateOperationMixin
179
+ Conversion
180
+ Transformation
181
+ CoordinateSystem
182
+ Crs
183
+ Datum
184
+ Ellipsoid
185
+ PrimeMerdian
186
+
187
+ The PjObject class defines several methods to create new objects:
188
+
189
+ * PjObject.create
190
+ * PjObject.create_from_database
191
+ * PjObject.create_from_name
192
+ * PjObject.create_from_wkt
193
+
194
+ The methods will return instances of the correct subclass.
157
195
 
158
196
  == Tests
159
197
  Proj4rb ships with a full test suite designed to work using Proj 6. If you are using an earlier version of Proj,
@@ -162,7 +200,7 @@ then expect *many* test failures.
162
200
  == License
163
201
  Proj4rb is released under the MIT license.
164
202
 
165
- ==Authors
203
+ == Authors
166
204
  The proj4rb Ruby bindings were started by Guilhem Vellut with most of the code
167
205
  written by Jochen Topf. Charlie Savage ported the code to Windows and added
168
206
  the Windows build infrastructure. Later, he rewrote the code to support
data/Rakefile CHANGED
@@ -1,28 +1,28 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "rubygems"
4
- require "rake/testtask"
5
- require "rubygems/package_task"
6
- require "yard"
7
- require "yaml"
8
-
9
- # Read the spec file
10
- GEM_NAME = "proj4rb"
11
- spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
12
-
13
- # Setup generic gem
14
- Gem::PackageTask.new(spec) do |pkg|
15
- pkg.package_dir = 'pkg'
16
- pkg.need_tar = false
17
- end
18
-
19
- # Yard Task
20
- desc "Generate documentation"
21
- YARD::Rake::YardocTask.new
22
-
23
- # Test Task
24
- Rake::TestTask.new do |t|
25
- t.libs << "test"
26
- t.test_files = FileList['test/*_test.rb']
27
- t.verbose = true
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "rake/testtask"
5
+ require "rubygems/package_task"
6
+ require "yard"
7
+ require "yaml"
8
+
9
+ # Read the spec file
10
+ GEM_NAME = "proj4rb"
11
+ spec = Gem::Specification.load("#{GEM_NAME}.gemspec")
12
+
13
+ # Setup generic gem
14
+ Gem::PackageTask.new(spec) do |pkg|
15
+ pkg.package_dir = 'pkg'
16
+ pkg.need_tar = false
17
+ end
18
+
19
+ # Yard Task
20
+ desc "Generate documentation"
21
+ YARD::Rake::YardocTask.new
22
+
23
+ # Test Task
24
+ Rake::TestTask.new do |t|
25
+ t.libs << "test"
26
+ t.test_files = FileList['test/*_test.rb']
27
+ t.verbose = true
28
28
  end
data/lib/api/api.rb CHANGED
@@ -1,118 +1,117 @@
1
- require 'rbconfig'
2
- require 'ffi'
3
-
4
- module Proj
5
- module Api
6
- extend FFI::Library
7
-
8
- def self.library_versions
9
- [22, # 8.0 and 8.1
10
- 19, # 7.x
11
- 17, # 6.2 *and* 6.1
12
- 15, # 6.0
13
- 14, # 5.2
14
- 13, # 5.0
15
- 12, # 4.9
16
- 11] # 4.9
17
- end
18
-
19
- def self.search_paths
20
- result = case RbConfig::CONFIG['host_os']
21
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
22
- self.windows_search_paths
23
- when /darwin|mac os/
24
- self.macos_search_paths
25
- else
26
- self.linux_search_paths
27
- end
28
-
29
- result << 'libproj'
30
- result
31
- end
32
-
33
- def self.windows_search_paths
34
- self.library_versions.map do |version|
35
- "libproj-#{version}"
36
- end
37
- end
38
-
39
- def self.linux_search_paths
40
- self.library_versions.map do |version|
41
- "libproj.so.#{version}"
42
- end
43
- end
44
-
45
- def self.macos_search_paths
46
- # Mac Ports
47
- paths1 = self.library_versions.map do |version|
48
- case version
49
- when 15..17
50
- "/opt/local/lib/proj6/lib/libproj.#{version}.dylib"
51
- when 13..14
52
- "/opt/local/lib/proj5/lib/libproj.#{version}.dylib"
53
- when 11..12
54
- "/opt/local/lib/proj49/lib/libproj.#{version}.dylib"
55
- end
56
- end
57
-
58
- # Mac HomeBrew
59
- paths2 = self.library_versions.map do |version|
60
- "/usr/local/lib/libproj.#{version}.dylib"
61
- end
62
-
63
- paths1 + paths2
64
- end
65
-
66
- ffi_lib self.search_paths
67
-
68
- library = ffi_libraries.first
69
-
70
- # proj_info was introduced in Proj 5
71
- if library.find_function('proj_info')
72
- require_relative './api_5_0'
73
- PROJ_VERSION = Gem::Version.new(self.proj_info[:version])
74
- else
75
- # Load the old deprecated api
76
- require_relative './api_4_9'
77
-
78
- release = self.pj_get_release
79
- version = release.match(/\d\.\d\.\d/)
80
- PROJ_VERSION = Gem::Version.new(version)
81
- end
82
- end
83
-
84
- if Api::PROJ_VERSION < Gem::Version.new('5.0.0')
85
- def Api.proj_torad(value)
86
- value * 0.017453292519943296
87
- end
88
-
89
- def Api.proj_todeg(value)
90
- value * 57.295779513082321
91
- end
92
- end
93
-
94
- # Load the old deprecated API for versions before version 8
95
- if Api::PROJ_VERSION < Gem::Version.new('8.0.0')
96
- require_relative './api_4_9'
97
- end
98
-
99
- if Api::PROJ_VERSION >= Gem::Version.new('5.1.0')
100
- require_relative './api_5_1'
101
- end
102
-
103
- if Api::PROJ_VERSION >= Gem::Version.new('5.2.0')
104
- require_relative './api_5_2'
105
- end
106
-
107
- if Api::PROJ_VERSION >= Gem::Version.new('6.0.0')
108
- require_relative './api_6_0'
109
- end
110
-
111
- if Api::PROJ_VERSION >= Gem::Version.new('6.1.0')
112
- require_relative './api_6_1'
113
- end
114
-
115
- if Api::PROJ_VERSION >= Gem::Version.new('6.2.0')
116
- require_relative './api_6_2'
117
- end
118
- end
1
+ require 'rbconfig'
2
+ require 'ffi'
3
+
4
+ module Proj
5
+ module Api
6
+ extend FFI::Library
7
+
8
+ # List of knows PROJ library versions
9
+ #
10
+ # @return [Array<String>]
11
+ def self.library_versions
12
+ ["25", # 9.2
13
+ "9_1", # 9.1
14
+ "22", # 8.0 and 8.1
15
+ "19", # 7.x
16
+ "17", # 6.1 *and* 6.2
17
+ "15", # 6.0
18
+ "14", # 5.2
19
+ "13", # 5.0
20
+ "12", # 4.9
21
+ "11"] # 4.9
22
+ end
23
+
24
+ # Search paths to use when looking for PROJ library
25
+ #
26
+ # @return [Array<String>]
27
+ def self.search_paths
28
+ result = case RbConfig::CONFIG['host_os']
29
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
30
+ self.windows_search_paths
31
+ when /darwin|mac os/
32
+ self.macos_search_paths
33
+ else
34
+ self.linux_search_paths
35
+ end
36
+
37
+ # Try libproj as catch all
38
+ result << 'libproj'
39
+ result
40
+ end
41
+
42
+ # Windows search paths for PROJ library
43
+ #
44
+ # @return [Array<String>]
45
+ def self.windows_search_paths
46
+ self.library_versions.map do |version|
47
+ ["libproj-#{version}", "libproj_#{version}"]
48
+ end.flatten
49
+ end
50
+
51
+ # Linux search paths for PROJ library
52
+ #
53
+ # @return [Array<String>]
54
+ def self.linux_search_paths
55
+ self.library_versions.map do |version|
56
+ "libproj.so.#{version}"
57
+ end
58
+ end
59
+
60
+ # MacOS search paths for PROJ library
61
+ #
62
+ # @return [Array<String>]
63
+ def self.macos_search_paths
64
+ # On MacOS only support HomeBrew since the MacPort is unsupported and ancient (5.2).
65
+ self.library_versions.map do |version|
66
+ "libproj.#{version}.dylib"
67
+ end
68
+ end
69
+
70
+ # Load PROJ library
71
+ #
72
+ # @return [FFI::DynamicLibrary]
73
+ def self.load_library
74
+ if ENV["PROJ_LIB_PATH"]
75
+ ffi_lib ENV["PROJ_LIB_PATH"]
76
+ else
77
+ ffi_lib self.search_paths
78
+ end
79
+
80
+ ffi_libraries.first
81
+ end
82
+
83
+ # Load API files based on PROJ version
84
+ #
85
+ # @return [nil]
86
+ def self.load_api
87
+ # First load the base 5.0 api so we can determine the Proj Version
88
+ require_relative './api_5_0'
89
+ Api.const_set('PROJ_VERSION', Gem::Version.new(self.proj_info[:version]))
90
+
91
+ # Now load the rest of the apis based on the proj version
92
+ versions = ['5.1.0', '5.2.0',
93
+ '6.0.0', '6.1.0', '6.2.0', '6.3.0',
94
+ '7.0.0', '7.1.0', '7.2.0',
95
+ '8.0.0', '8.1.0', '8.2.0',
96
+ '9.1.0', '9.2.0']
97
+
98
+ versions.each do |version|
99
+ api_version = Gem::Version.new(version)
100
+
101
+ if PROJ_VERSION >= api_version
102
+ require_relative "./api_#{api_version.segments[0]}_#{api_version.segments[1]}"
103
+ end
104
+ end
105
+
106
+ # Add in the experimental api
107
+ require_relative "./api_experimental"
108
+ end
109
+
110
+ # Load the library
111
+ load_library
112
+
113
+ # Load the api
114
+ load_api
115
+ end
116
+ end
117
+