proj4rb 4.1.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +98 -0
  3. data/Gemfile +4 -4
  4. data/README.md +53 -0
  5. data/lib/api/proj.rb +750 -0
  6. data/lib/api/proj_experimental.rb +7 -0
  7. data/lib/api/proj_ffi.rb +47 -0
  8. data/lib/api/proj_version.rb +26 -0
  9. data/lib/examples/axis_order_normalization.rb +13 -0
  10. data/lib/examples/batch_transformation.rb +25 -0
  11. data/lib/examples/context_logging.rb +26 -0
  12. data/lib/examples/crs_identification.rb +18 -0
  13. data/lib/examples/database_query.rb +27 -0
  14. data/lib/examples/geodetic_distance.rb +38 -0
  15. data/lib/examples/geodetic_to_projected.rb +18 -0
  16. data/lib/examples/operation_factory_context.rb +19 -0
  17. data/lib/examples/pipeline_operator.rb +21 -0
  18. data/lib/examples/promote_demote_3d.rb +23 -0
  19. data/lib/examples/serialization_formats.rb +17 -0
  20. data/lib/examples/transform_bounds.rb +18 -0
  21. data/lib/examples/transformation_with_area.rb +18 -0
  22. data/lib/proj/area.rb +74 -74
  23. data/lib/proj/axis_info.rb +44 -44
  24. data/lib/proj/bounds.rb +22 -0
  25. data/lib/proj/bounds3d.rb +45 -0
  26. data/lib/proj/context.rb +57 -23
  27. data/lib/proj/conversion.rb +94 -91
  28. data/lib/proj/coordinate.rb +304 -281
  29. data/lib/proj/coordinate_metadata.rb +38 -0
  30. data/lib/proj/coordinate_operation_mixin.rb +464 -381
  31. data/lib/proj/coordinate_system.rb +143 -137
  32. data/lib/proj/crs.rb +688 -672
  33. data/lib/proj/crs_info.rb +47 -47
  34. data/lib/proj/database.rb +310 -305
  35. data/lib/proj/datum.rb +32 -32
  36. data/lib/proj/datum_ensemble.rb +34 -34
  37. data/lib/proj/domain.rb +82 -0
  38. data/lib/proj/ellipsoid.rb +77 -77
  39. data/lib/proj/error.rb +7 -8
  40. data/lib/proj/file_api_callbacks.rb +165 -0
  41. data/lib/proj/grid.rb +121 -121
  42. data/lib/proj/grid_cache.rb +65 -64
  43. data/lib/proj/grid_info.rb +19 -19
  44. data/lib/proj/life_span.rb +21 -0
  45. data/lib/proj/network_api_callbacks.rb +86 -0
  46. data/lib/proj/operation.rb +66 -42
  47. data/lib/proj/operation_factory_context.rb +4 -2
  48. data/lib/proj/options.rb +41 -0
  49. data/lib/proj/parameter.rb +37 -37
  50. data/lib/proj/parameters.rb +106 -107
  51. data/lib/proj/pj_axis_description.rb +26 -0
  52. data/lib/proj/pj_object.rb +602 -670
  53. data/lib/proj/pj_objects.rb +45 -45
  54. data/lib/proj/pj_param_description.rb +28 -0
  55. data/lib/proj/prime_meridian.rb +65 -65
  56. data/lib/proj/projection.rb +1771 -698
  57. data/lib/proj/session.rb +2 -0
  58. data/lib/proj/transformation.rb +102 -102
  59. data/lib/proj/unit.rb +81 -108
  60. data/lib/proj.rb +10 -3
  61. data/lib/proj4.rb +5 -5
  62. data/proj4rb.gemspec +10 -5
  63. data/test/abstract_test.rb +7 -28
  64. data/test/context_test.rb +210 -172
  65. data/test/context_validation_test.rb +11 -0
  66. data/test/conversion_test.rb +376 -368
  67. data/test/coordinate_metadata_test.rb +34 -0
  68. data/test/coordinate_system_test.rb +162 -144
  69. data/test/coordinate_test.rb +289 -34
  70. data/test/crs_test.rb +1112 -1072
  71. data/test/database_test.rb +407 -359
  72. data/test/datum_ensemble_test.rb +64 -64
  73. data/test/datum_test.rb +61 -54
  74. data/test/domain_test.rb +72 -0
  75. data/test/ellipsoid_test.rb +80 -80
  76. data/test/examples_test.rb +149 -0
  77. data/test/file_api_example.rb +58 -0
  78. data/test/file_api_test.rb +74 -66
  79. data/test/grid_cache_test.rb +72 -72
  80. data/test/grid_test.rb +126 -141
  81. data/test/network_api_example.rb +48 -0
  82. data/test/network_api_test.rb +33 -45
  83. data/test/operation_factory_context_test.rb +225 -201
  84. data/test/operation_test.rb +40 -29
  85. data/test/options_test.rb +17 -0
  86. data/test/parameters_test.rb +86 -40
  87. data/test/pj_object_test.rb +221 -179
  88. data/test/prime_meridian_test.rb +75 -75
  89. data/test/proj_test.rb +58 -58
  90. data/test/projection_test.rb +680 -650
  91. data/test/session_test.rb +78 -77
  92. data/test/transformation_test.rb +238 -210
  93. data/test/unit_test.rb +114 -76
  94. metadata +45 -31
  95. data/ChangeLog +0 -89
  96. data/README.rdoc +0 -207
  97. data/lib/api/api.rb +0 -117
  98. data/lib/api/api_5_0.rb +0 -338
  99. data/lib/api/api_5_1.rb +0 -7
  100. data/lib/api/api_5_2.rb +0 -5
  101. data/lib/api/api_6_0.rb +0 -146
  102. data/lib/api/api_6_1.rb +0 -5
  103. data/lib/api/api_6_2.rb +0 -10
  104. data/lib/api/api_6_3.rb +0 -6
  105. data/lib/api/api_7_0.rb +0 -69
  106. data/lib/api/api_7_1.rb +0 -73
  107. data/lib/api/api_7_2.rb +0 -14
  108. data/lib/api/api_8_0.rb +0 -6
  109. data/lib/api/api_8_1.rb +0 -24
  110. data/lib/api/api_8_2.rb +0 -6
  111. data/lib/api/api_9_1.rb +0 -7
  112. data/lib/api/api_9_2.rb +0 -9
  113. data/lib/api/api_experimental.rb +0 -201
  114. data/lib/proj/file_api.rb +0 -166
  115. data/lib/proj/network_api.rb +0 -92
@@ -0,0 +1,41 @@
1
+ module Proj
2
+ # Wraps a hash of key-value pairs as a null-terminated array of
3
+ # "KEY=VALUE" C string pointers suitable for PROJ option parameters.
4
+ #
5
+ # Many PROJ C API functions accept an optional array of "KEY=VALUE" strings
6
+ # to control their behavior. This class builds the required pointer array
7
+ # and keeps the underlying FFI memory alive so that the garbage collector
8
+ # cannot free it before the C call returns.
9
+ #
10
+ # @example
11
+ # options = Proj::Options.new("MULTILINE": "YES", "INDENTATION_WIDTH": 4)
12
+ # Api.proj_as_wkt(context, pj, :PJ_WKT2_2019, options)
13
+ class Options
14
+ # Creates a new Options instance.
15
+ #
16
+ # @param options [Hash{String, Symbol => String, Integer, nil}] Key-value pairs.
17
+ # Entries with nil values are removed.
18
+ def initialize(options = {})
19
+ options = options.compact
20
+ @string_ptrs = options.map do |key, value|
21
+ FFI::MemoryPointer.from_string("#{key}=#{value}")
22
+ end
23
+
24
+ if @string_ptrs.empty?
25
+ @pointer = nil
26
+ else
27
+ @pointer = FFI::MemoryPointer.new(:pointer, options.size + 1)
28
+ # PROJ expects a NULL-terminated char* array.
29
+ @pointer.write_array_of_pointer(@string_ptrs + [FFI::Pointer::NULL])
30
+ end
31
+ end
32
+
33
+ # Returns the pointer to the null-terminated string array, or a
34
+ # NULL pointer if no options were provided.
35
+ #
36
+ # @return [FFI::Pointer]
37
+ def to_ptr
38
+ @pointer || FFI::Pointer::NULL
39
+ end
40
+ end
41
+ end
@@ -1,38 +1,38 @@
1
- module Proj
2
- class Parameter
3
- # @!attribute [r] name
4
- # @return [String] Param name
5
- # @!attribute [r] auth_name
6
- # @return [String] Authority name
7
- # @!attribute [r] code
8
- # @return [String] Authority code
9
- # @!attribute [r] value
10
- # @return [String] Param value
11
- # @!attribute [r] unit_conv_factor
12
- # @return [String] Param unit_conv_factor
13
- # @!attribute [r] unit_name
14
- # @return [String] Param unit_name
15
- # @!attribute [r] unit_type
16
- # @return [PJ_UNIT_TYPE] Unit type
17
- attr_reader :name, :auth_name, :code, :value,
18
- :unit_conv_factor, :unit_name, :unit_type
19
-
20
- def initialize(name:, auth_name: nil, code: nil, value:, unit_conv_factor:, unit_name: nil, unit_type:)
21
- @name = name
22
- @auth_name = auth_name
23
- @code = code
24
- @value = value
25
- @unit_conv_factor = unit_conv_factor
26
- @unit_name = unit_name
27
- @unit_type = unit_type
28
- end
29
-
30
- # Returns param information in PJ_PARAM_DESCRIPTION structure
31
- #
32
- # @return [PJ_PARAM_DESCRIPTION]
33
- def to_description
34
- Api::PJ_PARAM_DESCRIPTION.create(name: name, auth_name: auth_name, code: code, value: value,
35
- unit_conv_factor: unit_conv_factor, unit_name: name, unit_type: unit_type)
36
- end
37
- end
1
+ module Proj
2
+ class Parameter
3
+ # @!attribute [r] name
4
+ # @return [String] Param name
5
+ # @!attribute [r] auth_name
6
+ # @return [String] Authority name
7
+ # @!attribute [r] code
8
+ # @return [String] Authority code
9
+ # @!attribute [r] value
10
+ # @return [String] Param value
11
+ # @!attribute [r] unit_conv_factor
12
+ # @return [String] Param unit_conv_factor
13
+ # @!attribute [r] unit_name
14
+ # @return [String] Param unit_name
15
+ # @!attribute [r] unit_type
16
+ # @return [PjUnitType] Unit type
17
+ attr_reader :name, :auth_name, :code, :value,
18
+ :unit_conv_factor, :unit_name, :unit_type
19
+
20
+ def initialize(name:, auth_name: nil, code: nil, value:, unit_conv_factor:, unit_name: nil, unit_type:)
21
+ @name = name
22
+ @auth_name = auth_name
23
+ @code = code
24
+ @value = value
25
+ @unit_conv_factor = unit_conv_factor
26
+ @unit_name = unit_name
27
+ @unit_type = unit_type
28
+ end
29
+
30
+ # Returns param information in PjParamDescription structure
31
+ #
32
+ # @return [PjParamDescription]
33
+ def to_description
34
+ Api::PjParamDescription.create(name: name, auth_name: auth_name, code: code, value: value,
35
+ unit_conv_factor: unit_conv_factor, unit_name: unit_name, unit_type: unit_type)
36
+ end
37
+ end
38
38
  end
@@ -1,107 +1,106 @@
1
- # encoding: UTF-8
2
- module Proj
3
- class Parameters
4
- # @!visibility private
5
- def self.finalize(pointer)
6
- proc do
7
- Api.proj_get_crs_list_parameters_destroy(pointer)
8
- end
9
- end
10
-
11
- def initialize
12
- pointer = Api.proj_get_crs_list_parameters_create
13
- @params = Api::PROJ_CRS_LIST_PARAMETERS.new(pointer)
14
- ObjectSpace.define_finalizer(self, self.class.finalize(pointer))
15
- end
16
-
17
- def to_ptr
18
- @params.to_ptr
19
- end
20
-
21
- def types
22
- result = Array.new
23
-
24
- unless @params[:types].null?
25
- ints = @params[:types].read_array_of_int(@params[:types_count])
26
- ints.each do |int|
27
- result << Api::PJ_TYPE[int]
28
- end
29
- end
30
- result
31
- end
32
-
33
- def types=(values)
34
- ptr = FFI::MemoryPointer.new(:int, values.size)
35
- ints = values.map {|symbol| Api::PJ_TYPE[symbol]}
36
- ptr.write_array_of_int(ints)
37
-
38
- @params[:types] = ptr
39
- @params[:types_count] = values.size
40
- end
41
-
42
- def crs_area_of_use_contains_bbox
43
- @params[:crs_area_of_use_contains_bbox]
44
- end
45
-
46
- def crs_area_of_use_contains_bbox=(value)
47
- @params[:crs_area_of_use_contains_bbox] = value
48
- end
49
-
50
- def bbox_valid
51
- @params[:bbox_valid] == 1 ? true : false
52
- end
53
-
54
- def bbox_valid=(value)
55
- @params[:bbox_valid] = value ? 1 : 0
56
- end
57
-
58
- def west_lon_degree
59
- @params[:west_lon_degree]
60
- end
61
-
62
- def west_lon_degree=(value)
63
- @params[:west_lon_degree] = value
64
- end
65
-
66
- def south_lat_degree
67
- @params[:south_lat_degree]
68
- end
69
-
70
- def south_lat_degree=(value)
71
- @params[:south_lat_degree] = value
72
- end
73
-
74
- def east_lon_degree
75
- @params[:east_lon_degree]
76
- end
77
-
78
- def east_lon_degree=(value)
79
- @params[:east_lon_degree] = value
80
- end
81
-
82
- def north_lat_degree
83
- @params[:north_lat_degree]
84
- end
85
-
86
- def north_lat_degree=(value)
87
- @params[:north_lat_degree] = value
88
- end
89
-
90
- def allow_deprecated
91
- @params[:allow_deprecated] == 1 ? true : false
92
- end
93
-
94
- def allow_deprecated=(value)
95
- @params[:allow_deprecated] = value ? 1 : 0
96
- end
97
-
98
- def celestial_body_name
99
- @params[:celestial_body_name].read_string_to_null
100
- end
101
-
102
- def celestial_body_name=(value)
103
- ptr = FFI::MemoryPointer.from_string(value)
104
- @params[:celestial_body_name] = ptr
105
- end
106
- end
107
- end
1
+ # encoding: UTF-8
2
+ module Proj
3
+ class Parameters
4
+ # @!visibility private
5
+ def self.finalize(params)
6
+ proc do
7
+ Api.proj_get_crs_list_parameters_destroy(params)
8
+ end
9
+ end
10
+
11
+ def initialize
12
+ @params = Api.proj_get_crs_list_parameters_create
13
+ ObjectSpace.define_finalizer(self, self.class.finalize(@params))
14
+ end
15
+
16
+ def to_ptr
17
+ @params.to_ptr
18
+ end
19
+
20
+ def types
21
+ result = Array.new
22
+
23
+ unless @params[:types].null?
24
+ ints = @params[:types].read_array_of_int(@params[:types_count])
25
+ ints.each do |int|
26
+ result << Api::PjType[int]
27
+ end
28
+ end
29
+ result
30
+ end
31
+
32
+ def types=(values)
33
+ @types_ptr = FFI::MemoryPointer.new(:int, values.size)
34
+ ints = values.map {|symbol| Api::PjType[symbol]}
35
+ @types_ptr.write_array_of_int(ints)
36
+
37
+ @params[:types] = @types_ptr
38
+ @params[:types_count] = values.size
39
+ end
40
+
41
+ def crs_area_of_use_contains_bbox
42
+ @params[:crs_area_of_use_contains_bbox]
43
+ end
44
+
45
+ def crs_area_of_use_contains_bbox=(value)
46
+ @params[:crs_area_of_use_contains_bbox] = value
47
+ end
48
+
49
+ def bbox_valid
50
+ @params[:bbox_valid] == 1 ? true : false
51
+ end
52
+
53
+ def bbox_valid=(value)
54
+ @params[:bbox_valid] = value ? 1 : 0
55
+ end
56
+
57
+ def west_lon_degree
58
+ @params[:west_lon_degree]
59
+ end
60
+
61
+ def west_lon_degree=(value)
62
+ @params[:west_lon_degree] = value
63
+ end
64
+
65
+ def south_lat_degree
66
+ @params[:south_lat_degree]
67
+ end
68
+
69
+ def south_lat_degree=(value)
70
+ @params[:south_lat_degree] = value
71
+ end
72
+
73
+ def east_lon_degree
74
+ @params[:east_lon_degree]
75
+ end
76
+
77
+ def east_lon_degree=(value)
78
+ @params[:east_lon_degree] = value
79
+ end
80
+
81
+ def north_lat_degree
82
+ @params[:north_lat_degree]
83
+ end
84
+
85
+ def north_lat_degree=(value)
86
+ @params[:north_lat_degree] = value
87
+ end
88
+
89
+ def allow_deprecated
90
+ @params[:allow_deprecated] == 1 ? true : false
91
+ end
92
+
93
+ def allow_deprecated=(value)
94
+ @params[:allow_deprecated] = value ? 1 : 0
95
+ end
96
+
97
+ def celestial_body_name
98
+ @params[:celestial_body_name]
99
+ end
100
+
101
+ def celestial_body_name=(value)
102
+ @celestial_body_name = FFI::MemoryPointer.from_string(value)
103
+ @params.pointer.put_pointer(@params.offset_of(:celestial_body_name), @celestial_body_name)
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,26 @@
1
+ module Proj
2
+ module Api
3
+ class PjAxisDescription
4
+ attr_accessor :retained_ptrs
5
+
6
+ def self.create(name:, abbreviation:, direction:, unit_name:, unit_conv_factor:, unit_type:)
7
+ result = PjAxisDescription.new
8
+ result.retained_ptrs = []
9
+ result.put_string(:name, name)
10
+ result.put_string(:abbreviation, abbreviation)
11
+ result.put_string(:direction, direction)
12
+ result.put_string(:unit_name, unit_name)
13
+ result[:unit_conv_factor] = unit_conv_factor
14
+ result[:unit_type] = unit_type
15
+ result
16
+ end
17
+
18
+ # Write a string into a :string field and retain the pointer to prevent GC.
19
+ def put_string(field, value)
20
+ ptr = FFI::MemoryPointer.from_string(value)
21
+ @retained_ptrs << ptr
22
+ pointer.put_pointer(offset_of(field), ptr)
23
+ end
24
+ end
25
+ end
26
+ end