From a4f81ac7c4182761d5d9a3eb1dc4a66d2d7bdbf2 Mon Sep 17 00:00:00 2001 From: AJ Date: Fri, 14 Oct 2022 16:47:06 -0400 Subject: [PATCH] feat: remove/fix rubocop todos * fix `Layout/ArgumentAlignment` * fix `Layout/EmptyLineBetweenDefs` * fix `Layout/ExtraSpacing` * fix `Layout/FirstArrayElementIndentation` * fix `Layout/MultilineMethodCallBraceLayout` * fix `Layout/MultilineMethodCallIndentation` * fix `Layout/SpaceAroundOperators` * fix `Layout/SpaceBeforeBlockBraces` * fix `Lint/EmptyWhen` * fix `Lint/LiteralAsCondition` * fix `Lint/UnusedBlockArgument` * fix `Style/BlockDelimiters` * fix `Style/CaseLikeIf` * fix `Style/ClassEqualityComparison` * fix `Style/ConditionalAssignment` * fix `Style/EmptyMethod` * fix `Style/IfInsideElse` * fix `Style/MultilineTernaryOperator` * fix `Style/OrAssignment` * fix `Style/RedundantConditional` * fix `Style/RedundantRegexpEscape` * fix `Style/StringConcatenation` * fix `Style/StringLiterals` * fix `Style/SymbolArray` * fix `Style/PerlBackrefs` * fix `Naming/AccessorMethodName` * fix `Naming/MemoizedInstanceVariableName` * fix `Style/NegatedIfElseCondition` * fix `Style/NestedTernaryOperator` * fix `Lint/FloatComparison` * fix `Lint/DuplicateBranch` * fix `Lint/UnusedMethodArgument` * fix `Naming/BinaryOperatorParameterName` * fix `Style/AccessorGrouping` * fix `Style/InverseMethods` * fix `Style/IfUnlessModifier` * fix `Style/MultilineIfModifier` * fix `Style/MultipleComparison` * fix `Style/SoleNestedConditional` * fix `Style/UnpackFirst` * fix `Security/MarshalLoad` * fix `Style/GuardClause` * fix `Style/Documentation` * fix `Style/MultilineBlockChain` * partially fix `Metrics/BlockNesting` * fix `Layout/LineLength` * fix `Style/GlobalVars` updates rgeo/rgeo#336 --- .rubocop.yml | 6 +- .rubocop_todo.yml | 402 +----------------- Rakefile | 2 +- lib/rgeo/cartesian/analysis.rb | 8 +- lib/rgeo/cartesian/bounding_box.rb | 153 ++++--- lib/rgeo/cartesian/calculations.rb | 46 +- lib/rgeo/cartesian/factory.rb | 102 ++--- lib/rgeo/cartesian/feature_classes.rb | 2 +- lib/rgeo/cartesian/interface.rb | 2 +- lib/rgeo/cartesian/planar_graph.rb | 22 +- lib/rgeo/cartesian/sweepline_intersector.rb | 4 +- lib/rgeo/cartesian/valid_op.rb | 8 +- lib/rgeo/coord_sys/cs/entities.rb | 134 +++--- lib/rgeo/coord_sys/cs/factories.rb | 2 - lib/rgeo/coord_sys/cs/wkt_parser.rb | 99 +++-- lib/rgeo/feature/curve.rb | 1 - lib/rgeo/feature/factory.rb | 28 +- lib/rgeo/feature/factory_generator.rb | 7 +- lib/rgeo/feature/geometry.rb | 59 ++- lib/rgeo/feature/geometry_collection.rb | 7 +- lib/rgeo/feature/line_string.rb | 3 +- lib/rgeo/feature/linear_ring.rb | 1 - lib/rgeo/feature/multi_curve.rb | 1 - lib/rgeo/feature/multi_surface.rb | 1 - lib/rgeo/feature/point.rb | 1 - lib/rgeo/feature/polygon.rb | 3 +- lib/rgeo/feature/surface.rb | 1 - lib/rgeo/feature/types.rb | 158 ++++--- lib/rgeo/geographic/factory.rb | 173 ++++---- lib/rgeo/geographic/interface.rb | 59 ++- .../geographic/projected_feature_classes.rb | 2 +- .../geographic/projected_feature_methods.rb | 8 +- lib/rgeo/geographic/projected_window.rb | 46 +- .../geographic/simple_mercator_projector.rb | 33 +- .../geographic/spherical_feature_classes.rb | 2 +- .../geographic/spherical_feature_methods.rb | 11 +- lib/rgeo/geographic/spherical_math.rb | 47 +- lib/rgeo/geos.rb | 2 +- lib/rgeo/geos/capi_factory.rb | 104 ++--- lib/rgeo/geos/capi_feature_classes.rb | 6 +- lib/rgeo/geos/ffi_factory.rb | 87 ++-- lib/rgeo/geos/ffi_feature_classes.rb | 2 +- lib/rgeo/geos/ffi_feature_methods.rb | 96 +++-- lib/rgeo/geos/interface.rb | 34 +- lib/rgeo/geos/utils.rb | 6 +- lib/rgeo/geos/zm_factory.rb | 96 +++-- lib/rgeo/geos/zm_feature_methods.rb | 23 +- .../basic_geometry_collection_methods.rb | 8 +- .../impl_helper/basic_geometry_methods.rb | 3 +- .../impl_helper/basic_line_string_methods.rb | 39 +- lib/rgeo/impl_helper/basic_point_methods.rb | 10 +- lib/rgeo/impl_helper/basic_polygon_methods.rb | 31 +- lib/rgeo/impl_helper/utils.rb | 12 +- lib/rgeo/impl_helper/valid_op.rb | 28 +- lib/rgeo/wkrep/wkb_generator.rb | 89 ++-- lib/rgeo/wkrep/wkb_parser.rb | 35 +- lib/rgeo/wkrep/wkt_generator.rb | 35 +- lib/rgeo/wkrep/wkt_parser.rb | 32 +- rgeo.gemspec | 2 +- test/cartesian_bbox_test.rb | 3 +- test/common/factory_tests.rb | 3 +- test/common/line_string_tests.rb | 3 +- test/common/multi_polygon_tests.rb | 17 +- test/common/point_tests.rb | 19 +- test/common/polygon_tests.rb | 12 +- test/coord_sys/ogc_cs_test.rb | 309 ++++++++++++-- test/docs/examples_test.rb | 1 + test/docs/factory_compatibility_table_test.rb | 60 +-- test/geos_capi/factory_test.rb | 24 +- test/geos_capi/geometry_collection_test.rb | 50 +-- test/geos_capi/line_string_test.rb | 66 +-- test/geos_capi/misc_test.rb | 274 +++++++----- test/geos_capi/multi_line_string_test.rb | 150 +++---- test/geos_capi/multi_point_test.rb | 22 +- test/geos_capi/multi_polygon_test.rb | 56 +-- test/geos_capi/point_test.rb | 98 ++--- test/geos_capi/polygon_test.rb | 280 ++++++------ test/geos_capi/validity_test.rb | 38 +- test/geos_capi/zmfactory_test.rb | 72 ++-- test/geos_ffi/factory_test.rb | 24 +- test/geos_ffi/geometry_collection_test.rb | 12 +- test/geos_ffi/line_string_test.rb | 12 +- test/geos_ffi/misc_test.rb | 147 ++++--- test/geos_ffi/multi_line_string_test.rb | 12 +- test/geos_ffi/multi_point_test.rb | 12 +- test/geos_ffi/multi_polygon_test.rb | 22 +- test/geos_ffi/point_test.rb | 92 ++-- test/geos_ffi/polygon_test.rb | 90 ++-- test/geos_ffi/validity_test.rb | 12 +- test/geos_ffi/zmfactory_test.rb | 74 ++-- test/simple_cartesian/calculations_test.rb | 6 +- test/simple_cartesian/point_test.rb | 4 +- .../sweepline_intersector_test.rb | 16 +- test/simple_mercator/window_test.rb | 136 ++++-- .../spherical_geographic/calculations_test.rb | 6 +- test/spherical_geographic/polygon_test.rb | 2 +- test/support/minitest/assert_wkt_similar.rb | 4 +- test/test_helper.rb | 13 +- test/types_test.rb | 10 +- test/wkrep/wkb_generator_test.rb | 70 ++- test/wkrep/wkb_parser_test.rb | 51 ++- test/wkrep/wkt_generator_test.rb | 58 ++- test/wkrep/wkt_parser_test.rb | 8 +- 103 files changed, 2537 insertions(+), 2337 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index b3efff70..458652e6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,7 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 2.5 + TargetRubyVersion: 2.6 NewCops: enable Layout/ParameterAlignment: @@ -42,6 +42,10 @@ Naming/PredicateName: Style/CaseEquality: Enabled: false +Style/GlobalVars: + Exclude: + - 'ext/geos_c_impl/extconf.rb' + Style/NumericPredicate: Enabled: false diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 41ff5c6b..bb176936 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,116 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 26 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: with_first_argument, with_fixed_indentation -Layout/ArgumentAlignment: - Exclude: - - 'lib/rgeo/feature/types.rb' - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/geographic/interface.rb' - - 'lib/rgeo/geographic/projected_window.rb' - - 'lib/rgeo/geographic/simple_mercator_projector.rb' - - 'lib/rgeo/geos/capi_factory.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - - 'lib/rgeo/geos/ffi_feature_methods.rb' - - 'lib/rgeo/impl_helper/basic_polygon_methods.rb' - - 'test/simple_cartesian/point_test.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EmptyLineBetweenMethodDefs, EmptyLineBetweenClassDefs, EmptyLineBetweenModuleDefs, AllowAdjacentOneLineDefs, NumberOfEmptyLines. -Layout/EmptyLineBetweenDefs: - Exclude: - - 'lib/rgeo/impl_helper/basic_polygon_methods.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Layout/EmptyLines: - Exclude: - - 'lib/rgeo/impl_helper/basic_polygon_methods.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, AllowBeforeTrailingComments, ForceEqualSignAlignment. -Layout/ExtraSpacing: - Exclude: - - 'test/common/polygon_tests.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Layout/FirstArrayElementIndentation: - Exclude: - - 'test/geos_capi/geometry_collection_test.rb' - -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: symmetrical, new_line, same_line -Layout/MultilineMethodCallBraceLayout: - Exclude: - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/impl_helper/basic_polygon_methods.rb' - - 'test/cartesian_bbox_test.rb' - - 'test/geos_capi/misc_test.rb' - - 'test/geos_ffi/misc_test.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, IndentationWidth. -# SupportedStyles: aligned, indented, indented_relative_to_receiver -Layout/MultilineMethodCallIndentation: - Exclude: - - 'test/geos_capi/geometry_collection_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, EnforcedStyleForExponentOperator. -# SupportedStylesForExponentOperator: space, no_space -Layout/SpaceAroundOperators: - Exclude: - - 'test/common/polygon_tests.rb' - - 'test/spherical_geographic/polygon_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces. -# SupportedStyles: space, no_space -# SupportedStylesForEmptyBraces: space, no_space -Layout/SpaceBeforeBlockBraces: - Exclude: - - 'test/geos_capi/polygon_test.rb' - -# Offense count: 8 -# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches. -Lint/DuplicateBranch: - Exclude: - - 'lib/rgeo/cartesian/bounding_box.rb' - - 'lib/rgeo/geos.rb' - - 'lib/rgeo/wkrep/wkb_generator.rb' - -# Offense count: 3 -# Configuration parameters: AllowComments. -Lint/EmptyWhen: - Exclude: - - 'test/common/polygon_tests.rb' - -# Offense count: 8 -Lint/FloatComparison: - Exclude: - - 'lib/rgeo/cartesian/analysis.rb' - - 'lib/rgeo/geographic/projected_window.rb' - - 'lib/rgeo/geographic/spherical_math.rb' - -# Offense count: 2 -Lint/LiteralAsCondition: - Exclude: - - 'test/coord_sys/sr_org_test.rb' - - 'test/coord_sys/url_reader_test.rb' - # Offense count: 4 Lint/MissingSuper: Exclude: @@ -126,72 +16,16 @@ Lint/NonLocalExitFromIterator: Exclude: - 'lib/rgeo/geos/ffi_factory.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments. -Lint/UnusedBlockArgument: - Exclude: - - 'lib/rgeo/feature/factory_generator.rb' - - 'lib/rgeo/geos/utils.rb' - -# Offense count: 53 -# Cop supports --auto-correct. -# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods, IgnoreNotImplementedMethods. -Lint/UnusedMethodArgument: - Exclude: - - 'lib/rgeo/coord_sys/cs/entities.rb' - - 'lib/rgeo/feature/factory.rb' - - 'lib/rgeo/feature/factory_generator.rb' - - 'lib/rgeo/feature/geometry.rb' - - 'lib/rgeo/feature/geometry_collection.rb' - - 'lib/rgeo/feature/line_string.rb' - - 'lib/rgeo/feature/polygon.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - # Offense count: 141 # Configuration parameters: IgnoredMethods, CountRepeatedAttributes. Metrics/AbcSize: Max: 180 -# Offense count: 3 +# Offense count: 4 # Configuration parameters: CountBlocks. Metrics/BlockNesting: - Max: 6 - -# Offense count: 1 -Naming/AccessorMethodName: - Exclude: - - 'lib/rgeo/wkrep/wkb_parser.rb' - -# Offense count: 19 -# Cop supports --auto-correct. -Naming/BinaryOperatorParameterName: Exclude: - - 'lib/rgeo/cartesian/bounding_box.rb' - - 'lib/rgeo/cartesian/calculations.rb' - - 'lib/rgeo/cartesian/factory.rb' - - 'lib/rgeo/coord_sys/cs/entities.rb' - - 'lib/rgeo/feature/geometry.rb' - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/geographic/projected_window.rb' - - 'lib/rgeo/geographic/spherical_math.rb' - - 'lib/rgeo/geos/capi_factory.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - - 'lib/rgeo/geos/ffi_feature_methods.rb' - - 'lib/rgeo/geos/zm_factory.rb' - -# Offense count: 5 -# Configuration parameters: EnforcedStyleForLeadingUnderscores. -# SupportedStylesForLeadingUnderscores: disallowed, required, optional -Naming/MemoizedInstanceVariableName: - Exclude: - - 'lib/rgeo/geographic/projected_window.rb' - -# Offense count: 67 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Enabled: false + - 'lib/rgeo/feature/types.rb' # Offense count: 20 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers. @@ -208,168 +42,6 @@ Naming/VariableNumber: - 'test/geos_capi/multi_polygon_test.rb' - 'test/simple_cartesian/point_test.rb' -# Offense count: 6 -Security/MarshalLoad: - Exclude: - - 'test/common/factory_tests.rb' - - 'test/common/line_string_tests.rb' - - 'test/common/point_tests.rb' - - 'test/coord_sys/ogc_cs_test.rb' - -# Offense count: 42 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: separated, grouped -Style/AccessorGrouping: - Exclude: - - 'lib/rgeo/cartesian/bounding_box.rb' - - 'lib/rgeo/cartesian/calculations.rb' - - 'lib/rgeo/cartesian/factory.rb' - - 'lib/rgeo/coord_sys/cs/wkt_parser.rb' - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/geographic/projected_window.rb' - - 'lib/rgeo/geographic/spherical_math.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - - 'lib/rgeo/geos/ffi_feature_methods.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, IgnoredMethods, AllowBracesOnProceduralOneLiners, BracesRequiredMethods. -# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces -# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object -# FunctionalMethods: let, let!, subject, watch -# IgnoredMethods: lambda, proc, it -Style/BlockDelimiters: - Exclude: - - 'test/simple_mercator/window_test.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/CaseLikeIf: - Exclude: - - 'lib/rgeo/geographic/spherical_feature_methods.rb' - - 'lib/rgeo/wkrep/wkb_generator.rb' - - 'lib/rgeo/wkrep/wkt_generator.rb' - -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: IgnoredMethods. -# IgnoredMethods: ==, equal?, eql? -Style/ClassEqualityComparison: - Exclude: - - 'lib/rgeo/coord_sys/cs/entities.rb' - - 'lib/rgeo/geos/ffi_feature_methods.rb' - -# Offense count: 36 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions. -# SupportedStyles: assign_to_condition, assign_inside_condition -Style/ConditionalAssignment: - Exclude: - - 'lib/rgeo/cartesian/factory.rb' - - 'lib/rgeo/coord_sys/cs/entities.rb' - - 'lib/rgeo/coord_sys/srs_database/url_reader.rb' - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/geos/capi_factory.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - - 'lib/rgeo/geos/interface.rb' - - 'lib/rgeo/geos/zm_factory.rb' - - 'lib/rgeo/wkrep/wkt_generator.rb' - -# Offense count: 60 -Style/Documentation: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle. -# SupportedStyles: compact, expanded -Style/EmptyMethod: - Exclude: - - 'lib/rgeo/impl_helper/basic_geometry_methods.rb' - -# Offense count: 3 -# Configuration parameters: AllowedVariables. -Style/GlobalVars: - Exclude: - - 'ext/geos_c_impl/extconf.rb' - -# Offense count: 29 -# Configuration parameters: MinBodyLength. -Style/GuardClause: - Exclude: - - 'lib/rgeo/cartesian/bounding_box.rb' - - 'lib/rgeo/cartesian/calculations.rb' - - 'lib/rgeo/coord_sys/cs/entities.rb' - - 'lib/rgeo/coord_sys/cs/wkt_parser.rb' - - 'lib/rgeo/coord_sys/srs_database/entry.rb' - - 'lib/rgeo/geographic/factory.rb' - - 'lib/rgeo/geographic/projected_feature_methods.rb' - - 'lib/rgeo/geos/capi_factory.rb' - - 'lib/rgeo/geos/ffi_feature_methods.rb' - - 'lib/rgeo/geos/interface.rb' - - 'lib/rgeo/geos/zm_factory.rb' - - 'lib/rgeo/impl_helper/basic_line_string_methods.rb' - - 'lib/rgeo/wkrep/wkt_parser.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: AllowIfModifier. -Style/IfInsideElse: - Exclude: - - 'lib/rgeo/feature/types.rb' - - 'lib/rgeo/geos/capi_factory.rb' - -# Offense count: 71 -# Cop supports --auto-correct. -Style/IfUnlessModifier: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: InverseMethods, InverseBlocks. -Style/InverseMethods: - Exclude: - - 'lib/rgeo/impl_helper/basic_polygon_methods.rb' - -# Offense count: 1 -Style/MultilineBlockChain: - Exclude: - - 'test/coord_sys/ogc_cs_test.rb' - -# Offense count: 24 -# Cop supports --auto-correct. -Style/MultilineIfModifier: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/MultilineTernaryOperator: - Exclude: - - 'lib/rgeo/wkrep/wkt_generator.rb' - -# Offense count: 8 -# Cop supports --auto-correct. -Style/MultipleComparison: - Exclude: - - 'lib/rgeo/feature/types.rb' - - 'lib/rgeo/geos/ffi_factory.rb' - -# Offense count: 2 -# Cop supports --auto-correct. -Style/NegatedIfElseCondition: - Exclude: - - 'lib/rgeo/geos/capi_factory.rb' - - 'lib/rgeo/impl_helper/basic_line_string_methods.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/NestedTernaryOperator: - Exclude: - - 'lib/rgeo/cartesian/bounding_box.rb' - - 'lib/rgeo/wkrep/wkt_generator.rb' - - 'lib/rgeo/wkrep/wkt_parser.rb' - # Offense count: 5 # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? @@ -379,73 +51,3 @@ Style/OptionalBooleanParameter: - 'lib/rgeo/wkrep/wkb_generator.rb' - 'lib/rgeo/wkrep/wkt_generator.rb' - 'lib/rgeo/wkrep/wkt_parser.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/OrAssignment: - Exclude: - - 'lib/rgeo/coord_sys/srs_database/entry.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/PerlBackrefs: - Exclude: - - 'lib/rgeo/wkrep/wkt_parser.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -Style/RedundantConditional: - Exclude: - - 'lib/rgeo/geos/ffi_factory.rb' - - 'lib/rgeo/wkrep/wkt_parser.rb' - -# Offense count: 4 -# Cop supports --auto-correct. -Style/RedundantRegexpEscape: - Exclude: - - 'lib/rgeo/coord_sys/cs/wkt_parser.rb' - - 'lib/rgeo/wkrep/wkt_parser.rb' - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: AllowModifier. -Style/SoleNestedConditional: - Exclude: - - 'lib/rgeo/cartesian/factory.rb' - - 'lib/rgeo/coord_sys/srs_database/entry.rb' - - 'lib/rgeo/geographic/factory.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -Style/StringConcatenation: - Exclude: - - 'ext/geos_c_impl/extconf.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline. -# SupportedStyles: single_quotes, double_quotes -Style/StringLiterals: - Exclude: - - 'lib/rgeo/geos/capi_factory.rb' - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: MinSize. -# SupportedStyles: percent, brackets -Style/SymbolArray: - EnforcedStyle: brackets - -# Offense count: 3 -# Cop supports --auto-correct. -Style/UnpackFirst: - Exclude: - - 'lib/rgeo/wkrep/wkb_generator.rb' - - 'lib/rgeo/wkrep/wkb_parser.rb' - -# Offense count: 116 -# Cop supports --auto-correct. -# Configuration parameters: AutoCorrect, AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns. -# URISchemes: http, https -Layout/LineLength: - Max: 1219 diff --git a/Rakefile b/Rakefile index ebce626c..2531b47b 100644 --- a/Rakefile +++ b/Rakefile @@ -44,4 +44,4 @@ YARD::Rake::YardocTask.new do |t| end task test: :compile -task default: [:clean, :test] +task default: %i[clean test] diff --git a/lib/rgeo/cartesian/analysis.rb b/lib/rgeo/cartesian/analysis.rb index b8708e31..2fdf0a69 100644 --- a/lib/rgeo/cartesian/analysis.rb +++ b/lib/rgeo/cartesian/analysis.rb @@ -10,7 +10,6 @@ module RGeo module Cartesian # This provides includes some spatial analysis algorithms supporting # Cartesian data. - module Analysis class << self # Check orientation of a ring, returns `true` if it is counter-clockwise @@ -79,8 +78,11 @@ def ring_direction(ring) sin = 0.0 cos = 1.0 angs.each_slice(2) do |(x, y)| - ready = y > 0.0 && (sin > 0.0 || sin == 0.0 && direction == -1) || y < 0.0 && (sin < 0.0 || sin == 0.0 && direction == 1) - if y != 0.0 + ready = y > 0.0 && + (sin > 0.0 || sin == 0 && direction == -1) || + y < 0.0 && + (sin < 0.0 || sin == 0 && direction == 1) + unless y == 0 s = sin * x + cos * y c = cos * x - sin * y r = Math.sqrt(s * s + c * c) diff --git a/lib/rgeo/cartesian/bounding_box.rb b/lib/rgeo/cartesian/bounding_box.rb index 20d98163..49444718 100644 --- a/lib/rgeo/cartesian/bounding_box.rb +++ b/lib/rgeo/cartesian/bounding_box.rb @@ -19,8 +19,40 @@ module Cartesian # adding the geometries to it. You may then query it for the bounds, # or use it to determine whether it encloses other geometries or # bounding boxes. - class BoundingBox + # Returns the bounding box's factory. + attr_reader :factory + + # Returns true if this bounding box tracks Z coordinates. + attr_reader :has_z + + # Returns true if this bounding box tracks M coordinates. + attr_reader :has_m + + # Returns the minimum X, or nil if this bounding box is empty. + attr_reader :min_x + + # Returns the maximum X, or nil if this bounding box is empty. + attr_reader :max_x + + # Returns the minimum Y, or nil if this bounding box is empty. + attr_reader :min_y + + # Returns the maximum Y, or nil if this bounding box is empty. + attr_reader :max_y + + # Returns the minimum Z, or nil if this bounding box is empty. + attr_reader :min_z + + # Returns the maximum Z, or nil if this bounding box is empty. + attr_reader :max_z + + # Returns the minimum M, or nil if this bounding box is empty. + attr_reader :min_m + + # Returns the maximum M, or nil if this bounding box is empty. + attr_reader :max_m + # Create a bounding box given two corner points. # The bounding box will be given the factory of the first point. # You may also provide the same options available to @@ -69,19 +101,15 @@ def initialize(factory, opts = {}) end end - def eql?(rhs) # :nodoc: - rhs.is_a?(BoundingBox) && @factory == rhs.factory && - @min_x == rhs.min_x && @max_x == rhs.max_x && - @min_y == rhs.min_y && @max_y == rhs.max_y && - @min_z == rhs.min_z && @max_z == rhs.max_z && - @min_m == rhs.min_m && @max_m == rhs.max_m + def eql?(other) # :nodoc: + other.is_a?(BoundingBox) && @factory == other.factory && + @min_x == other.min_x && @max_x == other.max_x && + @min_y == other.min_y && @max_y == other.max_y && + @min_z == other.min_z && @max_z == other.max_z && + @min_m == other.min_m && @max_m == other.max_m end alias == eql? - # Returns the bounding box's factory. - - attr_reader :factory - # Returns true if this bounding box is still empty. def empty? @@ -105,22 +133,6 @@ def degenerate? @min_x && (@min_x == @max_x || @min_y == @max_y) end - # Returns true if this bounding box tracks Z coordinates. - - attr_reader :has_z - - # Returns true if this bounding box tracks M coordinates. - - attr_reader :has_m - - # Returns the minimum X, or nil if this bounding box is empty. - - attr_reader :min_x - - # Returns the maximum X, or nil if this bounding box is empty. - - attr_reader :max_x - # Returns the midpoint X, or nil if this bounding box is empty. def center_x @@ -133,14 +145,6 @@ def x_span @max_x ? @max_x - @min_x : 0 end - # Returns the minimum Y, or nil if this bounding box is empty. - - attr_reader :min_y - - # Returns the maximum Y, or nil if this bounding box is empty. - - attr_reader :max_y - # Returns the midpoint Y, or nil if this bounding box is empty. def center_y @@ -153,14 +157,6 @@ def y_span @max_y ? @max_y - @min_y : 0 end - # Returns the minimum Z, or nil if this bounding box is empty. - - attr_reader :min_z - - # Returns the maximum Z, or nil if this bounding box is empty. - - attr_reader :max_z - # Returns the midpoint Z, or nil if this bounding box is empty or has no Z. def center_z @@ -170,16 +166,12 @@ def center_z # Returns the Z span, 0 if this bounding box is empty, or nil if it has no Z. def z_span - @has_z ? (@max_z ? @max_z - @min_z : 0) : nil - end + return unless @has_z - # Returns the minimum M, or nil if this bounding box is empty. - - attr_reader :min_m + return 0 unless @max_z - # Returns the maximum M, or nil if this bounding box is empty. - - attr_reader :max_m + @max_z - @min_z + end # Returns the midpoint M, or nil if this bounding box is empty or has no M. @@ -190,31 +182,37 @@ def center_m # Returns the M span, 0 if this bounding box is empty, or nil if it has no M. def m_span - @has_m ? (@max_m ? @max_m - @min_m : 0) : nil + return unless @has_m + + return 0 unless @max_m + + @max_m - @min_m end # Returns a point representing the minimum extent in all dimensions, # or nil if this bounding box is empty. def min_point - if @min_x - extras = [] - extras << @min_z if @has_z - extras << @min_m if @has_m - @factory.point(@min_x, @min_y, *extras) - end + return unless @min_x + + extras = [] + extras << @min_z if @has_z + extras << @min_m if @has_m + + @factory.point(@min_x, @min_y, *extras) end # Returns a point representing the maximum extent in all dimensions, # or nil if this bounding box is empty. def max_point - if @min_x - extras = [] - extras << @max_z if @has_z - extras << @max_m if @has_m - @factory.point(@max_x, @max_y, *extras) - end + return unless @min_x + + extras = [] + extras << @max_z if @has_z + extras << @max_m if @has_m + + @factory.point(@max_x, @max_y, *extras) end # Adjusts the extents of this bounding box to encompass the given @@ -280,21 +278,18 @@ def to_geometry # have M. Default is false. def contains?(rhs, opts = {}) - if Feature::Geometry === rhs - contains?(BoundingBox.new(@factory).add(rhs)) - elsif rhs.empty? - true - elsif empty? - false - elsif @min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y - false - elsif @has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m) - false - elsif @has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z) # rubocop:disable Style/IfWithBooleanLiteralBranches - false - else - true - end + return contains?(BoundingBox.new(@factory).add(rhs)) if Feature::Geometry === rhs + + return true if rhs.empty? + + return false if empty? + + cmp_xymz = + (@min_x > rhs.min_x || @max_x < rhs.max_x || @min_y > rhs.min_y || @max_y < rhs.max_y) || + (@has_m && rhs.has_m && !opts[:ignore_m] && (@min_m > rhs.min_m || @max_m < rhs.max_m)) || + (@has_z && rhs.has_z && !opts[:ignore_z] && (@min_z > rhs.min_z || @max_z < rhs.max_z)) + + !cmp_xymz end # Returns this bounding box subdivided, as an array of bounding boxes. diff --git a/lib/rgeo/cartesian/calculations.rb b/lib/rgeo/cartesian/calculations.rb index f9c4a6de..a2719e4e 100644 --- a/lib/rgeo/cartesian/calculations.rb +++ b/lib/rgeo/cartesian/calculations.rb @@ -23,17 +23,14 @@ def initialize(start, stop) @lensq = @dx * @dx + @dy * @dy end - attr_reader :s - attr_reader :e - attr_reader :dx - attr_reader :dy + attr_reader :s, :e, :dx, :dy def to_s "#{@s} - #{@e}" end - def eql?(rhs) - rhs.is_a?(Segment) && @s == rhs.s && @e == rhs.e + def eql?(other) + other.is_a?(Segment) && @s == other.s && @e == other.e end alias == eql? @@ -45,23 +42,23 @@ def degenerate? # a positive value if the point is to the right, or # 0 if the point is collinear to the segment. - def side(p) - px = p.x - py = p.y + def side(point) + px = point.x + py = point.y (@sx - px) * (@ey - py) - (@sy - py) * (@ex - px) end - def tproj(p) + def tproj(point) if @lensq == 0 nil else - (@dx * (p.x - @sx) + @dy * (p.y - @sy)) / @lensq + (@dx * (point.x - @sx) + @dy * (point.y - @sy)) / @lensq end end - def contains_point?(p) - if side(p) == 0 - t = tproj(p) + def contains_point?(point) + if side(point) == 0 + t = tproj(point) t && t >= 0.0 && t <= 1.0 else false @@ -84,11 +81,9 @@ def segment_intersection(seg) s2 = seg.s # Handle degenerate cases if seg.degenerate? - if @lensq == 0 && @s == s2 - return @s - else - return contains_point?(s2) ? s2 : nil - end + return @s if @lensq == 0 && @s == s2 + + return contains_point?(s2) ? s2 : nil elsif @lensq == 0 return seg.contains_point?(@s) ? @s : nil end @@ -132,13 +127,12 @@ def segment_intersection(seg) # If this is the case, return the closest point from # either segment. int_pt = @s.factory.point(x, y) - if contains_point?(int_pt) - int_pt - else - # find closest of @s, @e, seg.s, seg.e - [@e, seg.s, seg.e].reduce(@s) do |closest, pt| - int_pt.distance(pt) < int_pt.distance(closest) ? pt : closest - end + + return int_pt if contains_point?(int_pt) + + # find closest of @s, @e, seg.s, seg.e + [@e, seg.s, seg.e].reduce(@s) do |closest, pt| + int_pt.distance(pt) < int_pt.distance(closest) ? pt : closest end end end diff --git a/lib/rgeo/cartesian/factory.rb b/lib/rgeo/cartesian/factory.rb index a4417fe6..1228a788 100644 --- a/lib/rgeo/cartesian/factory.rb +++ b/lib/rgeo/cartesian/factory.rb @@ -10,11 +10,18 @@ module RGeo module Cartesian # This class implements the factory for the simple cartesian # implementation. - class Factory include Feature::Factory::Instance include ImplHelper::Utils + attr_reader :coordinate_dimension, :spatial_dimension + + # Returns the SRID. + attr_reader :srid + + # See RGeo::Feature::Factory#coord_sys + attr_reader :coord_sys + # Create a new simple cartesian factory. # # See RGeo::Cartesian.simple_factory for a list of supported options. @@ -35,43 +42,46 @@ def initialize(opts = {}) @buffer_resolution = 1 if @buffer_resolution < 1 wkt_generator = opts[:wkt_generator] - case wkt_generator - when Hash - @wkt_generator = WKRep::WKTGenerator.new(wkt_generator) - else - @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper) - end + @wkt_generator = + case wkt_generator + when Hash + WKRep::WKTGenerator.new(wkt_generator) + else + WKRep::WKTGenerator.new(convert_case: :upper) + end wkb_generator = opts[:wkb_generator] - case wkb_generator - when Hash - @wkb_generator = WKRep::WKBGenerator.new(wkb_generator) - else - @wkb_generator = WKRep::WKBGenerator.new - end + @wkb_generator = + case wkb_generator + when Hash + WKRep::WKBGenerator.new(wkb_generator) + else + WKRep::WKBGenerator.new + end wkt_parser = opts[:wkt_parser] - case wkt_parser - when Hash - @wkt_parser = WKRep::WKTParser.new(self, wkt_parser) - else - @wkt_parser = WKRep::WKTParser.new(self) - end + @wkt_parser = + case wkt_parser + when Hash + WKRep::WKTParser.new(self, wkt_parser) + else + WKRep::WKTParser.new(self) + end wkb_parser = opts[:wkb_parser] - case wkb_parser - when Hash - @wkb_parser = WKRep::WKBParser.new(self, wkb_parser) - else - @wkb_parser = WKRep::WKBParser.new(self) - end + @wkb_parser = + case wkb_parser + when Hash + WKRep::WKBParser.new(self, wkb_parser) + else + WKRep::WKBParser.new(self) + end end - attr_reader :coordinate_dimension, :spatial_dimension # Equivalence test. - def eql?(rhs) - rhs.is_a?(self.class) && @srid == rhs.srid && - @has_z == rhs.property(:has_z_coordinate) && - @has_m == rhs.property(:has_m_coordinate) && - @coord_sys == rhs.instance_variable_get(:@coord_sys) + def eql?(other) + other.is_a?(self.class) && @srid == other.srid && + @has_z == other.property(:has_z_coordinate) && + @has_m == other.property(:has_m_coordinate) && + @coord_sys == other.instance_variable_get(:@coord_sys) end alias == eql? @@ -99,11 +109,10 @@ def marshal_dump # :nodoc: end def marshal_load(data) # :nodoc: - if (coord_sys_data = data["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = data["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) + end initialize( has_z_coordinate: data["hasz"], has_m_coordinate: data["hasm"], @@ -132,11 +141,10 @@ def encode_with(coder) # :nodoc: end def init_with(coder) # :nodoc: - if (coord_sys_data = coder["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = coder["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) + end initialize( has_z_coordinate: coder["has_z_coordinate"], has_m_coordinate: coder["has_m_coordinate"], @@ -150,10 +158,6 @@ def init_with(coder) # :nodoc: ) end - # Returns the SRID. - - attr_reader :srid - # See RGeo::Feature::Factory#property def property(name) @@ -183,8 +187,8 @@ def parse_wkb(str) # See RGeo::Feature::Factory#point - def point(x, y, *extra) - PointImpl.new(self, x, y, *extra) + def point(x_coord, y_coord, *extra) + PointImpl.new(self, x_coord, y_coord, *extra) end # See RGeo::Feature::Factory#line_string @@ -235,10 +239,6 @@ def multi_polygon(elems) MultiPolygonImpl.new(self, elems) end - # See RGeo::Feature::Factory#coord_sys - - attr_reader :coord_sys - def generate_wkt(obj) @wkt_generator.generate(obj) end diff --git a/lib/rgeo/cartesian/feature_classes.rb b/lib/rgeo/cartesian/feature_classes.rb index 725eba2d..5d11be59 100644 --- a/lib/rgeo/cartesian/feature_classes.rb +++ b/lib/rgeo/cartesian/feature_classes.rb @@ -9,7 +9,7 @@ require_relative "../impl_helper/validity_check" module RGeo - module Cartesian + module Cartesian # :nodoc: class PointImpl # :nodoc: include Feature::Point include ImplHelper::ValidityCheck diff --git a/lib/rgeo/cartesian/interface.rb b/lib/rgeo/cartesian/interface.rb index 7f1ea2a1..c764fe76 100644 --- a/lib/rgeo/cartesian/interface.rb +++ b/lib/rgeo/cartesian/interface.rb @@ -7,7 +7,7 @@ # ----------------------------------------------------------------------------- module RGeo - module Cartesian + module Cartesian # :nodoc: class << self # Creates and returns a cartesian factory of the preferred # Cartesian implementation. diff --git a/lib/rgeo/cartesian/planar_graph.rb b/lib/rgeo/cartesian/planar_graph.rb index 1f0bf92b..912eebe1 100644 --- a/lib/rgeo/cartesian/planar_graph.rb +++ b/lib/rgeo/cartesian/planar_graph.rb @@ -166,17 +166,15 @@ def intersection_map # list of intersections for that edge. s1_intersects = int.point != int.s1.s && int.point != int.s1.e if s1_intersects - unless intersection_map[int.s1] - intersection_map[int.s1] = [] - end + intersection_map[int.s1] = [] unless intersection_map[int.s1] intersection_map[int.s1] << int.point end s2_intersects = int.point != int.s2.s && int.point != int.s2.e + next unless s2_intersects - unless intersection_map[int.s2] - intersection_map[int.s2] = [] - end + + intersection_map[int.s2] = [] unless intersection_map[int.s2] intersection_map[int.s2] << int.point end intersection_map @@ -194,11 +192,9 @@ def create_half_edge(edge) insert_half_edge(e2) end - def insert_half_edge(he) - unless incident_edges[he.origin.coordinates] - @incident_edges[he.origin.coordinates] = [] - end - @incident_edges[he.origin.coordinates] << he + def insert_half_edge(half_edge) + @incident_edges[half_edge.origin.coordinates] = [] unless incident_edges[half_edge.origin.coordinates] + @incident_edges[half_edge.origin.coordinates] << half_edge end # Links all half-edges where possible. @@ -299,9 +295,7 @@ def add_geometry(geom) def add_line_string(geom) add_edges(geom.segments) - hedge = unless geom.empty? - @incident_edges[geom.start_point.coordinates].first - end + hedge = @incident_edges[geom.start_point.coordinates].first unless geom.empty? @geom_edges << GeomEdge.new(hedge, nil) end diff --git a/lib/rgeo/cartesian/sweepline_intersector.rb b/lib/rgeo/cartesian/sweepline_intersector.rb index 16741e5b..9c24de58 100644 --- a/lib/rgeo/cartesian/sweepline_intersector.rb +++ b/lib/rgeo/cartesian/sweepline_intersector.rb @@ -46,9 +46,7 @@ def proper_intersections s2 = intersection.s2 pt = intersection.point - unless (pt == s1.s && pt == s2.e) || (pt == s1.e && pt == s2.s) - @proper_intersections << intersection - end + @proper_intersections << intersection unless (pt == s1.s && pt == s2.e) || (pt == s1.e && pt == s2.s) end @proper_intersections end diff --git a/lib/rgeo/cartesian/valid_op.rb b/lib/rgeo/cartesian/valid_op.rb index 1bfa7413..49a5fd52 100644 --- a/lib/rgeo/cartesian/valid_op.rb +++ b/lib/rgeo/cartesian/valid_op.rb @@ -2,7 +2,7 @@ module RGeo module Cartesian - module ValidOp + module ValidOp # :nodoc: include ImplHelper::ValidOp def validity_helper @@ -10,7 +10,7 @@ def validity_helper end end - module ValidOpHelpers + module ValidOpHelpers # :nodoc: include ImplHelper::ValidOpHelpers module_function(*ImplHelper::ValidOpHelpers.singleton_methods) # rubocop:disable Style/AccessModifierDeclarations @@ -33,9 +33,7 @@ def check_consistent_area(poly) # if additional nodes were added, there must be an intersection # through a boundary. - if poly.send(:graph).incident_edges.size > num_points - return Error::SELF_INTERSECTION - end + return Error::SELF_INTERSECTION if poly.send(:graph).incident_edges.size > num_points rings = [poly.exterior_ring] + poly.interior_rings return Error::SELF_INTERSECTION if rings.uniq.size != rings.size diff --git a/lib/rgeo/coord_sys/cs/entities.rb b/lib/rgeo/coord_sys/cs/entities.rb index a5878f5f..13c48478 100644 --- a/lib/rgeo/coord_sys/cs/entities.rb +++ b/lib/rgeo/coord_sys/cs/entities.rb @@ -147,7 +147,6 @@ module CS # Coordinate Transformation spec. # # This is a non-instantiable abstract class. - class Base # Standard object inspection output @@ -158,8 +157,8 @@ def inspect # Tests for equality. Two objects are defined as equal if they # have the same type (class) and the same WKT representation. - def eql?(rhs) - rhs.class == self.class && rhs.to_wkt == to_wkt + def eql?(other) + other.class == self.class && other.to_wkt == to_wkt end alias == eql? @@ -183,16 +182,14 @@ def to_s def to_wkt(standard_brackets = false) open, close = brackets(standard_brackets) content = wkt_content(standard_brackets).map { |obj| ",#{obj}" }.join - if defined?(@authority) && @authority - authority = ",AUTHORITY#{open}#{@authority.inspect},#{@authority_code.inspect}#{close}" - else - authority = "" - end - if defined?(@extensions) && @extensions - extensions = @extensions.map { |k, v| ",EXTENSION#{open}#{k.inspect},#{v.inspect}#{close}" }.join - else - extensions = "" - end + authority = + defined?(@authority) && + @authority && + ",AUTHORITY#{open}#{@authority.inspect},#{@authority_code.inspect}#{close}" + extensions = + defined?(@extensions) && + @extensions && + @extensions.map { |k, v| ",EXTENSION#{open}#{k.inspect},#{v.inspect}#{close}" }.join "#{wkt_typename}#{open}#{@name.inspect}#{content}#{extensions}#{authority}#{close}" end @@ -205,12 +202,11 @@ def marshal_dump # :nodoc: def marshal_load(data) # :nodoc: data = data["wkt"] if data.is_a?(Hash) temp = CS.create_from_wkt(data) - if temp.class == self.class - temp.instance_variables.each do |iv| - instance_variable_set(iv, temp.instance_variable_get(iv)) - end - else - raise TypeError, "Bad Marshal data" + + raise TypeError, "Bad Marshal data" unless temp.instance_of?(self.class) + + temp.instance_variables.each do |iv| + instance_variable_set(iv, temp.instance_variable_get(iv)) end end @@ -222,12 +218,11 @@ def encode_with(coder) # :nodoc: def init_with(coder) # :nodoc: temp = CS.create_from_wkt(coder.type == :scalar ? coder.scalar : coder["wkt"]) - if temp.class == self.class - temp.instance_variables.each do |iv| - instance_variable_set(iv, temp.instance_variable_get(iv)) - end - else - raise TypeError, "Bad YAML data" + + raise TypeError, "Bad YAML data" unless temp.instance_of?(self.class) + + temp.instance_variables.each do |iv| + instance_variable_set(iv, temp.instance_variable_get(iv)) end end @@ -246,7 +241,6 @@ def brackets(standard) # # Details of axis. This is used to label axes, and indicate the # orientation. - class AxisInfo < Base # :stopdoc: NAMES_BY_VALUE = %w[OTHER NORTH SOUTH EAST WEST UP DOWN].freeze @@ -254,12 +248,13 @@ class AxisInfo < Base def initialize(name, orientation) # :nodoc: @name = name - case orientation - when String, Symbol - @orientation = NAMES_BY_VALUE.index(orientation.to_s.upcase).to_i - else - @orientation = orientation.to_i - end + @orientation = + case orientation + when String, Symbol + NAMES_BY_VALUE.index(orientation.to_s.upcase).to_i + else + orientation.to_i + end end # Human readable name for axis. Possible values are "X", "Y", @@ -301,7 +296,6 @@ def wkt_content(_) # projected coordinate system. The angular units of parameter # values match the angular units of the geographic coordinate # system that the projected coordinate system is based on. - class ProjectionParameter < Base def initialize(name, value) # :nodoc: @name = name @@ -339,15 +333,14 @@ def wkt_content(_) # Wolf parameters should be applied to geocentric coordinates, where # the X axis points towards the Greenwich Prime Meridian, the Y axis # points East, and the Z axis points North. - class WGS84ConversionInfo < Base - def initialize(dx, dy, dz, ex, ey, ez, ppm) # :nodoc: - @dx = dx.to_f - @dy = dy.to_f - @dz = dz.to_f - @ex = ex.to_f - @ey = ey.to_f - @ez = ez.to_f + def initialize(dxm, dym, dzm, exas, eyas, ezas, ppm) # :nodoc: + @dx = dxm.to_f + @dy = dym.to_f + @dz = dzm.to_f + @ex = exas.to_f + @ey = eyas.to_f + @ez = ezas.to_f @ppm = ppm.to_f end @@ -383,8 +376,8 @@ class << self # The Bursa Wolf shift should be in meters, the rotation in arc # seconds, and the scaling in parts per million. - def create(dx, dy, dz, ex, ey, ez, ppm) - new(dx, dy, dz, ex, ey, ez, ppm) + def create(dxm, dym, dzm, exas, eyas, ezas, ppm) + new(dxm, dym, dzm, exas, eyas, ezas, ppm) end end end @@ -427,9 +420,9 @@ def create(dx, dy, dz, ex, ey, ez, ppm) # * alias: an alias # * remarks: provider-supplied remarks. # * extensions: a hash of extension keys and values - class Info < Base - def initialize(name, authority = nil, authority_code = nil, abbreviation = nil, init_alias = nil, remarks = nil, extensions = nil) # :nodoc: + def initialize(name, authority = nil, authority_code = nil, abbreviation = nil, init_alias = nil, + remarks = nil, extensions = nil) # :nodoc: @name = name @authority = authority ? authority.to_s : nil @authority_code = authority_code ? authority_code.to_s : nil @@ -488,7 +481,6 @@ def extension(key) # Normally, you will instantiate one of the subclasses LinearUnit or # AngularUnit. However, it is possible to instantiate Unit if it is # not clear whether the data refers to a LinearUnit or AngularUnit. - class Unit < Info def initialize(name, conversion_factor, *optional) # :nodoc: super(name, *optional) @@ -525,7 +517,6 @@ def wkt_content(_) # == OGC spec description # # Definition of linear units. - class LinearUnit < Unit # Returns the number of meters per LinearUnit. # Also available as Unit#conversion_factor. @@ -548,7 +539,6 @@ def create(name, meters_per_unit, *optional) # == OGC spec description # # Definition of angular units. - class AngularUnit < Unit # Returns the number of radians per AngularUnit. # Also available as Unit#conversion_factor. @@ -571,7 +561,6 @@ def create(name, radians_per_unit, *optional) # == OGC spec description # # A meridian used to take longitude measurements from. - class PrimeMeridian < Info def initialize(name, angular_unit, longitude, *optional) # :nodoc: super(name, *optional) @@ -611,9 +600,9 @@ def wkt_content(_) # == OGC spec description # # An approximation of the Earth's surface as a squashed sphere. - class Ellipsoid < Info - def initialize(name, semi_major_axis, semi_minor_axis, inverse_flattening, ivf_definitive, linear_unit, *optional) # :nodoc: + def initialize(name, semi_major_axis, semi_minor_axis, inverse_flattening, ivf_definitive, + linear_unit, *optional) # :nodoc: super(name, *optional) @semi_major_axis = semi_major_axis.to_f @semi_minor_axis = semi_minor_axis.to_f @@ -718,7 +707,6 @@ def wkt_content(_) # This is a non-instantiable abstract class. You must instantiate # one of the subclasses HorizontalDatum, VerticalDatum, or # LocalDatum. - class Datum < Info def initialize(name, datum_type, *optional) # :nodoc: super(name, *optional) @@ -738,7 +726,6 @@ def wkt_content(_) # == OGC spec description # # Procedure used to measure vertical distances. - class VerticalDatum < Datum def wkt_typename "VERT_DATUM" @@ -768,7 +755,6 @@ def wkt_content(_) # coordinates can be transformed between two different local # coordinate systems, as long as they are based on the same local # datum. - class LocalDatum < Datum def wkt_typename "LOCAL_DATUM" @@ -794,7 +780,6 @@ def wkt_content(_) # == OGC spec description # # Procedure used to measure positions on the surface of the Earth. - class HorizontalDatum < Datum def initialize(name, datum_type, ellipsoid, wgs84_parameters, *optional) # :nodoc: super(name, datum_type, *optional) @@ -837,7 +822,6 @@ def wkt_content(standard_brackets) # == OGC spec description # # A projection from geographic coordinates to projected coordinates. - class Projection < Info def initialize(name, class_name, parameters, *optional) # :nodoc: super(name, *optional) @@ -916,7 +900,6 @@ def wkt_content(_) # GeographicCoordinateSystem, ProjectedCoordinateSystem, # VerticalCoordinateSystem, LocalCoordinateSystem, or # CompoundCoordinateSystem. - class CoordinateSystem < Info def initialize(name, dimension, *optional) # :nodoc: super(name, *optional) @@ -929,14 +912,14 @@ def initialize(name, dimension, *optional) # :nodoc: # Gets axis details for dimension within coordinate system. Each # dimension in the coordinate system has a corresponding axis. - def get_axis(dimension) + def get_axis(_dimension) nil end # Gets units for dimension within coordinate system. Each # dimension in the coordinate system has corresponding units. - def get_units(dimension) + def get_units(_dimension) nil end @@ -954,9 +937,9 @@ def wkt_typename # Not an OGC method, but useful for being able to # transform directly from a CoordinateSystem object. - def transform_coords(target_cs, x, y, z = nil) + def transform_coords(target_cs, x_coord, y_coord, z_coord = nil) ct = CoordinateTransform.create(self, target_cs) - ct.transform_coords(x, y, z) + ct.transform_coords(x_coord, y_coord, z_coord) end class << self @@ -993,7 +976,6 @@ def wkt_content(_) # as a geographic or a projected coordinate system with a horizontal # datum. The other is a vertical CRS which is a one-dimensional # coordinate system with a vertical datum. - class CompoundCoordinateSystem < CoordinateSystem def initialize(name, head, tail, *optional) # :nodoc: super(name, head.dimension + tail.dimension, *optional) @@ -1060,7 +1042,6 @@ def wkt_content(standard_brackets) # # RGeo's implementation does not provide the Coordinate # Transformation (CT) package. - class LocalCoordinateSystem < CoordinateSystem def initialize(name, local_datum, unit, axes, *optional) # :nodoc: super(name, axes.size, *optional) @@ -1080,7 +1061,7 @@ def get_axis(index) # Implements CoordinateSystem#get_units - def get_units(index) + def get_units(_index) @unit end @@ -1117,7 +1098,6 @@ def wkt_content(standard_brackets) # the Z axis will point North, and the Y axis will point East (e.g. # a right handed system), but you should check the axes for # non-default values. - class GeocentricCoordinateSystem < CoordinateSystem def initialize(name, horizontal_datum, prime_meridian, linear_unit, axis0, axis1, axis2, *optional) # :nodoc: super(name, 3, *optional) @@ -1143,7 +1123,7 @@ def initialize(name, horizontal_datum, prime_meridian, linear_unit, axis0, axis1 # Implements CoordinateSystem#get_units - def get_units(index) + def get_units(_index) @linear_unit end @@ -1192,7 +1172,6 @@ def wkt_content(standard_brackets) # # A one-dimensional coordinate system suitable for vertical # measurements. - class VerticalCoordinateSystem < CoordinateSystem def initialize(name, vertical_datum, vertical_unit, axis, *optional) # :nodoc: super(name, 1, *optional) @@ -1210,13 +1189,13 @@ def initialize(name, vertical_datum, vertical_unit, axis, *optional) # :nodoc: # Implements CoordinateSystem#get_units - def get_units(index) + def get_units(_index) @vertical_unit end # Implements CoordinateSystem#get_axis - def get_axis(index) + def get_axis(_index) @axis end @@ -1253,7 +1232,6 @@ def wkt_content(standard_brackets) # This is a non-instantiable abstract class. You must instantiate # one of the subclasses GeographicCoordinateSystem or # ProjectedCoordinateSystem. - class HorizontalCoordinateSystem < CoordinateSystem def initialize(name, horizontal_datum, *optional) # :nodoc: super(name, 2, *optional) @@ -1271,7 +1249,6 @@ def initialize(name, horizontal_datum, *optional) # :nodoc: # You can find out which this is by examining the axes. You should # also check the angular units, since not all geographic coordinate # systems use degrees. - class GeographicCoordinateSystem < HorizontalCoordinateSystem def initialize(name, angular_unit, horizontal_datum, prime_meridian, axis0, axis1, *optional) # :nodoc: super(name, horizontal_datum, *optional) @@ -1290,7 +1267,7 @@ def initialize(name, angular_unit, horizontal_datum, prime_meridian, axis0, axis # Implements CoordinateSystem#get_units - def get_units(index) + def get_units(_index) @angular_unit end @@ -1312,7 +1289,7 @@ def num_conversion_to_wgs84 # of interest. The first conversion (with index=0) should provide # acceptable accuracy over the largest possible area of interest. - def get_wgs84_conversion_info(index) + def get_wgs84_conversion_info(_index) @horizontal_datum.wgs84_parameters end @@ -1353,7 +1330,6 @@ def wkt_content(standard_brackets) # == OGC spec description # # A 2D cartographic coordinate system. - class ProjectedCoordinateSystem < HorizontalCoordinateSystem def initialize(name, geographic_coordinate_system, projection, linear_unit, axis0, axis1, *optional) # :nodoc: super(name, geographic_coordinate_system.horizontal_datum, *optional) @@ -1376,7 +1352,7 @@ def initialize(name, geographic_coordinate_system, projection, linear_unit, axis # Implements CoordinateSystem#get_units - def get_units(index) + def get_units(_index) @linear_unit end @@ -1517,11 +1493,11 @@ def codomain_convex_hull(points) # Transforms a coordinate point. The passed parameter point should not be modified. # - # @param [Integer] x - # @param [Integer] y - # @param [Integer] z optional + # @param [Integer] x_coord + # @param [Integer] y_coord + # @param [Integer] z_coord optional # @return [Array] transformed point coordinates in (x,y,z) order - def transform_coords(x, y, z = nil) + def transform_coords(x_coord, y_coord, z_coord = nil) raise NotImplementedError, "#{__method__} is not implemented in the abstract CoordinateTransform class." end diff --git a/lib/rgeo/coord_sys/cs/factories.rb b/lib/rgeo/coord_sys/cs/factories.rb index 9c82c8c6..69010ec2 100644 --- a/lib/rgeo/coord_sys/cs/factories.rb +++ b/lib/rgeo/coord_sys/cs/factories.rb @@ -28,7 +28,6 @@ module CoordSys # * FittedCoordinateSystem is not implemented. # * The defaultEnvelope attribute of CS_CoordinateSystem is not # implemented. - module CS # A class implementing the CS_CoordinateSystemFactory interface. # It provides methods for building up complex objects from simpler @@ -37,7 +36,6 @@ module CS # Note that the methods of CS_CoordinateSystemFactory do not provide # facilities for setting the authority. If you need to set authority # values, use the create methods for the object classes themselves. - class CoordinateSystemFactory # Create a CompoundCoordinateSystem from a name, and two # constituent coordinate systems. diff --git a/lib/rgeo/coord_sys/cs/wkt_parser.rb b/lib/rgeo/coord_sys/cs/wkt_parser.rb index 7737510b..947a5c40 100644 --- a/lib/rgeo/coord_sys/cs/wkt_parser.rb +++ b/lib/rgeo/coord_sys/cs/wkt_parser.rb @@ -23,9 +23,11 @@ def parse(containing_type = nil) # :nodoc: next_token return value end + unless @cur_token.is_a?(TypeString) raise Error::ParseError, "Found token #{@cur_token} when we expected a value" end + type = @cur_token next_token consume_tokentype(:begin) @@ -47,9 +49,11 @@ def parse(containing_type = nil) # :nodoc: obj = AxisInfo.create(args.shift(QuotedString), args.shift(TypeString)) when "TOWGS84" bursa_wolf_params = args.find_all(Numeric) + unless bursa_wolf_params.size == 7 raise Error::ParseError, "Expected 7 Bursa Wolf parameters but found #{bursa_wolf_params.size}" end + obj = WGS84ConversionInfo.create(*bursa_wolf_params) when "UNIT" klass = case containing_type @@ -66,7 +70,13 @@ def parse(containing_type = nil) # :nodoc: when "PRIMEM" obj = PrimeMeridian.create(args.shift(QuotedString), nil, args.shift(Numeric), *args.create_optionals) when "SPHEROID" - obj = Ellipsoid.create_flattened_sphere(args.shift(QuotedString), args.shift(Numeric), args.shift(Numeric), args.find_first(LinearUnit), *args.create_optionals) + obj = Ellipsoid.create_flattened_sphere( + args.shift(QuotedString), + args.shift(Numeric), + args.shift(Numeric), + args.find_first(LinearUnit), + *args.create_optionals + ) when "PROJECTION" name = args.shift(QuotedString) obj = Projection.create(name, name, args.find_all(ProjectionParameter), *args.create_optionals) @@ -87,15 +97,18 @@ def parse(containing_type = nil) # :nodoc: optionals = args.create_optionals obj = CoordinateSystem.create(defn, dim, *optionals) when "COMPD_CS" - obj = CompoundCoordinateSystem.create(args.shift(QuotedString), args.shift(CoordinateSystem), args.shift(CoordinateSystem), *args.create_optionals) + obj = CompoundCoordinateSystem.create( + args.shift(QuotedString), + args.shift(CoordinateSystem), + args.shift(CoordinateSystem), + *args.create_optionals + ) when "LOCAL_CS" name = args.shift(QuotedString) local_datum = args.find_first(LocalDatum) unit = args.find_first(Unit) axes = args.find_all(AxisInfo) - unless axes.size > 0 - raise Error::ParseError, "Expected at least one AXIS in a LOCAL_CS" - end + raise Error::ParseError, "Expected at least one AXIS in a LOCAL_CS" unless axes.size > 0 obj = LocalCoordinateSystem.create(name, local_datum, unit, axes, *args.create_optionals) when "GEOCCS" name = args.shift(QuotedString) @@ -103,10 +116,21 @@ def parse(containing_type = nil) # :nodoc: prime_meridian = args.find_first(PrimeMeridian) linear_unit = args.find_first(LinearUnit) axes = args.find_all(AxisInfo) + unless axes.size == 0 || axes.size == 3 raise Error::ParseError, "GEOCCS must contain either 0 or 3 AXIS parameters" end - obj = GeocentricCoordinateSystem.create(name, horizontal_datum, prime_meridian, linear_unit, axes[0], axes[1], axes[2], *args.create_optionals) + + obj = GeocentricCoordinateSystem.create( + name, + horizontal_datum, + prime_meridian, + linear_unit, + axes[0], + axes[1], + axes[2], + *args.create_optionals + ) when "VERT_CS" name = args.shift(QuotedString) vertical_datum = args.find_first(VerticalDatum) @@ -119,10 +143,20 @@ def parse(containing_type = nil) # :nodoc: prime_meridian = args.find_first(PrimeMeridian) angular_unit = args.find_first(AngularUnit) axes = args.find_all(AxisInfo) + unless axes.size == 0 || axes.size == 2 raise Error::ParseError, "GEOGCS must contain either 0 or 2 AXIS parameters" end - obj = GeographicCoordinateSystem.create(name, angular_unit, horizontal_datum, prime_meridian, axes[0], axes[1], *args.create_optionals) + + obj = GeographicCoordinateSystem.create( + name, + angular_unit, + horizontal_datum, + prime_meridian, + axes[0], + axes[1], + *args.create_optionals + ) when "PROJCS" name = args.shift(QuotedString) geographic_coordinate_system = args.find_first(GeographicCoordinateSystem) @@ -131,10 +165,20 @@ def parse(containing_type = nil) # :nodoc: projection.instance_variable_get(:@parameters).concat(parameters) linear_unit = args.find_first(LinearUnit) axes = args.find_all(AxisInfo) + unless axes.size == 0 || axes.size == 2 raise Error::ParseError, "PROJCS must contain either 0 or 2 AXIS parameters" end - obj = ProjectedCoordinateSystem.create(name, geographic_coordinate_system, projection, linear_unit, axes[0], axes[1], *args.create_optionals) + + obj = ProjectedCoordinateSystem.create( + name, + geographic_coordinate_system, + projection, + linear_unit, + axes[0], + axes[1], + *args.create_optionals + ) else raise Error::ParseError, "Unrecognized type: #{type}" end @@ -150,9 +194,9 @@ def consume_tokentype(type) # :nodoc: end def expect_tokentype(type) # :nodoc: - unless type === @cur_token - raise Error::ParseError, "#{type.inspect} expected but #{@cur_token.inspect} found." - end + return if type === @cur_token + + raise Error::ParseError, "#{type.inspect} expected but #{@cur_token.inspect} found." end def next_token # :nodoc: @@ -176,13 +220,14 @@ def next_token # :nodoc: when "", nil @cur_token = nil else - @scanner.scan_until(/[^\s\(\)\[\],"]+/) + @scanner.scan_until(/[^\s()\[\],"]+/) token = @scanner.matched - if token =~ /^[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?$/ - @cur_token = token.to_f - else + + unless token =~ /^[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?$/ raise Error::ParseError, "Bad token: #{token.inspect}" end + + @cur_token = token.to_f end @cur_token end @@ -207,13 +252,12 @@ def to_a # :nodoc: end class ExtensionClause # :nodoc: + attr_reader :key, :value + def initialize(key, value) # :nodoc: @key = key @value = value end - - attr_reader :key # :nodoc: - attr_reader :value # :nodoc: end class ArgumentList # :nodoc: @@ -226,12 +270,13 @@ def <<(value) # :nodoc: end def assert_empty # :nodoc: - if @values.size > 0 - names = @values.map do |val| - val.is_a?(Base) ? val.wkt_typename : val.inspect - end - raise Error::ParseError, "#{@values.size} unexpected arguments: #{names.join(', ')}" + return if @values.size.zero? + + names = @values.map do |val| + val.is_a?(Base) ? val.wkt_typename : val.inspect end + + raise Error::ParseError, "#{@values.size} unexpected arguments: #{names.join(', ')}" end def find_first(klass) # :nodoc: @@ -266,12 +311,8 @@ def create_optionals # :nodoc: def shift(klass = nil) # :nodoc: val = @values.shift - unless val - raise Error::ParseError, "No arguments left... expected #{klass}" - end - if klass && !val.is_a?(klass) - raise Error::ParseError, "Expected #{klass} but got #{val.class}" - end + raise Error::ParseError, "No arguments left... expected #{klass}" unless val + raise Error::ParseError, "Expected #{klass} but got #{val.class}" if klass && !val.is_a?(klass) val end end diff --git a/lib/rgeo/feature/curve.rb b/lib/rgeo/feature/curve.rb index e46feb68..a2cb4c3a 100644 --- a/lib/rgeo/feature/curve.rb +++ b/lib/rgeo/feature/curve.rb @@ -40,7 +40,6 @@ module Feature # class method (or === operator) defined in the Type module. # # Some implementations may support higher dimensional points. - module Curve include Geometry extend Type diff --git a/lib/rgeo/feature/factory.rb b/lib/rgeo/feature/factory.rb index 81222111..3cadef48 100644 --- a/lib/rgeo/feature/factory.rb +++ b/lib/rgeo/feature/factory.rb @@ -30,12 +30,10 @@ module Feature # is provided. All factory implementation classes MUST include # Factory::Instance, and you may use it in is_a?, # ===, and case-when constructs. - module Factory # All factory implementations MUST include this submodule. # This serves as a marker that may be used to test an object for # factory-ness. - module Instance end @@ -74,21 +72,21 @@ module Instance # information is present about whether the coordinate system is # meant to be so interpreted. - def property(name) + def property(_name) nil end # Parse the given string in well-known-text format and return the # resulting feature. Returns nil if the string couldn't be parsed. - def parse_wkt(str) + def parse_wkt(_str) nil end # Parse the given string in well-known-binary format and return the # resulting feature. Returns nil if the string couldn't be parsed. - def parse_wkb(str) + def parse_wkb(_str) nil end @@ -99,7 +97,7 @@ def parse_wkb(str) # supported. If both Z and M coordinates are supported, Z should # be passed first. - def point(x, y, *extra) + def point(_x_coord, _y_coord, *_extra) nil end @@ -112,7 +110,7 @@ def point(x, y, *extra) # result of building geometries from objects of the wrong factory # is undefined. - def line_string(points) + def line_string(_points) nil end @@ -125,7 +123,7 @@ def line_string(points) # result of building geometries from objects of the wrong factory # is undefined. - def line(start, stop) + def line(_start, _stop) nil end @@ -141,7 +139,7 @@ def line(start, stop) # result of building geometries from objects of the wrong factory # is undefined. - def linear_ring(points) + def linear_ring(_points) nil end @@ -157,7 +155,7 @@ def linear_ring(points) # result of building geometries from objects of the wrong factory # is undefined. - def polygon(outer_ring, inner_rings = nil) + def polygon(_outer_ring, _inner_rings = nil) nil end @@ -169,7 +167,7 @@ def polygon(outer_ring, inner_rings = nil) # result of building geometries from objects of the wrong factory # is undefined. - def collection(elems) + def collection(_elems) nil end @@ -184,7 +182,7 @@ def collection(elems) # result of building geometries from objects of the wrong factory # is undefined. - def multi_point(elems) + def multi_point(_elems) nil end @@ -199,7 +197,7 @@ def multi_point(elems) # result of building geometries from objects of the wrong factory # is undefined. - def multi_line_string(elems) + def multi_line_string(_elems) nil end @@ -216,7 +214,7 @@ def multi_line_string(elems) # result of building geometries from objects of the wrong factory # is undefined. - def multi_polygon(elems) + def multi_polygon(_elems) nil end @@ -264,7 +262,7 @@ def coord_sys # algorithm to cast the object. Therefore, by default, you should # return false. - def override_cast(original, type, flags) + def override_cast(_original, _type, _flags) false end end diff --git a/lib/rgeo/feature/factory_generator.rb b/lib/rgeo/feature/factory_generator.rb index 54afee59..408638a1 100644 --- a/lib/rgeo/feature/factory_generator.rb +++ b/lib/rgeo/feature/factory_generator.rb @@ -31,7 +31,6 @@ module Feature # necessarily include this module itself. Therefore, you should not # depend on the kind_of? method to determine if an object is a # factory generator. - module FactoryGenerator # Generate a factory given a configuration as a hash. # @@ -67,7 +66,7 @@ module FactoryGenerator # [:has_m_coordinate] # Support M coordinates. Default is usually false. - def call(config = {}) + def call(_config = {}) nil end @@ -75,7 +74,7 @@ def call(config = {}) # factory. def self.single(factory) - proc { |c| factory } + proc { |_c| factory } end # Return a new FactoryGenerator that calls the given delegate, but @@ -84,7 +83,7 @@ def self.single(factory) # force certain values to override the given configuration. def self.decorate(delegate, default_config = {}, force_config = {}) - proc { |c| delegate_.call(default_config.merge(c).merge(force_config)) } + proc { |c| delegate.call(default_config.merge(c).merge(force_config)) } end end end diff --git a/lib/rgeo/feature/geometry.rb b/lib/rgeo/feature/geometry.rb index 7a0b1fa9..ad182bd7 100644 --- a/lib/rgeo/feature/geometry.rb +++ b/lib/rgeo/feature/geometry.rb @@ -78,7 +78,6 @@ module Feature # Therefore, if an implementation cannot provide a suitable test for # their equivalence types, they must degrade to use a stronger form # of equivalence. - module Geometry extend Type @@ -294,7 +293,7 @@ def boundary # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def equals?(another_geometry) + def equals?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#equals? not defined." end @@ -313,7 +312,7 @@ def equals?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def disjoint?(another_geometry) + def disjoint?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#disjoint? not defined." end @@ -332,7 +331,7 @@ def disjoint?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def intersects?(another_geometry) + def intersects?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#intersects? not defined." end @@ -351,7 +350,7 @@ def intersects?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def touches?(another_geometry) + def touches?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#touches? not defined." end @@ -370,7 +369,7 @@ def touches?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def crosses?(another_geometry) + def crosses?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#crosses? not defined." end @@ -389,7 +388,7 @@ def crosses?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def within?(another_geometry) + def within?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#within? not defined." end @@ -408,7 +407,7 @@ def within?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def contains?(another_geometry) + def contains?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#contains? not defined." end @@ -427,7 +426,7 @@ def contains?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def overlaps?(another_geometry) + def overlaps?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#overlaps? not defined." end @@ -453,7 +452,7 @@ def overlaps?(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def relate?(another_geometry, _intersection_pattern_matrix_) + def relate?(_another_geometry, _intersection_pattern_matrix_) raise Error::UnsupportedOperation, "Method #{self.class}#relate not defined." end @@ -499,7 +498,7 @@ def locate_between # this geometry, strictly speaking, the result of measuring the # distance between objects from different factories is undefined. - def distance(another_geometry) + def distance(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#distance not defined." end @@ -545,7 +544,7 @@ def convex_hull # this geometry, strictly speaking, the result of performing # operations on objects from different factories is undefined. - def intersection(another_geometry) + def intersection(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#intersection not defined." end @@ -563,7 +562,7 @@ def intersection(another_geometry) # this geometry, strictly speaking, the result of performing # operations on objects from different factories is undefined. - def union(another_geometry) + def union(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#union not defined." end @@ -581,7 +580,7 @@ def union(another_geometry) # this geometry, strictly speaking, the result of performing # operations on objects from different factories is undefined. - def difference(another_geometry) + def difference(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#difference not defined." end @@ -599,7 +598,7 @@ def difference(another_geometry) # this geometry, strictly speaking, the result of performing # operations on objects from different factories is undefined. - def sym_difference(another_geometry) + def sym_difference(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#sym_difference not defined." end @@ -611,7 +610,7 @@ def sym_difference(another_geometry) # this geometry, strictly speaking, the result of comparing objects # from different factories is undefined. - def rep_equals?(another_geometry) + def rep_equals?(_another_geometry) raise Error::UnsupportedOperation, "Method #{self.class}#rep_equals? not defined." end @@ -647,12 +646,12 @@ def unary_union # representational equivalence test, this method must fall back on # objective equivalence. - def eql?(rhs) - if rhs.is_a?(RGeo::Feature::Instance) + def eql?(other) + if other.is_a?(RGeo::Feature::Instance) begin - rep_equals?(rhs) + rep_equals?(other) rescue Error::UnsupportedOperation - equal?(rhs) + equal?(other) end else false @@ -673,12 +672,12 @@ def eql?(rhs) # test, the == operator must fall back on representational or # objective equivalence. - def ==(rhs) - if rhs.is_a?(RGeo::Feature::Instance) + def ==(other) + if other.is_a?(RGeo::Feature::Instance) begin - equals?(rhs) + equals?(other) rescue Error::UnsupportedOperation - eql?(rhs) + eql?(other) end else false @@ -690,8 +689,8 @@ def ==(rhs) # types is not specified; an implementation may choose to provide # additional capabilities as appropriate. - def -(rhs) - difference(rhs) + def -(other) + difference(other) end # If the given rhs is a geometry object, this operator must behave @@ -699,8 +698,8 @@ def -(rhs) # is not specified; an implementation may choose to provide # additional capabilities as appropriate. - def +(rhs) - union(rhs) + def +(other) + union(other) end # If the given rhs is a geometry object, this operator must behave @@ -708,8 +707,8 @@ def +(rhs) # types is not specified; an implementation may choose to provide # additional capabilities as appropriate. - def *(rhs) - intersection(rhs) + def *(other) + intersection(other) end end end diff --git a/lib/rgeo/feature/geometry_collection.rb b/lib/rgeo/feature/geometry_collection.rb index 2725ffba..bfae4dcc 100644 --- a/lib/rgeo/feature/geometry_collection.rb +++ b/lib/rgeo/feature/geometry_collection.rb @@ -28,7 +28,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module GeometryCollection include Geometry extend Type @@ -58,7 +57,7 @@ def num_geometries # Also note that this method is different from GeometryCollection#[] # in that it does not support negative indexes. - def geometry_n(n) + def geometry_n(_idx) raise Error::UnsupportedOperation, "Method #{self.class}#geometry_n not defined." end @@ -78,7 +77,7 @@ def size # the same way Ruby's array indexing works. Hence, geometry_n(-1) # returns nil, where [-1] returns the last element of the collection. - def [](n) + def [](_idx) raise Error::UnsupportedOperation, "Method #{self.class}#[] not defined." end @@ -95,7 +94,7 @@ def node # Note that all GeometryCollection implementations must also # include the Enumerable mixin. - def each(&block) + def each(&_block) raise Error::UnsupportedOperation, "Method #{self.class}#each not defined." end diff --git a/lib/rgeo/feature/line_string.rb b/lib/rgeo/feature/line_string.rb index b4cb74dd..6910536a 100644 --- a/lib/rgeo/feature/line_string.rb +++ b/lib/rgeo/feature/line_string.rb @@ -20,7 +20,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module LineString include Curve extend Type @@ -47,7 +46,7 @@ def num_points # if the given N is out of range. N is zero-based. # Does not support negative indexes. - def point_n(n) + def point_n(_idx) raise Error::UnsupportedOperation, "Method #{self.class}#point_n not defined." end diff --git a/lib/rgeo/feature/linear_ring.rb b/lib/rgeo/feature/linear_ring.rb index f9bac283..e8f8ff85 100644 --- a/lib/rgeo/feature/linear_ring.rb +++ b/lib/rgeo/feature/linear_ring.rb @@ -19,7 +19,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module LinearRing include LineString extend Type diff --git a/lib/rgeo/feature/multi_curve.rb b/lib/rgeo/feature/multi_curve.rb index e5fc9b17..1d43350b 100644 --- a/lib/rgeo/feature/multi_curve.rb +++ b/lib/rgeo/feature/multi_curve.rb @@ -37,7 +37,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module MultiCurve include GeometryCollection extend Type diff --git a/lib/rgeo/feature/multi_surface.rb b/lib/rgeo/feature/multi_surface.rb index 54a5e00a..3f9f59cd 100644 --- a/lib/rgeo/feature/multi_surface.rb +++ b/lib/rgeo/feature/multi_surface.rb @@ -28,7 +28,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module MultiSurface include GeometryCollection extend Type diff --git a/lib/rgeo/feature/point.rb b/lib/rgeo/feature/point.rb index 4bc79aeb..9d986917 100644 --- a/lib/rgeo/feature/point.rb +++ b/lib/rgeo/feature/point.rb @@ -33,7 +33,6 @@ module Feature # replace them with empty GeometryCollection objects. Therefore, # currently, every RGeo Point object represents an actual location # with real coordinates. - module Point include Geometry extend Type diff --git a/lib/rgeo/feature/polygon.rb b/lib/rgeo/feature/polygon.rb index 9878d2cc..652c7e73 100644 --- a/lib/rgeo/feature/polygon.rb +++ b/lib/rgeo/feature/polygon.rb @@ -45,7 +45,6 @@ module Feature # include this module itself. Therefore, you should not depend on the # kind_of? method to check type. Instead, use the provided check_type # class method (or === operator) defined in the Type module. - module Polygon include Surface extend Type @@ -84,7 +83,7 @@ def num_interior_rings # if the given N is out of range. N is zero-based. # Does not support negative indexes. - def interior_ring_n(n) + def interior_ring_n(_idx) raise Error::UnsupportedOperation, "Method Polygon#interior_ring_n not defined." end diff --git a/lib/rgeo/feature/surface.rb b/lib/rgeo/feature/surface.rb index 3ea1073e..6a67edee 100644 --- a/lib/rgeo/feature/surface.rb +++ b/lib/rgeo/feature/surface.rb @@ -34,7 +34,6 @@ module Feature # class method (or === operator) defined in the Type module. # # Some implementations may support higher dimensional points. - module Surface include Geometry extend Type diff --git a/lib/rgeo/feature/types.rb b/lib/rgeo/feature/types.rb index 99c575c6..61e13c83 100644 --- a/lib/rgeo/feature/types.rb +++ b/lib/rgeo/feature/types.rb @@ -7,11 +7,10 @@ # ----------------------------------------------------------------------------- module RGeo - module Feature + module Feature # :nodoc: # All geometry implementations MUST include this submodule. # This serves as a marker that may be used to test an object for # feature-ness. - module Instance end @@ -49,7 +48,6 @@ module Instance # a particular object is a feature type: # # RGeo::Feature::Type === object.geometry_type # true - module Type # Returns true if the given object is this type or a subtype # thereof, or if it is a feature object whose geometry_type is @@ -192,92 +190,84 @@ def cast(obj, *params) # Types are the same if nfactory == factory force_new ? obj.dup : obj - else - if type == Point - cs = ncs = nil - if project - cs = factory.coord_sys - ncs = nfactory.coord_sys - end - hasz = factory.property(:has_z_coordinate) - nhasz = nfactory.property(:has_z_coordinate) - if cs && ncs - coords = cs.transform_coords(ncs, obj.x, obj.y, hasz ? obj.z : nil) - coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3 - else - coords = [obj.x, obj.y] - coords << (hasz ? obj.z : 0.0) if nhasz - end - coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate) - nfactory.point(*coords) - elsif type == Line - nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts)) - elsif type == LinearRing - nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) - elsif type == LineString - nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) - elsif type == Polygon - nfactory.polygon(cast(obj.exterior_ring, nfactory, opts), - obj.interior_rings.map { |r| cast(r, nfactory, opts) }) - elsif type == MultiPoint - nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) }) - elsif type == MultiLineString - nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) }) - elsif type == MultiPolygon - nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) }) - elsif type == GeometryCollection - nfactory.collection(obj.map { |g| cast(g, nfactory, opts) }) - end - end - else - # Types are different - if ntype == Point && (type == MultiPoint || type == GeometryCollection) || - (ntype == Line || ntype == LineString || ntype == LinearRing) && (type == MultiLineString || type == GeometryCollection) || - ntype == Polygon && (type == MultiPolygon || type == GeometryCollection) - if obj.num_geometries == 1 - cast(obj.geometry_n(0), nfactory, ntype, opts) - end - elsif ntype == Point - raise(Error::InvalidGeometry, "Cannot cast to Point") - elsif ntype == Line - if type == LineString && obj.num_points == 2 - nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts)) - end - elsif ntype == LinearRing - if type == LineString - nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) - end - elsif ntype == LineString - if type == Line || type == LinearRing - nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) + elsif type == Point + cs = ncs = nil + if project + cs = factory.coord_sys + ncs = nfactory.coord_sys end - elsif ntype == MultiPoint - if type == Point - nfactory.multi_point([cast(obj, nfactory, opts)]) - elsif type == GeometryCollection - nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) }) - end - elsif ntype == MultiLineString - if type == Line || type == LinearRing || type == LineString - nfactory.multi_line_string([cast(obj, nfactory, opts)]) - elsif type == GeometryCollection - nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) }) - end - elsif ntype == MultiPolygon - if type == Polygon - nfactory.multi_polygon([cast(obj, nfactory, opts)]) - elsif type == GeometryCollection - nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) }) - end - elsif ntype == GeometryCollection - if type == MultiPoint || type == MultiLineString || type == MultiPolygon - nfactory.collection(obj.map { |p| cast(p, nfactory, opts) }) + hasz = factory.property(:has_z_coordinate) + nhasz = nfactory.property(:has_z_coordinate) + if cs && ncs + coords = cs.transform_coords(ncs, obj.x, obj.y, hasz ? obj.z : nil) + coords << (hasz ? obj.z : 0.0) if nhasz && coords.size < 3 else - nfactory.collection([cast(obj, nfactory, opts)]) + coords = [obj.x, obj.y] + coords << (hasz ? obj.z : 0.0) if nhasz end + coords << (factory.property(:has_m_coordinate) ? obj.m : 0.0) if nfactory.property(:has_m_coordinate) + nfactory.point(*coords) + elsif type == Line + nfactory.line(cast(obj.start_point, nfactory, opts), cast(obj.end_point, nfactory, opts)) + elsif type == LinearRing + nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) + elsif type == LineString + nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) + elsif type == Polygon + nfactory.polygon( + cast(obj.exterior_ring, nfactory, opts), + obj.interior_rings.map { |r| cast(r, nfactory, opts) } + ) + elsif type == MultiPoint + nfactory.multi_point(obj.map { |g| cast(g, nfactory, opts) }) + elsif type == MultiLineString + nfactory.multi_line_string(obj.map { |g| cast(g, nfactory, opts) }) + elsif type == MultiPolygon + nfactory.multi_polygon(obj.map { |g| cast(g, nfactory, opts) }) + elsif type == GeometryCollection + nfactory.collection(obj.map { |g| cast(g, nfactory, opts) }) + end + # Types are different + elsif ntype == Point && [MultiPoint, GeometryCollection].include?(type) || + [Line, LineString, LinearRing].include?(ntype) && [MultiLineString, GeometryCollection].include?(type) || + ntype == Polygon && [MultiPolygon, GeometryCollection].include?(type) + cast(obj.geometry_n(0), nfactory, ntype, opts) if obj.num_geometries == 1 + elsif ntype == Point + raise(Error::InvalidGeometry, "Cannot cast to Point") + elsif ntype == Line + if type == LineString && obj.num_points == 2 + nfactory.line(cast(obj.point_n(0), nfactory, opts), cast(obj.point_n(1), nfactory, opts)) + end + elsif ntype == LinearRing + nfactory.linear_ring(obj.points.map { |p| cast(p, nfactory, opts) }) if type == LineString + elsif ntype == LineString + nfactory.line_string(obj.points.map { |p| cast(p, nfactory, opts) }) if [Line, LinearRing].include?(type) + elsif ntype == MultiPoint + if type == Point + nfactory.multi_point([cast(obj, nfactory, opts)]) + elsif type == GeometryCollection + nfactory.multi_point(obj.map { |p| cast(p, nfactory, opts) }) + end + elsif ntype == MultiLineString + if [Line, LinearRing, LineString].include?(type) + nfactory.multi_line_string([cast(obj, nfactory, opts)]) + elsif type == GeometryCollection + nfactory.multi_line_string(obj.map { |p| cast(p, nfactory, opts) }) + end + elsif ntype == MultiPolygon + if type == Polygon + nfactory.multi_polygon([cast(obj, nfactory, opts)]) + elsif type == GeometryCollection + nfactory.multi_polygon(obj.map { |p| cast(p, nfactory, opts) }) + end + elsif ntype == GeometryCollection + if [MultiPoint, MultiLineString, MultiPolygon].include?(type) + nfactory.collection(obj.map { |p| cast(p, nfactory, opts) }) else - raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}") + nfactory.collection([cast(obj, nfactory, opts)]) end + else + raise(RGeo::Error::InvalidGeometry, "Undefined type cast from #{type.name} to #{ntype.name}") end end end diff --git a/lib/rgeo/geographic/factory.rb b/lib/rgeo/geographic/factory.rb index d06f1619..519b4ba8 100644 --- a/lib/rgeo/geographic/factory.rb +++ b/lib/rgeo/geographic/factory.rb @@ -11,13 +11,20 @@ module Geographic # This class implements the various factories for geography features. # See methods of the RGeo::Geographic module for the API for creating # geography factories. - class Factory include Feature::Factory::Instance include ImplHelper::Utils attr_writer :projector + attr_reader :coordinate_dimension, :spatial_dimension + + # Returns the srid reported by this factory. + attr_reader :srid + + # See RGeo::Feature::Factory#coord_sys + attr_reader :coord_sys + def initialize(impl_prefix, opts = {}) # :nodoc: @impl_prefix = impl_prefix @point_class = Geographic.const_get("#{impl_prefix}PointImpl") @@ -45,45 +52,48 @@ def initialize(impl_prefix, opts = {}) # :nodoc: @buffer_resolution = 1 if @buffer_resolution < 1 wkt_generator = opts[:wkt_generator] - case wkt_generator - when Hash - @wkt_generator = WKRep::WKTGenerator.new(wkt_generator) - else - @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper) - end + @wkt_generator = + case wkt_generator + when Hash + WKRep::WKTGenerator.new(wkt_generator) + else + WKRep::WKTGenerator.new(convert_case: :upper) + end wkb_generator = opts[:wkb_generator] - case wkb_generator - when Hash - @wkb_generator = WKRep::WKBGenerator.new(wkb_generator) - else - @wkb_generator = WKRep::WKBGenerator.new - end + @wkb_generator = + case wkb_generator + when Hash + WKRep::WKBGenerator.new(wkb_generator) + else + WKRep::WKBGenerator.new + end wkt_parser = opts[:wkt_parser] - case wkt_parser - when Hash - @wkt_parser = WKRep::WKTParser.new(self, wkt_parser) - else - @wkt_parser = WKRep::WKTParser.new(self) - end + @wkt_parser = + case wkt_parser + when Hash + WKRep::WKTParser.new(self, wkt_parser) + else + WKRep::WKTParser.new(self) + end wkb_parser = opts[:wkb_parser] - case wkb_parser - when Hash - @wkb_parser = WKRep::WKBParser.new(self, wkb_parser) - else - @wkb_parser = WKRep::WKBParser.new(self) - end + @wkb_parser = + case wkb_parser + when Hash + WKRep::WKBParser.new(self, wkb_parser) + else + WKRep::WKBParser.new(self) + end @projector = nil end - attr_reader :coordinate_dimension, :spatial_dimension # Equivalence test. - def eql?(rhs_) - rhs_.is_a?(Geographic::Factory) && - @impl_prefix == rhs_.instance_variable_get(:@impl_prefix) && - @support_z == rhs_.instance_variable_get(:@support_z) && - @support_m == rhs_.instance_variable_get(:@support_m) && - @coord_sys == rhs_.instance_variable_get(:@coord_sys) + def eql?(other) + other.is_a?(Geographic::Factory) && + @impl_prefix == other.instance_variable_get(:@impl_prefix) && + @support_z == other.instance_variable_get(:@support_z) && + @support_m == other.instance_variable_get(:@support_m) && + @coord_sys == other.instance_variable_get(:@coord_sys) end alias == eql? @@ -116,12 +126,12 @@ def marshal_dump # :nodoc: end def marshal_load(data_) # :nodoc: - if (coord_sys_data = data_["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) - else - coord_sys = nil - end - initialize(data_["pref"], + coord_sys = + if (coord_sys_data = data_["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) + end + initialize( + data_["pref"], has_z_coordinate: data_["hasz"], has_m_coordinate: data_["hasm"], srid: data_["srid"], @@ -132,14 +142,18 @@ def marshal_load(data_) # :nodoc: buffer_resolution: data_["bufr"], coord_sys: coord_sys ) - if (proj_klass = data_["prjc"]) && (proj_factory = data_["prjf"]) - klass_ = RGeo::Geographic.const_get(proj_klass) - if klass_ - projector = klass_.allocate - projector.set_factories(self, proj_factory) - @projector = projector - end - end + proj_klass = data_["prjc"] + proj_factory = data_["prjf"] + + return unless proj_klass && proj_factory + + klass_ = RGeo::Geographic.const_get(proj_klass) + + return unless klass_ + + projector = klass_.allocate + projector.set_factories(self, proj_factory) + @projector = projector end # Psych support @@ -155,19 +169,20 @@ def encode_with(coder) # :nodoc: coder["wkb_parser"] = @wkb_parser.properties coder["buffer_resolution"] = @buffer_resolution coder["coord_sys"] = @coord_sys.to_wkt if @coord_sys - if @projector - coder["projectorclass"] = @projector.class.name.sub(/.*::/, "") - coder["projection_factory"] = @projector.projection_factory - end + + return unless @projector + + coder["projectorclass"] = @projector.class.name.sub(/.*::/, "") + coder["projection_factory"] = @projector.projection_factory end def init_with(coder) # :nodoc: - if (coord_sys_data = coder["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) - else - coord_sys = nil - end - initialize(coder["impl_prefix"], + coord_sys = + if (coord_sys_data = coder["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) + end + initialize( + coder["impl_prefix"], has_z_coordinate: coder["has_z_coordinate"], has_m_coordinate: coder["has_m_coordinate"], srid: coder["srid"], @@ -178,19 +193,19 @@ def init_with(coder) # :nodoc: buffer_resolution: coder["buffer_resolution"], coord_sys: coord_sys ) - if (proj_klass = coder["projectorclass"]) && (proj_factory = coder["projection_factory"]) - klass_ = RGeo::Geographic.const_get(proj_klass) - if klass_ - projector = klass_.allocate - projector.set_factories(self, proj_factory) - @projector = projector - end - end - end + proj_klass = coder["projectorclass"] + proj_factory = coder["projection_factory"] - # Returns the srid reported by this factory. + return unless proj_klass && proj_factory - attr_reader :srid + klass_ = RGeo::Geographic.const_get(proj_klass) + + return unless klass_ + + projector = klass_.allocate + projector.set_factories(self, proj_factory) + @projector = projector + end # Returns true if this factory supports a projection. @@ -213,9 +228,7 @@ def projection_factory def project(geometry) return unless @projector && geometry - unless geometry.factory == self - raise Error::InvalidGeometry, "Wrong geometry type" - end + raise Error::InvalidGeometry, "Wrong geometry type" unless geometry.factory == self @projector.project(geometry) end @@ -226,9 +239,11 @@ def project(geometry) def unproject(geometry) return unless geometry + unless @projector && @projector.projection_factory == geometry.factory raise Error::InvalidGeometry, "You can unproject only features that are in the projected coordinate space." end + @projector.unproject(geometry) end @@ -249,12 +264,10 @@ def projection_wraps? # projection limits are not known. def projection_limits_window - if @projector - unless defined?(@projection_limits_window) - @projection_limits_window = @projector.limits_window - end - @projection_limits_window - end + return unless @projector + + @projection_limits_window = @projector.limits_window unless defined?(@projection_limits_window) + @projection_limits_window end # See RGeo::Feature::Factory#property @@ -286,8 +299,8 @@ def parse_wkb(str) # See RGeo::Feature::Factory#point - def point(x, y, *extra) - @point_class.new(self, x, y, *extra) + def point(x_point, y_point, *extra) + @point_class.new(self, x_point, y_point, *extra) end # See RGeo::Feature::Factory#line_string @@ -338,10 +351,6 @@ def multi_polygon(elems) @multi_polygon_class.new(self, elems) end - # See RGeo::Feature::Factory#coord_sys - - attr_reader :coord_sys - def generate_wkt(obj) @wkt_generator.generate(obj) end diff --git a/lib/rgeo/geographic/interface.rb b/lib/rgeo/geographic/interface.rb index 1b5f44de..f33757d0 100644 --- a/lib/rgeo/geographic/interface.rb +++ b/lib/rgeo/geographic/interface.rb @@ -7,7 +7,7 @@ # ----------------------------------------------------------------------------- module RGeo - module Geographic + module Geographic # :nodoc: class << self # Creates and returns a geographic factory that does not include a # a projection, and which performs calculations assuming a @@ -102,7 +102,8 @@ def spherical_factory(opts = {}) coord_sys = opts[:coord_sys] srid = opts[:srid] srid ||= coord_sys.authority_code if coord_sys - Geographic::Factory.new("Spherical", + Geographic::Factory.new( + "Spherical", has_z_coordinate: opts[:has_z_coordinate], has_m_coordinate: opts[:has_m_coordinate], coord_sys: coord_sys || coord_sys_4055, @@ -111,7 +112,8 @@ def spherical_factory(opts = {}) wkb_parser: opts[:wkb_parser], wkt_generator: opts[:wkt_generator], wkb_generator: opts[:wkb_generator], - srid: (srid || 4055).to_i) + srid: (srid || 4055).to_i + ) end # Creates and returns a geographic factory that is designed for @@ -185,7 +187,8 @@ def spherical_factory(opts = {}) # options. See RGeo::Geos.factory for more details. def simple_mercator_factory(opts = {}) - factory = Geographic::Factory.new("Projected", + factory = Geographic::Factory.new( + "Projected", coord_sys: coord_sys_4326, srid: 4326, wkt_parser: opts[:wkt_parser], @@ -193,11 +196,14 @@ def simple_mercator_factory(opts = {}) wkt_generator: opts[:wkt_generator], wkb_generator: opts[:wkb_generator], has_z_coordinate: opts[:has_z_coordinate], - has_m_coordinate: opts[:has_m_coordinate]) - projector = Geographic::SimpleMercatorProjector.new(factory, + has_m_coordinate: opts[:has_m_coordinate] + ) + projector = Geographic::SimpleMercatorProjector.new( + factory, buffer_resolution: opts[:buffer_resolution], has_z_coordinate: opts[:has_z_coordinate], - has_m_coordinate: opts[:has_m_coordinate]) + has_m_coordinate: opts[:has_m_coordinate] + ) factory.projector = projector factory end @@ -306,6 +312,7 @@ def projected_factory(opts = {}) if projection_coord_sys && !projection_coord_sys.projected? raise ArgumentError, "The :projection_factory's coord_sys is not a ProjectedCoordinateSystem." end + # Determine geographic coordinate system. First check parameters. coord_sys = opts[:coord_sys] srid = opts[:srid] @@ -314,18 +321,26 @@ def projected_factory(opts = {}) srid ||= coord_sys.authority_code if coord_sys srid ||= 4326 # Now we should have all the coordinate system info. - factory = Geographic::Factory.new("Projected", + factory = Geographic::Factory.new( + "Projected", coord_sys: coord_sys, srid: srid.to_i, has_z_coordinate: projection_factory.property(:has_z_coordinate), has_m_coordinate: projection_factory.property(:has_m_coordinate), wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator], - wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]) - projector = Geographic::Projector.create_from_existing_factory(factory, - projection_factory) + wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator] + ) + projector = Geographic::Projector.create_from_existing_factory( + factory, + projection_factory + ) else # Determine projection coordinate system. First check the parameters. - projection_coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:projection_srid], opts[:projection_coord_sys], opts[:projection_coord_sys_class]) + projection_coord_sys_info = ImplHelper::Utils.setup_coord_sys( + opts[:projection_srid], + opts[:projection_coord_sys], + opts[:projection_coord_sys_class] + ) projection_coord_sys = projection_coord_sys_info[:coord_sys] projection_srid = projection_coord_sys_info[:srid] @@ -338,21 +353,25 @@ def projected_factory(opts = {}) srid ||= coord_sys.authority_code if coord_sys srid ||= 4326 # Now we should have all the coordinate system info. - factory = Geographic::Factory.new("Projected", + factory = Geographic::Factory.new( + "Projected", coord_sys: coord_sys, srid: srid.to_i, has_z_coordinate: opts[:has_z_coordinate], has_m_coordinate: opts[:has_m_coordinate], wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator], - wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]) - projector = Geographic::Projector.create_from_opts(factory, + wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator] + ) + projector = Geographic::Projector.create_from_opts( + factory, srid: projection_srid, coord_sys: projection_coord_sys, buffer_resolution: opts[:buffer_resolution], has_z_coordinate: opts[:has_z_coordinate], has_m_coordinate: opts[:has_m_coordinate], wkt_parser: opts[:wkt_parser], wkt_generator: opts[:wkt_generator], - wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator]) + wkb_parser: opts[:wkb_parser], wkb_generator: opts[:wkb_generator] + ) end factory.projector = projector factory @@ -361,16 +380,12 @@ def projected_factory(opts = {}) private def coord_sys_4055 - unless defined?(@coord_sys_4055) - @coord_sys_4055 = CoordSys::CONFIG.default_coord_sys_class.create(4055) - end + @coord_sys_4055 = CoordSys::CONFIG.default_coord_sys_class.create(4055) unless defined?(@coord_sys_4055) @coord_sys_4055 end def coord_sys_4326 - unless defined?(@coord_sys_4326) - @coord_sys_4326 = CoordSys::CONFIG.default_coord_sys_class.create(4326) - end + @coord_sys_4326 = CoordSys::CONFIG.default_coord_sys_class.create(4326) unless defined?(@coord_sys_4326) @coord_sys_4326 end end diff --git a/lib/rgeo/geographic/projected_feature_classes.rb b/lib/rgeo/geographic/projected_feature_classes.rb index 30179d9f..8528d9d7 100644 --- a/lib/rgeo/geographic/projected_feature_classes.rb +++ b/lib/rgeo/geographic/projected_feature_classes.rb @@ -7,7 +7,7 @@ # ----------------------------------------------------------------------------- module RGeo - module Geographic + module Geographic # :nodoc: class ProjectedPointImpl include Feature::Point include ImplHelper::ValidityCheck diff --git a/lib/rgeo/geographic/projected_feature_methods.rb b/lib/rgeo/geographic/projected_feature_methods.rb index f5fece7b..8715fc0a 100644 --- a/lib/rgeo/geographic/projected_feature_methods.rb +++ b/lib/rgeo/geographic/projected_feature_methods.rb @@ -219,9 +219,7 @@ module ProjectedPolygonMethods # :nodoc: # Ensure projection is available. def init_geometry super - unless projection - raise Error::InvalidGeometry, "Polygon failed assertions" - end + raise Error::InvalidGeometry, "Polygon failed assertions" unless projection end end @@ -231,9 +229,7 @@ module ProjectedMultiPolygonMethods # :nodoc: # Ensure projection is available. def init_geometry super - unless projection - raise Error::InvalidGeometry, "MultiPolygon failed assertions" - end + raise Error::InvalidGeometry, "MultiPolygon failed assertions" unless projection end end end diff --git a/lib/rgeo/geographic/projected_window.rb b/lib/rgeo/geographic/projected_window.rb index de648fc1..5242af37 100644 --- a/lib/rgeo/geographic/projected_window.rb +++ b/lib/rgeo/geographic/projected_window.rb @@ -13,7 +13,6 @@ module Geographic # map visualization, an envelope in a projected coordinate system, or # a spatial constraint. It must be attached to a Geographic::Factory # that has a projection. - class ProjectedWindow # Create a new ProjectedWindow given the Geographic::Factory, and the # x and y extents of the rectangle. @@ -64,10 +63,10 @@ def inspect # :nodoc: to_s end - def eql?(obj_) # :nodoc: - return false unless obj_.is_a?(ProjectedWindow) - @factory == obj_.factory && @x_min == obj_.x_min && @x_max == obj_.x_max && - @y_min = obj_.y_min && @y_max = obj_.y_max + def eql?(other) # :nodoc: + return false unless other.is_a?(ProjectedWindow) + @factory == other.factory && @x_min == other.x_min && @x_max == other.x_max && + @y_min = other.y_min && @y_max = other.y_max end alias == eql? @@ -79,23 +78,18 @@ def hash # :nodoc: # Note that this factory is the overall geography factory, not the # projected factory (which can be obtained by calling # Geographic::Factory#projection_factory on this factory). - attr_reader :factory # Returns the lower limit in the x (easting) direction. - attr_reader :x_min # Returns the upper limit in the x (easting) direction. - attr_reader :x_max # Returns the lower limit in the y (northing) direction. - attr_reader :y_min # Returns the upper limit in the y (northing) direction. - attr_reader :y_max # Returns true if the projection wraps along the x axis, and this @@ -146,35 +140,35 @@ def center_xy # (lat/lng) space, as a Feature::Point object. def sw_point - @sw ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_min)) + @sw_point ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_min)) end # Returns the southeast corner of the rectangle in _unprojected_ # (lat/lng) space, as a Feature::Point object. def se_point - @se ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_min)) + @se_point ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_min)) end # Returns the northwest corner of the rectangle in _unprojected_ # (lat/lng) space, as a Feature::Point object. def nw_point - @nw ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_max)) + @nw_point ||= @factory.unproject(@factory.projection_factory.point(@x_min, @y_max)) end # Returns the northeast corner of the rectangle in _unprojected_ # (lat/lng) space, as a Feature::Point object. def ne_point - @ne ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_max)) + @ne_point ||= @factory.unproject(@factory.projection_factory.point(@x_max, @y_max)) end # Returns the center of the rectangle in _unprojected_ # (lat/lng) space, as a Feature::Point object. def center_point - @center ||= @factory.unproject(@factory.projection_factory.point(*center_xy)) + @center_point ||= @factory.unproject(@factory.projection_factory.point(*center_xy)) end # Returns a random point inside the rectangle in _unprojected_ @@ -233,7 +227,7 @@ def contains_window?(window_) def scaled_by(x_factor_, y_factor_ = nil) y_factor_ ||= x_factor_ - if x_factor_ != 1.0 || y_factor_ != 1.0 + if x_factor_ != 1 || y_factor_ != 1 x_, y_ = *center_xy xr_ = x_span * 0.5 * x_factor_ yr_ = y_span * 0.5 * y_factor_ @@ -287,9 +281,14 @@ def clamped_by(min_width_, min_height_, max_width_, max_height_) def with_margin(x_margin_, y_margin_ = nil) y_margin_ ||= x_margin_ - if x_margin_ != 0.0 || y_margin_ != 0.0 - ProjectedWindow.new(@factory, @x_min - x_margin_, @y_min - y_margin_, - @x_max + x_margin_, @y_max + y_margin_) + if x_margin_ != 0 || y_margin_ != 0 + ProjectedWindow.new( + @factory, + @x_min - x_margin_, + @y_min - y_margin_, + @x_max + x_margin_, + @y_max + y_margin_ + ) else self end @@ -318,8 +317,13 @@ def surrounding_point(point_, x_margin_ = nil, y_margin_ = nil) y_margin_ ||= x_margin_ factory_ = point_.factory projection_ = factory_.project(point_) - ProjectedWindow.new(factory_, projection_.x - x_margin_, projection_.y - y_margin_, - projection_.x + x_margin_, projection_.y + y_margin_) + ProjectedWindow.new( + factory_, + projection_.x - x_margin_, + projection_.y - y_margin_, + projection_.x + x_margin_, + projection_.y + y_margin_ + ) end # Creates a new window that contains all of the given points. diff --git a/lib/rgeo/geographic/simple_mercator_projector.rb b/lib/rgeo/geographic/simple_mercator_projector.rb index a731b005..4184bbeb 100644 --- a/lib/rgeo/geographic/simple_mercator_projector.rb +++ b/lib/rgeo/geographic/simple_mercator_projector.rb @@ -32,8 +32,10 @@ def project(geometry) when Feature::Point rpd_ = ImplHelper::Math::RADIANS_PER_DEGREE radius = EQUATORIAL_RADIUS - @projection_factory.point(geometry.x * rpd_ * radius, - Math.log(Math.tan(Math::PI / 4.0 + geometry.y * rpd_ / 2.0)) * radius) + @projection_factory.point( + geometry.x * rpd_ * radius, + Math.log(Math.tan(Math::PI / 4.0 + geometry.y * rpd_ / 2.0)) * radius + ) when Feature::Line @projection_factory.line(project(geometry.start_point), project(geometry.end_point)) when Feature::LinearRing @@ -59,8 +61,10 @@ def unproject(geometry) when Feature::Point dpr = ImplHelper::Math::DEGREES_PER_RADIAN radius = EQUATORIAL_RADIUS - @geography_factory.point(geometry.x / radius * dpr, - (2.0 * Math.atan(Math.exp(geometry.y / radius)) - Math::PI / 2.0) * dpr) + @geography_factory.point( + geometry.x / radius * dpr, + (2.0 * Math.atan(Math.exp(geometry.y / radius)) - Math::PI / 2.0) * dpr + ) when Feature::Line @geography_factory.line(unproject(geometry.start_point), unproject(geometry.end_point)) when Feature::LinearRing @@ -68,8 +72,10 @@ def unproject(geometry) when Feature::LineString @geography_factory.line_string(geometry.points.map { |p| unproject(p) }) when Feature::Polygon - @geography_factory.polygon(unproject(geometry.exterior_ring), - geometry.interior_rings.map { |p| unproject(p) }) + @geography_factory.polygon( + unproject(geometry.exterior_ring), + geometry.interior_rings.map { |p| unproject(p) } + ) when Feature::MultiPoint @geography_factory.multi_point(geometry.map { |p| unproject(p) }) when Feature::MultiLineString @@ -86,15 +92,18 @@ def wraps? end def limits_window - @limits_window ||= ProjectedWindow.new(@geography_factory, - -20_037_508.342789, -20_037_508.342789, 20_037_508.342789, 20_037_508.342789, - is_limits: true) + @limits_window ||= ProjectedWindow.new( + @geography_factory, + -20_037_508.342789, + -20_037_508.342789, + 20_037_508.342789, + 20_037_508.342789, + is_limits: true + ) end def self._coordsys_3857 # :nodoc: - unless defined?(@coordsys_3857) - @coordsys_3857 = CoordSys::CONFIG.default_coord_sys_class.create(3857) - end + @coordsys_3857 = CoordSys::CONFIG.default_coord_sys_class.create(3857) unless defined?(@coordsys_3857) @coordsys_3857 end end diff --git a/lib/rgeo/geographic/spherical_feature_classes.rb b/lib/rgeo/geographic/spherical_feature_classes.rb index ac635038..d9bdb1f5 100644 --- a/lib/rgeo/geographic/spherical_feature_classes.rb +++ b/lib/rgeo/geographic/spherical_feature_classes.rb @@ -7,7 +7,7 @@ # ----------------------------------------------------------------------------- module RGeo - module Geographic + module Geographic # :nodoc: class SphericalPointImpl include Feature::Point include ImplHelper::ValidityCheck diff --git a/lib/rgeo/geographic/spherical_feature_methods.rb b/lib/rgeo/geographic/spherical_feature_methods.rb index 894c86fc..1465d096 100644 --- a/lib/rgeo/geographic/spherical_feature_methods.rb +++ b/lib/rgeo/geographic/spherical_feature_methods.rb @@ -49,9 +49,10 @@ def equals?(rhs) return false unless rhs.is_a?(self.class) && rhs.factory == factory case rhs when Feature::Point - if @y == 90 + case @y + when 90 rhs.y == 90 - elsif @y == -90 + when -90 rhs.y == -90 else rhs.x == @x && rhs.y == @y @@ -193,7 +194,11 @@ def crosses_line_string?(rhs) next unless arc.intersects_arc?(rhs_arc) # check that endpoints aren't the intersection point - is_endpoint = arc.contains_point?(rhs_arc.s) || arc.contains_point?(rhs_arc.e) || rhs_arc.contains_point?(arc.s) || rhs_arc.contains_point?(arc.e) + is_endpoint = arc.contains_point?(rhs_arc.s) || + arc.contains_point?(rhs_arc.e) || + rhs_arc.contains_point?(arc.s) || + rhs_arc.contains_point?(arc.e) + return true unless is_endpoint end end diff --git a/lib/rgeo/geographic/spherical_math.rb b/lib/rgeo/geographic/spherical_math.rb index d2a52a31..653bc929 100644 --- a/lib/rgeo/geographic/spherical_math.rb +++ b/lib/rgeo/geographic/spherical_math.rb @@ -23,11 +23,13 @@ module SphericalMath # :nodoc: # of rotation. class PointXYZ # :nodoc: - def initialize(x, y, z) - r = Math.sqrt(x * x + y * y + z * z) - @x = (x / r).to_f - @y = (y / r).to_f - @z = (z / r).to_f + attr_reader :x, :y, :z + + def initialize(x_coord, y_coord, z_coord) + r = Math.sqrt(x_coord * x_coord + y_coord * y_coord + z_coord * z_coord) + @x = (x_coord / r).to_f + @y = (y_coord / r).to_f + @z = (z_coord / r).to_f raise "Not a number" if @x.nan? || @y.nan? || @z.nan? end @@ -35,12 +37,8 @@ def to_s "(#{@x}, #{@y}, #{@z})" end - attr_reader :x - attr_reader :y - attr_reader :z - - def eql?(rhs) - rhs.is_a?(PointXYZ) && @x == rhs.x && @y == rhs.y && @z == rhs.z + def eql?(other) + other.is_a?(PointXYZ) && @x == other.x && @y == other.y && @z == other.z end alias == eql? @@ -58,17 +56,17 @@ def lonlat [lon_rad / rpd, lat_rad / rpd] end - def *(rhs) - val = @x * rhs.x + @y * rhs.y + @z * rhs.z + def *(other) + val = @x * other.x + @y * other.y + @z * other.z val = 1.0 if val > 1.0 val = -1.0 if val < -1.0 val end - def %(rhs) - rx = rhs.x - ry = rhs.y - rz = rhs.z + def %(other) + rx = other.x + ry = other.y + rz = other.z begin PointXYZ.new(@y * rz - @z * ry, @z * rx - @x * rz, @x * ry - @y * rx) rescue StandardError @@ -113,8 +111,8 @@ def self.from_latlon(lat, lon) new(x, y, z) end - def self.weighted_combination(p1, w1, p2, w2) - new(p1.x * w1 + p2.x * w2, p1.y * w1 + p2.y * w2, p1.z * w1 + p2.z * w2) + def self.weighted_combination(pt1, wt1, pt2, wt2) + new(pt1.x * wt1 + pt2.x * wt2, pt1.y * wt1 + pt2.y * wt2, pt1.z * wt1 + pt2.z * wt2) end P1 = new(1, 0, 0) @@ -124,21 +122,20 @@ def self.weighted_combination(p1, w1, p2, w2) # Represents a finite arc on the sphere. class ArcXYZ # :nodoc: + attr_reader :s, :e + def initialize(start, stop) @s = start @e = stop @axis = false end - attr_reader :s - attr_reader :e - def to_s "#{@s} - #{@e}" end - def eql?(rhs) - rhs.is_a?(ArcXYZ) && @s == rhs.s && @e == rhs.e + def eql?(other) + other.is_a?(ArcXYZ) && @s == other.s && @e == other.e end alias == eql? @@ -156,7 +153,7 @@ def contains_point?(obj) my_axis = axis s_axis = ArcXYZ.new(@s, obj).axis e_axis = ArcXYZ.new(obj, @e).axis - !s_axis || !e_axis || obj * my_axis == 0.0 && s_axis * my_axis > 0 && e_axis * my_axis > 0 + !s_axis || !e_axis || obj * my_axis == 0 && s_axis * my_axis > 0 && e_axis * my_axis > 0 end def intersects_arc?(obj) diff --git a/lib/rgeo/geos.rb b/lib/rgeo/geos.rb index 0300f836..d4879d65 100644 --- a/lib/rgeo/geos.rb +++ b/lib/rgeo/geos.rb @@ -20,7 +20,7 @@ # :stopdoc: module RGeo - module Geos + module Geos # :nodoc: require_relative "geos/utils" require_relative "geos/interface" begin diff --git a/lib/rgeo/geos/capi_factory.rb b/lib/rgeo/geos/capi_factory.rb index d5eb621d..9df51db5 100644 --- a/lib/rgeo/geos/capi_factory.rb +++ b/lib/rgeo/geos/capi_factory.rb @@ -9,7 +9,6 @@ module RGeo module Geos # This the GEOS CAPI implementation of RGeo::Feature::Factory. - class CAPIFactory include Feature::Factory::Instance include ImplHelper::Utils @@ -28,9 +27,11 @@ def create(opts = {}) flags = 0 flags |= 2 if opts[:has_z_coordinate] flags |= 4 if opts[:has_m_coordinate] + if flags & 6 == 6 raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time." end + flags |= 8 unless opts[:auto_prepare] == :disabled # Buffer resolution @@ -39,19 +40,17 @@ def create(opts = {}) # Interpret the generator options wkt_generator = opts[:wkt_generator] - case wkt_generator - when Hash - wkt_generator = WKRep::WKTGenerator.new(wkt_generator) - else - wkt_generator = nil - end + wkt_generator = + case wkt_generator + when Hash + WKRep::WKTGenerator.new(wkt_generator) + end wkb_generator = opts[:wkb_generator] - case wkb_generator - when Hash - wkb_generator = WKRep::WKBGenerator.new(wkb_generator) - else - wkb_generator = nil - end + wkb_generator = + case wkb_generator + when Hash + WKRep::WKBGenerator.new(wkb_generator) + end # Coordinate system (srid and coord_sys) coord_sys_info = ImplHelper::Utils.setup_coord_sys(opts[:srid], opts[:coord_sys], opts[:coord_sys_class]) @@ -59,24 +58,28 @@ def create(opts = {}) coord_sys = coord_sys_info[:coord_sys] # Create the factory and set instance variables - result = _create(flags, srid.to_i, buffer_resolution, - wkt_generator, wkb_generator, coord_sys) + result = _create( + flags, + srid.to_i, + buffer_resolution, + wkt_generator, + wkb_generator, + coord_sys + ) # Interpret parser options wkt_parser = opts[:wkt_parser] - case wkt_parser - when Hash - wkt_parser = WKRep::WKTParser.new(result, wkt_parser) - else - wkt_parser = nil - end + wkt_parser = + case wkt_parser + when Hash + WKRep::WKTParser.new(result, wkt_parser) + end wkb_parser = opts[:wkb_parser] - case wkb_parser - when Hash - wkb_parser = WKRep::WKBParser.new(result, wkb_parser) - else - wkb_parser = nil - end + wkb_parser = + case wkb_parser + when Hash + WKRep::WKBParser.new(result, wkb_parser) + end result._set_wkrep_parsers(wkt_parser, wkb_parser) # Return the result @@ -93,10 +96,10 @@ def inspect # Factory equivalence test. - def eql?(rhs_) - rhs_.is_a?(CAPIFactory) && rhs_.srid == _srid && - rhs_._buffer_resolution == _buffer_resolution && rhs_._flags == _flags && - rhs_.coord_sys == coord_sys + def eql?(other) + other.is_a?(CAPIFactory) && other.srid == _srid && + other._buffer_resolution == _buffer_resolution && other._flags == _flags && + other.coord_sys == coord_sys end alias == eql? @@ -127,11 +130,10 @@ def marshal_dump # :nodoc: end def marshal_load(data_) # :nodoc: - if (coord_sys_data_ = data_["cs"]) - coord_sys_ = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_) - else - coord_sys_ = nil - end + coord_sys_ = + if (coord_sys_data_ = data_["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_) + end initialize_copy( CAPIFactory.create( has_z_coordinate: data_["hasz"], @@ -160,17 +162,17 @@ def encode_with(coder_) # :nodoc: coder_["wkt_parser"] = _wkt_parser ? _wkt_parser.properties : {} coder_["wkb_parser"] = _wkb_parser ? _wkb_parser.properties : {} coder_["auto_prepare"] = auto_prepare - if (coord_sys_ = _coord_sys) - coder_["coord_sys"] = coord_sys_.to_wkt - end + + return unless (coord_sys_ = _coord_sys) + + coder_["coord_sys"] = coord_sys_.to_wkt end def init_with(coder_) # :nodoc: - if (coord_sys_data_ = coder_["cs"]) - coord_sys_ = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_.to_s) - else - coord_sys_ = nil - end + coord_sys_ = + if (coord_sys_data_ = coder_["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data_.to_s) + end initialize_copy( CAPIFactory.create( has_z_coordinate: coder_["has_z_coordinate"], @@ -238,12 +240,10 @@ def parse_wkb(str_) # See RGeo::Feature::Factory#point - def point(x, y, *extra) - if extra.length > (supports_z_or_m? ? 1 : 0) - raise(RGeo::Error::InvalidGeometry, "Parse error") - else - CAPIPointImpl.create(self, x, y, extra[0].to_f) - end + def point(x_coord, y_coord, *extra) + raise(RGeo::Error::InvalidGeometry, "Parse error") if extra.length > (supports_z_or_m? ? 1 : 0) + + CAPIPointImpl.create(self, x_coord, y_coord, extra[0].to_f) end # See RGeo::Feature::Factory#line_string @@ -341,7 +341,9 @@ def override_cast(original, ntype, flags) # compatible factory if supports_z? && !supports_m? && self == original.factory.z_factory return Feature.cast(original.z_geometry, ntype, flags) - elsif supports_m? && !supports_z? && self == original.factory.m_factory + end + + if supports_m? && !supports_z? && self == original.factory.m_factory return Feature.cast(original.m_geometry, ntype, flags) end end diff --git a/lib/rgeo/geos/capi_feature_classes.rb b/lib/rgeo/geos/capi_feature_classes.rb index 7042aec2..69c8bf51 100644 --- a/lib/rgeo/geos/capi_feature_classes.rb +++ b/lib/rgeo/geos/capi_feature_classes.rb @@ -9,8 +9,8 @@ require_relative "../impl_helper/validity_check" module RGeo - module Geos - module CAPIGeometryMethods + module Geos # :nodoc: + module CAPIGeometryMethods # :nodoc: include Feature::Instance def coordinate_dimension @@ -95,7 +95,7 @@ class CAPILineStringImpl include CAPILineStringMethods end - class CAPILinearRingImpl + class CAPILinearRingImpl # :nodoc: include Feature::LinearRing include ImplHelper::ValidityCheck include CAPIGeometryMethods diff --git a/lib/rgeo/geos/ffi_factory.rb b/lib/rgeo/geos/ffi_factory.rb index 3cf2ba3a..24100306 100644 --- a/lib/rgeo/geos/ffi_factory.rb +++ b/lib/rgeo/geos/ffi_factory.rb @@ -9,11 +9,22 @@ module RGeo module Geos # This the FFI-GEOS implementation of RGeo::Feature::Factory. - class FFIFactory include Feature::Factory::Instance include ImplHelper::Utils + attr_reader :coordinate_dimension, :spatial_dimension, :_has_3d, :_auto_prepare + + # Returns the SRID of geometries created by this factory. + attr_reader :srid + + # Returns the resolution used by buffer calculations on geometries + # created by this factory + attr_reader :buffer_resolution + + # See RGeo::Feature::Factory#coord_sys + attr_reader :coord_sys + # Create a new factory. Returns nil if the FFI-GEOS implementation # is not supported. # @@ -22,9 +33,11 @@ class FFIFactory def initialize(opts = {}) @has_z = opts[:has_z_coordinate] ? true : false @has_m = opts[:has_m_coordinate] ? true : false + if @has_z && @has_m raise Error::UnsupportedOperation, "GEOS cannot support both Z and M coordinates at the same time." end + @coordinate_dimension = 2 @coordinate_dimension += 1 if @has_z @coordinate_dimension += 1 if @has_m @@ -81,7 +94,6 @@ def initialize(opts = {}) @wkb_parser = nil end end - attr_reader :coordinate_dimension, :spatial_dimension # Standard object inspection output @@ -91,12 +103,12 @@ def inspect # Factory equivalence test. - def eql?(rhs) - rhs.is_a?(self.class) && @srid == rhs.srid && - @has_z == rhs.property(:has_z_coordinate) && - @has_m == rhs.property(:has_m_coordinate) && - @buffer_resolution == rhs.property(:buffer_resolution) && - @coord_sys.eql?(rhs.coord_sys) + def eql?(other) + other.is_a?(self.class) && @srid == other.srid && + @has_z == other.property(:has_z_coordinate) && + @has_m == other.property(:has_m_coordinate) && + @buffer_resolution == other.property(:buffer_resolution) && + @coord_sys.eql?(other.coord_sys) end alias == eql? @@ -125,11 +137,10 @@ def marshal_dump # :nodoc: end def marshal_load(data) # :nodoc: - if (coord_sys_data = data["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = data["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) + end initialize( has_z_coordinate: data["hasz"], has_m_coordinate: data["hasm"], @@ -160,11 +171,10 @@ def encode_with(coder) # :nodoc: end def init_with(coder) # :nodoc: - if (coord_sys_data = coder["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = coder["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) + end initialize( has_z_coordinate: coder["has_z_coordinate"], has_m_coordinate: coder["has_m_coordinate"], @@ -179,15 +189,6 @@ def init_with(coder) # :nodoc: ) end - # Returns the SRID of geometries created by this factory. - - attr_reader :srid - - # Returns the resolution used by buffer calculations on geometries - # created by this factory - - attr_reader :buffer_resolution - # See RGeo::Feature::Factory#property def property(name_) case name_ @@ -234,11 +235,11 @@ def parse_wkb(str) # See RGeo::Feature::Factory#point - def point(x, y, z = 0) + def point(x_coord, y_coord, z_coord = 0) cs = ::Geos::CoordinateSequence.new(1, 3) - cs.set_x(0, x) - cs.set_y(0, y) - cs.set_z(0, z) + cs.set_x(0, x_coord) + cs.set_y(0, y_coord) + cs.set_z(0, z_coord) FFIPointImpl.new(self, ::Geos::Utils.create_point(cs), nil) end @@ -328,8 +329,13 @@ def collection(elems) def multi_point(elems) elems = elems.to_a unless elems.is_a?(Array) elems = elems.map do |elem| - elem = RGeo::Feature.cast(elem, self, RGeo::Feature::Point, - :force_new, :keep_subtype) + elem = RGeo::Feature.cast( + elem, + self, + RGeo::Feature::Point, + :force_new, + :keep_subtype + ) return unless elem elem.detach_fg_geom end @@ -367,13 +373,9 @@ def multi_polygon(elems) FFIMultiPolygonImpl.new(self, fg_geom, klasses) end - # See RGeo::Feature::Factory#coord_sys - - attr_reader :coord_sys - # See RGeo::Feature::Factory#override_cast - def override_cast(original, ntype, flags) + def override_cast(_original, _ntype, _flags) false # TODO end @@ -421,13 +423,8 @@ def wrap_fg_geom(fg_geom, klass = nil) klass.new(self, fg_geom, klasses) end - attr_reader :_has_3d # :nodoc: - attr_reader :_auto_prepare # :nodoc: - def convert_to_fg_geometry(obj, type = nil) - if type && obj.factory != self - obj = Feature.cast(obj, self, type) - end + obj = Feature.cast(obj, self, type) if type && obj.factory != self obj&.fg_geom end @@ -480,7 +477,7 @@ def read_for_psych(str) def create_fg_linear_ring(points) size = points.size - return if size == 1 || size == 2 + return if size.between?(1, 2) if size > 0 && points.first != points.last points += [points.first] size += 1 diff --git a/lib/rgeo/geos/ffi_feature_classes.rb b/lib/rgeo/geos/ffi_feature_classes.rb index d4e1122d..b3314476 100644 --- a/lib/rgeo/geos/ffi_feature_classes.rb +++ b/lib/rgeo/geos/ffi_feature_classes.rb @@ -9,7 +9,7 @@ require_relative "../impl_helper/validity_check" module RGeo - module Geos + module Geos # :nodoc: class FFIGeometryImpl include Feature::Geometry include ImplHelper::ValidityCheck diff --git a/lib/rgeo/geos/ffi_feature_methods.rb b/lib/rgeo/geos/ffi_feature_methods.rb index 53610535..df545d92 100644 --- a/lib/rgeo/geos/ffi_feature_methods.rb +++ b/lib/rgeo/geos/ffi_feature_methods.rb @@ -13,6 +13,8 @@ module Geos module FFIGeometryMethods # :nodoc: include Feature::Instance + attr_reader :factory, :fg_geom, :_klasses + def initialize(factory, fg_geom, klasses) @factory = factory @fg_geom = fg_geom @@ -56,11 +58,6 @@ def init_with(coder) # :nodoc: @_klasses = nil end - attr_reader :factory - attr_reader :fg_geom - - attr_reader :_klasses # :nodoc: - def initialize_copy(orig) @factory = orig.factory @fg_geom = orig.fg_geom.clone @@ -94,9 +91,7 @@ def prepared? end def prepare! - if @_fg_prep.is_a?(Integer) - @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom) - end + @_fg_prep = ::Geos::PreparedGeometry.new(@fg_geom) if @_fg_prep.is_a?(Integer) self end @@ -149,11 +144,13 @@ def invalid_reason # (see RGeo::ImplHelper::ValidityCheck#make_valid) # Only available since GEOS 3.8+ - def make_valid - @factory.wrap_fg_geom(@fg_geom.make_valid, nil) - rescue ::Geos::GEOSException - raise Error::UnsupportedOperation - end if ::Geos::FFIGeos.respond_to?(:GEOSMakeValid_r) + if ::Geos::FFIGeos.respond_to?(:GEOSMakeValid_r) + def make_valid + @factory.wrap_fg_geom(@fg_geom.make_valid, nil) + rescue ::Geos::GEOSException + raise Error::UnsupportedOperation + end + end def equals?(rhs) return false unless rhs.is_a?(RGeo::Feature::Instance) @@ -290,8 +287,8 @@ def sym_difference(rhs) fg ? @factory.wrap_fg_geom(@fg_geom.sym_difference(fg), nil) : nil end - def eql?(rhs) - rep_equals?(rhs) + def eql?(other) + rep_equals?(other) end def detach_fg_geom @@ -343,7 +340,7 @@ def geometry_type end def rep_equals?(rhs) - rhs.class == self.class && rhs.factory.eql?(@factory) && + rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) && Utils.ffi_coord_seqs_equal?(rhs.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d) end @@ -372,14 +369,15 @@ def num_points @fg_geom.num_points end - def point_n(n) - if n >= 0 && n < @fg_geom.num_points - coord_seq = @fg_geom.coord_seq - x = coord_seq.get_x(n) - y = coord_seq.get_y(n) - extra = @factory._has_3d ? [coord_seq.get_z(n)] : [] - @factory.point(x, y, *extra) - end + def point_n(idx) + return unless idx >= 0 && idx < @fg_geom.num_points + + coord_seq = @fg_geom.coord_seq + x = coord_seq.get_x(idx) + y = coord_seq.get_y(idx) + extra = @factory._has_3d ? [coord_seq.get_z(idx)] : [] + + @factory.point(x, y, *extra) end def start_point @@ -410,7 +408,7 @@ def ring? end def rep_equals?(rhs) - rhs.class == self.class && rhs.factory.eql?(@factory) && + rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) && Utils.ffi_coord_seqs_equal?(rhs.fg_geom.coord_seq, @fg_geom.coord_seq, @factory._has_3d) end @@ -464,10 +462,10 @@ def num_interior_rings @fg_geom.num_interior_rings end - def interior_ring_n(n) - if n >= 0 && n < @fg_geom.num_interior_rings - @factory.wrap_fg_geom(@fg_geom.interior_ring_n(n), FFILinearRingImpl) - end + def interior_ring_n(idx) + return unless idx >= 0 && idx < @fg_geom.num_interior_rings + + @factory.wrap_fg_geom(@fg_geom.interior_ring_n(idx), FFILinearRingImpl) end def interior_rings @@ -477,7 +475,7 @@ def interior_rings end def rep_equals?(rhs) - if rhs.class == self.class && rhs.factory.eql?(@factory) && + if rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) && rhs.exterior_ring.rep_equals?(exterior_ring) sn = @fg_geom.num_interior_rings rn = rhs.num_interior_rings @@ -493,8 +491,10 @@ def rep_equals?(rhs) def hash @hash ||= begin - hash = Utils.ffi_coord_seq_hash(@fg_geom.exterior_ring.coord_seq, - [@factory, geometry_type].hash) + hash = Utils.ffi_coord_seq_hash( + @fg_geom.exterior_ring.coord_seq, + [@factory, geometry_type].hash + ) @fg_geom.interior_rings.inject(hash) do |h, r| Utils.ffi_coord_seq_hash(r.coord_seq, h) end @@ -512,7 +512,7 @@ def geometry_type end def rep_equals?(rhs) - if rhs.class == self.class && rhs.factory.eql?(@factory) + if rhs.instance_of?(self.class) && rhs.factory.eql?(@factory) size = @fg_geom.num_geometries if size == rhs.num_geometries size.times do |n| @@ -529,19 +529,24 @@ def num_geometries end alias size num_geometries - def geometry_n(n) - if n >= 0 && n < @fg_geom.num_geometries - @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n), - @_klasses ? @_klasses[n] : nil) - end + def geometry_n(idx) + return unless idx >= 0 && idx < @fg_geom.num_geometries + + @factory.wrap_fg_geom( + @fg_geom.get_geometry_n(idx), + @_klasses ? @_klasses[idx] : nil + ) end - def [](n) - n += @fg_geom.num_geometries if n < 0 - if n >= 0 && n < @fg_geom.num_geometries - @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n), - @_klasses ? @_klasses[n] : nil) - end + def [](idx) + idx += @fg_geom.num_geometries if idx < 0 + + return unless idx >= 0 && idx < @fg_geom.num_geometries + + @factory.wrap_fg_geom( + @fg_geom.get_geometry_n(idx), + @_klasses ? @_klasses[idx] : nil + ) end def hash @@ -551,8 +556,7 @@ def hash def each if block_given? @fg_geom.num_geometries.times do |n| - yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n), - @_klasses ? @_klasses[n] : nil) + yield @factory.wrap_fg_geom(@fg_geom.get_geometry_n(n), @_klasses ? @_klasses[n] : nil) end self else diff --git a/lib/rgeo/geos/interface.rb b/lib/rgeo/geos/interface.rb index d74c4a35..11a73dd1 100644 --- a/lib/rgeo/geos/interface.rb +++ b/lib/rgeo/geos/interface.rb @@ -7,7 +7,7 @@ # ----------------------------------------------------------------------------- module RGeo - module Geos + module Geos # :nodoc: class << self # Returns true if the CAPI GEOS implementation is supported. @@ -62,13 +62,12 @@ def geos?(object) def version unless defined?(@version) - if RGeo::Geos::CAPI_SUPPORTED - @version = RGeo::Geos::CAPIFactory._geos_version.freeze - elsif RGeo::Geos::FFI_SUPPORTED - @version = ::Geos::FFIGeos.GEOSversion.sub(/-CAPI-.*$/, "").freeze - else - @version = nil - end + @version = + if RGeo::Geos::CAPI_SUPPORTED + RGeo::Geos::CAPIFactory._geos_version.freeze + elsif RGeo::Geos::FFI_SUPPORTED + ::Geos::FFIGeos.GEOSversion.sub(/-CAPI-.*$/, "").freeze + end end @version end @@ -163,15 +162,16 @@ def version # never automatically generates a prepared geometry (unless you # generate one explicitly using the prepare! method). def factory(opts = {}) - if supported? - native_interface = opts[:native_interface] || Geos.preferred_native_interface - if opts[:has_z_coordinate] && opts[:has_m_coordinate] - ZMFactory.new(opts) - elsif native_interface == :ffi - FFIFactory.new(opts) - else - CAPIFactory.create(opts) - end + return unless supported? + + native_interface = opts[:native_interface] || Geos.preferred_native_interface + + if opts[:has_z_coordinate] && opts[:has_m_coordinate] + ZMFactory.new(opts) + elsif native_interface == :ffi + FFIFactory.new(opts) + else + CAPIFactory.create(opts) end end end diff --git a/lib/rgeo/geos/utils.rb b/lib/rgeo/geos/utils.rb index e5a807fa..bff2f4a5 100644 --- a/lib/rgeo/geos/utils.rb +++ b/lib/rgeo/geos/utils.rb @@ -49,9 +49,9 @@ def ffi_compute_dimension(geom) result end - def ffi_coord_seq_hash(cs, hash = 0) - (0...cs.length).inject(hash) do |h, i| - [hash, cs.get_x(i), cs.get_y(i), cs.get_z(i)].hash + def ffi_coord_seq_hash(coord_seq, hash = 0) + (0...coord_seq.length).inject(hash) do |_h, i| + [hash, coord_seq.get_x(i), coord_seq.get_y(i), coord_seq.get_z(i)].hash end end diff --git a/lib/rgeo/geos/zm_factory.rb b/lib/rgeo/geos/zm_factory.rb index e8fa22e3..1637471c 100644 --- a/lib/rgeo/geos/zm_factory.rb +++ b/lib/rgeo/geos/zm_factory.rb @@ -9,7 +9,6 @@ module RGeo module Geos # A factory for Geos that handles both Z and M. - class ZMFactory include Feature::Factory::Instance include ImplHelper::Utils @@ -60,33 +59,37 @@ def initialize(opts = {}) # :nodoc: end wkt_generator = opts[:wkt_generator] - case wkt_generator - when Hash - @wkt_generator = WKRep::WKTGenerator.new(wkt_generator) - else - @wkt_generator = WKRep::WKTGenerator.new(convert_case: :upper) - end + @wkt_generator = + case wkt_generator + when Hash + WKRep::WKTGenerator.new(wkt_generator) + else + WKRep::WKTGenerator.new(convert_case: :upper) + end wkb_generator = opts[:wkb_generator] - case wkb_generator - when Hash - @wkb_generator = WKRep::WKBGenerator.new(wkb_generator) - else - @wkb_generator = WKRep::WKBGenerator.new - end + @wkb_generator = + case wkb_generator + when Hash + WKRep::WKBGenerator.new(wkb_generator) + else + WKRep::WKBGenerator.new + end wkt_parser = opts[:wkt_parser] - case wkt_parser - when Hash - @wkt_parser = WKRep::WKTParser.new(self, wkt_parser) - else - @wkt_parser = WKRep::WKTParser.new(self) - end + @wkt_parser = + case wkt_parser + when Hash + WKRep::WKTParser.new(self, wkt_parser) + else + WKRep::WKTParser.new(self) + end wkb_parser = opts[:wkb_parser] - case wkb_parser - when Hash - @wkb_parser = WKRep::WKBParser.new(self, wkb_parser) - else - @wkb_parser = WKRep::WKBParser.new(self) - end + @wkb_parser = + case wkb_parser + when Hash + WKRep::WKBParser.new(self, wkb_parser) + else + WKRep::WKBParser.new(self) + end end # Marshal support @@ -108,11 +111,10 @@ def marshal_dump # :nodoc: end def marshal_load(data) # :nodoc: - if (coord_sys_data = data["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = data["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data) + end initialize( native_interface: (data["nffi"] ? :ffi : :capi), has_z_coordinate: data["hasz"], @@ -139,17 +141,17 @@ def encode_with(coder) # :nodoc: coder["wkb_parser"] = @wkb_parser.properties coder["auto_prepare"] = @zfactory.property(:auto_prepare).to_s coder["native_interface"] = @zfactory.is_a?(FFIFactory) ? "ffi" : "capi" - if (coord_sys = @zfactory.coord_sys) - coder["coord_sys"] = coord_sys.to_wkt - end + + return unless (coord_sys = @zfactory.coord_sys) + + coder["coord_sys"] = coord_sys.to_wkt end def init_with(coder) # :nodoc: - if (coord_sys_data = coder["cs"]) - coord_sys = CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) - else - coord_sys = nil - end + coord_sys = + if (coord_sys_data = coder["cs"]) + CoordSys::CONFIG.default_coord_sys_class.create_from_wkt(coord_sys_data.to_s) + end initialize( native_interface: coder["native_interface"] == "ffi" ? :ffi : :capi, has_z_coordinate: coder["has_z_coordinate"], @@ -192,8 +194,8 @@ def m_factory # Factory equivalence test. - def eql?(rhs) - rhs.is_a?(ZMFactory) && rhs.z_factory == @zfactory + def eql?(other) + other.is_a?(ZMFactory) && other.z_factory == @zfactory end alias == eql? @@ -226,8 +228,12 @@ def parse_wkb(str) # See RGeo::Feature::Factory#point - def point(x, y, z = 0, m = 0) - create_feature(ZMPointImpl, @zfactory.point(x, y, z), @mfactory.point(x, y, m)) + def point(x_coord, y_coord, z_coord = 0, m_coord = 0) + create_feature( + ZMPointImpl, + @zfactory.point(x_coord, y_coord, z_coord), + @mfactory.point(x_coord, y_coord, m_coord) + ) end # See RGeo::Feature::Factory#line_string @@ -251,7 +257,11 @@ def linear_ring(points) # See RGeo::Feature::Factory#polygon def polygon(outer_ring, inner_rings = nil) - create_feature(ZMPolygonImpl, @zfactory.polygon(outer_ring, inner_rings), @mfactory.polygon(outer_ring, inner_rings)) + create_feature( + ZMPolygonImpl, + @zfactory.polygon(outer_ring, inner_rings), + @mfactory.polygon(outer_ring, inner_rings) + ) end # See RGeo::Feature::Factory#collection diff --git a/lib/rgeo/geos/zm_feature_methods.rb b/lib/rgeo/geos/zm_feature_methods.rb index a04ee6a1..e178cbef 100644 --- a/lib/rgeo/geos/zm_feature_methods.rb +++ b/lib/rgeo/geos/zm_feature_methods.rb @@ -159,12 +159,19 @@ def difference(rhs) def sym_difference(rhs) rhs = RGeo::Feature.cast(rhs, self) - @factory.create_feature(nil, @zgeometry.sym_difference(rhs.z_geometry), @mgeometry.sym_difference(rhs.m_geometry)) + @factory.create_feature( + nil, + @zgeometry.sym_difference(rhs.z_geometry), + @mgeometry.sym_difference(rhs.m_geometry) + ) end def rep_equals?(rhs) rhs = RGeo::Feature.cast(rhs, self) - rhs.is_a?(self.class) && @factory.eql?(rhs.factory) && @zgeometry.rep_equals?(rhs.z_geometry) && @mgeometry.rep_equals?(rhs.m_geometry) + rhs.is_a?(self.class) && + @factory.eql?(rhs.factory) && + @zgeometry.rep_equals?(rhs.z_geometry) && + @mgeometry.rep_equals?(rhs.m_geometry) end alias eql? rep_equals? @@ -250,8 +257,8 @@ def num_points @zgeometry.num_points end - def point_n(n) - @factory.create_feature(ZMPointImpl, @zgeometry.point_n(n), @mgeometry.point_n(n)) + def point_n(idx) + @factory.create_feature(ZMPointImpl, @zgeometry.point_n(idx), @mgeometry.point_n(idx)) end def points @@ -290,8 +297,8 @@ def num_interior_rings @zgeometry.num_interior_rings end - def interior_ring_n(n) - @factory.create_feature(ZMLineStringImpl, @zgeometry.interior_ring_n(n), @mgeometry.interior_ring_n(n)) + def interior_ring_n(idx) + @factory.create_feature(ZMLineStringImpl, @zgeometry.interior_ring_n(idx), @mgeometry.interior_ring_n(idx)) end def interior_rings @@ -315,8 +322,8 @@ def num_geometries end alias size num_geometries - def geometry_n(n) - @factory.create_feature(nil, @zgeometry.geometry_n(n), @mgeometry.geometry_n(n)) + def geometry_n(idx) + @factory.create_feature(nil, @zgeometry.geometry_n(idx), @mgeometry.geometry_n(idx)) end alias [] geometry_n diff --git a/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb b/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb index ceb7b87e..1b2eecda 100644 --- a/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb +++ b/lib/rgeo/impl_helper/basic_geometry_collection_methods.rb @@ -27,12 +27,12 @@ def num_geometries @elements.size end - def geometry_n(n) - n < 0 ? nil : @elements[n] + def geometry_n(idx) + idx < 0 ? nil : @elements[idx] end - def [](n) - @elements[n] + def [](idx) + @elements[idx] end def each(&block) diff --git a/lib/rgeo/impl_helper/basic_geometry_methods.rb b/lib/rgeo/impl_helper/basic_geometry_methods.rb index f57fff45..efaa2f80 100644 --- a/lib/rgeo/impl_helper/basic_geometry_methods.rb +++ b/lib/rgeo/impl_helper/basic_geometry_methods.rb @@ -52,8 +52,7 @@ def copy_state_from(obj) @factory = obj.factory end - def init_geometry - end + def init_geometry; end end end end diff --git a/lib/rgeo/impl_helper/basic_line_string_methods.rb b/lib/rgeo/impl_helper/basic_line_string_methods.rb index 6c6b1521..e2c0a07c 100644 --- a/lib/rgeo/impl_helper/basic_line_string_methods.rb +++ b/lib/rgeo/impl_helper/basic_line_string_methods.rb @@ -19,9 +19,7 @@ def initialize(factory, points) # LineStrings in general need to check that there's not one point # GEOS doesn't allow instantiation of single point LineStrings so # we should handle it. - if @points.size == 1 - raise Error::InvalidGeometry, "LineString Cannot Have 1 Point" - end + raise Error::InvalidGeometry, "LineString Cannot Have 1 Point" if @points.size == 1 init_geometry end @@ -29,8 +27,8 @@ def num_points @points.size end - def point_n(n) - n < 0 ? nil : @points[n] + def point_n(idx) + idx < 0 ? nil : @points[idx] end def points @@ -64,9 +62,7 @@ def end_point end def closed? - unless defined?(@closed) - @closed = @points.size > 2 && @points.first == @points.last - end + @closed = @points.size > 2 && @points.first == @points.last unless defined?(@closed) @closed end @@ -111,15 +107,15 @@ def contains_point?(point) def point_intersect_segment?(point, start_point, end_point) return false unless point_collinear?(point, start_point, end_point) - if start_point.x != end_point.x - between_coordinate?(point.x, start_point.x, end_point.x) - else + if start_point.x == end_point.x between_coordinate?(point.y, start_point.y, end_point.y) + else + between_coordinate?(point.x, start_point.x, end_point.x) end end - def point_collinear?(a, b, c) - (b.x - a.x) * (c.y - a.y) == (c.x - a.x) * (b.y - a.y) + def point_collinear?(pt1, pt2, pt3) + (pt2.x - pt1.x) * (pt3.y - pt1.y) == (pt3.x - pt1.x) * (pt2.y - pt1.y) end def between_coordinate?(coord, start_coord, end_coord) @@ -137,9 +133,7 @@ module BasicLineMethods # :nodoc: def initialize(factory, start, stop) self.factory = factory cstart = Feature.cast(start, factory, Feature::Point) - unless cstart - raise Error::InvalidGeometry, "Could not cast start: #{start}" - end + raise Error::InvalidGeometry, "Could not cast start: #{start}" unless cstart cstop = Feature.cast(stop, factory, Feature::Point) raise Error::InvalidGeometry, "Could not cast end: #{stop}" unless cstop @points = [cstart, cstop] @@ -158,9 +152,7 @@ def coordinates module BasicLinearRingMethods # :nodoc: def initialize(factory, points) super - unless @points.size >= 4 || @points.size == 0 - raise Error::InvalidGeometry, "LinearRings must have 0 or >= 4 points" - end + raise Error::InvalidGeometry, "LinearRings must have 0 or >= 4 points" if @points.size.between?(1, 3) end def geometry_type @@ -176,10 +168,11 @@ def ccw? # Close ring if necessary. def init_geometry super - if @points.size > 0 - @points << @points.first if @points.first != @points.last - @points = @points.chunk { |x| x }.map(&:first) - end + + return if @points.size.zero? + + @points << @points.first if @points.first != @points.last + @points = @points.chunk { |x| x }.map(&:first) end end end diff --git a/lib/rgeo/impl_helper/basic_point_methods.rb b/lib/rgeo/impl_helper/basic_point_methods.rb index f11e93d3..e722c871 100644 --- a/lib/rgeo/impl_helper/basic_point_methods.rb +++ b/lib/rgeo/impl_helper/basic_point_methods.rb @@ -9,15 +9,13 @@ module RGeo module ImplHelper # :nodoc: module BasicPointMethods # :nodoc: - def initialize(factory, x, y, *extra) + def initialize(factory, x_coord, y_coord, *extra) self.factory = factory - @x = x.to_f - @y = y.to_f + @x = x_coord.to_f + @y = y_coord.to_f @z = factory.property(:has_z_coordinate) ? extra.shift.to_f : nil @m = factory.property(:has_m_coordinate) ? extra.shift.to_f : nil - if extra.size > 0 - raise ArgumentError, "Too many arguments for point initializer" - end + raise ArgumentError, "Too many arguments for point initializer" if extra.size.positive? init_geometry end diff --git a/lib/rgeo/impl_helper/basic_polygon_methods.rb b/lib/rgeo/impl_helper/basic_polygon_methods.rb index 52e54ca2..62640887 100644 --- a/lib/rgeo/impl_helper/basic_polygon_methods.rb +++ b/lib/rgeo/impl_helper/basic_polygon_methods.rb @@ -12,14 +12,10 @@ module BasicPolygonMethods # :nodoc: def initialize(factory, exterior_ring, interior_rings) self.factory = factory @exterior_ring = Feature.cast(exterior_ring, factory, Feature::LinearRing) - unless @exterior_ring - raise Error::InvalidGeometry, "Failed to cast exterior ring #{exterior_ring}" - end + raise Error::InvalidGeometry, "Failed to cast exterior ring #{exterior_ring}" unless @exterior_ring @interior_rings = (interior_rings || []).map do |elem| elem = Feature.cast(elem, factory, Feature::LinearRing) - unless elem - raise Error::InvalidGeometry, "Could not cast interior ring #{elem}" - end + raise Error::InvalidGeometry, "Could not cast interior ring #{elem}" unless elem elem end init_geometry @@ -33,8 +29,8 @@ def num_interior_rings @interior_rings.size end - def interior_ring_n(n) - n < 0 ? nil : @interior_rings[n] + def interior_ring_n(idx) + idx < 0 ? nil : @interior_rings[idx] end def interior_rings @@ -61,11 +57,14 @@ def boundary end def rep_equals?(rhs) - if rhs.is_a?(self.class) && rhs.factory.eql?(@factory) && @exterior_ring.rep_equals?(rhs.exterior_ring) && @interior_rings.size == rhs.num_interior_rings - rhs.interior_rings.each_with_index { |r, i| return false unless @interior_rings[i].rep_equals?(r) } - else - false - end + proper_match = rhs.is_a?(self.class) && + rhs.factory.eql?(@factory) && + @exterior_ring.rep_equals?(rhs.exterior_ring) && + @interior_rings.size == rhs.num_interior_rings + + return false unless proper_match + + rhs.interior_rings.each_with_index { |r, i| return false unless @interior_rings[i].rep_equals?(r) } end def hash @@ -80,7 +79,8 @@ def contains?(rhs) if Feature::Point === rhs contains_point?(rhs) else - raise(Error::UnsupportedOperation, + raise( + Error::UnsupportedOperation, "Method Polygon#contains? is only defined for Point" ) end @@ -90,7 +90,7 @@ def contains?(rhs) def contains_point?(point) ring_encloses_point?(@exterior_ring, point) && - !@interior_rings.any? do |exclusion| + @interior_rings.none? do |exclusion| ring_encloses_point?(exclusion, point, on_border_return: true) end end @@ -114,7 +114,6 @@ def ring_encloses_point?(ring, point, on_border_return: false) encloses_point end - def copy_state_from(obj) super @exterior_ring = obj.exterior_ring diff --git a/lib/rgeo/impl_helper/utils.rb b/lib/rgeo/impl_helper/utils.rb index 997f0450..9f5664a8 100644 --- a/lib/rgeo/impl_helper/utils.rb +++ b/lib/rgeo/impl_helper/utils.rb @@ -18,20 +18,14 @@ module Utils # :nodoc: # multiple times with different values and others pass the data # to a CAPI or FFI. def self.setup_coord_sys(srid, coord_sys, coord_sys_class) - unless coord_sys_class.is_a?(Class) - coord_sys_class = CoordSys::CONFIG.default_coord_sys_class - end + coord_sys_class = CoordSys::CONFIG.default_coord_sys_class unless coord_sys_class.is_a?(Class) - if coord_sys.is_a?(String) - coord_sys = coord_sys_class.create_from_wkt(coord_sys) - end + coord_sys = coord_sys_class.create_from_wkt(coord_sys) if coord_sys.is_a?(String) srid ||= coord_sys.authority_code if coord_sys srid = srid.to_i # Create a coord sys based on the SRID if one was not given - if coord_sys.nil? && srid != 0 - coord_sys = coord_sys_class.create(srid) - end + coord_sys = coord_sys_class.create(srid) if coord_sys.nil? && srid != 0 { coord_sys: coord_sys, srid: srid } end diff --git a/lib/rgeo/impl_helper/valid_op.rb b/lib/rgeo/impl_helper/valid_op.rb index 0993a702..751c5744 100644 --- a/lib/rgeo/impl_helper/valid_op.rb +++ b/lib/rgeo/impl_helper/valid_op.rb @@ -181,12 +181,12 @@ module ValidOpHelpers # Checks that the given point has valid coordinates. # - # @param pt [RGeo::Feature::Point] + # @param point [RGeo::Feature::Point] # # @return [String] invalid_reason - def check_invalid_coordinate(pt) - x = pt.x - y = pt.y + def check_invalid_coordinate(point) + x = point.x + y = point.y return if x.finite? && y.finite? && x.real? && y.real? Error::INVALID_COORDINATE @@ -265,9 +265,7 @@ def check_holes_in_shell(poly) poly.interior_rings.each do |interior| test_pt = interior.start_point - unless shell.contains?(test_pt) || poly.exterior_ring.contains?(test_pt) - return Error::HOLE_OUTSIDE_SHELL - end + return Error::HOLE_OUTSIDE_SHELL unless shell.contains?(test_pt) || poly.exterior_ring.contains?(test_pt) end nil @@ -322,27 +320,25 @@ def check_connected_interiors(poly) # Checks that polygons do not intersect in a multipolygon. # - # @param mp [RGeo::Feature::MultiPolygon] + # @param mpoly [RGeo::Feature::MultiPolygon] # # @return [String] invalid_reason - def check_consistent_area_mp(mp) - mp.geometries.combination(2) do |p1, p2| - if p1.exterior_ring.crosses?(p2.exterior_ring) - return Error::SELF_INTERSECTION - end + def check_consistent_area_mp(mpoly) + mpoly.geometries.combination(2) do |p1, p2| + return Error::SELF_INTERSECTION if p1.exterior_ring.crosses?(p2.exterior_ring) end nil end # Checks that individual polygons within a multipolygon are not nested. # - # @param mp [RGeo::Feature::MultiPolygon] + # @param mpoly [RGeo::Feature::MultiPolygon] # # @return [String] invalid_reason - def check_shells_not_nested(mp) + def check_shells_not_nested(mpoly) # Since we've passed the consistent area test, we can just check # that one point lies in the other. - mp.geometries.combination(2) do |p1, p2| + mpoly.geometries.combination(2) do |p1, p2| if p1.contains?(p2.exterior_ring.start_point) || p2.contains?(p1.exterior_ring.start_point) return Error::NESTED_SHELLS end diff --git a/lib/rgeo/wkrep/wkb_generator.rb b/lib/rgeo/wkrep/wkb_generator.rb index da8aeddc..3244bc25 100644 --- a/lib/rgeo/wkrep/wkb_generator.rb +++ b/lib/rgeo/wkrep/wkb_generator.rb @@ -39,7 +39,6 @@ module WKRep # [:little_endian] # If true, output little endian (NDR) byte order. If false, output # big endian (XDR), or network byte order. Default is false. - class WKBGenerator # :stopdoc: TYPE_CODES = { @@ -113,7 +112,7 @@ def generate(obj) private - class Result + class Result # :nodoc: def initialize(has_z, has_m) @buffer = [] @has_z = has_z @@ -126,7 +125,7 @@ def <<(data) def emit(hex_format) str = @buffer.join - hex_format ? str.unpack("H*")[0] : str + hex_format ? str.unpack1("H*") : str end def z? @@ -139,79 +138,75 @@ def m? end private_constant :Result - def emit_byte(value, rv) - rv << [value].pack("C") + def emit_byte(value, rval) + rval << [value].pack("C") end - def emit_integer(value, rv) - rv << [value].pack(@little_endian ? "V" : "N") + def emit_integer(value, rval) + rval << [value].pack(@little_endian ? "V" : "N") end - def emit_doubles(array, rv) - rv << array.pack(@little_endian ? "E*" : "G*") + def emit_doubles(array, rval) + rval << array.pack(@little_endian ? "E*" : "G*") end - def emit_line_string_coords(obj, rv) + def emit_line_string_coords(obj, rval) array = [] - obj.points.each { |pt| point_coords(pt, rv, array) } - emit_integer(obj.num_points, rv) - emit_doubles(array, rv) + obj.points.each { |pt| point_coords(pt, rval, array) } + emit_integer(obj.num_points, rval) + emit_doubles(array, rval) end - def point_coords(obj, rv, array = []) + def point_coords(obj, rval, array = []) array << obj.x array << obj.y - array << obj.z if rv.z? - array << obj.m if rv.m? + array << obj.z if rval.z? + array << obj.m if rval.m? array end - def generate_feature(obj, rv, toplevel = false) - emit_byte(@little_endian ? 1 : 0, rv) + def generate_feature(obj, rval, toplevel = false) + emit_byte(@little_endian ? 1 : 0, rval) type = obj.geometry_type type_code = TYPE_CODES[type] - unless type_code - raise Error::ParseError, "Unrecognized Geometry Type: #{type}" - end + raise Error::ParseError, "Unrecognized Geometry Type: #{type}" unless type_code emit_srid = false - if @type_format == :ewkb - type_code |= 0x80000000 if rv.z? - type_code |= 0x40000000 if rv.m? + case @type_format + when :ewkb + type_code |= 0x80000000 if rval.z? + type_code |= 0x40000000 if rval.m? if @emit_ewkb_srid && toplevel type_code |= 0x20000000 emit_srid = true end - elsif @type_format == :wkb12 - type_code += 1000 if rv.z? - type_code += 2000 if rv.m? + when :wkb12 + type_code += 1000 if rval.z? + type_code += 2000 if rval.m? end - emit_integer(type_code, rv) - emit_integer(obj.srid, rv) if emit_srid + emit_integer(type_code, rval) + emit_integer(obj.srid, rval) if emit_srid + multi_obj = [ + Feature::GeometryCollection, + Feature::MultiPoint, + Feature::MultiLineString, + Feature::MultiPolygon + ].include?(type) if type == Feature::Point - emit_doubles(point_coords(obj, rv), rv) + emit_doubles(point_coords(obj, rval), rval) elsif type.subtype_of?(Feature::LineString) - emit_line_string_coords(obj, rv) + emit_line_string_coords(obj, rval) elsif type == Feature::Polygon exterior_ring = obj.exterior_ring if exterior_ring.empty? - emit_integer(0, rv) + emit_integer(0, rval) else - emit_integer(1 + obj.num_interior_rings, rv) - emit_line_string_coords(exterior_ring, rv) - obj.interior_rings.each { |r| emit_line_string_coords(r, rv) } + emit_integer(1 + obj.num_interior_rings, rval) + emit_line_string_coords(exterior_ring, rval) + obj.interior_rings.each { |r| emit_line_string_coords(r, rval) } end - elsif type == Feature::GeometryCollection - emit_integer(obj.num_geometries, rv) - obj.each { |g| generate_feature(g, rv) } - elsif type == Feature::MultiPoint - emit_integer(obj.num_geometries, rv) - obj.each { |g| generate_feature(g, rv) } - elsif type == Feature::MultiLineString - emit_integer(obj.num_geometries, rv) - obj.each { |g| generate_feature(g, rv) } - elsif type == Feature::MultiPolygon - emit_integer(obj.num_geometries, rv) - obj.each { |g| generate_feature(g, rv) } + elsif multi_obj + emit_integer(obj.num_geometries, rval) + obj.each { |g| generate_feature(g, rval) } end end end diff --git a/lib/rgeo/wkrep/wkb_parser.rb b/lib/rgeo/wkrep/wkb_parser.rb index 6ac15996..7ae94174 100644 --- a/lib/rgeo/wkrep/wkb_parser.rb +++ b/lib/rgeo/wkrep/wkb_parser.rb @@ -42,7 +42,6 @@ module WKRep # [:default_srid] # A SRID to pass to the factory generator if no SRID is present in # the input. Defaults to nil (i.e. don't specify a SRID). - class WKBParser # Create and configure a WKB parser. See the WKBParser # documentation for the options that can be passed. @@ -118,9 +117,7 @@ def parse(data) obj = parse_object(false) unless @ignore_extra_bytes bytes = bytes_remaining - if bytes > 0 - raise Error::ParseError, "Found #{bytes} extra bytes at the end of the stream." - end + raise Error::ParseError, "Found #{bytes} extra bytes at the end of the stream." if bytes > 0 end ensure @data = nil @@ -133,7 +130,7 @@ def parse(data) private def parse_object(contained) - endian_value = get_byte + endian_value = byte case endian_value when 0 little_endian = false @@ -161,14 +158,20 @@ def parse_object(contained) if contained != true && contained != type_code raise Error::ParseError, "Enclosed type=#{type_code} is different from container constraint #{contained}" end + if has_z != @cur_has_z raise Error::ParseError, "Enclosed hasZ=#{has_z} is different from toplevel hasZ=#{@cur_has_z}" end + if has_m != @cur_has_m raise Error::ParseError, "Enclosed hasM=#{has_m} is different from toplevel hasM=#{@cur_has_m}" end + if srid && srid != @cur_srid - raise Error::ParseError, "Enclosed SRID #{srid} is different from toplevel srid #{@cur_srid || '(unspecified)'}" + raise( + Error::ParseError, + "Enclosed SRID #{srid} is different from toplevel srid #{@cur_srid || '(unspecified)'}" + ) end else @cur_has_z = has_z @@ -176,9 +179,11 @@ def parse_object(contained) @cur_dims = 2 + (@cur_has_z ? 1 : 0) + (@cur_has_m ? 1 : 0) @cur_srid = srid @cur_factory = @factory_generator.call(srid: @cur_srid, has_z_coordinate: has_z, has_m_coordinate: has_m) + if @cur_has_z && !@cur_factory.property(:has_z_coordinate) raise Error::ParseError, "Data has Z coordinates but the factory doesn't have Z coordinates" end + if @cur_has_m && !@cur_factory.property(:has_m_coordinate) raise Error::ParseError, "Data has M coordinates but the factory doesn't have M coordinates" end @@ -222,29 +227,23 @@ def bytes_remaining @len - @pos end - def get_byte - if @pos + 1 > @len - raise Error::ParseError, "Not enough bytes left to fulfill 1 byte" - end + def byte + raise Error::ParseError, "Not enough bytes left to fulfill 1 byte" if @pos + 1 > @len str = @data[@pos, 1] @pos += 1 - str.unpack("C").first + str.unpack1("C") end def get_integer(little_endian) - if @pos + 4 > @len - raise Error::ParseError, "Not enough bytes left to fulfill 1 integer" - end + raise Error::ParseError, "Not enough bytes left to fulfill 1 integer" if @pos + 4 > @len str = @data[@pos, 4] @pos += 4 - str.unpack(little_endian ? "V" : "N").first + str.unpack1(little_endian ? "V" : "N") end def get_doubles(little_endian, count) len = 8 * count - if @pos + len > @len - raise Error::ParseError, "Not enough bytes left to fulfill #{count} doubles" - end + raise Error::ParseError, "Not enough bytes left to fulfill #{count} doubles" if @pos + len > @len str = @data[@pos, len] @pos += len str.unpack("#{little_endian ? 'E' : 'G'}*") diff --git a/lib/rgeo/wkrep/wkt_generator.rb b/lib/rgeo/wkrep/wkt_generator.rb index 9cdf4b16..067b4b31 100644 --- a/lib/rgeo/wkrep/wkt_generator.rb +++ b/lib/rgeo/wkrep/wkt_generator.rb @@ -45,15 +45,16 @@ module WKRep # letters to lower case; or nil, indicating no case changes from # the default (which is not specified exactly, but is chosen by the # generator to emphasize readability.) Default is nil. - class WKTGenerator # Create and configure a WKT generator. See the WKTGenerator # documentation for the options that can be passed. def initialize(opts = {}) @tag_format = opts[:tag_format] || opts[:type_format] || :wkt11 - @emit_ewkt_srid = @tag_format == :ewkt ? - (opts[:emit_ewkt_srid] ? true : false) : nil + @emit_ewkt_srid = + if @tag_format == :ewkt + (opts[:emit_ewkt_srid] ? true : false) + end @square_brackets = opts[:square_brackets] ? true : false @convert_case = opts[:convert_case] end @@ -100,9 +101,10 @@ def generate(obj) support_m = factory.property(:has_m_coordinate) end str = generate_feature(obj, support_z, support_m, true) - if @convert_case == :upper + case @convert_case + when :upper str.upcase - elsif @convert_case == :lower + when :lower str.downcase else str @@ -115,16 +117,18 @@ def generate_feature(obj, support_z, support_m, toplevel = false) type = obj.geometry_type type = Feature::LineString if type.subtype_of?(Feature::LineString) tag = type.type_name.dup - if @tag_format == :ewkt + case @tag_format + when :ewkt tag << "M" if support_m && !support_z tag = "SRID=#{obj.srid};#{tag}" if toplevel && @emit_ewkt_srid - elsif @tag_format == :wkt12 + when :wkt12 if support_z - if support_m - tag << " ZM" - else - tag << " Z" - end + tag << + if support_m + " ZM" + else + " Z" + end elsif support_m tag << " M" end @@ -163,7 +167,8 @@ def generate_line_string(obj, support_z, support_m) if obj.empty? "EMPTY" else - "#{@begin_bracket}#{obj.points.map { |p| generate_coords(p, support_z, support_m) }.join(', ')}#{@end_bracket}" + points = obj.points.map { |p| generate_coords(p, support_z, support_m) } + "#{@begin_bracket}#{points.join(', ')}#{@end_bracket}" end end @@ -171,7 +176,9 @@ def generate_polygon(obj, support_z, support_m) if obj.empty? "EMPTY" else - "#{@begin_bracket}#{([generate_line_string(obj.exterior_ring, support_z, support_m)] + obj.interior_rings.map { |r| generate_line_string(r, support_z, support_m) }).join(', ')}#{@end_bracket}" + lines = [generate_line_string(obj.exterior_ring, support_z, support_m)] + lines += obj.interior_rings.map { |r| generate_line_string(r, support_z, support_m) } + "#{@begin_bracket}#{lines.join(', ')}#{@end_bracket}" end end diff --git a/lib/rgeo/wkrep/wkt_parser.rb b/lib/rgeo/wkrep/wkt_parser.rb index d93f8255..3f6356e9 100644 --- a/lib/rgeo/wkrep/wkt_parser.rb +++ b/lib/rgeo/wkrep/wkt_parser.rb @@ -48,7 +48,6 @@ module WKRep # [:default_srid] # A SRID to pass to the factory generator if no SRID is present in # the input. Defaults to nil (i.e. don't specify a SRID). - class WKTParser # Create and configure a WKT parser. See the WKTParser # documentation for the options that can be passed. @@ -66,7 +65,12 @@ def initialize(factory_generator = nil, opts = {}) end @support_ewkt = opts[:support_ewkt] ? true : false @support_wkt12 = opts[:support_wkt12] ? true : false - @strict_wkt11 = @support_ewkt || @support_wkt12 ? false : opts[:strict_wkt11] ? true : false + @strict_wkt11 = + if @support_ewkt || @support_wkt12 + false + else + opts[:strict_wkt11] ? true : false + end @ignore_extra_tokens = opts[:ignore_extra_tokens] ? true : false @default_srid = opts[:default_srid] @mutex = Mutex.new @@ -127,12 +131,13 @@ def parse(str) @cur_expect_m = nil @cur_srid = @default_srid if @support_ewkt && str =~ /^srid=(\d+);/i - str = $' + str = Regexp.last_match&.post_match @cur_srid = Regexp.last_match(1).to_i end begin start_scanner(str) obj = parse_type_tag + if @cur_token && !@ignore_extra_tokens raise Error::ParseError, "Extra tokens beginning with #{@cur_token.inspect}." end @@ -149,14 +154,19 @@ def check_factory_support if @cur_expect_z && !@cur_factory_support_z raise Error::ParseError, "Geometry calls for Z coordinate but factory doesn't support it." end - if @cur_expect_m && !@cur_factory_support_m - raise Error::ParseError, "Geometry calls for M coordinate but factory doesn't support it." - end + + return unless @cur_expect_m && !@cur_factory_support_m + + raise Error::ParseError, "Geometry calls for M coordinate but factory doesn't support it." end def ensure_factory unless @cur_factory - @cur_factory = @factory_generator.call(srid: @cur_srid, has_z_coordinate: @cur_expect_z, has_m_coordinate: @cur_expect_m) + @cur_factory = @factory_generator.call( + srid: @cur_srid, + has_z_coordinate: @cur_expect_z, + has_m_coordinate: @cur_expect_m + ) @cur_factory_support_z = @cur_factory.property(:has_z_coordinate) ? true : false @cur_factory_support_m = @cur_factory.property(:has_m_coordinate) ? true : false check_factory_support unless @cur_expect_z.nil? @@ -238,9 +248,11 @@ def parse_coords num_extras -= 1 if @cur_expect_z @cur_expect_m = num_extras > 0 && (!@cur_factory || @cur_factory_support_m) ? true : false num_extras -= 1 if @cur_expect_m + if num_extras > 0 raise Error::ParseError, "Found #{extra.size + 2} coordinates, which is too many for this factory." end + ensure_factory else val = 0 @@ -390,13 +402,11 @@ def clean_scanner end def expect_token_type(type) - unless type === @cur_token - raise Error::ParseError, "#{type.inspect} expected but #{@cur_token.inspect} found." - end + raise Error::ParseError, "#{type.inspect} expected but #{@cur_token.inspect} found." unless type === @cur_token end def next_token - if @scanner.scan_until(/\(|\)|\[|\]|,|[^\s\(\)\[\],]+/) + if @scanner.scan_until(/\(|\)|\[|\]|,|[^\s()\[\],]+/) token = @scanner.matched case token when /^[-+]?(\d+(\.\d*)?|\.\d+)(e[-+]?\d+)?$/ diff --git a/rgeo.gemspec b/rgeo.gemspec index 92733c0f..1d1056ea 100644 --- a/rgeo.gemspec +++ b/rgeo.gemspec @@ -17,7 +17,7 @@ Gem::Specification.new do |spec| spec.authors = ["Daniel Azuma", "Tee Parham"] spec.email = ["dazuma@gmail.com", "parhameter@gmail.com", "kfdoggett@gmail.com", "buonomo.ulysse@gmail.com"] spec.homepage = "https://github.com/rgeo/rgeo" - spec.required_ruby_version = ">= 2.5.0" + spec.required_ruby_version = ">= 2.6.0" spec.license = "BSD-3-Clause" spec.metadata["rubygems_mfa_required"] = "true" diff --git a/test/cartesian_bbox_test.rb b/test/cartesian_bbox_test.rb index ab333ba8..6fa9e2fe 100644 --- a/test/cartesian_bbox_test.rb +++ b/test/cartesian_bbox_test.rb @@ -83,7 +83,8 @@ def test_bbox_from_points bbox.add(@factory.point(1, 4)) bbox.add(@factory.point(2, 3)) bbox2 = RGeo::Cartesian::BoundingBox.create_from_points( - @factory.point(2, 3), @factory.point(1, 4)) + @factory.point(2, 3), @factory.point(1, 4) + ) assert_equal(bbox, bbox2) end diff --git a/test/common/factory_tests.rb b/test/common/factory_tests.rb index ac543315..24a115c2 100644 --- a/test/common/factory_tests.rb +++ b/test/common/factory_tests.rb @@ -56,8 +56,7 @@ def test_dup_factoryresults_in_equal_hashes end def test_marshal_dump_load_factory - data = Marshal.dump(@factory) - factory2 = Marshal.load(data) + factory2 = Marshal.load(Marshal.dump(@factory)) assert_equal(@factory, factory2) assert_equal(srid, factory2.srid) end diff --git a/test/common/line_string_tests.rb b/test/common/line_string_tests.rb index ca4e33b6..48d35bf7 100644 --- a/test/common/line_string_tests.rb +++ b/test/common/line_string_tests.rb @@ -297,8 +297,7 @@ def test_marshal_roundtrip point1 = @factory.point(0, 0) point2 = @factory.point(0, 1) line1 = @factory.line_string([point1, point2]) - data = Marshal.dump(line1) - line2 = Marshal.load(data) + line2 = Marshal.load(Marshal.dump(line1)) assert_equal(line1, line2) end diff --git a/test/common/multi_polygon_tests.rb b/test/common/multi_polygon_tests.rb index 5cbc7c55..d36e2f80 100644 --- a/test/common/multi_polygon_tests.rb +++ b/test/common/multi_polygon_tests.rb @@ -94,7 +94,13 @@ def test_hashes_equal_for_representationally_equivalent_objects end def test_wkt_creation_simple - parsed_geom = @factory.parse_wkt("MULTIPOLYGON(((0 0, 0 -10, -10 0, 0 0)), ((0 0, 0 10, 10 10, 10 0, 0 0), (4 4, 5 6, 6 4, 4 4)))") + multipolygon = <<~WKT + MULTIPOLYGON ( + ((0 0, 0 -10, -10 0, 0 0)), + ((0 0, 0 10, 10 10, 10 0, 0 0), (4 4, 5 6, 6 4, 4 4)) + ) + WKT + parsed_geom = @factory.parse_wkt(format_wkt(multipolygon)) built_geom = @factory.multi_polygon([@poly1, @poly2]) assert(built_geom.eql?(parsed_geom)) end @@ -186,7 +192,14 @@ def test_point_on_surface end def test_boundary - parsed_geom = @factory.parse_wkt("MULTILINESTRING ((0.0 0.0, 0.0 -10.0, -10.0 0.0, 0.0 0.0), (0.0 0.0, 0.0 10.0, 10.0 10.0, 10.0 0.0, 0.0 0.0), (4.0 4.0, 5.0 6.0, 6.0 4.0, 4.0 4.0))") + multilinestring = <<~WKT + MULTILINESTRING ( + (0.0 0.0, 0.0 -10.0, -10.0 0.0, 0.0 0.0), + (0.0 0.0, 0.0 10.0, 10.0 10.0, 10.0 0.0, 0.0 0.0), + (4.0 4.0, 5.0 6.0, 6.0 4.0, 4.0 4.0) + ) + WKT + parsed_geom = @factory.parse_wkt(format_wkt(multilinestring)) built_geom = @factory.multi_polygon([@poly1, @poly2]) boundary_geom = built_geom.boundary parsed_coordinates = parsed_geom.coordinates diff --git a/test/common/point_tests.rb b/test/common/point_tests.rb index a00d890b..2c650489 100644 --- a/test/common/point_tests.rb +++ b/test/common/point_tests.rb @@ -10,13 +10,13 @@ module RGeo module Tests # :nodoc: module Common # :nodoc: module PointTests # :nodoc: - def assert_close_enough(p1, p2) - assert_in_delta(p1.x, p2.x, 1e-8, "x axis not close enough") - assert_in_delta(p1.y, p2.y, 1e-8, "y axis not close enough") + def assert_close_enough(pt1, pt2) + assert_in_delta(pt1.x, pt2.x, 1e-8, "x axis not close enough") + assert_in_delta(pt1.y, pt2.y, 1e-8, "y axis not close enough") end - def assert_contains_approx(p, mp) - assert(mp.any? { |q| (p.x - q.x).abs < 1e-8 && (p.y - q.y).abs < 1e-8 }) + def assert_contains_approx(point, multipt) + assert(multipt.any? { |q| (point.x - q.x).abs < 1e-8 && (point.y - q.y).abs < 1e-8 }) end def test_creation @@ -294,22 +294,19 @@ def test_wkt_creation_3d def test_marshal_roundtrip point = @factory.point(11, 12) - data = Marshal.dump(point) - point2 = Marshal.load(data) + point2 = Marshal.load(Marshal.dump(point)) assert_equal(point, point2) end def test_marshal_roundtrip_3d point = @zfactory.point(11, 12, 13) - data = Marshal.dump(point) - point2 = Marshal.load(data) + point2 = Marshal.load(Marshal.dump(point)) assert_equal(point, point2) end def test_marshal_roundtrip_4d point = @zmfactory.point(11, 12, 13, 14) - data = Marshal.dump(point) - point2 = Marshal.load(data) + point2 = Marshal.load(Marshal.dump(point)) assert_equal(point, point2) end diff --git a/test/common/polygon_tests.rb b/test/common/polygon_tests.rb index b0246699..5907b5b8 100644 --- a/test/common/polygon_tests.rb +++ b/test/common/polygon_tests.rb @@ -218,7 +218,7 @@ def test_boundary_simple point2 = @factory.point(0, 1) point3 = @factory.point(1, 0) exterior = @factory.linear_ring([point1, point2, point3, point1]) - boundary = @factory.multi_line_string([exterior]) + boundary = @factory.multi_line_string([exterior]) polygon = @factory.polygon(exterior) assert_equal(boundary, polygon.boundary) end @@ -233,7 +233,7 @@ def test_boundary_one_hole point7 = @factory.point(6, 4) exterior = @factory.linear_ring([point1, point2, point3, point4, point1]) interior = @factory.linear_ring([point5, point6, point7, point5]) - boundary = @factory.multi_line_string([exterior, interior]) + boundary = @factory.multi_line_string([exterior, interior]) polygon = @factory.polygon(exterior, [interior]) assert_equal(boundary, polygon.boundary) end @@ -267,10 +267,10 @@ def test_ignores_consecutive_repeated_points line_string = poly1.exterior_ring case line_string.class.name - when "GeosPolygonTest" - when "RGeo::Geos::FFILinearRingImpl" - when "RGeo::Geos::CAPILinearRingImpl" - when "GeosFFIPolygonTest" + when "GeosPolygonTest", + "RGeo::Geos::FFILinearRingImpl", + "RGeo::Geos::CAPILinearRingImpl", + "GeosFFIPolygonTest" assert(line_string.points.count == 9) else assert(line_string.num_points == 4) diff --git a/test/coord_sys/ogc_cs_test.rb b/test/coord_sys/ogc_cs_test.rb index f1bb8111..493984d5 100644 --- a/test/coord_sys/ogc_cs_test.rb +++ b/test/coord_sys/ogc_cs_test.rb @@ -12,11 +12,16 @@ class OgcCsTest < Minitest::Test # :nodoc: # Handle differences in floating-point output. def lenient_regex_for(str) - Regexp.new(str.gsub(/(\d)\.(\d{10,})/) do - before = Regexp.last_match(1) - after = Regexp.last_match(2)[0, 10] - "#{before}.#{after}\\d*" - end.gsub(/(\.|\[|\]|\(|\)|\$|\^|\||\+)/) { "\\#{Regexp.last_match(1)}" }) + fmstr = + str.gsub(/(\d)\.(\d{10,})/) do + before = Regexp.last_match(1) + after = Regexp.last_match(2)[0, 10] + "#{before}.#{after}\\d*" + end + + fmstr = fmstr.gsub(/([.\[\]()$^|+])/) { "\\#{Regexp.last_match(1)}" } + + Regexp.new(fmstr) end def test_axis_info_by_value @@ -93,7 +98,14 @@ def test_prime_meridian def test_create_flattened_sphere obj1 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1) - obj = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("WGS 84", 6_378_137, 298.257223563, obj1, "EPSG", "7030") + obj = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "WGS 84", + 6_378_137, + 298.257223563, + obj1, + "EPSG", + "7030" + ) assert_equal("WGS 84", obj.name) assert_equal(6_378_137, obj.semi_major_axis) assert_in_delta(298.257223563, obj.inverse_flattening, 0.1) @@ -105,7 +117,14 @@ def test_create_flattened_sphere def test_create_unflattened_sphere obj1 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1) - obj = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("Popular Visualisation Sphere", 6_378_137, 0, obj1, "EPSG", "7059") + obj = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "Popular Visualisation Sphere", + 6_378_137, + 0, + obj1, + "EPSG", + "7059" + ) assert_equal("Popular Visualisation Sphere", obj.name) assert_equal(6_378_137, obj.semi_major_axis) assert_equal(0, obj.inverse_flattening) @@ -123,7 +142,14 @@ def test_create_ellipsoid def test_create_spherical_ellipsoid obj1 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1) - obj = RGeo::CoordSys::CS::Ellipsoid.create_ellipsoid("Popular Visualisation Sphere", 6_378_137, 6_378_137, obj1, "EPSG", "7059") + obj = RGeo::CoordSys::CS::Ellipsoid.create_ellipsoid( + "Popular Visualisation Sphere", + 6_378_137, + 6_378_137, + obj1, + "EPSG", + "7059" + ) assert_equal(0, obj.inverse_flattening) end @@ -135,14 +161,28 @@ def test_local_datum end def test_local_datum_with_extension - obj = RGeo::CoordSys::CS::LocalDatum.create("Random Local Datum", RGeo::CoordSys::CS::LD_MIN, nil, nil, nil, nil, nil, foo: :bar) + obj = RGeo::CoordSys::CS::LocalDatum.create( + "Random Local Datum", + RGeo::CoordSys::CS::LD_MIN, + nil, + nil, + nil, + nil, + nil, + foo: :bar + ) assert_equal("bar", obj.extension(:foo)) assert_nil(obj.extension(:bar)) assert_equal('LOCAL_DATUM["Random Local Datum",10000,EXTENSION["foo","bar"]]', obj.to_wkt) end def test_vertical_datum - obj = RGeo::CoordSys::CS::VerticalDatum.create("Ordnance Datum Newlyn", RGeo::CoordSys::CS::VD_GEOID_MODE_DERIVED, "EPSG", "5101") + obj = RGeo::CoordSys::CS::VerticalDatum.create( + "Ordnance Datum Newlyn", + RGeo::CoordSys::CS::VD_GEOID_MODE_DERIVED, + "EPSG", + "5101" + ) assert_equal("Ordnance Datum Newlyn", obj.name) assert_equal(RGeo::CoordSys::CS::VD_GEOID_MODE_DERIVED, obj.datum_type) assert_equal("EPSG", obj.authority) @@ -152,14 +192,30 @@ def test_vertical_datum def test_horizontal_datum obj1 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1) - obj2 = RGeo::CoordSys::CS::Ellipsoid.create_ellipsoid("Popular Visualisation Sphere", 6_378_137, 6_378_137, obj1, "EPSG", "7059") + obj2 = RGeo::CoordSys::CS::Ellipsoid.create_ellipsoid( + "Popular Visualisation Sphere", + 6_378_137, + 6_378_137, + obj1, + "EPSG", + "7059" + ) obj3 = RGeo::CoordSys::CS::WGS84ConversionInfo.create(0, 0, 0, 0, 0, 0, 0) - obj = RGeo::CoordSys::CS::HorizontalDatum.create("Popular_Visualisation_Datum", RGeo::CoordSys::CS::HD_GEOCENTRIC, obj2, obj3, "EPSG", "6055") + obj = RGeo::CoordSys::CS::HorizontalDatum.create( + "Popular_Visualisation_Datum", + RGeo::CoordSys::CS::HD_GEOCENTRIC, + obj2, + obj3, + "EPSG", + "6055" + ) assert_equal("Popular_Visualisation_Datum", obj.name) assert_equal(RGeo::CoordSys::CS::HD_GEOCENTRIC, obj.datum_type) assert_equal("EPSG", obj.authority) assert_equal("6055", obj.authority_code) - assert_equal('DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137.0,0.0,AUTHORITY["EPSG","7059"]],TOWGS84[0.0,0.0,0.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6055"]]', obj.to_wkt) + datum = 'DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137.0,0.0,' \ + 'AUTHORITY["EPSG","7059"]],TOWGS84[0.0,0.0,0.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6055"]]' + assert_equal(datum, obj.to_wkt) end def test_projection @@ -183,18 +239,44 @@ def test_local_coordinate_system assert_equal("E", obj.get_axis(1).name) assert_equal("metre", obj.get_units(0).name) assert_equal("metre", obj.get_units(1).name) - assert_equal('LOCAL_CS["My CS",LOCAL_DATUM["Random Local Datum",10000],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["N",NORTH],AXIS["E",EAST]]', obj.to_wkt) + local_cs = 'LOCAL_CS["My CS",LOCAL_DATUM["Random Local Datum",10000],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],' \ + 'AXIS["N",NORTH],AXIS["E",EAST]]' + assert_equal(local_cs, obj.to_wkt) end def test_geocentric_coordinate_system - obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("WGS 84", 6_378_137, 298.257223563, nil, "EPSG", "7030") - obj2 = RGeo::CoordSys::CS::HorizontalDatum.create("World Geodetic System 1984", RGeo::CoordSys::CS::HD_GEOCENTRIC, obj1, nil, "EPSG", "6326") + obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "WGS 84", + 6_378_137, + 298.257223563, + nil, + "EPSG", + "7030" + ) + obj2 = RGeo::CoordSys::CS::HorizontalDatum.create( + "World Geodetic System 1984", + RGeo::CoordSys::CS::HD_GEOCENTRIC, + obj1, + nil, + "EPSG", + "6326" + ) obj3 = RGeo::CoordSys::CS::PrimeMeridian.create("Greenwich", nil, 0.0, "EPSG", "8901") obj4 = RGeo::CoordSys::CS::LinearUnit.create("m", 1.0) obj5 = RGeo::CoordSys::CS::AxisInfo.create("Geocentric X", RGeo::CoordSys::CS::AO_OTHER) obj6 = RGeo::CoordSys::CS::AxisInfo.create("Geocentric Y", RGeo::CoordSys::CS::AO_EAST) obj7 = RGeo::CoordSys::CS::AxisInfo.create("Geocentric Z", RGeo::CoordSys::CS::AO_NORTH) - obj = RGeo::CoordSys::CS::GeocentricCoordinateSystem.create("WGS 84 (geocentric)", obj2, obj3, obj4, obj5, obj6, obj7, "EPSG", 4328) + obj = RGeo::CoordSys::CS::GeocentricCoordinateSystem.create( + "WGS 84 (geocentric)", + obj2, + obj3, + obj4, + obj5, + obj6, + obj7, + "EPSG", + 4328 + ) assert_equal("WGS 84 (geocentric)", obj.name) assert_equal(3, obj.dimension) assert_equal("World Geodetic System 1984", obj.horizontal_datum.name) @@ -206,11 +288,20 @@ def test_geocentric_coordinate_system assert_equal("m", obj.get_units(0).name) assert_equal("m", obj.get_units(1).name) assert_equal("m", obj.get_units(2).name) - assert_equal('GEOCCS["WGS 84 (geocentric)",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137.0,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["m",1.0],AXIS["Geocentric X",OTHER],AXIS["Geocentric Y",EAST],AXIS["Geocentric Z",NORTH],AUTHORITY["EPSG","4328"]]', obj.to_wkt) + geo_ccs = 'GEOCCS["WGS 84 (geocentric)",DATUM["World Geodetic System 1984",SPHEROID["WGS 84",6378137.0,' \ + '298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,' \ + 'AUTHORITY["EPSG","8901"]],UNIT["m",1.0],AXIS["Geocentric X",OTHER],AXIS["Geocentric Y",EAST],' \ + 'AXIS["Geocentric Z",NORTH],AUTHORITY["EPSG","4328"]]' + assert_equal(geo_ccs, obj.to_wkt) end def test_vertical_coordinate_system - obj1 = RGeo::CoordSys::CS::VerticalDatum.create("Ordnance Datum Newlyn", RGeo::CoordSys::CS::VD_GEOID_MODE_DERIVED, "EPSG", 5101) + obj1 = RGeo::CoordSys::CS::VerticalDatum.create( + "Ordnance Datum Newlyn", + RGeo::CoordSys::CS::VD_GEOID_MODE_DERIVED, + "EPSG", + 5101 + ) obj2 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1, "EPSG", 9001) obj3 = RGeo::CoordSys::CS::AxisInfo.create("Up", RGeo::CoordSys::CS::AO_UP) obj = RGeo::CoordSys::CS::VerticalCoordinateSystem.create("Newlyn", obj1, obj2, obj3, "EPSG", 5701) @@ -220,13 +311,29 @@ def test_vertical_coordinate_system assert_equal("metre", obj.vertical_unit.name) assert_equal("Up", obj.get_axis(0).name) assert_equal("metre", obj.get_units(0).name) - assert_equal('VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["Up",UP],AUTHORITY["EPSG","5701"]]', obj.to_wkt) + vert_cs = 'VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["metre",1.0,' \ + 'AUTHORITY["EPSG","9001"]],AXIS["Up",UP],AUTHORITY["EPSG","5701"]]' + assert_equal(vert_cs, obj.to_wkt) end def test_geographic_coordinate_system - obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("WGS 84", 6_378_137, 298.257223563, nil, "EPSG", "7030") + obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "WGS 84", + 6_378_137, + 298.257223563, + nil, + "EPSG", + "7030" + ) obj2 = RGeo::CoordSys::CS::AngularUnit.create("degree", 0.01745329251994328, "EPSG", 9122) - obj3 = RGeo::CoordSys::CS::HorizontalDatum.create("WGS_1984", RGeo::CoordSys::CS::HD_GEOCENTRIC, obj1, nil, "EPSG", "6326") + obj3 = RGeo::CoordSys::CS::HorizontalDatum.create( + "WGS_1984", + RGeo::CoordSys::CS::HD_GEOCENTRIC, + obj1, + nil, + "EPSG", + "6326" + ) obj4 = RGeo::CoordSys::CS::PrimeMeridian.create("Greenwich", nil, 0, "EPSG", "8901") obj = RGeo::CoordSys::CS::GeographicCoordinateSystem.create("WGS 84", obj2, obj3, obj4, nil, nil, "EPSG", 4326) assert_equal("WGS 84", obj.name) @@ -238,28 +345,67 @@ def test_geographic_coordinate_system assert_nil(obj.get_axis(1)) assert_equal("degree", obj.get_units(0).name) assert_equal("degree", obj.get_units(1).name) - assert_match(lenient_regex_for('GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137.0,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]'), obj.to_wkt) + geo_gcs = 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137.0,298.257223563,AUTHORITY["EPSG","7030"]],' \ + 'AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",' \ + '0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]' + assert_match(lenient_regex_for(geo_gcs), obj.to_wkt) end def test_projected_coordinate_system - obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("Airy 1830", 6_377_563.396, 299.3249646, nil, "EPSG", "7001") + obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "Airy 1830", + 6_377_563.396, + 299.3249646, + nil, + "EPSG", + "7001" + ) obj2 = RGeo::CoordSys::CS::WGS84ConversionInfo.create(375, -111, 431, 0, 0, 0, 0) obj3 = RGeo::CoordSys::CS::AngularUnit.create("DMSH", 0.0174532925199433, "EPSG", 9108) - obj4 = RGeo::CoordSys::CS::HorizontalDatum.create("OSGB_1936", RGeo::CoordSys::CS::HD_CLASSIC, obj1, obj2, "EPSG", "6277") + obj4 = RGeo::CoordSys::CS::HorizontalDatum.create( + "OSGB_1936", + RGeo::CoordSys::CS::HD_CLASSIC, + obj1, + obj2, + "EPSG", + "6277" + ) obj5 = RGeo::CoordSys::CS::PrimeMeridian.create("Greenwich", nil, 0, "EPSG", "8901") obj6 = RGeo::CoordSys::CS::AxisInfo.create("Lat", RGeo::CoordSys::CS::AO_NORTH) obj7 = RGeo::CoordSys::CS::AxisInfo.create("Long", RGeo::CoordSys::CS::AO_EAST) - obj8 = RGeo::CoordSys::CS::GeographicCoordinateSystem.create("OSGB 1936", obj3, obj4, obj5, obj6, obj7, "EPSG", 4277) + obj8 = RGeo::CoordSys::CS::GeographicCoordinateSystem.create( + "OSGB 1936", + obj3, + obj4, + obj5, + obj6, + obj7, + "EPSG", + 4277 + ) obj9 = RGeo::CoordSys::CS::ProjectionParameter.create("latitude_of_origin", 49) obj10 = RGeo::CoordSys::CS::ProjectionParameter.create("central_meridian", -2) obj11 = RGeo::CoordSys::CS::ProjectionParameter.create("scale_factor", 0.999601272) obj12 = RGeo::CoordSys::CS::ProjectionParameter.create("false_easting", 400_000) obj13 = RGeo::CoordSys::CS::ProjectionParameter.create("false_northing", -100_000) - obj14 = RGeo::CoordSys::CS::Projection.create("Transverse_Mercator", "Transverse_Mercator", [obj9, obj10, obj11, obj12, obj13]) + obj14 = RGeo::CoordSys::CS::Projection.create( + "Transverse_Mercator", + "Transverse_Mercator", + [obj9, obj10, obj11, obj12, obj13] + ) obj15 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1, "EPSG", 9001) obj16 = RGeo::CoordSys::CS::AxisInfo.create("E", RGeo::CoordSys::CS::AO_EAST) obj17 = RGeo::CoordSys::CS::AxisInfo.create("N", RGeo::CoordSys::CS::AO_NORTH) - obj = RGeo::CoordSys::CS::ProjectedCoordinateSystem.create("OSGB 1936 / British National Grid", obj8, obj14, obj15, obj16, obj17, "EPSG", 27_700) + obj = RGeo::CoordSys::CS::ProjectedCoordinateSystem.create( + "OSGB 1936 / British National Grid", + obj8, + obj14, + obj15, + obj16, + obj17, + "EPSG", + 27_700 + ) assert_equal("OSGB 1936 / British National Grid", obj.name) assert_equal(2, obj.dimension) assert_equal("OSGB_1936", obj.horizontal_datum.name) @@ -275,28 +421,72 @@ def test_projected_coordinate_system assert_equal("N", obj.get_axis(1).name) assert_equal("metre", obj.get_units(0).name) assert_equal("metre", obj.get_units(1).name) - assert_equal('PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[375.0,-111.0,431.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["DMSH",0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG","4277"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49.0],PARAMETER["central_meridian",-2.0],PARAMETER["scale_factor",0.999601272],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["E",EAST],AXIS["N",NORTH],AUTHORITY["EPSG","27700"]]', obj.to_wkt) + projcs = 'PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",' \ + '6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[375.0,-111.0,431.0,0.0,0.0,0.0,0.0],' \ + 'AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["DMSH",' \ + '0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG",' \ + '"4277"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49.0],PARAMETER[' \ + '"central_meridian",-2.0],PARAMETER["scale_factor",0.999601272],PARAMETER["false_easting",400000.0],' \ + 'PARAMETER["false_northing",-100000.0],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["E",EAST],' \ + 'AXIS["N",NORTH],AUTHORITY["EPSG","27700"]]' + assert_equal(projcs, obj.to_wkt) end def test_coordinate_transform - obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere("Airy 1830", 6_377_563.396, 299.3249646, nil, "EPSG", "7001") + obj1 = RGeo::CoordSys::CS::Ellipsoid.create_flattened_sphere( + "Airy 1830", + 6_377_563.396, + 299.3249646, + nil, + "EPSG", + "7001" + ) obj2 = RGeo::CoordSys::CS::WGS84ConversionInfo.create(375, -111, 431, 0, 0, 0, 0) obj3 = RGeo::CoordSys::CS::AngularUnit.create("DMSH", 0.0174532925199433, "EPSG", 9108) - obj4 = RGeo::CoordSys::CS::HorizontalDatum.create("OSGB_1936", RGeo::CoordSys::CS::HD_CLASSIC, obj1, obj2, "EPSG", "6277") + obj4 = RGeo::CoordSys::CS::HorizontalDatum.create( + "OSGB_1936", + RGeo::CoordSys::CS::HD_CLASSIC, + obj1, + obj2, + "EPSG", + "6277" + ) obj5 = RGeo::CoordSys::CS::PrimeMeridian.create("Greenwich", nil, 0, "EPSG", "8901") obj6 = RGeo::CoordSys::CS::AxisInfo.create("Lat", RGeo::CoordSys::CS::AO_NORTH) obj7 = RGeo::CoordSys::CS::AxisInfo.create("Long", RGeo::CoordSys::CS::AO_EAST) - obj8 = RGeo::CoordSys::CS::GeographicCoordinateSystem.create("OSGB 1936", obj3, obj4, obj5, obj6, obj7, "EPSG", 4277) + obj8 = RGeo::CoordSys::CS::GeographicCoordinateSystem.create( + "OSGB 1936", + obj3, + obj4, + obj5, + obj6, + obj7, + "EPSG", + 4277 + ) obj9 = RGeo::CoordSys::CS::ProjectionParameter.create("latitude_of_origin", 49) obj10 = RGeo::CoordSys::CS::ProjectionParameter.create("central_meridian", -2) obj11 = RGeo::CoordSys::CS::ProjectionParameter.create("scale_factor", 0.999601272) obj12 = RGeo::CoordSys::CS::ProjectionParameter.create("false_easting", 400_000) obj13 = RGeo::CoordSys::CS::ProjectionParameter.create("false_northing", -100_000) - obj14 = RGeo::CoordSys::CS::Projection.create("Transverse_Mercator", "Transverse_Mercator", [obj9, obj10, obj11, obj12, obj13]) + obj14 = RGeo::CoordSys::CS::Projection.create( + "Transverse_Mercator", + "Transverse_Mercator", + [obj9, obj10, obj11, obj12, obj13] + ) obj15 = RGeo::CoordSys::CS::LinearUnit.create("metre", 1, "EPSG", 9001) obj16 = RGeo::CoordSys::CS::AxisInfo.create("E", RGeo::CoordSys::CS::AO_EAST) obj17 = RGeo::CoordSys::CS::AxisInfo.create("N", RGeo::CoordSys::CS::AO_NORTH) - source_cs = RGeo::CoordSys::CS::ProjectedCoordinateSystem.create("OSGB 1936 / British National Grid", obj8, obj14, obj15, obj16, obj17, "EPSG", 27_700) + source_cs = RGeo::CoordSys::CS::ProjectedCoordinateSystem.create( + "OSGB 1936 / British National Grid", + obj8, + obj14, + obj15, + obj16, + obj17, + "EPSG", + 27_700 + ) target_cs = source_cs.dup ct = RGeo::CoordSys::CS::CoordinateTransform.create(source_cs, target_cs) @@ -317,7 +507,8 @@ def test_coordinate_transform end def test_parse_epsg_6055 - input = 'DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137.0,0.0,AUTHORITY["EPSG","7059"]],TOWGS84[0.0,0.0,0.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6055"]]' + input = 'DATUM["Popular_Visualisation_Datum",SPHEROID["Popular Visualisation Sphere",6378137.0,0.0,' \ + 'AUTHORITY["EPSG","7059"]],TOWGS84[0.0,0.0,0.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6055"]]' obj = RGeo::CoordSys::CS.create_from_wkt(input) assert_kind_of(RGeo::CoordSys::CS::HorizontalDatum, obj) assert_equal("Popular_Visualisation_Datum", obj.name) @@ -335,7 +526,17 @@ def test_parse_epsg_6055 end def test_parse_epsg_7405 - input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AUTHORITY["EPSG","4277"]],PROJECTION["Transverse Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["central_meridian",-2.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["m",1.0],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["m",1.0],AXIS["Gravity-related height",UP],AUTHORITY["EPSG","5701"]],AUTHORITY["EPSG","7405"]]' + input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",GEOGCS[' \ + '"OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],' \ + 'TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],AUTHORITY["EPSG","6277"]],' \ + 'PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS[' \ + '"Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AUTHORITY["EPSG","4277"]],PROJECTION[' \ + '"Transverse Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["central_meridian",-2.0],PARAMETER[' \ + '"latitude_of_origin",49.0],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000.0],' \ + 'PARAMETER["false_northing",-100000.0],UNIT["m",1.0],AXIS["Easting",EAST],AXIS["Northing",NORTH],' \ + 'AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY[' \ + '"EPSG","5101"]],UNIT["m",1.0],AXIS["Gravity-related height",UP],AUTHORITY["EPSG","5701"]],AUTHORITY[' \ + '"EPSG","7405"]]' obj = RGeo::CoordSys::CS.create_from_wkt(input) assert_kind_of(RGeo::CoordSys::CS::CompoundCoordinateSystem, obj) assert_kind_of(RGeo::CoordSys::CS::ProjectedCoordinateSystem, obj.head) @@ -354,15 +555,34 @@ def test_parse_local_datum_with_extension end def test_marshal_roundtrip - input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AUTHORITY["EPSG","4277"]],PROJECTION["Transverse Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["central_meridian",-2.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["m",1.0],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["m",1.0],AXIS["Gravity-related height",UP],AUTHORITY["EPSG","5701"]],AUTHORITY["EPSG","7405"]]' + input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",' \ + 'GEOGCS["OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,' \ + 'AUTHORITY["EPSG","7001"]],TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],' \ + 'AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",' \ + '0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],' \ + 'AUTHORITY["EPSG","4277"]],PROJECTION["Transverse Mercator",AUTHORITY["EPSG","9807"]],' \ + 'PARAMETER["central_meridian",-2.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["scale_factor",' \ + '0.9996012717],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["m",1.0],' \ + 'AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",' \ + 'VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["m",1.0],AXIS[' \ + '"Gravity-related height",UP],AUTHORITY["EPSG","5701"]],AUTHORITY["EPSG","7405"]]' obj1 = RGeo::CoordSys::CS.create_from_wkt(input) - dump = Marshal.dump(obj1) - obj2 = Marshal.load(dump) + obj2 = Marshal.load(Marshal.dump(obj1)) assert_equal(obj1, obj2) end def test_yaml_roundtrip - input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS["Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AUTHORITY["EPSG","4277"]],PROJECTION["Transverse Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["central_meridian",-2.0],PARAMETER["latitude_of_origin",49.0],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["m",1.0],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY["EPSG","5101"]],UNIT["m",1.0],AXIS["Gravity-related height",UP],AUTHORITY["EPSG","5701"]],AUTHORITY["EPSG","7405"]]' + input = 'COMPD_CS["OSGB36 / British National Grid + ODN",PROJCS["OSGB 1936 / British National Grid",GEOGCS[' \ + '"OSGB 1936",DATUM["OSGB 1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],' \ + 'TOWGS84[446.448,-125.157,542.06,0.15,0.247,0.842,-4.2261596151967575],AUTHORITY["EPSG","6277"]],' \ + 'PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943295],AXIS[' \ + '"Geodetic latitude",NORTH],AXIS["Geodetic longitude",EAST],AUTHORITY["EPSG","4277"]],PROJECTION[' \ + '"Transverse Mercator",AUTHORITY["EPSG","9807"]],PARAMETER["central_meridian",-2.0],PARAMETER[' \ + '"latitude_of_origin",49.0],PARAMETER["scale_factor",0.9996012717],PARAMETER["false_easting",400000.0],' \ + 'PARAMETER["false_northing",-100000.0],UNIT["m",1.0],AXIS["Easting",EAST],AXIS["Northing",NORTH],' \ + 'AUTHORITY["EPSG","27700"]],VERT_CS["Newlyn",VERT_DATUM["Ordnance Datum Newlyn",2005,AUTHORITY[' \ + '"EPSG","5101"]],UNIT["m",1.0],AXIS["Gravity-related height",UP],AUTHORITY["EPSG","5701"]],' \ + 'AUTHORITY["EPSG","7405"]]' obj1 = RGeo::CoordSys::CS.create_from_wkt(input) dump = Psych.dump(obj1) obj2 = psych_load(dump) @@ -395,7 +615,14 @@ def test_parse_error_for_geogcs def test_parse_error_for_projcs # Missing NORTH axis - input = 'PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[375.0,-111.0,431.0,0.0,0.0,0.0,0.0],AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["DMSH",0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG","4277"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49.0],PARAMETER["central_meridian",-2.0],PARAMETER["scale_factor",0.999601272],PARAMETER["false_easting",400000.0],PARAMETER["false_northing",-100000.0],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["E",EAST],AUTHORITY["EPSG","27700"]]' + input = 'PROJCS["OSGB 1936 / British National Grid",GEOGCS["OSGB 1936",DATUM["OSGB_1936",SPHEROID["Airy 1830",' \ + '6377563.396,299.3249646,AUTHORITY["EPSG","7001"]],TOWGS84[375.0,-111.0,431.0,0.0,0.0,0.0,0.0],' \ + 'AUTHORITY["EPSG","6277"]],PRIMEM["Greenwich",0.0,AUTHORITY["EPSG","8901"]],UNIT["DMSH",' \ + '0.0174532925199433,AUTHORITY["EPSG","9108"]],AXIS["Lat",NORTH],AXIS["Long",EAST],AUTHORITY["EPSG",' \ + '"4277"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",49.0],PARAMETER[' \ + '"central_meridian",-2.0],PARAMETER["scale_factor",0.999601272],PARAMETER["false_easting",400000.0],' \ + 'PARAMETER["false_northing",-100000.0],UNIT["metre",1.0,AUTHORITY["EPSG","9001"]],AXIS["E",EAST],' \ + 'AUTHORITY["EPSG","27700"]]' error = assert_raises(RGeo::Error::ParseError) do RGeo::CoordSys::CS.create_from_wkt(input) end diff --git a/test/docs/examples_test.rb b/test/docs/examples_test.rb index 02f2dadd..188add0f 100644 --- a/test/docs/examples_test.rb +++ b/test/docs/examples_test.rb @@ -11,6 +11,7 @@ def test_examples unless RGeo::Geos.ffi_supported? && RGeo::Geos.capi_supported? skip "Examples can only be run with FFI and CAPI support" end + read_examples do |example, line_no| _out, err = capture_io do eval example # rubocop:disable Security/Eval diff --git a/test/docs/factory_compatibility_table_test.rb b/test/docs/factory_compatibility_table_test.rb index e90ed793..8a0f864c 100644 --- a/test/docs/factory_compatibility_table_test.rb +++ b/test/docs/factory_compatibility_table_test.rb @@ -50,19 +50,19 @@ def basic_method_handled?(geometry, method_sym, description) end def basic_methods - @basic_methods ||= [ - :factory, - :dimension, - :geometry_type, - :srid, - :envelope, - :as_text, - :as_binary, - :empty?, - :simple?, - :boundary, - :convex_hull, - :buffer + @basic_methods ||= %i[ + factory + dimension + geometry_type + srid + envelope + as_text + as_binary + empty? + simple? + boundary + convex_hull + buffer ].freeze end @@ -87,7 +87,12 @@ def compute_handled_methods_per_factory relational_methods.each do |method_sym| geometries_per_factory(factory).each do |other_geometry_key, other_geometry| description = "#{classify_sym(geometry_key)}##{method_sym}(#{classify_sym(other_geometry_key)})" - results[factory_key][description] = relational_method_handled?(geometry, other_geometry, method_sym, description) + results[factory_key][description] = relational_method_handled?( + geometry, + other_geometry, + method_sym, + description + ) end end end @@ -130,9 +135,10 @@ def generate_markdown(handled_per_factory_per_description) markdown = "" markdown += "| #{titles.zip(sizes).map { |title, size| title.to_s.center(size) } * ' | '} |\n" - markdown += "| #{"#{'-' * (sizes.first - 1)}:"} | #{sizes[1..-1].map { |size| ":#{'-' * (size - 2)}:" } * ' | '} |\n" + markdown += "| #{"#{'-' * (sizes.first - 1)}:"} | #{sizes[1..].map { |size| ":#{'-' * (size - 2)}:" } * ' | '} |\n" rows.each do |row| - markdown += "| #{row.first.rjust(sizes.first)} | #{row[1..-1].zip(sizes[1..-1]).map { |cell, size| cell.center(size) } * ' | '} |\n" + center = row[1..].zip(sizes[1..]).map { |cell, size| cell.center(size) } + markdown += "| #{row.first.rjust(sizes.first)} | #{center * ' | '} |\n" end markdown @@ -216,17 +222,17 @@ def relational_method_handled?(geometry, other_geometry, method_sym, description end def relational_methods - @relational_methods ||= [ - :equals?, - :eql?, - :disjoint?, - :intersects?, - :touches?, - :crosses?, - :within?, - :contains?, - :overlaps?, - :relate? + @relational_methods ||= %i[ + equals? + eql? + disjoint? + intersects? + touches? + crosses? + within? + contains? + overlaps? + relate? ].freeze end diff --git a/test/geos_capi/factory_test.rb b/test/geos_capi/factory_test.rb index 0ef3ab90..4d44d26d 100644 --- a/test/geos_capi/factory_test.rb +++ b/test/geos_capi/factory_test.rb @@ -8,17 +8,19 @@ require "test_helper" -class GeosFactoryTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::FactoryTests +if RGeo::Geos.capi_supported? + class GeosFactoryTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::FactoryTests - def setup - @factory = RGeo::Geos.factory(srid: 1000) - @srid = 1000 - end + def setup + @factory = RGeo::Geos.factory(srid: 1000) + @srid = 1000 + end - def test_is_geos_factory - assert_equal(true, RGeo::Geos.geos?(@factory)) - assert_equal(true, RGeo::Geos.capi_geos?(@factory)) - assert_equal(false, RGeo::Geos.ffi_geos?(@factory)) + def test_is_geos_factory + assert_equal(true, RGeo::Geos.geos?(@factory)) + assert_equal(true, RGeo::Geos.capi_geos?(@factory)) + assert_equal(false, RGeo::Geos.ffi_geos?(@factory)) + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/geometry_collection_test.rb b/test/geos_capi/geometry_collection_test.rb index c928350a..d519ae8a 100644 --- a/test/geos_capi/geometry_collection_test.rb +++ b/test/geos_capi/geometry_collection_test.rb @@ -8,41 +8,43 @@ require_relative "../test_helper" -class GeosGeometryCollectionTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::GeometryCollectionTests +if RGeo::Geos.capi_supported? + class GeosGeometryCollectionTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::GeometryCollectionTests - def create_factory - RGeo::Geos.factory - end + def create_factory + RGeo::Geos.factory + end - def test_collection_node - lines = [[[0, 0], [0, 2]], [[-1, 1], [1, 1]]] - .map { |p1, p2| [@factory.point(*p1), @factory.point(*p2)] } - .map { |p1, p2| @factory.line(p1, p2) } + def test_collection_node + lines = [[[0, 0], [0, 2]], [[-1, 1], [1, 1]]] + .map { |p1, p2| [@factory.point(*p1), @factory.point(*p2)] } + .map { |p1, p2| @factory.line(p1, p2) } - multi = @factory.multi_line_string(lines) + multi = @factory.multi_line_string(lines) - expected_lines = [ + expected_lines = [ [[0, 0], [0, 1]], [[0, 1], [0, 2]], [[-1, 1], [0, 1]], [[0, 1], [1, 1]] ].map { |p1, p2| @factory.line(@factory.point(*p1), @factory.point(*p2)) } - noded = multi.node + noded = multi.node - assert_equal(noded.count, 4) - assert(expected_lines.all? { |line| noded.include? line }) - end + assert_equal(noded.count, 4) + assert(expected_lines.all? { |line| noded.include? line }) + end - def test_polygonize_collection - input = @factory.parse_wkt( - "GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1, 1 0, 0 0), POINT(2 2))" - ) - expected = @factory.parse_wkt( - "GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))" - ) + def test_polygonize_collection + input = @factory.parse_wkt( + "GEOMETRYCOLLECTION(LINESTRING(0 0, 1 1, 1 0, 0 0), POINT(2 2))" + ) + expected = @factory.parse_wkt( + "GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))" + ) - assert_equal expected, input.polygonize + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/line_string_test.rb b/test/geos_capi/line_string_test.rb index 6acb01ab..70327f6d 100644 --- a/test/geos_capi/line_string_test.rb +++ b/test/geos_capi/line_string_test.rb @@ -8,46 +8,48 @@ require_relative "../test_helper" -class GeosLineStringTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::LineStringTests +if RGeo::Geos.capi_supported? + class GeosLineStringTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::LineStringTests - def setup - @factory = RGeo::Geos.factory - end + def setup + @factory = RGeo::Geos.factory + end - def test_project_interpolate_round_trip - point = @factory.point(2, 2) - line_string = @factory.line_string([[0, 0], [5, 5]].map { |x, y| @factory.point(x, y) }) - location = line_string.project_point point - interpolated_point = line_string.interpolate_point location - assert_equal point, interpolated_point - end + def test_project_interpolate_round_trip + point = @factory.point(2, 2) + line_string = @factory.line_string([[0, 0], [5, 5]].map { |x, y| @factory.point(x, y) }) + location = line_string.project_point point + interpolated_point = line_string.interpolate_point location + assert_equal point, interpolated_point + end - def test_polygonize_valid_ring - input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0, 0 0)") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))") + def test_polygonize_valid_ring + input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0, 0 0)") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))") - assert_equal expected, input.polygonize - end + assert_equal expected, input.polygonize + end - def test_polygonize_not_closed_ring - input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0)") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + def test_polygonize_not_closed_ring + input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0)") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - assert_equal expected, input.polygonize - end + assert_equal expected, input.polygonize + end - def test_polygonize_self_intersection - input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0, 0 1, 0 0)") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + def test_polygonize_self_intersection + input = @factory.parse_wkt("LINESTRING(0 0, 1 1, 1 0, 0 1, 0 0)") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - assert_equal expected, input.polygonize - end + assert_equal expected, input.polygonize + end - def test_polygonize_dangle - input = @factory.parse_wkt("LINESTRING(0 0, 2 2, 1 1, 1 0, 0 0)") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + def test_polygonize_dangle + input = @factory.parse_wkt("LINESTRING(0 0, 2 2, 1 1, 1 0, 0 0)") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - assert_equal expected, input.polygonize + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/misc_test.rb b/test/geos_capi/misc_test.rb index 8a230713..d72350d0 100644 --- a/test/geos_capi/misc_test.rb +++ b/test/geos_capi/misc_test.rb @@ -10,139 +10,181 @@ require_relative "../test_helper" require_relative "../common/validity_tests" -class GeosMiscTest < Minitest::Test # :nodoc: - def setup - @factory = RGeo::Geos.factory(srid: 4326) - end - - def test_marshal_dump_with_geos - @factory = RGeo::Geos.factory(srid: 4326) +if RGeo::Geos.capi_supported? + class GeosMiscTest < Minitest::Test # :nodoc: + def setup + @factory = RGeo::Geos.factory(srid: 4326) + end - dump = @factory.marshal_dump - assert_equal({}, dump["wktg"]) - assert_equal({}, dump["wkbg"]) - assert_equal({}, dump["wktp"]) - assert_equal({}, dump["wkbp"]) - end + def test_marshal_dump_with_geos + @factory = RGeo::Geos.factory(srid: 4326) - def test_encode_with_geos - @factory = RGeo::Geos.factory(srid: 4326) - coder = Psych::Coder.new("test") + dump = @factory.marshal_dump + assert_equal({}, dump["wktg"]) + assert_equal({}, dump["wkbg"]) + assert_equal({}, dump["wktp"]) + assert_equal({}, dump["wkbp"]) + end - @factory.encode_with(coder) - assert_equal({}, coder["wkt_generator"]) - assert_equal({}, coder["wkb_generator"]) - assert_equal({}, coder["wkt_parser"]) - assert_equal({}, coder["wkb_parser"]) - end + def test_encode_with_geos + @factory = RGeo::Geos.factory(srid: 4326) + coder = Psych::Coder.new("test") - def test_uninitialized - geom = RGeo::Geos::CAPIGeometryImpl.new - assert_equal(false, geom.initialized?) - assert_nil(geom.geometry_type) - end + @factory.encode_with(coder) + assert_equal({}, coder["wkt_generator"]) + assert_equal({}, coder["wkb_generator"]) + assert_equal({}, coder["wkt_parser"]) + assert_equal({}, coder["wkb_parser"]) + end - def test_empty_geometries_equal - geom1 = @factory.collection([]) - geom2 = @factory.line_string([]) - assert(!geom1.eql?(geom2)) - assert(geom1.equals?(geom2)) - end + def test_uninitialized + geom = RGeo::Geos::CAPIGeometryImpl.new + assert_equal(false, geom.initialized?) + assert_nil(geom.geometry_type) + end - def test_invalid_geometry_equal_itself - geom = @factory.parse_wkt("MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)), ((0 0, 2 2, 2 0, 0 0)))") - assert(geom.eql?(geom)) - assert(geom.equals?(geom)) - end + def test_empty_geometries_equal + geom1 = @factory.collection([]) + geom2 = @factory.line_string([]) + assert(!geom1.eql?(geom2)) + assert(geom1.equals?(geom2)) + end - def test_prepare - p1 = @factory.point(1, 2) - p2 = @factory.point(3, 4) - p3 = @factory.point(5, 2) - polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon.prepared?) - polygon.prepare! - assert_equal(true, polygon.prepared?) - end + def test_invalid_geometry_equal_itself + geom = @factory.parse_wkt("MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)), ((0 0, 2 2, 2 0, 0 0)))") + assert(geom.eql?(geom)) + assert(geom.equals?(geom)) + end - def test_auto_prepare - p1 = @factory.point(1, 2) - p2 = @factory.point(3, 4) - p3 = @factory.point(5, 2) - polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon.prepared?) - polygon.intersects?(p1) - assert_equal(false, polygon.prepared?) - polygon.intersects?(p2) - assert_equal(true, polygon.prepared?) - - factory_no_auto_prepare = RGeo::Geos.factory(srid: 4326, auto_prepare: :disabled) - polygon2 = factory_no_auto_prepare.polygon( - factory_no_auto_prepare.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon2.prepared?) - polygon2.intersects?(p1) - assert_equal(false, polygon2.prepared?) - polygon2.intersects?(p2) - assert_equal(false, polygon2.prepared?) - end + def test_prepare + p1 = @factory.point(1, 2) + p2 = @factory.point(3, 4) + p3 = @factory.point(5, 2) + polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) + assert_equal(false, polygon.prepared?) + polygon.prepare! + assert_equal(true, polygon.prepared?) + end - def test_gh_21 - # Test for GH-21 (seg fault in rgeo_convert_to_geos_geometry) - # This seemed to fail under Ruby 1.8.7 only. - f = RGeo::Geographic.simple_mercator_factory - loc = f.line_string([f.point(-123, 37), f.point(-122, 38)]) - f2 = f.projection_factory - loc2 = f2.line_string([f2.point(-123, 37), f2.point(-122, 38)]) - loc2.intersection(loc) - end + def test_auto_prepare + p1 = @factory.point(1, 2) + p2 = @factory.point(3, 4) + p3 = @factory.point(5, 2) + polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) + assert_equal(false, polygon.prepared?) + polygon.intersects?(p1) + assert_equal(false, polygon.prepared?) + polygon.intersects?(p2) + assert_equal(true, polygon.prepared?) + + factory_no_auto_prepare = RGeo::Geos.factory(srid: 4326, auto_prepare: :disabled) + polygon2 = factory_no_auto_prepare.polygon( + factory_no_auto_prepare.linear_ring([p1, p2, p3, p1]) + ) + assert_equal(false, polygon2.prepared?) + polygon2.intersects?(p1) + assert_equal(false, polygon2.prepared?) + polygon2.intersects?(p2) + assert_equal(false, polygon2.prepared?) + end - def test_geos_version - assert_match(/^\d+\.\d+(\.\d+)?$/, RGeo::Geos.version) - end + def test_gh_21 + # Test for GH-21 (seg fault in rgeo_convert_to_geos_geometry) + # This seemed to fail under Ruby 1.8.7 only. + f = RGeo::Geographic.simple_mercator_factory + loc = f.line_string([f.point(-123, 37), f.point(-122, 38)]) + f2 = f.projection_factory + loc2 = f2.line_string([f2.point(-123, 37), f2.point(-122, 38)]) + loc2.intersection(loc) + end - def test_geos_wkb_parser_inputs - c_factory = RGeo::Geos::CAPIFactory.new - binary_wkb = "\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x05@^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@^\x00\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@j@\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@j@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@^\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02@D\x00\x00\x00\x00\x00\x00@I\x00\x00\x00\x00\x00\x00@D\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02@d\x00\x00\x00\x00\x00\x00@I\x00\x00\x00\x00\x00\x00@d\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01@N\x00\x00\x00\x00\x00\x00@I\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01@N\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01@D\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00" - wkt = @factory.parse_wkb(binary_wkb).as_text - assert_equal(wkt, c_factory.parse_wkb(binary_wkb).as_text) + def test_geos_version + assert_match(/^\d+\.\d+(\.\d+)?$/, RGeo::Geos.version) + end - hexidecimal_wkb = "00000000070000000700000000030000000100000005000000000000000000000000000000000000000000000000405680000000000040568000000000004056800000000000405680000000000000000000000000000000000000000000000000000000000000000000030000000100000005405e0000000000000000000000000000405e0000000000004056800000000000406a4000000000004056800000000000406a4000000000000000000000000000405e0000000000000000000000000000000000000200000002404400000000000040490000000000004044000000000000406180000000000000000000020000000240640000000000004049000000000000406400000000000040618000000000000000000001404e00000000000040490000000000000000000001404e0000000000004061800000000000000000000140440000000000004061800000000000" - assert_equal(wkt, c_factory.parse_wkb(hexidecimal_wkb).as_text) - end + def test_geos_wkb_parser_inputs + c_factory = RGeo::Geos::CAPIFactory.new + binary_wkb = "\x00\x00\x00\x00\a\x00\x00\x00\a\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00" \ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@V\x80" \ + "\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x00\x03\x00\x00\x00\x01\x00\x00\x00\x05@^\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x00@^\x00\x00\x00\x00\x00\x00@V\x80\x00\x00\x00\x00\x00@j@\x00\x00\x00\x00" \ + "\x00@V\x80\x00\x00\x00\x00\x00@j@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@^\x00\x00" \ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02@D\x00\x00" \ + "\x00\x00\x00\x00@I\x00\x00\x00\x00\x00\x00@D\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x02\x00\x00\x00\x02@d\x00\x00\x00\x00\x00\x00@I\x00\x00\x00\x00\x00\x00@d\x00" \ + "\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01@N\x00\x00\x00\x00\x00\x00@I" \ + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01@N\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00" \ + "\x00\x00\x00\x00\x01@D\x00\x00\x00\x00\x00\x00@a\x80\x00\x00\x00\x00\x00" + + wkt = @factory.parse_wkb(binary_wkb).as_text + assert_equal(wkt, c_factory.parse_wkb(binary_wkb).as_text) + + hexidecimal_wkb = "000000000700000007000000000300000001000000050000000000000000000000000000000000000000000000" \ + "004056800000000000405680000000000040568000000000004056800000000000000000000000000000000000" \ + "00000000000000000000000000000000030000000100000005405e0000000000000000000000000000405e0000" \ + "000000004056800000000000406a4000000000004056800000000000406a400000000000000000000000000040" \ + "5e0000000000000000000000000000000000000200000002404400000000000040490000000000004044000000" \ + "000000406180000000000000000000020000000240640000000000004049000000000000406400000000000040" \ + "618000000000000000000001404e00000000000040490000000000000000000001404e00000000000040618000" \ + "00000000000000000140440000000000004061800000000000" + + assert_equal(wkt, c_factory.parse_wkb(hexidecimal_wkb).as_text) + end - def test_unary_union_simple_points - p1 = @factory.point(1, 1) - p2 = @factory.point(2, 2) - mp = @factory.multi_point([p1, p2]) - collection = @factory.collection([p1, p2]) - geom = collection.unary_union - if RGeo::Geos::CAPIFactory._supports_unary_union? - assert(geom.eql?(mp)) - else - assert_equal(nil, geom) + def test_unary_union_simple_points + p1 = @factory.point(1, 1) + p2 = @factory.point(2, 2) + mp = @factory.multi_point([p1, p2]) + collection = @factory.collection([p1, p2]) + geom = collection.unary_union + if RGeo::Geos::CAPIFactory._supports_unary_union? + assert(geom.eql?(mp)) + else + assert_equal(nil, geom) + end end - end - def test_unary_union_mixed_collection - collection = @factory.parse_wkt("GEOMETRYCOLLECTION (POLYGON ((0 0, 0 90, 90 90, 90 0, 0 0)), POLYGON ((120 0, 120 90, 210 90, 210 0, 120 0)), LINESTRING (40 50, 40 140), LINESTRING (160 50, 160 140), POINT (60 50), POINT (60 140), POINT (40 140))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION (POINT (60 140), LINESTRING (40 90, 40 140), LINESTRING (160 90, 160 140), POLYGON ((0 0, 0 90, 40 90, 90 90, 90 0, 0 0)), POLYGON ((120 0, 120 90, 160 90, 210 90, 210 0, 120 0)))") - geom = collection.unary_union - if RGeo::Geos::CAPIFactory._supports_unary_union? - # Note that here `.eql?` is not guaranteed on all GEOS implementation. - assert(geom == expected) - else - assert_equal(nil, geom) + def test_unary_union_mixed_collection + geometrycollection = <<~WKT + GEOMETRYCOLLECTION ( + POLYGON ((0 0, 0 90, 90 90, 90 0, 0 0)), + POLYGON ((120 0, 120 90, 210 90, 210 0, 120 0)), + LINESTRING (40 50, 40 140), + LINESTRING (160 50, 160 140), + POINT (60 50), + POINT (60 140), + POINT (40 140) + ) + WKT + expected_geometrycollection = <<~WKT + GEOMETRYCOLLECTION ( + POINT (60 140), + LINESTRING (40 90, 40 140), + LINESTRING (160 90, 160 140), + POLYGON ((0 0, 0 90, 40 90, 90 90, 90 0, 0 0)), + POLYGON ((120 0, 120 90, 160 90, 210 90, 210 0, 120 0)) + ) + WKT + collection = @factory.parse_wkt(format_wkt(geometrycollection)) + expected = @factory.parse_wkt(format_wkt(expected_geometrycollection)) + geom = collection.unary_union + if RGeo::Geos::CAPIFactory._supports_unary_union? + # Note that here `.eql?` is not guaranteed on all GEOS implementation. + assert(geom == expected) + else + assert_equal(nil, geom) + end end - end - def test_casting_dumb_objects - assert_raises(TypeError) do - # We use an OpenStruct here because we want an object that respond `nil` to unknown methods. - RGeo::Geos.factory.point(1, 1).contains?(OpenStruct.new(factory: RGeo::Geos.factory)) # rubocop:disable Style/OpenStructUse + def test_casting_dumb_objects + assert_raises(TypeError) do + # We use an OpenStruct here because we want an object that respond `nil` to unknown methods. + RGeo::Geos.factory.point(1, 1).contains?(OpenStruct.new(factory: RGeo::Geos.factory)) # rubocop:disable Style/OpenStructUse + end end end -end if RGeo::Geos.capi_supported? - -unless RGeo::Geos.capi_supported? - puts "WARNING: GEOS CAPI support not available. Related tests skipped." end + +puts "WARNING: GEOS CAPI support not available. Related tests skipped." unless RGeo::Geos.capi_supported? diff --git a/test/geos_capi/multi_line_string_test.rb b/test/geos_capi/multi_line_string_test.rb index b390db91..e1830959 100644 --- a/test/geos_capi/multi_line_string_test.rb +++ b/test/geos_capi/multi_line_string_test.rb @@ -8,78 +8,80 @@ require "test_helper" -class GeosMultiLineStringTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiLineStringTests - - def create_factory - RGeo::Geos.factory - end - - def test_polygonize_lines_forming_valid_ring - input = @factory.parse_wkt("MULTILINESTRING((0 0, 1 1), (1 1, 1 0), (1 0, 0 0))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))") - - assert_equal expected, input.polygonize - end - - def test_polygonize_two_valid_rings - input = @factory.parse_wkt("MULTILINESTRING( - (0 0, 1 1, 1 0, 0 0), - (2 2, 3 3, 3 2, 2 2) - )") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION( - POLYGON ((0 0, 1 1, 1 0, 0 0)), - POLYGON ((2 2, 3 3, 3 2, 2 2)) - )") - - assert_equal expected, input.polygonize - end - - def test_polygonize_one_ring_inside_other - input = @factory.parse_wkt("MULTILINESTRING( - (0 0, 0 3, 3 3, 3 0, 0 0), - (1 1, 1 2, 2 2, 2 1, 1 1) - )") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION( - POLYGON ((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), - POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1)) - )") - - assert_equal expected, input.polygonize - end - - def test_polygonize_valid_ring_and_line_over_it - input = @factory.parse_wkt("MULTILINESTRING( - (0 0, 0 2, 2 2, 2 0, 0 0), - (1 0, 1 2) - )") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION( - POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0)) - )") - - assert_equal expected, input.polygonize - end - - def test_polygonize_two_unclosed_rings_closed_with_one_common_line - input = @factory.parse_wkt("MULTILINESTRING( - (1 0, 0 0, 0 1, 1 1), - (1 1, 2 1, 2 0, 1 0), - (1 0, 1 1) - )") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION( - POLYGON ((1 0, 0 0, 0 1, 1 1, 1 0)), - POLYGON ((1 1, 2 1, 2 0, 1 0, 1 1)) - )") - - assert_equal expected, input.polygonize - end - - def test_polygonize_duplicate_edge - input = @factory.parse_wkt("MULTILINESTRING( - (0 0, 1 1), (1 1, 0 1), (0 1, 0 1), (0 0, 1 1) - )") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - - assert_equal expected, input.polygonize +if RGeo::Geos.capi_supported? + class GeosMultiLineStringTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiLineStringTests + + def create_factory + RGeo::Geos.factory + end + + def test_polygonize_lines_forming_valid_ring + input = @factory.parse_wkt("MULTILINESTRING((0 0, 1 1), (1 1, 1 0), (1 0, 0 0))") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION(POLYGON ((0 0, 1 1, 1 0, 0 0)))") + + assert_equal expected, input.polygonize + end + + def test_polygonize_two_valid_rings + input = @factory.parse_wkt("MULTILINESTRING( + (0 0, 1 1, 1 0, 0 0), + (2 2, 3 3, 3 2, 2 2) + )") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION( + POLYGON ((0 0, 1 1, 1 0, 0 0)), + POLYGON ((2 2, 3 3, 3 2, 2 2)) + )") + + assert_equal expected, input.polygonize + end + + def test_polygonize_one_ring_inside_other + input = @factory.parse_wkt("MULTILINESTRING( + (0 0, 0 3, 3 3, 3 0, 0 0), + (1 1, 1 2, 2 2, 2 1, 1 1) + )") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION( + POLYGON ((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 2 1, 2 2, 1 2, 1 1)), + POLYGON ((1 1, 1 2, 2 2, 2 1, 1 1)) + )") + + assert_equal expected, input.polygonize + end + + def test_polygonize_valid_ring_and_line_over_it + input = @factory.parse_wkt("MULTILINESTRING( + (0 0, 0 2, 2 2, 2 0, 0 0), + (1 0, 1 2) + )") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION( + POLYGON ((0 0, 0 2, 2 2, 2 0, 0 0)) + )") + + assert_equal expected, input.polygonize + end + + def test_polygonize_two_unclosed_rings_closed_with_one_common_line + input = @factory.parse_wkt("MULTILINESTRING( + (1 0, 0 0, 0 1, 1 1), + (1 1, 2 1, 2 0, 1 0), + (1 0, 1 1) + )") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION( + POLYGON ((1 0, 0 0, 0 1, 1 1, 1 0)), + POLYGON ((1 1, 2 1, 2 0, 1 0, 1 1)) + )") + + assert_equal expected, input.polygonize + end + + def test_polygonize_duplicate_edge + input = @factory.parse_wkt("MULTILINESTRING( + (0 0, 1 1), (1 1, 0 1), (0 1, 0 1), (0 0, 1 1) + )") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/multi_point_test.rb b/test/geos_capi/multi_point_test.rb index 38051956..094786ac 100644 --- a/test/geos_capi/multi_point_test.rb +++ b/test/geos_capi/multi_point_test.rb @@ -8,17 +8,19 @@ require "test_helper" -class GeosMultiPointTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiPointTests +if RGeo::Geos.capi_supported? + class GeosMultiPointTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiPointTests - def create_factory(opts = {}) - RGeo::Geos.factory(opts) - end + def create_factory(opts = {}) + RGeo::Geos.factory(opts) + end - def test_polygonize - input = @factory.parse_wkt("MULTIPOINT ((1 1))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + def test_polygonize + input = @factory.parse_wkt("MULTIPOINT ((1 1))") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - assert_equal expected, input.polygonize + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/multi_polygon_test.rb b/test/geos_capi/multi_polygon_test.rb index 33c9f43f..50aa2452 100644 --- a/test/geos_capi/multi_polygon_test.rb +++ b/test/geos_capi/multi_polygon_test.rb @@ -8,31 +8,33 @@ require "test_helper" -class GeosMultiPolygonTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiPolygonTests - - def create_factories - @factory = RGeo::Geos.factory - end - - # Centroid of an empty should return an empty collection rather than crash - - def test_empty_centroid - assert_equal(@factory.collection([]), @factory.multi_polygon([]).centroid) - end - - def test_geos_bug_582 - f = RGeo::Geos.factory(buffer_resolution: 2) - p1 = f.polygon(f.linear_ring([])) - p2 = f.polygon(f.linear_ring([f.point(0, 0), f.point(0, 1), f.point(1, 1), f.point(1, 0)])) - mp = f.multi_polygon([p2, p1]) - mp.centroid.as_text - end - - def test_polygonize - input = @factory.parse_wkt("MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION (MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0))))") - - assert_equal expected, input.polygonize +if RGeo::Geos.capi_supported? + class GeosMultiPolygonTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiPolygonTests + + def create_factories + @factory = RGeo::Geos.factory + end + + # Centroid of an empty should return an empty collection rather than crash + + def test_empty_centroid + assert_equal(@factory.collection([]), @factory.multi_polygon([]).centroid) + end + + def test_geos_bug_582 + f = RGeo::Geos.factory(buffer_resolution: 2) + p1 = f.polygon(f.linear_ring([])) + p2 = f.polygon(f.linear_ring([f.point(0, 0), f.point(0, 1), f.point(1, 1), f.point(1, 0)])) + mp = f.multi_polygon([p2, p1]) + mp.centroid.as_text + end + + def test_polygonize + input = @factory.parse_wkt("MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)))") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION (MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0))))") + + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/point_test.rb b/test/geos_capi/point_test.rb index ace452b8..bfe9d310 100644 --- a/test/geos_capi/point_test.rb +++ b/test/geos_capi/point_test.rb @@ -8,61 +8,63 @@ require "test_helper" -class GeosPointTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::PointTests +if RGeo::Geos.capi_supported? + class GeosPointTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::PointTests - def setup - @factory = RGeo::Geos.factory(buffer_resolution: 8) - @zfactory = RGeo::Geos.factory(has_z_coordinate: true) - @mfactory = RGeo::Geos.factory(has_m_coordinate: true) - @zmfactory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true) - end + def setup + @factory = RGeo::Geos.factory(buffer_resolution: 8) + @zfactory = RGeo::Geos.factory(has_z_coordinate: true) + @mfactory = RGeo::Geos.factory(has_m_coordinate: true) + @zmfactory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true) + end - def test_is_geos - point = @factory.point(21, -22) - assert_equal(true, RGeo::Geos.geos?(point)) - assert_equal(true, RGeo::Geos.capi_geos?(point)) - assert_equal(false, RGeo::Geos.ffi_geos?(point)) - point2 = @zmfactory.point(21, -22, 0, 0) - assert_equal(true, RGeo::Geos.geos?(point2)) - assert_equal(true, RGeo::Geos.capi_geos?(point2)) - assert_equal(false, RGeo::Geos.ffi_geos?(point2)) - end + def test_is_geos + point = @factory.point(21, -22) + assert_equal(true, RGeo::Geos.geos?(point)) + assert_equal(true, RGeo::Geos.capi_geos?(point)) + assert_equal(false, RGeo::Geos.ffi_geos?(point)) + point2 = @zmfactory.point(21, -22, 0, 0) + assert_equal(true, RGeo::Geos.geos?(point2)) + assert_equal(true, RGeo::Geos.capi_geos?(point2)) + assert_equal(false, RGeo::Geos.ffi_geos?(point2)) + end - def test_has_no_projection - point = @factory.point(21, -22) - assert(!point.respond_to?(:projection)) - end + def test_has_no_projection + point = @factory.point(21, -22) + assert(!point.respond_to?(:projection)) + end - def test_srid - point = @factory.point(11, 12) - assert_equal(0, point.srid) - end + def test_srid + point = @factory.point(11, 12) + assert_equal(0, point.srid) + end - def test_distance - point1 = @factory.point(11, 12) - point2 = @factory.point(11, 12) - point3 = @factory.point(13, 12) - assert_equal(0, point1.distance(point2)) - assert_equal(2, point1.distance(point3)) - end + def test_distance + point1 = @factory.point(11, 12) + point2 = @factory.point(11, 12) + point3 = @factory.point(13, 12) + assert_equal(0, point1.distance(point2)) + assert_equal(2, point1.distance(point3)) + end - def test_as_text_encoding - factory = RGeo::Geos.factory(wkt_generator: :geos) - point = factory.point(11, 12) - assert_equal(Encoding::US_ASCII, point.as_text.encoding) - end + def test_as_text_encoding + factory = RGeo::Geos.factory(wkt_generator: :geos) + point = factory.point(11, 12) + assert_equal(Encoding::US_ASCII, point.as_text.encoding) + end - def test_as_binary_encoding - factory = RGeo::Geos.factory(wkb_generator: :geos) - point = factory.point(11, 12) - assert_equal(Encoding::ASCII_8BIT, point.as_binary.encoding) - end + def test_as_binary_encoding + factory = RGeo::Geos.factory(wkb_generator: :geos) + point = factory.point(11, 12) + assert_equal(Encoding::ASCII_8BIT, point.as_binary.encoding) + end - def test_polygonize - input = @factory.parse_wkt("POINT (1 1)") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") + def test_polygonize + input = @factory.parse_wkt("POINT (1 1)") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION EMPTY") - assert_equal expected, input.polygonize + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/polygon_test.rb b/test/geos_capi/polygon_test.rb index 76b9471c..7a96b914 100644 --- a/test/geos_capi/polygon_test.rb +++ b/test/geos_capi/polygon_test.rb @@ -8,168 +8,170 @@ require_relative "../test_helper" -class GeosPolygonTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::PolygonTests +if RGeo::Geos.capi_supported? + class GeosPolygonTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::PolygonTests - def assert_close_enough(p1, p2) - assert((p1.x - p2.x).abs < 0.00000001 && (p1.y - p2.y).abs < 0.00000001) - end + def assert_close_enough(pt1, pt2) + assert((pt1.x - pt2.x).abs < 0.00000001 && (pt1.y - pt2.y).abs < 0.00000001) + end - def setup - @factory = RGeo::Geos.factory - end + def setup + @factory = RGeo::Geos.factory + end - def test_intersection - point1 = @factory.point(0, 0) - point2 = @factory.point(0, 2) - point3 = @factory.point(2, 2) - point4 = @factory.point(2, 0) - poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) - poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) - poly3 = poly1.intersection(poly2) - assert_equal(poly2, poly3) - end + def test_intersection + point1 = @factory.point(0, 0) + point2 = @factory.point(0, 2) + point3 = @factory.point(2, 2) + point4 = @factory.point(2, 0) + poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) + poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) + poly3 = poly1.intersection(poly2) + assert_equal(poly2, poly3) + end - def test_union - point1 = @factory.point(0, 0) - point2 = @factory.point(0, 2) - point3 = @factory.point(2, 2) - point4 = @factory.point(2, 0) - poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) - poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) - poly3 = poly1.union(poly2) - assert_equal(poly1, poly3) - end + def test_union + point1 = @factory.point(0, 0) + point2 = @factory.point(0, 2) + point3 = @factory.point(2, 2) + point4 = @factory.point(2, 0) + poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) + poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) + poly3 = poly1.union(poly2) + assert_equal(poly1, poly3) + end - def test_simplify - xys = [[0, 0], [5, 0], [10, 0], [10, 10], [5, 10.2], [0, 10], [0, 0]] - points = xys.collect { |x, y| @factory.point(x, y) } - poly = @factory.polygon(@factory.linear_ring(points)) - simplified = poly.simplify(0.3) - new_points = simplified.exterior_ring.points - extra = new_points.reject { |p| [0, 10].include?(p.x) && [0, 10].include?(p.y) } - assert_equal 5, new_points.length, "Closed ring of the square should have 5 points" - assert_equal 0, extra.length, "Should only have x/y's on 0 and 10" - end + def test_simplify + xys = [[0, 0], [5, 0], [10, 0], [10, 10], [5, 10.2], [0, 10], [0, 0]] + points = xys.collect { |x, y| @factory.point(x, y) } + poly = @factory.polygon(@factory.linear_ring(points)) + simplified = poly.simplify(0.3) + new_points = simplified.exterior_ring.points + extra = new_points.reject { |p| [0, 10].include?(p.x) && [0, 10].include?(p.y) } + assert_equal 5, new_points.length, "Closed ring of the square should have 5 points" + assert_equal 0, extra.length, "Should only have x/y's on 0 and 10" + end - def test_buffer - polygon_coordinates = [[0.5527864045000421, 3.776393202250021], - [0.7763932022500211, 4.447213595499958], - [1.4472135954999579, 4.223606797749979], - [2.447213595499958, 2.223606797749979], - [2.223606797749979, 1.5527864045000421], - [1.5527864045000421, 1.776393202250021], - [0.5527864045000421, 3.776393202250021]] - - points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) - - point1 = @factory.point(2, 2) - point2 = @factory.point(1, 4) - line_string = @factory.line_string([point1, point2]) - polygon2 = line_string.buffer(0.5) - - assert_equal polygon, polygon2 - end + def test_buffer + polygon_coordinates = [[0.5527864045000421, 3.776393202250021], + [0.7763932022500211, 4.447213595499958], + [1.4472135954999579, 4.223606797749979], + [2.447213595499958, 2.223606797749979], + [2.223606797749979, 1.5527864045000421], + [1.5527864045000421, 1.776393202250021], + [0.5527864045000421, 3.776393202250021]] + + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) + + point1 = @factory.point(2, 2) + point2 = @factory.point(1, 4) + line_string = @factory.line_string([point1, point2]) + polygon2 = line_string.buffer(0.5) + + assert_equal polygon, polygon2 + end - def test_simplify_preserve_topology - xys1 = [[0.0, 0.0], [5.0, 0.0], [10.0, 0.0], [10.0, 10.0], [5.0, 12.0], [0.0, 10.0], [0.0, 0.0]] - xys2 = [[0.1, 0.1], [0.1, 0.6], [0.3, 0.8], [0.5, 0.5], [0.7, 0.3], [0.3, 0.1], [0.1, 0.1]] + def test_simplify_preserve_topology + xys1 = [[0.0, 0.0], [5.0, 0.0], [10.0, 0.0], [10.0, 10.0], [5.0, 12.0], [0.0, 10.0], [0.0, 0.0]] + xys2 = [[0.1, 0.1], [0.1, 0.6], [0.3, 0.8], [0.5, 0.5], [0.7, 0.3], [0.3, 0.1], [0.1, 0.1]] - points1 = xys1.collect { |x, y| @factory.point(x, y) } - points2 = xys2.collect { |x, y| @factory.point(x, y) } + points1 = xys1.collect { |x, y| @factory.point(x, y) } + points2 = xys2.collect { |x, y| @factory.point(x, y) } - ln1 = @factory.line_string(points1) - ln2 = @factory.line_string(points2) + ln1 = @factory.line_string(points1) + ln2 = @factory.line_string(points2) - poly = @factory.polygon(ln1, [ln2]) + poly = @factory.polygon(ln1, [ln2]) - simplified = poly.simplify_preserve_topology(1) - interior_points = simplified.interior_rings[0].points + simplified = poly.simplify_preserve_topology(1) + interior_points = simplified.interior_rings[0].points - assert_equal 5, interior_points.length - end + assert_equal 5, interior_points.length + end - def test_buffer_with_style - polygon_coordinates = [[0.514589803375032, 4.299999999999999], - [6.0, 4.3], - [6.3, 4.3], - [6.3, 3.7], - [1.4854101966249682, 3.7], - [2.2683281572999747, 2.134164078649987], - [2.4024922359499623, 1.8658359213500124], - [1.8658359213500126, 1.597507764050038], - [0.514589803375032, 4.299999999999999]] - - points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) - - point1 = @factory.point(2, 2) - point2 = @factory.point(1, 4) - point3 = @factory.point(6, 4) - line_string = @factory.line_string([point1, point2, point3]) - buffered_line_string = - line_string.buffer_with_style(0.3, RGeo::Geos::CAP_SQUARE, RGeo::Geos::JOIN_MITRE, 5) - - # having issues with floating point errors on some systems - # 4.3 -> 4.29999999999999, for example, and throws an error - # iterating through points and using assert_in_delta instead - # of assert_equal - buffered_points = buffered_line_string.exterior_ring.points - polygon.exterior_ring.points.each_with_index do |pt, idx| - assert_close_enough(pt, buffered_points[idx]) + def test_buffer_with_style + polygon_coordinates = [[0.514589803375032, 4.299999999999999], + [6.0, 4.3], + [6.3, 4.3], + [6.3, 3.7], + [1.4854101966249682, 3.7], + [2.2683281572999747, 2.134164078649987], + [2.4024922359499623, 1.8658359213500124], + [1.8658359213500126, 1.597507764050038], + [0.514589803375032, 4.299999999999999]] + + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) + + point1 = @factory.point(2, 2) + point2 = @factory.point(1, 4) + point3 = @factory.point(6, 4) + line_string = @factory.line_string([point1, point2, point3]) + buffered_line_string = + line_string.buffer_with_style(0.3, RGeo::Geos::CAP_SQUARE, RGeo::Geos::JOIN_MITRE, 5) + + # having issues with floating point errors on some systems + # 4.3 -> 4.29999999999999, for example, and throws an error + # iterating through points and using assert_in_delta instead + # of assert_equal + buffered_points = buffered_line_string.exterior_ring.points + polygon.exterior_ring.points.each_with_index do |pt, idx| + assert_close_enough(pt, buffered_points[idx]) + end end - end - def test_is_valid_polygon - polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] - points_arr = polygon_coordinates.map{ |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) + def test_is_valid_polygon + polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) - assert_equal(polygon.valid?, true) + assert_equal(polygon.valid?, true) - polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] - points_arr = polygon_coordinates.map{ |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) + polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) - assert_equal(polygon.valid?, false) - end + assert_equal(polygon.valid?, false) + end - def test_invalid_reason - polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] - points_arr = polygon_coordinates.map{ |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) + def test_invalid_reason + polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) - assert_equal("Self-intersection", polygon.invalid_reason) - end + assert_equal("Self-intersection", polygon.invalid_reason) + end - def test_invalid_reason_with_valid_polygon - polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] - points_arr = polygon_coordinates.map{ |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) - assert_nil(polygon.invalid_reason) - end + def test_invalid_reason_with_valid_polygon + polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) + assert_nil(polygon.invalid_reason) + end - def test_self_intersecting_polygon - # issue 218 - polygon_coordinates = [[0, 0], [1, 1], [0, 1], [1, 0], [0, 0]] - points_arr = polygon_coordinates.map{ |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) + def test_self_intersecting_polygon + # issue 218 + polygon_coordinates = [[0, 0], [1, 1], [0, 1], [1, 0], [0, 0]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) - refute(polygon.simple?) - end + refute(polygon.simple?) + end - def test_polygonize - input = @factory.parse_wkt("POLYGON ((0 0, 1 1, 1 0, 0 0))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION (POLYGON ((0 0, 1 1, 1 0, 0 0)))") + def test_polygonize + input = @factory.parse_wkt("POLYGON ((0 0, 1 1, 1 0, 0 0))") + expected = @factory.parse_wkt("GEOMETRYCOLLECTION (POLYGON ((0 0, 1 1, 1 0, 0 0)))") - assert_equal expected, input.polygonize + assert_equal expected, input.polygonize + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/validity_test.rb b/test/geos_capi/validity_test.rb index ff587900..61a9e879 100644 --- a/test/geos_capi/validity_test.rb +++ b/test/geos_capi/validity_test.rb @@ -8,25 +8,27 @@ require_relative "../test_helper" -class GeosValidityTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::ValidityTests +if RGeo::Geos.capi_supported? + class GeosValidityTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::ValidityTests - def setup - @factory = RGeo::Geos.factory - end + def setup + @factory = RGeo::Geos.factory + end - def test_valid_linear_ring_invalid_reason_location - lr = @factory.linear_ring([point1, point3, point2, point4, point1]) - assert_nil(lr.invalid_reason_location) - assert_nil(lr.invalid_reason) - assert(lr.valid?) - end + def test_valid_linear_ring_invalid_reason_location + lr = @factory.linear_ring([point1, point3, point2, point4, point1]) + assert_nil(lr.invalid_reason_location) + assert_nil(lr.invalid_reason) + assert(lr.valid?) + end - def test_invalid_polygon_self_intersecting_ring_invalid_reason_location - hourglass = @factory.linear_ring([point1, point2, point3, point4, point1]) - poly = @factory.polygon(hourglass) - assert_equal(@factory.point(0.5, 0.5), poly.invalid_reason_location) - assert_equal(RGeo::Error::SELF_INTERSECTION, poly.invalid_reason) - assert_equal(false, poly.valid?) + def test_invalid_polygon_self_intersecting_ring_invalid_reason_location + hourglass = @factory.linear_ring([point1, point2, point3, point4, point1]) + poly = @factory.polygon(hourglass) + assert_equal(@factory.point(0.5, 0.5), poly.invalid_reason_location) + assert_equal(RGeo::Error::SELF_INTERSECTION, poly.invalid_reason) + assert_equal(false, poly.valid?) + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_capi/zmfactory_test.rb b/test/geos_capi/zmfactory_test.rb index a4a9ad55..63f82410 100644 --- a/test/geos_capi/zmfactory_test.rb +++ b/test/geos_capi/zmfactory_test.rb @@ -8,43 +8,45 @@ require "test_helper" -class GeosZMFactoryTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::FactoryTests +if RGeo::Geos.capi_supported? + class GeosZMFactoryTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::FactoryTests - def setup - @factory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, srid: 1000, buffer_resolution: 2) - @srid = 1000 - end + def setup + @factory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, srid: 1000, buffer_resolution: 2) + @srid = 1000 + end - def test_is_geos_factory - assert_equal(true, RGeo::Geos.geos?(@factory)) - assert_equal(true, RGeo::Geos.capi_geos?(@factory)) - assert_equal(false, RGeo::Geos.ffi_geos?(@factory)) - end + def test_is_geos_factory + assert_equal(true, RGeo::Geos.geos?(@factory)) + assert_equal(true, RGeo::Geos.capi_geos?(@factory)) + assert_equal(false, RGeo::Geos.ffi_geos?(@factory)) + end - def test_factory_parts - assert_equal(1000, @factory.srid) - assert_equal(1000, @factory.z_factory.srid) - assert_equal(1000, @factory.m_factory.srid) - assert_equal(2, @factory.buffer_resolution) - assert_equal(2, @factory.z_factory.buffer_resolution) - assert_equal(2, @factory.m_factory.buffer_resolution) - assert(@factory.property(:has_z_coordinate)) - assert(@factory.property(:has_m_coordinate)) - assert(@factory.z_factory.property(:has_z_coordinate)) - assert(!@factory.z_factory.property(:has_m_coordinate)) - assert(!@factory.m_factory.property(:has_z_coordinate)) - assert(@factory.m_factory.property(:has_m_coordinate)) - end + def test_factory_parts + assert_equal(1000, @factory.srid) + assert_equal(1000, @factory.z_factory.srid) + assert_equal(1000, @factory.m_factory.srid) + assert_equal(2, @factory.buffer_resolution) + assert_equal(2, @factory.z_factory.buffer_resolution) + assert_equal(2, @factory.m_factory.buffer_resolution) + assert(@factory.property(:has_z_coordinate)) + assert(@factory.property(:has_m_coordinate)) + assert(@factory.z_factory.property(:has_z_coordinate)) + assert(!@factory.z_factory.property(:has_m_coordinate)) + assert(!@factory.m_factory.property(:has_z_coordinate)) + assert(@factory.m_factory.property(:has_m_coordinate)) + end - def test_4d_point - point = @factory.point(1, 2, 3, 4) - assert_equal(RGeo::Feature::Point, point.geometry_type) - assert_equal(3, point.z) - assert_equal(4, point.m) - assert_equal(3, point.z_geometry.z) - assert_nil(point.z_geometry.m) - assert_nil(point.m_geometry.z) - assert_equal(4, point.m_geometry.m) + def test_4d_point + point = @factory.point(1, 2, 3, 4) + assert_equal(RGeo::Feature::Point, point.geometry_type) + assert_equal(3, point.z) + assert_equal(4, point.m) + assert_equal(3, point.z_geometry.z) + assert_nil(point.z_geometry.m) + assert_nil(point.m_geometry.z) + assert_equal(4, point.m_geometry.m) + end end -end if RGeo::Geos.capi_supported? +end diff --git a/test/geos_ffi/factory_test.rb b/test/geos_ffi/factory_test.rb index ae6f9596..7f7b390c 100644 --- a/test/geos_ffi/factory_test.rb +++ b/test/geos_ffi/factory_test.rb @@ -8,17 +8,19 @@ require_relative "../test_helper" -class GeosFFIFactoryTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::FactoryTests +if RGeo::Geos.ffi_supported? + class GeosFFIFactoryTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::FactoryTests - def setup - @factory = RGeo::Geos.factory(srid: 1000, native_interface: :ffi) - @srid = 1000 - end + def setup + @factory = RGeo::Geos.factory(srid: 1000, native_interface: :ffi) + @srid = 1000 + end - def test_is_geos_factory - assert_equal(true, RGeo::Geos.geos?(@factory)) - assert_equal(false, RGeo::Geos.capi_geos?(@factory)) - assert_equal(true, RGeo::Geos.ffi_geos?(@factory)) + def test_is_geos_factory + assert_equal(true, RGeo::Geos.geos?(@factory)) + assert_equal(false, RGeo::Geos.capi_geos?(@factory)) + assert_equal(true, RGeo::Geos.ffi_geos?(@factory)) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/geometry_collection_test.rb b/test/geos_ffi/geometry_collection_test.rb index a8b4832f..f0eac95a 100644 --- a/test/geos_ffi/geometry_collection_test.rb +++ b/test/geos_ffi/geometry_collection_test.rb @@ -8,10 +8,12 @@ require "test_helper" -class GeosFFIGeometryCollectionTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::GeometryCollectionTests +if RGeo::Geos.ffi_supported? + class GeosFFIGeometryCollectionTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::GeometryCollectionTests - def create_factory - RGeo::Geos.factory(native_interface: :ffi) + def create_factory + RGeo::Geos.factory(native_interface: :ffi) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/line_string_test.rb b/test/geos_ffi/line_string_test.rb index a9f7f3f9..4e64a2d3 100644 --- a/test/geos_ffi/line_string_test.rb +++ b/test/geos_ffi/line_string_test.rb @@ -8,10 +8,12 @@ require "test_helper" -class GeosFFILineStringTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::LineStringTests +if RGeo::Geos.ffi_supported? + class GeosFFILineStringTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::LineStringTests - def setup - @factory = RGeo::Geos.factory(native_interface: :ffi) + def setup + @factory = RGeo::Geos.factory(native_interface: :ffi) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/misc_test.rb b/test/geos_ffi/misc_test.rb index 361c2caa..24a0c5a2 100644 --- a/test/geos_ffi/misc_test.rb +++ b/test/geos_ffi/misc_test.rb @@ -9,76 +9,97 @@ require_relative "../test_helper" require_relative "../common/validity_tests" -class GeosFFIMiscTest < Minitest::Test # :nodoc: - def setup - @factory = RGeo::Geos.factory(srid: 4326, native_interface: :ffi) - end +if RGeo::Geos.ffi_supported? + class GeosFFIMiscTest < Minitest::Test # :nodoc: + def setup + @factory = RGeo::Geos.factory(srid: 4326, native_interface: :ffi) + end - def test_empty_geometries_equal - geom1 = @factory.collection([]) - geom2 = @factory.line_string([]) - assert(!geom1.eql?(geom2)) - assert(geom1.equals?(geom2)) - end + def test_empty_geometries_equal + geom1 = @factory.collection([]) + geom2 = @factory.line_string([]) + assert(!geom1.eql?(geom2)) + assert(geom1.equals?(geom2)) + end - def test_prepare - p1 = @factory.point(1, 2) - p2 = @factory.point(3, 4) - p3 = @factory.point(5, 2) - polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon.prepared?) - polygon.prepare! - assert_equal(true, polygon.prepared?) - end + def test_prepare + p1 = @factory.point(1, 2) + p2 = @factory.point(3, 4) + p3 = @factory.point(5, 2) + polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) + assert_equal(false, polygon.prepared?) + polygon.prepare! + assert_equal(true, polygon.prepared?) + end - def test_auto_prepare - p1 = @factory.point(1, 2) - p2 = @factory.point(3, 4) - p3 = @factory.point(5, 2) - polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon.prepared?) - polygon.intersects?(p1) - assert_equal(false, polygon.prepared?) - polygon.intersects?(p2) - assert_equal(true, polygon.prepared?) + def test_auto_prepare + p1 = @factory.point(1, 2) + p2 = @factory.point(3, 4) + p3 = @factory.point(5, 2) + polygon = @factory.polygon(@factory.linear_ring([p1, p2, p3, p1])) + assert_equal(false, polygon.prepared?) + polygon.intersects?(p1) + assert_equal(false, polygon.prepared?) + polygon.intersects?(p2) + assert_equal(true, polygon.prepared?) - factory_no_auto_prepare = - RGeo::Geos.factory(srid: 4326, native_interface: :ffi, auto_prepare: :disabled) - polygon2 = factory_no_auto_prepare.polygon( - factory_no_auto_prepare.linear_ring([p1, p2, p3, p1])) - assert_equal(false, polygon2.prepared?) - polygon2.intersects?(p1) - assert_equal(false, polygon2.prepared?) - polygon2.intersects?(p2) - assert_equal(false, polygon2.prepared?) - end + factory_no_auto_prepare = + RGeo::Geos.factory(srid: 4326, native_interface: :ffi, auto_prepare: :disabled) + polygon2 = factory_no_auto_prepare.polygon( + factory_no_auto_prepare.linear_ring([p1, p2, p3, p1]) + ) + assert_equal(false, polygon2.prepared?) + polygon2.intersects?(p1) + assert_equal(false, polygon2.prepared?) + polygon2.intersects?(p2) + assert_equal(false, polygon2.prepared?) + end - def test_unary_union_simple_points - p1 = @factory.point(1, 1) - p2 = @factory.point(2, 2) - mp = @factory.multi_point([p1, p2]) - collection = @factory.collection([p1, p2]) - geom = collection.unary_union - if RGeo::Geos::Utils.ffi_supports_unary_union - assert(geom.eql?(mp)) - else - assert_equal(nil, geom) + def test_unary_union_simple_points + p1 = @factory.point(1, 1) + p2 = @factory.point(2, 2) + mp = @factory.multi_point([p1, p2]) + collection = @factory.collection([p1, p2]) + geom = collection.unary_union + if RGeo::Geos::Utils.ffi_supports_unary_union + assert(geom.eql?(mp)) + else + assert_equal(nil, geom) + end end - end - def test_unary_union_mixed_collection - collection = @factory.parse_wkt("GEOMETRYCOLLECTION (POLYGON ((0 0, 0 90, 90 90, 90 0, 0 0)), POLYGON ((120 0, 120 90, 210 90, 210 0, 120 0)), LINESTRING (40 50, 40 140), LINESTRING (160 50, 160 140), POINT (60 50), POINT (60 140), POINT (40 140))") - expected = @factory.parse_wkt("GEOMETRYCOLLECTION (POINT (60 140), LINESTRING (40 90, 40 140), LINESTRING (160 90, 160 140), POLYGON ((0 0, 0 90, 40 90, 90 90, 90 0, 0 0)), POLYGON ((120 0, 120 90, 160 90, 210 90, 210 0, 120 0)))") - geom = collection.unary_union - if RGeo::Geos::Utils.ffi_supports_unary_union - # Representation may differ, hence the test with `==` rather than `eql?` - assert(geom == expected) - else - assert_equal(nil, geom) + def test_unary_union_mixed_collection + geometrycollection = <<~WKT + GEOMETRYCOLLECTION ( + POLYGON ((0 0, 0 90, 90 90, 90 0, 0 0)), + POLYGON ((120 0, 120 90, 210 90, 210 0, 120 0)), + LINESTRING (40 50, 40 140), + LINESTRING (160 50, 160 140), + POINT (60 50), + POINT (60 140), + POINT (40 140) + ) + WKT + expected_geometrycollection = <<~WKT + GEOMETRYCOLLECTION ( + POINT (60 140), + LINESTRING (40 90, 40 140), + LINESTRING (160 90, 160 140), + POLYGON ((0 0, 0 90, 40 90, 90 90, 90 0, 0 0)), + POLYGON ((120 0, 120 90, 160 90, 210 90, 210 0, 120 0)) + ) + WKT + collection = @factory.parse_wkt(format_wkt(geometrycollection)) + expected = @factory.parse_wkt(format_wkt(expected_geometrycollection)) + geom = collection.unary_union + if RGeo::Geos::Utils.ffi_supports_unary_union + # Representation may differ, hence the test with `==` rather than `eql?` + assert(geom == expected) + else + assert_equal(nil, geom) + end end end -end if RGeo::Geos.ffi_supported? - -unless RGeo::Geos.ffi_supported? - puts "WARNING: FFI-GEOS support not available. Related tests skipped." end + +puts "WARNING: FFI-GEOS support not available. Related tests skipped." unless RGeo::Geos.ffi_supported? diff --git a/test/geos_ffi/multi_line_string_test.rb b/test/geos_ffi/multi_line_string_test.rb index bda6aee3..125a9cde 100644 --- a/test/geos_ffi/multi_line_string_test.rb +++ b/test/geos_ffi/multi_line_string_test.rb @@ -8,10 +8,12 @@ require "test_helper" -class GeosFFIMultiLineStringTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiLineStringTests +if RGeo::Geos.ffi_supported? + class GeosFFIMultiLineStringTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiLineStringTests - def create_factory - RGeo::Geos.factory(native_interface: :ffi) + def create_factory + RGeo::Geos.factory(native_interface: :ffi) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/multi_point_test.rb b/test/geos_ffi/multi_point_test.rb index 95ef252d..1d42aa93 100644 --- a/test/geos_ffi/multi_point_test.rb +++ b/test/geos_ffi/multi_point_test.rb @@ -8,10 +8,12 @@ require "test_helper" -class GeosFFIMultiPointTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiPointTests +if RGeo::Geos.ffi_supported? + class GeosFFIMultiPointTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiPointTests - def create_factory(opts = {}) - RGeo::Geos.factory(opts.merge(native_interface: :ffi)) + def create_factory(opts = {}) + RGeo::Geos.factory(opts.merge(native_interface: :ffi)) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/multi_polygon_test.rb b/test/geos_ffi/multi_polygon_test.rb index 87b0f591..4adb3a57 100644 --- a/test/geos_ffi/multi_polygon_test.rb +++ b/test/geos_ffi/multi_polygon_test.rb @@ -8,16 +8,18 @@ require "test_helper" -class GeosFFIMultiPolygonTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::MultiPolygonTests +if RGeo::Geos.ffi_supported? + class GeosFFIMultiPolygonTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::MultiPolygonTests - def create_factories - @factory = RGeo::Geos.factory(native_interface: :ffi) - end + def create_factories + @factory = RGeo::Geos.factory(native_interface: :ffi) + end - # Centroid of an empty should return an empty collection - # rather than throw a weird exception out of ffi-geos - def test_empty_centroid - assert_equal(@factory.collection([]), @factory.multi_polygon([]).centroid) + # Centroid of an empty should return an empty collection + # rather than throw a weird exception out of ffi-geos + def test_empty_centroid + assert_equal(@factory.collection([]), @factory.multi_polygon([]).centroid) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/point_test.rb b/test/geos_ffi/point_test.rb index 640149b2..3661ccf0 100644 --- a/test/geos_ffi/point_test.rb +++ b/test/geos_ffi/point_test.rb @@ -8,55 +8,57 @@ require "test_helper" -class GeosFFIPointTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::PointTests - - def setup - @factory = RGeo::Geos.factory(native_interface: :ffi, buffer_resolution: 8) - @zfactory = RGeo::Geos.factory(has_z_coordinate: true, native_interface: :ffi) - @mfactory = RGeo::Geos.factory(has_m_coordinate: true, native_interface: :ffi) - @zmfactory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, - native_interface: :ffi) - end +if RGeo::Geos.ffi_supported? + class GeosFFIPointTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::PointTests - def test_is_geos - point = @factory.point(21, -22) - assert_equal(true, RGeo::Geos.geos?(point)) - assert_equal(false, RGeo::Geos.capi_geos?(point)) - assert_equal(true, RGeo::Geos.ffi_geos?(point)) - point2 = @zmfactory.point(21, -22, 0, 0) - assert_equal(true, RGeo::Geos.geos?(point2)) - assert_equal(false, RGeo::Geos.capi_geos?(point2)) - assert_equal(true, RGeo::Geos.ffi_geos?(point2)) - end + def setup + @factory = RGeo::Geos.factory(native_interface: :ffi, buffer_resolution: 8) + @zfactory = RGeo::Geos.factory(has_z_coordinate: true, native_interface: :ffi) + @mfactory = RGeo::Geos.factory(has_m_coordinate: true, native_interface: :ffi) + @zmfactory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, + native_interface: :ffi) + end - def test_has_no_projection - point = @factory.point(21, -22) - assert(!point.respond_to?(:projection)) - end + def test_is_geos + point = @factory.point(21, -22) + assert_equal(true, RGeo::Geos.geos?(point)) + assert_equal(false, RGeo::Geos.capi_geos?(point)) + assert_equal(true, RGeo::Geos.ffi_geos?(point)) + point2 = @zmfactory.point(21, -22, 0, 0) + assert_equal(true, RGeo::Geos.geos?(point2)) + assert_equal(false, RGeo::Geos.capi_geos?(point2)) + assert_equal(true, RGeo::Geos.ffi_geos?(point2)) + end - def test_srid - point = @factory.point(11, 12) - assert_equal(0, point.srid) - end + def test_has_no_projection + point = @factory.point(21, -22) + assert(!point.respond_to?(:projection)) + end - def test_distance - point1 = @factory.point(11, 12) - point2 = @factory.point(11, 12) - point3 = @factory.point(13, 12) - assert_equal(0, point1.distance(point2)) - assert_equal(2, point1.distance(point3)) - end + def test_srid + point = @factory.point(11, 12) + assert_equal(0, point.srid) + end - def test_as_text_encoding - factory = RGeo::Geos.factory(native_interface: :ffi, wkt_generator: :geos) - point = factory.point(11, 12) - assert_equal(Encoding::US_ASCII, point.as_text.encoding) - end + def test_distance + point1 = @factory.point(11, 12) + point2 = @factory.point(11, 12) + point3 = @factory.point(13, 12) + assert_equal(0, point1.distance(point2)) + assert_equal(2, point1.distance(point3)) + end + + def test_as_text_encoding + factory = RGeo::Geos.factory(native_interface: :ffi, wkt_generator: :geos) + point = factory.point(11, 12) + assert_equal(Encoding::US_ASCII, point.as_text.encoding) + end - def test_as_binary_encoding - factory = RGeo::Geos.factory(native_interface: :ffi, wkb_generator: :geos) - point = factory.point(11, 12) - assert_equal(Encoding::ASCII_8BIT, point.as_binary.encoding) + def test_as_binary_encoding + factory = RGeo::Geos.factory(native_interface: :ffi, wkb_generator: :geos) + point = factory.point(11, 12) + assert_equal(Encoding::ASCII_8BIT, point.as_binary.encoding) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/polygon_test.rb b/test/geos_ffi/polygon_test.rb index 3440c19c..a5a04459 100644 --- a/test/geos_ffi/polygon_test.rb +++ b/test/geos_ffi/polygon_test.rb @@ -8,48 +8,50 @@ require "test_helper" -class GeosFFIPolygonTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::PolygonTests - - def setup - @factory = RGeo::Geos.factory(native_interface: :ffi) - end - - def test_intersection - point1 = @factory.point(0, 0) - point2 = @factory.point(0, 2) - point3 = @factory.point(2, 2) - point4 = @factory.point(2, 0) - poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) - poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) - poly3 = poly1.intersection(poly2) - assert_equal(poly2, poly3) - end - - def test_union - point1 = @factory.point(0, 0) - point2 = @factory.point(0, 2) - point3 = @factory.point(2, 2) - point4 = @factory.point(2, 0) - poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) - poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) - poly3 = poly1.union(poly2) - assert_equal(poly1, poly3) - end - - def test_is_valid_polygon - polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] - points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) - - assert_equal(polygon.valid?, true) - - polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] - points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } - outer_ring = @factory.linear_ring(points_arr) - polygon = @factory.polygon(outer_ring) - - assert_equal(polygon.valid?, false) +if RGeo::Geos.ffi_supported? + class GeosFFIPolygonTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::PolygonTests + + def setup + @factory = RGeo::Geos.factory(native_interface: :ffi) + end + + def test_intersection + point1 = @factory.point(0, 0) + point2 = @factory.point(0, 2) + point3 = @factory.point(2, 2) + point4 = @factory.point(2, 0) + poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) + poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) + poly3 = poly1.intersection(poly2) + assert_equal(poly2, poly3) + end + + def test_union + point1 = @factory.point(0, 0) + point2 = @factory.point(0, 2) + point3 = @factory.point(2, 2) + point4 = @factory.point(2, 0) + poly1 = @factory.polygon(@factory.linear_ring([point1, point2, point3, point4])) + poly2 = @factory.polygon(@factory.linear_ring([point1, point2, point4])) + poly3 = poly1.union(poly2) + assert_equal(poly1, poly3) + end + + def test_is_valid_polygon + polygon_coordinates = [[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) + + assert_equal(polygon.valid?, true) + + polygon_coordinates = [[-1, -1], [-1, 0], [1, 0], [1, 1], [0, 1], [0, -1], [-1, -1]] + points_arr = polygon_coordinates.map { |v| @factory.point(v[0], v[1]) } + outer_ring = @factory.linear_ring(points_arr) + polygon = @factory.polygon(outer_ring) + + assert_equal(polygon.valid?, false) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/validity_test.rb b/test/geos_ffi/validity_test.rb index df03aba4..1ad92cb4 100644 --- a/test/geos_ffi/validity_test.rb +++ b/test/geos_ffi/validity_test.rb @@ -8,10 +8,12 @@ require_relative "../test_helper" -class GeosFFIValidityTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::ValidityTests +if RGeo::Geos.ffi_supported? + class GeosFFIValidityTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::ValidityTests - def setup - @factory = RGeo::Geos.factory(native_interface: :ffi) + def setup + @factory = RGeo::Geos.factory(native_interface: :ffi) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/geos_ffi/zmfactory_test.rb b/test/geos_ffi/zmfactory_test.rb index 6fb2c576..a2ebe699 100644 --- a/test/geos_ffi/zmfactory_test.rb +++ b/test/geos_ffi/zmfactory_test.rb @@ -8,44 +8,46 @@ require "test_helper" -class GeosFFIZMFactoryTest < Minitest::Test # :nodoc: - include RGeo::Tests::Common::FactoryTests +if RGeo::Geos.ffi_supported? + class GeosFFIZMFactoryTest < Minitest::Test # :nodoc: + include RGeo::Tests::Common::FactoryTests - def setup - @factory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, - srid: 1000, buffer_resolution: 2, native_interface: :ffi) - @srid = 1000 - end + def setup + @factory = RGeo::Geos.factory(has_z_coordinate: true, has_m_coordinate: true, + srid: 1000, buffer_resolution: 2, native_interface: :ffi) + @srid = 1000 + end - def test_is_geos_factory - assert_equal(true, RGeo::Geos.geos?(@factory)) - assert_equal(false, RGeo::Geos.capi_geos?(@factory)) - assert_equal(true, RGeo::Geos.ffi_geos?(@factory)) - end + def test_is_geos_factory + assert_equal(true, RGeo::Geos.geos?(@factory)) + assert_equal(false, RGeo::Geos.capi_geos?(@factory)) + assert_equal(true, RGeo::Geos.ffi_geos?(@factory)) + end - def test_factory_parts - assert_equal(1000, @factory.srid) - assert_equal(1000, @factory.z_factory.srid) - assert_equal(1000, @factory.m_factory.srid) - assert_equal(2, @factory.buffer_resolution) - assert_equal(2, @factory.z_factory.buffer_resolution) - assert_equal(2, @factory.m_factory.buffer_resolution) - assert(@factory.property(:has_z_coordinate)) - assert(@factory.property(:has_m_coordinate)) - assert(@factory.z_factory.property(:has_z_coordinate)) - assert(!@factory.z_factory.property(:has_m_coordinate)) - assert(!@factory.m_factory.property(:has_z_coordinate)) - assert(@factory.m_factory.property(:has_m_coordinate)) - end + def test_factory_parts + assert_equal(1000, @factory.srid) + assert_equal(1000, @factory.z_factory.srid) + assert_equal(1000, @factory.m_factory.srid) + assert_equal(2, @factory.buffer_resolution) + assert_equal(2, @factory.z_factory.buffer_resolution) + assert_equal(2, @factory.m_factory.buffer_resolution) + assert(@factory.property(:has_z_coordinate)) + assert(@factory.property(:has_m_coordinate)) + assert(@factory.z_factory.property(:has_z_coordinate)) + assert(!@factory.z_factory.property(:has_m_coordinate)) + assert(!@factory.m_factory.property(:has_z_coordinate)) + assert(@factory.m_factory.property(:has_m_coordinate)) + end - def test_4d_point - point = @factory.point(1, 2, 3, 4) - assert_equal(RGeo::Feature::Point, point.geometry_type) - assert_equal(3, point.z) - assert_equal(4, point.m) - assert_equal(3, point.z_geometry.z) - assert_nil(point.z_geometry.m) - assert_nil(point.m_geometry.z) - assert_equal(4, point.m_geometry.m) + def test_4d_point + point = @factory.point(1, 2, 3, 4) + assert_equal(RGeo::Feature::Point, point.geometry_type) + assert_equal(3, point.z) + assert_equal(4, point.m) + assert_equal(3, point.z_geometry.z) + assert_nil(point.z_geometry.m) + assert_nil(point.m_geometry.z) + assert_equal(4, point.m_geometry.m) + end end -end if RGeo::Geos.ffi_supported? +end diff --git a/test/simple_cartesian/calculations_test.rb b/test/simple_cartesian/calculations_test.rb index 2a3d929f..8a775b38 100644 --- a/test/simple_cartesian/calculations_test.rb +++ b/test/simple_cartesian/calculations_test.rb @@ -45,11 +45,11 @@ def setup @li_seg5 = RGeo::Cartesian::Segment.new(@point14, @point15) end - def assert_close_enough(v1, v2) - diff = (v1 - v2).abs + def assert_close_enough(val1, val2) + diff = (val1 - val2).abs # denom = (v1 + v2).abs # diff /= denom if denom > 0.01 - assert(diff < 0.00000001, "#{v1} is not close to #{v2}") + assert(diff < 0.00000001, "#{val1} is not close to #{val2}") end def test_segment_degenerate diff --git a/test/simple_cartesian/point_test.rb b/test/simple_cartesian/point_test.rb index 78fdbca7..ae2ad560 100644 --- a/test/simple_cartesian/point_test.rb +++ b/test/simple_cartesian/point_test.rb @@ -37,8 +37,10 @@ def test_lon_180 [48.00000, 180.0] ].map { |coord| factory.point(coord[1], coord[0]) } - assert_equal "LINESTRING (-179.47466 48.02006, -179.7496 48.00986, 180.0 48.0)", + assert_equal( + "LINESTRING (-179.47466 48.02006, -179.7496 48.00986, 180.0 48.0)", factory.line_string(points).to_s + ) end undef_method :test_disjoint diff --git a/test/simple_cartesian/sweepline_intersector_test.rb b/test/simple_cartesian/sweepline_intersector_test.rb index 80dcc523..f201cb77 100644 --- a/test/simple_cartesian/sweepline_intersector_test.rb +++ b/test/simple_cartesian/sweepline_intersector_test.rb @@ -84,10 +84,22 @@ def test_sweepline_intersections_crossing_lines_and_touching_line end def test_sweepline_proper_intersections - square_pts = [@factory.point(0, 0), @factory.point(0, 1), @factory.point(1, 1), @factory.point(1, 0), @factory.point(0, 0)] + square_pts = [ + @factory.point(0, 0), + @factory.point(0, 1), + @factory.point(1, 1), + @factory.point(1, 0), + @factory.point(0, 0) + ] square = @factory.line_string(square_pts) - hourglass_pts = [@factory.point(0, 0), @factory.point(0, 1), @factory.point(1, 0), @factory.point(1, 1), @factory.point(0, 0)] + hourglass_pts = [ + @factory.point(0, 0), + @factory.point(0, 1), + @factory.point(1, 0), + @factory.point(1, 1), + @factory.point(0, 0) + ] hourglass = @factory.line_string(hourglass_pts) square_li = RGeo::Cartesian::SweeplineIntersector.new(square.segments) diff --git a/test/simple_mercator/window_test.rb b/test/simple_mercator/window_test.rb index 0a432049..c194aaef 100644 --- a/test/simple_mercator/window_test.rb +++ b/test/simple_mercator/window_test.rb @@ -17,8 +17,8 @@ def assert_close_enough(p1_, p2_) assert((p1_.x - p2_.x).abs < 0.00001 && (p1_.y - p2_.y).abs < 0.00001) end - def assert_contains_approx(p_, mp_) - assert(mp_.any? { |q_| (p_.x - q_.x).abs < 0.00001 && (p_.y - q_.y).abs < 0.00001 }) + def assert_contains_approx(point, mp_) + assert(mp_.any? { |q_| (point.x - q_.x).abs < 0.00001 && (point.y - q_.y).abs < 0.00001 }) end def test_limits @@ -87,36 +87,122 @@ def test_contains_point def test_noseam_contains_window window1_ = RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(10, 10), @factory.point(30, 30)) - assert(window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(25, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(5, 15), @factory.point(25, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(35, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(0, 15), @factory.point(5, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(35, 15), @factory.point(40, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(5, 15), @factory.point(35, 25)))) + assert( + window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(25, 25)) + ) + ) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 5), @factory.point(25, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(25, 35)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 0), @factory.point(25, 5)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 35), @factory.point(25, 40)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 5), @factory.point(25, 35)))) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(5, 15), @factory.point(25, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(35, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(0, 15), @factory.point(5, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(35, 15), @factory.point(40, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(5, 15), @factory.point(35, 25)) + ) + ) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 35), @factory.point(-170, 40)))) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 5), @factory.point(25, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 15), @factory.point(25, 35)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 0), @factory.point(25, 5)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 35), @factory.point(25, 40)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(15, 5), @factory.point(25, 35)) + ) + ) + + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 35), @factory.point(-170, 40)) + ) + ) end def test_seam_contains_window window1_ = RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(160, 10), @factory.point(-160, 30)) - assert(window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(175, 15), @factory.point(-175, 25)))) - assert(window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 15), @factory.point(175, 25)))) - assert(window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-175, 15), @factory.point(-170, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(170, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(-170, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-170, 15), @factory.point(-150, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 15), @factory.point(-150, 25)))) + assert( + window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(175, 15), @factory.point(-175, 25)) + ) + ) + assert( + window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 15), @factory.point(175, 25)) + ) + ) + assert( + window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-175, 15), @factory.point(-170, 25)) + ) + ) + + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(170, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(-170, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-170, 15), @factory.point(-150, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(170, 15), @factory.point(-150, 25)) + ) + ) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-150, 15), @factory.point(150, 25)))) - assert(!window1_.contains_window?(RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(-150, 25)))) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(-150, 15), @factory.point(150, 25)) + ) + ) + assert( + !window1_.contains_window?( + RGeo::Geographic::ProjectedWindow.for_corners(@factory.point(150, 15), @factory.point(-150, 25)) + ) + ) end def test_scaled_by @@ -171,9 +257,9 @@ def test_random_point_not_crossing_seam max_distance_mercator_ = 1000 max_distance_hypotenuse_ = Math.sqrt(max_distance_mercator_**2 * 2) window1_ = RGeo::Geographic::ProjectedWindow.surrounding_point(point_, max_distance_mercator_) - 10.times { + 10.times do actual_distance_ = window1_.random_point.distance(point_) assert_in_delta(0, actual_distance_, max_distance_hypotenuse_) - } + end end end diff --git a/test/spherical_geographic/calculations_test.rb b/test/spherical_geographic/calculations_test.rb index 9dc8b76c..be0d8562 100644 --- a/test/spherical_geographic/calculations_test.rb +++ b/test/spherical_geographic/calculations_test.rb @@ -9,11 +9,11 @@ require "test_helper" class SphericalCalculationsTest < Minitest::Test # :nodoc: - def assert_close_enough(v1, v2) - diff = (v1 - v2).abs + def assert_close_enough(val1, val2) + diff = (val1 - val2).abs # denom = (v1 + v2).abs # diff /= denom if denom > 0.01 - assert(diff < 0.00000001, "#{v1} is not close to #{v2}") + assert(diff < 0.00000001, "#{val1} is not close to #{val2}") end def test_point_eql diff --git a/test/spherical_geographic/polygon_test.rb b/test/spherical_geographic/polygon_test.rb index 007d7516..9fce7d8c 100644 --- a/test/spherical_geographic/polygon_test.rb +++ b/test/spherical_geographic/polygon_test.rb @@ -26,7 +26,7 @@ def test_centroid point3 = @factory.point(1, 0) exterior = @factory.linear_ring([point1, point2, point3, point1]) polygon = @factory.polygon(exterior) - assert_equal @factory.point(1.0/3.0, 1.0/3.0), polygon.centroid + assert_equal @factory.point(1.0 / 3.0, 1.0 / 3.0), polygon.centroid end def test_centroid_srid diff --git a/test/support/minitest/assert_wkt_similar.rb b/test/support/minitest/assert_wkt_similar.rb index 4ba93b63..983d220b 100644 --- a/test/support/minitest/assert_wkt_similar.rb +++ b/test/support/minitest/assert_wkt_similar.rb @@ -3,8 +3,8 @@ module Support module Minitest module AssertWktSimilar - def assert_wkt_similar(a, b) - assert_equal(Inner.normalize(a), Inner.normalize(b), "Normalized WKT differs") + def assert_wkt_similar(wkt1, wkt2) + assert_equal(Inner.normalize(wkt1), Inner.normalize(wkt2), "Normalized WKT differs") end module Inner diff --git a/test/test_helper.rb b/test/test_helper.rb index f02120e4..b0db2963 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -39,6 +39,15 @@ def psych_load(*args) # Live test for our implementation of Ruby's compaction methods (rb_gc_mark_movable # and rb_gc_location), enabling compaction for every major collection. -if defined?(GC.auto_compact) == "method" - GC.auto_compact = true +GC.auto_compact = true if defined?(GC.auto_compact) == "method" + +# Formats the WKT heredoc string into something that will match the +# {RGeo::WKRep::WKTGenerator#generate} method. +# +# @param wkt [String] +# +# @return [string] +# +def format_wkt(wkt) + wkt.gsub(/[[:space:]]+/, " ").gsub(/\(\s/, "(").gsub(/\)\s/, ")").gsub(/\s\)/, ")").strip end diff --git a/test/types_test.rb b/test/types_test.rb index eefc05e8..8fe871db 100644 --- a/test/types_test.rb +++ b/test/types_test.rb @@ -107,9 +107,9 @@ def initialize(value, dimension, *optional) end attr_accessor :value - def transform_coords(target_cs, x, y, z = nil) + def transform_coords(target_cs, x_coord, y_coord, z_coord = nil) ct = TestAffineCoordinateTransform.create(self, target_cs) - ct.transform_coords(x, y, z) + ct.transform_coords(x_coord, y_coord, z_coord) end class << self @@ -120,10 +120,10 @@ def create(value, dimension = 2) end class TestAffineCoordinateTransform < RGeo::CoordSys::CS::CoordinateTransform - def transform_coords(x, y, z = nil) + def transform_coords(x_coord, y_coord, z_coord = nil) diff = target_cs.value - source_cs.value - coords = [x + diff, y + diff] - coords << (z + diff) if z + coords = [x_coord + diff, y_coord + diff] + coords << (z_coord + diff) if z_coord coords end end diff --git a/test/wkrep/wkb_generator_test.rb b/test/wkrep/wkb_generator_test.rb index 35186d2c..da76c289 100644 --- a/test/wkrep/wkb_generator_test.rb +++ b/test/wkrep/wkb_generator_test.rb @@ -85,25 +85,33 @@ def test_point_with_wkb12_zm def test_linestring_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) obj = @factory.line_string([@factory.point(1, 2), @factory.point(3, 4), @factory.point(5, 6)]) - assert_equal("0000000002000000033ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000", generator.generate(obj)) + test_str = "0000000002000000033ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_linestring_with_ewkb_z generator = RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb) obj = @factoryz.line_string([@factoryz.point(1, 2, 3), @factoryz.point(4, 5, 6)]) - assert_equal("0080000002000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000", generator.generate(obj)) + test_str = "0080000002000000023ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_linestring_with_ewkb_z_and_srid generator = RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb, emit_ewkb_srid: true) obj = @factoryz.line_string([@factoryz.point(1, 2, 3), @factoryz.point(4, 5, 6)]) - assert_equal("00a0000002000003e8000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000", generator.generate(obj)) + test_str = "00a0000002000003e8000000023ff0000000000000400000000000000040080000000000004010000000000000401400000" \ + "00000004018000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_linestring_with_wkb12_m generator = RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :wkb12) obj = @factorym.line_string([@factorym.point(1, 2, 3), @factorym.point(4, 5, 6)]) - assert_equal("00000007d2000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000", generator.generate(obj)) + test_str = "00000007d2000000023ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_linestring_empty @@ -114,8 +122,12 @@ def test_linestring_empty def test_polygon_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) - obj = @factory.polygon(@factory.linear_ring([@factory.point(1, 2), @factory.point(3, 4), @factory.point(6, 5), @factory.point(1, 2)])) - assert_equal("000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401800000000000040140000000000003ff00000000000004000000000000000", generator.generate(obj)) + obj = @factory.polygon( + @factory.linear_ring([@factory.point(1, 2), @factory.point(3, 4), @factory.point(6, 5), @factory.point(1, 2)]) + ) + test_str = "000000000300000001000000043ff00000000000004000000000000000400800000000000040100000000000004018000000" \ + "00000040140000000000003ff00000000000004000000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_polygon_empty @@ -127,13 +139,18 @@ def test_polygon_empty def test_multipoint_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) obj = @factory.multi_point([@factory.point(1, 2), @factory.point(3, 4)]) - assert_equal("00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000", generator.generate(obj)) + assert_equal( + "00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000", + generator.generate(obj) + ) end def test_multipoint_with_ewkb_z generator = RGeo::WKRep::WKBGenerator.new(hex_format: true, type_format: :ewkb) obj = @factoryz.multi_point([@factoryz.point(1, 2, 5), @factoryz.point(3, 4, 6)]) - assert_equal("00800000040000000200800000013ff0000000000000400000000000000040140000000000000080000001400800000000000040100000000000004018000000000000", generator.generate(obj)) + test_str = "00800000040000000200800000013ff00000000000004000000000000000401400000000000000800000014008000000000" \ + "00040100000000000004018000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_multipoint_empty @@ -144,8 +161,16 @@ def test_multipoint_empty def test_multilinestring_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) - obj = @factory.multi_line_string([@factory.line_string([@factory.point(1, 2), @factory.point(3, 4), @factory.point(5, 6)]), @factory.line_string([@factory.point(-1, -2), @factory.point(-3, -4)])]) - assert_equal("0000000005000000020000000002000000033ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000000000000200000002bff0000000000000c000000000000000c008000000000000c010000000000000", generator.generate(obj)) + obj = @factory.multi_line_string( + [ + @factory.line_string([@factory.point(1, 2), @factory.point(3, 4), @factory.point(5, 6)]), + @factory.line_string([@factory.point(-1, -2), @factory.point(-3, -4)]) + ] + ) + test_str = "0000000005000000020000000002000000033ff0000000000000400000000000000040080000000000004010000000000000" \ + "40140000000000004018000000000000000000000200000002bff0000000000000c000000000000000c008000000000000" \ + "c010000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_multilinestring_empty @@ -156,8 +181,19 @@ def test_multilinestring_empty def test_multipolygon_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) - obj = @factory.multi_polygon([@factory.polygon(@factory.linear_ring([@factory.point(1, 2), @factory.point(3, 4), @factory.point(6, 5), @factory.point(1, 2)])), @factory.polygon(@factory.linear_ring([]))]) - assert_equal("000000000600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401800000000000040140000000000003ff00000000000004000000000000000000000000300000000", generator.generate(obj)) + obj = @factory.multi_polygon( + [ + @factory.polygon( + @factory.linear_ring([@factory.point(1, 2), @factory.point(3, 4), @factory.point(6, 5), @factory.point(1, 2)]) + ), + @factory.polygon( + @factory.linear_ring([]) + ) + ] + ) + test_str = "000000000600000002000000000300000001000000043ff000000000000040000000000000004008000000000000401000" \ + "0000000000401800000000000040140000000000003ff00000000000004000000000000000000000000300000000" + assert_equal(test_str, generator.generate(obj)) end def test_multipolygon_empty @@ -168,8 +204,14 @@ def test_multipolygon_empty def test_collection_basic generator = RGeo::WKRep::WKBGenerator.new(hex_format: true) - obj = @factory.collection([@factory.line_string([@factory.point(1, 2), @factory.point(3, 4), @factory.point(5, 6)]), @factory.point(-1, -2)]) - assert_equal("0000000007000000020000000002000000033ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000000000000001bff0000000000000c000000000000000", generator.generate(obj)) + obj = @factory.collection( + [ + @factory.line_string([@factory.point(1, 2), @factory.point(3, 4), @factory.point(5, 6)]), @factory.point(-1, -2) + ] + ) + test_str = "0000000007000000020000000002000000033ff0000000000000400000000000000040080000000000004010000000000000" \ + "401400000000000040180000000000000000000001bff0000000000000c000000000000000" + assert_equal(test_str, generator.generate(obj)) end def test_collection_empty diff --git a/test/wkrep/wkb_parser_test.rb b/test/wkrep/wkb_parser_test.rb index b1aff637..2d5e3320 100644 --- a/test/wkrep/wkb_parser_test.rb +++ b/test/wkrep/wkb_parser_test.rb @@ -117,7 +117,9 @@ def test_point_with_ewkb_z_and_srid def test_linestring_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("0000000002000000033ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000") + input = "0000000002000000033ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::LineString, obj.geometry_type) assert_equal(3, obj.num_points) assert_equal(1, obj.point_n(0).x) @@ -127,7 +129,9 @@ def test_linestring_basic def test_linestring_with_ewkb_z factory_ = RGeo::Cartesian.preferred_factory(has_z_coordinate: true) parser = RGeo::WKRep::WKBParser.new(factory_, support_ewkb: true) - obj = parser.parse("0080000002000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000") + input = "0080000002000000023ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::LineString, obj.geometry_type) assert_equal(2, obj.num_points) assert_equal(1, obj.point_n(0).x) @@ -139,7 +143,9 @@ def test_linestring_with_ewkb_z_and_srid RGeo::Cartesian.preferred_factory(has_z_coordinate: true, srid: config_[:srid]) end parser = RGeo::WKRep::WKBParser.new(factory_generator_, support_ewkb: true) - obj = parser.parse("00a0000002000003e8000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000") + input = "00a0000002000003e8000000023ff0000000000000400000000000000040080000000000004010000000000000401400000000" \ + "00004018000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::LineString, obj.geometry_type) assert_equal(2, obj.num_points) assert_equal(1, obj.point_n(0).x) @@ -150,7 +156,9 @@ def test_linestring_with_ewkb_z_and_srid def test_linestring_with_wkb12_z factory_ = RGeo::Cartesian.preferred_factory(has_z_coordinate: true) parser = RGeo::WKRep::WKBParser.new(factory_, support_wkb12: true) - obj = parser.parse("00000003ea000000023ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000") + input = "00000003ea000000023ff00000000000004000000000000000400800000000000040100000000000004014000000000000" \ + "4018000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::LineString, obj.geometry_type) assert_equal(2, obj.num_points) assert_equal(1, obj.point_n(0).x) @@ -166,7 +174,9 @@ def test_linestring_empty def test_polygon_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401800000000000040140000000000003ff00000000000004000000000000000") + input = "000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401800000000" \ + "000040140000000000003ff00000000000004000000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::Polygon, obj.geometry_type) assert_equal(4, obj.exterior_ring.num_points) assert_equal(1, obj.exterior_ring.point_n(0).x) @@ -182,7 +192,8 @@ def test_polygon_empty def test_multipoint_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000") + input = "00000000040000000200000000013ff00000000000004000000000000000000000000140080000000000004010000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::MultiPoint, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(1, obj[0].x) @@ -191,7 +202,8 @@ def test_multipoint_basic def test_multipoint_mixed_byte_order parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("0000000004000000020101000000000000000000f03f0000000000000040000000000140080000000000004010000000000000") + input = "0000000004000000020101000000000000000000f03f0000000000000040000000000140080000000000004010000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::MultiPoint, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(1, obj[0].x) @@ -201,7 +213,9 @@ def test_multipoint_mixed_byte_order def test_multipoint_with_ewkb_z factory_ = RGeo::Cartesian.preferred_factory(has_z_coordinate: true) parser = RGeo::WKRep::WKBParser.new(factory_, support_ewkb: true) - obj = parser.parse("00800000040000000200800000013ff0000000000000400000000000000040140000000000000080000001400800000000000040100000000000004018000000000000") + input = "00800000040000000200800000013ff00000000000004000000000000000401400000000000000800000014008000000000000" \ + "40100000000000004018000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::MultiPoint, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(1, obj[0].x) @@ -214,8 +228,10 @@ def test_multipoint_with_ewkb_z def test_multipoint_ewkb_with_mixed_z factory_ = RGeo::Cartesian.preferred_factory(has_z_coordinate: true) parser = RGeo::WKRep::WKBParser.new(factory_, support_ewkb: true) + input = "00800000040000000200800000013ff00000000000004000000000000000401400000000000000000000014008000000000000" \ + "4010000000000000" assert_raises(RGeo::Error::ParseError) do - parser.parse("00800000040000000200800000013ff000000000000040000000000000004014000000000000000000000140080000000000004010000000000000") + parser.parse(input) end end @@ -228,7 +244,10 @@ def test_multipoint_empty def test_multilinestring_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("0000000005000000020000000002000000033ff000000000000040000000000000004008000000000000401000000000000040140000000000004018000000000000000000000200000002bff0000000000000c000000000000000c008000000000000c010000000000000") + input = "0000000005000000020000000002000000033ff000000000000040000000000000004008000000000000401000000000000040" \ + "140000000000004018000000000000000000000200000002bff0000000000000c000000000000000c008000000000000c01000" \ + "0000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::MultiLineString, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(1, obj[0].point_n(0).x) @@ -237,8 +256,10 @@ def test_multilinestring_basic def test_multilinestring_wrong_element_type parser = RGeo::WKRep::WKBParser.new + input = "0000000005000000020000000002000000033ff000000000000040000000000000004008000000000000401000000000000040" \ + "14000000000000401800000000000000000000013ff00000000000004000000000000000" assert_raises(RGeo::Error::ParseError) do - parser.parse("0000000005000000020000000002000000033ff00000000000004000000000000000400800000000000040100000000000004014000000000000401800000000000000000000013ff00000000000004000000000000000") + parser.parse(input) end end @@ -251,7 +272,9 @@ def test_multilinestring_empty def test_multipolygon_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("000000000600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000000000401800000000000040140000000000003ff00000000000004000000000000000000000000300000000") + input = "000000000600000002000000000300000001000000043ff0000000000000400000000000000040080000000000004010000000" \ + "000000401800000000000040140000000000003ff00000000000004000000000000000000000000300000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::MultiPolygon, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(4, obj[0].exterior_ring.num_points) @@ -269,7 +292,9 @@ def test_multipolygon_empty def test_collection_basic parser = RGeo::WKRep::WKBParser.new - obj = parser.parse("0000000007000000020000000002000000033ff0000000000000400000000000000040080000000000004010000000000000401400000000000040180000000000000000000001bff0000000000000c000000000000000") + input = "0000000007000000020000000002000000033ff0000000000000400000000000000040080000000000004010000000000000" \ + "401400000000000040180000000000000000000001bff0000000000000c000000000000000" + obj = parser.parse(input) assert_equal(RGeo::Feature::GeometryCollection, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(RGeo::Feature::LineString, obj[0].geometry_type) diff --git a/test/wkrep/wkt_generator_test.rb b/test/wkrep/wkt_generator_test.rb index 359a16d9..6c1afd18 100644 --- a/test/wkrep/wkt_generator_test.rb +++ b/test/wkrep/wkt_generator_test.rb @@ -156,7 +156,14 @@ def test_polygon_with_hole ext = @factory.line_string([p1, p2, p3, p4, p1]) int = @factory.line_string([p5, p6, p7, p5]) obj = @factory.polygon(ext, [int]) - assert_equal("Polygon ((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0))", generator.generate(obj)) + test_polygon = + <<~WKT + Polygon ( + (0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), + (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0) + ) + WKT + assert_equal(format_wkt(test_polygon), generator.generate(obj)) end def test_polygon_empty @@ -193,7 +200,15 @@ def test_multilinestring_basic ls2 = @factory.line_string([p5, p6, p7]) ls3 = @factory.line_string([]) obj = @factory.multi_line_string([ls1, ls2, ls3]) - assert_equal("MultiLineString ((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0), EMPTY)", generator.generate(obj)) + test_multistring = + <<~WKT + MultiLineString ( + (0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), + (1.0 1.0, 2.0 2.0, 3.0 1.0), + EMPTY + ) + WKT + assert_equal(format_wkt(test_multistring), generator.generate(obj)) end def test_multilinestring_empty @@ -222,7 +237,15 @@ def test_multipolygon_basic poly2 = @factory.polygon(@factory.line_string([])) poly3 = @factory.polygon(ext3) obj = @factory.multi_polygon([poly1, poly2, poly3]) - assert_equal("MultiPolygon (((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0)), EMPTY, ((20.0 20.0, 30.0 20.0, 30.0 30.0, 20.0 30.0, 20.0 20.0)))", generator.generate(obj)) + test_multipolygon = + <<~WKT + MultiPolygon ( + ((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0)), + EMPTY, + ((20.0 20.0, 30.0 20.0, 30.0 30.0, 20.0 30.0, 20.0 20.0)) + ) + WKT + assert_equal(format_wkt(test_multipolygon), generator.generate(obj)) end def test_multipolygon_empty @@ -253,7 +276,18 @@ def test_collection_basic obj1 = @factory.multi_polygon([poly1, poly2, poly3]) obj2 = @factory.point(1, 2) obj = @factory.collection([obj1, obj2]) - assert_equal("GeometryCollection (MultiPolygon (((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0)), EMPTY, ((20.0 20.0, 30.0 20.0, 30.0 30.0, 20.0 30.0, 20.0 20.0))), Point (1.0 2.0))", generator.generate(obj)) + test_geo_c = + <<~WKT + GeometryCollection ( + MultiPolygon ( + ((0.0 0.0, 10.0 0.0, 10.0 10.0, 0.0 10.0, 0.0 0.0), (1.0 1.0, 2.0 2.0, 3.0 1.0, 1.0 1.0)), + EMPTY, + ((20.0 20.0, 30.0 20.0, 30.0 30.0, 20.0 30.0, 20.0 20.0)) + ), + Point (1.0 2.0) + ) + WKT + assert_equal(format_wkt(test_geo_c), generator.generate(obj)) end def test_collection_wkt12_z @@ -278,7 +312,21 @@ def test_collection_wkt12_z obj1 = @factoryz.multi_polygon([poly1, poly2, poly3]) obj2 = @factoryz.point(1, 2, 3) obj = @factoryz.collection([obj1, obj2]) - assert_equal("GeometryCollection Z (MultiPolygon Z (((0.0 0.0 0.0, 10.0 0.0 0.0, 10.0 10.0 0.0, 0.0 10.0 0.0, 0.0 0.0 0.0), (1.0 1.0 0.0, 2.0 2.0 0.0, 3.0 1.0 0.0, 1.0 1.0 0.0)), EMPTY, ((20.0 20.0 0.0, 30.0 20.0 0.0, 30.0 30.0 0.0, 20.0 30.0 0.0, 20.0 20.0 0.0))), Point Z (1.0 2.0 3.0))", generator.generate(obj)) + test_geo_c = + <<~WKT + GeometryCollection Z ( + MultiPolygon Z ( + ( + (0.0 0.0 0.0, 10.0 0.0 0.0, 10.0 10.0 0.0, 0.0 10.0 0.0, 0.0 0.0 0.0), + (1.0 1.0 0.0, 2.0 2.0 0.0, 3.0 1.0 0.0, 1.0 1.0 0.0) + ), + EMPTY, + ((20.0 20.0 0.0, 30.0 20.0 0.0, 30.0 30.0 0.0, 20.0 30.0 0.0, 20.0 20.0 0.0)) + ), + Point Z (1.0 2.0 3.0) + ) + WKT + assert_equal(format_wkt(test_geo_c), generator.generate(obj)) end def test_collection_empty diff --git a/test/wkrep/wkt_parser_test.rb b/test/wkrep/wkt_parser_test.rb index 5c3c6580..fdc63b5f 100644 --- a/test/wkrep/wkt_parser_test.rb +++ b/test/wkrep/wkt_parser_test.rb @@ -333,7 +333,13 @@ def test_multilinestring_empty def test_multipolygon_basic factory = RGeo::Cartesian.preferred_factory(has_z_coordinate: true) parser = RGeo::WKRep::WKTParser.new(factory) - obj = parser.parse("MULTIPOLYGON(((-1 -2 0, -3 -4 0, -5 -7 0, -1 -2 0)),((0 0 -1, 10 0 -2, 10 10 -3, 0 10 -4, 0 0 -5),(1 1 -6, 2 3 -7, 3 1 -8, 1 1 -9)))") + multipolygon = <<~WKT + MULTIPOLYGON ( + ((-1 -2 0, -3 -4 0, -5 -7 0, -1 -2 0)), + ((0 0 -1, 10 0 -2, 10 10 -3, 0 10 -4, 0 0 -5), (1 1 -6, 2 3 -7, 3 1 -8, 1 1 -9)) + ) + WKT + obj = parser.parse(format_wkt(multipolygon)) assert_equal(RGeo::Feature::MultiPolygon, obj.geometry_type) assert_equal(2, obj.num_geometries) assert_equal(4, obj[0].exterior_ring.num_points)