charta 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/charta.gemspec +21 -20
- data/lib/charta/bounding_box.rb +5 -1
- data/lib/charta/coordinates.rb +65 -0
- data/lib/charta/ewkt_serializer.rb +101 -0
- data/lib/charta/factory/ewkt_feature_builder.rb +17 -0
- data/lib/charta/factory/feature_factory_base.rb +15 -0
- data/lib/charta/factory/simple_feature_factory.rb +50 -0
- data/lib/charta/factory/simple_geometry_factory.rb +46 -0
- data/lib/charta/factory/srid_provider.rb +36 -0
- data/lib/charta/factory/transformers/ewkt_passthrough.rb +20 -0
- data/lib/charta/factory/transformers/ewkt_transformer.rb +20 -0
- data/lib/charta/factory/transformers/ewkt_transformer_chain.rb +42 -0
- data/lib/charta/factory/transformers/from_geo_json_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_gml_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_kml_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_wkb_transformer.rb +24 -0
- data/lib/charta/factory/transformers/transformation_error.rb +10 -0
- data/lib/charta/geo_json.rb +12 -124
- data/lib/charta/geometry.rb +70 -16
- data/lib/charta/geometry_collection.rb +6 -4
- data/lib/charta/gml.rb +18 -2
- data/lib/charta/gml_import.rb +24 -24
- data/lib/charta/kml.rb +21 -3
- data/lib/charta/multi_polygon.rb +1 -1
- data/lib/charta/point.rb +6 -0
- data/lib/charta/polygon.rb +5 -0
- data/lib/charta/version.rb +1 -1
- data/lib/charta.rb +39 -87
- data/lib/rgeo/svg.rb +44 -44
- metadata +78 -44
- data/.gitignore +0 -11
- data/.gitlab-ci.yml +0 -14
- data/.travis.yml +0 -7
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -21
- data/README.md +0 -44
- data/Rakefile +0 -10
    
        data/lib/charta/geo_json.rb
    CHANGED
    
    | @@ -7,12 +7,14 @@ module Charta | |
| 7 7 |  | 
| 8 8 | 
             
                def initialize(data, srid = :WGS84)
         | 
| 9 9 | 
             
                  srid ||= :WGS84
         | 
| 10 | 
            -
                  @json =  | 
| 10 | 
            +
                  @json = Coordinates.flatten(data.is_a?(Hash) ? data : JSON.parse(data))
         | 
| 11 11 | 
             
                  lsrid = @json['crs']['properties']['name'] if @json.is_a?(Hash) &&
         | 
| 12 12 | 
             
                                                                @json['crs'].is_a?(Hash) &&
         | 
| 13 13 | 
             
                                                                @json['crs']['properties'].is_a?(Hash)
         | 
| 14 14 | 
             
                  lsrid ||= srid
         | 
| 15 15 | 
             
                  @srid = ::Charta.find_srid(lsrid)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  @json = Coordinates.normalize_4326_geometry(@json) if @srid.to_i == 4326
         | 
| 16 18 | 
             
                end
         | 
| 17 19 |  | 
| 18 20 | 
             
                def geom
         | 
| @@ -24,7 +26,7 @@ module Charta | |
| 24 26 | 
             
                end
         | 
| 25 27 |  | 
| 26 28 | 
             
                def to_ewkt
         | 
| 27 | 
            -
                  "SRID=#{ | 
| 29 | 
            +
                  "SRID=#{srid};" + EwktSerializer.object_to_ewkt(@json)
         | 
| 28 30 | 
             
                end
         | 
| 29 31 |  | 
| 30 32 | 
             
                def valid?
         | 
| @@ -42,131 +44,17 @@ module Charta | |
| 42 44 | 
             
                    false
         | 
| 43 45 | 
             
                  end
         | 
| 44 46 |  | 
| 45 | 
            -
                  # Force coordinates to 2D
         | 
| 46 47 | 
             
                  def flatten(hash)
         | 
| 47 | 
            -
                     | 
| 48 | 
            -
                      flatten_feature_collection(hash)
         | 
| 49 | 
            -
                    elsif hash['type'] == 'Feature'
         | 
| 50 | 
            -
                      flatten_feature(hash)
         | 
| 51 | 
            -
                    else
         | 
| 52 | 
            -
                      flatten_geometry(hash)
         | 
| 53 | 
            -
                    end
         | 
| 54 | 
            -
                  end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                  def flatten_feature_collection(hash)
         | 
| 57 | 
            -
                    hash.merge('features' => hash['features'].map { |f| flatten_feature(f) })
         | 
| 58 | 
            -
                  end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                  def flatten_feature(hash)
         | 
| 61 | 
            -
                    hash.merge('geometry' => flatten_geometry(hash['geometry']))
         | 
| 62 | 
            -
                  end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                  def flatten_geometry(hash)
         | 
| 65 | 
            -
                    coordinates = hash['coordinates']
         | 
| 66 | 
            -
                    flattened =
         | 
| 67 | 
            -
                      case hash['type']
         | 
| 68 | 
            -
                      when 'Point' then
         | 
| 69 | 
            -
                        flatten_position(coordinates)
         | 
| 70 | 
            -
                      when 'MultiPoint', 'LineString'
         | 
| 71 | 
            -
                        coordinates.map { |p| flatten_position(p) }
         | 
| 72 | 
            -
                      when 'MultiLineString', 'Polygon'
         | 
| 73 | 
            -
                        coordinates.map { |l| l.map { |p| flatten_position(p) } }
         | 
| 74 | 
            -
                      when 'MultiPolygon'
         | 
| 75 | 
            -
                        coordinates.map { |m| m.map { |l| l.map { |p| flatten_position(p) } } }
         | 
| 76 | 
            -
                      when 'GeometryCollection' then
         | 
| 77 | 
            -
                        return hash.merge('geometries' => hash['geometries'].map { |g| flatten_geometry(g) })
         | 
| 78 | 
            -
                      else
         | 
| 79 | 
            -
                        raise StandardError, "Cannot handle: #{hash['type'].inspect}. In #{hash.inspect}"
         | 
| 80 | 
            -
                      end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                    hash.merge('coordinates' => flattened)
         | 
| 83 | 
            -
                  end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  def flatten_position(position)
         | 
| 86 | 
            -
                    position[0..1]
         | 
| 87 | 
            -
                  end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                  def object_to_ewkt(hash)
         | 
| 90 | 
            -
                    type = hash[:type] || hash['type']
         | 
| 91 | 
            -
                    send("#{type.gsub(/(.)([A-Z])/, '\1_\2').downcase}_to_ewkt", hash)
         | 
| 92 | 
            -
                  end
         | 
| 93 | 
            -
             | 
| 94 | 
            -
                  def feature_collection_to_ewkt(hash)
         | 
| 95 | 
            -
                    return 'GEOMETRYCOLLECTION EMPTY' if hash['features'].nil?
         | 
| 96 | 
            -
                    'GEOMETRYCOLLECTION(' + hash['features'].collect do |feature|
         | 
| 97 | 
            -
                      object_to_ewkt(feature)
         | 
| 98 | 
            -
                    end.join(', ') + ')'
         | 
| 99 | 
            -
                  end
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                  def geometry_collection_to_ewkt(hash)
         | 
| 102 | 
            -
                    return 'GEOMETRYCOLLECTION EMPTY' if hash['geometries'].nil?
         | 
| 103 | 
            -
                    'GEOMETRYCOLLECTION(' + hash['geometries'].collect do |feature|
         | 
| 104 | 
            -
                      object_to_ewkt(feature)
         | 
| 105 | 
            -
                    end.join(', ') + ')'
         | 
| 106 | 
            -
                  end
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                  def feature_to_ewkt(hash)
         | 
| 109 | 
            -
                    object_to_ewkt(hash['geometry'])
         | 
| 110 | 
            -
                  end
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                  def point_to_ewkt(hash)
         | 
| 113 | 
            -
                    return 'POINT EMPTY' if hash['coordinates'].nil?
         | 
| 114 | 
            -
                    'POINT(' + hash['coordinates'].join(' ') + ')'
         | 
| 115 | 
            -
                  end
         | 
| 116 | 
            -
             | 
| 117 | 
            -
                  def line_string_to_ewkt(hash)
         | 
| 118 | 
            -
                    return 'LINESTRING EMPTY' if hash['coordinates'].nil?
         | 
| 119 | 
            -
                    'LINESTRING(' + hash['coordinates'].collect do |point|
         | 
| 120 | 
            -
                      point.join(' ')
         | 
| 121 | 
            -
                    end.join(', ') + ')'
         | 
| 122 | 
            -
                  end
         | 
| 123 | 
            -
             | 
| 124 | 
            -
                  def polygon_to_ewkt(hash)
         | 
| 125 | 
            -
                    return 'POLYGON EMPTY' if hash['coordinates'].nil?
         | 
| 126 | 
            -
                    'POLYGON(' + hash['coordinates'].collect do |hole|
         | 
| 127 | 
            -
                      '(' + hole.collect do |point|
         | 
| 128 | 
            -
                        point.join(' ')
         | 
| 129 | 
            -
                      end.join(', ') + ')'
         | 
| 130 | 
            -
                    end.join(', ') + ')'
         | 
| 131 | 
            -
                  end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                  def multi_point_to_ewkt(hash)
         | 
| 134 | 
            -
                    return 'MULTIPOINT EMPTY' if hash['coordinates'].nil?
         | 
| 135 | 
            -
                    'MULTIPOINT(' + hash['coordinates'].collect do |point|
         | 
| 136 | 
            -
                      '(' + point.join(' ') + ')'
         | 
| 137 | 
            -
                    end.join(', ') + ')'
         | 
| 138 | 
            -
                  end
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                  def multi_line_string_to_ewkt(hash)
         | 
| 141 | 
            -
                    return 'MULTILINESTRING EMPTY' if hash['coordinates'].nil?
         | 
| 142 | 
            -
                    'MULTILINESTRING(' + hash['coordinates'].collect do |line|
         | 
| 143 | 
            -
                      '(' + line.collect do |point|
         | 
| 144 | 
            -
                        point.join(' ')
         | 
| 145 | 
            -
                      end.join(', ') + ')'
         | 
| 146 | 
            -
                    end.join(', ') + ')'
         | 
| 147 | 
            -
                  end
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                  def multipolygon_to_ewkt(hash)
         | 
| 150 | 
            -
                    return 'MULTIPOLYGON EMPTY' if hash['coordinates'].nil?
         | 
| 151 | 
            -
                    'MULTIPOLYGON(' + hash['coordinates'].collect do |polygon|
         | 
| 152 | 
            -
                      '(' + polygon.collect do |hole|
         | 
| 153 | 
            -
                        '(' + hole.collect do |point|
         | 
| 154 | 
            -
                          point.join(' ')
         | 
| 155 | 
            -
                        end.join(', ') + ')'
         | 
| 156 | 
            -
                      end.join(', ') + ')'
         | 
| 157 | 
            -
                    end.join(', ') + ')'
         | 
| 48 | 
            +
                    Coordinates.flatten hash
         | 
| 158 49 | 
             
                  end
         | 
| 159 50 |  | 
| 160 | 
            -
                   | 
| 161 | 
            -
             | 
| 162 | 
            -
                     | 
| 163 | 
            -
             | 
| 164 | 
            -
             | 
| 165 | 
            -
             | 
| 166 | 
            -
             | 
| 167 | 
            -
                        end.join(', ') + ')'
         | 
| 168 | 
            -
                      end.join(', ') + ')'
         | 
| 169 | 
            -
                    end.join(', ') + ')'
         | 
| 51 | 
            +
                  %i[
         | 
| 52 | 
            +
                    object_to_ewkt feature_collection_to_ewkt geometry_collection_to_ewkt feature_to_ewkt point_to_ewkt line_string_to_ewkt
         | 
| 53 | 
            +
                    polygon_to_ewkt multi_point_to_ewkt multi_line_string_to_ewkt multipolygon_to_ewkt multi_polygon_to_ewkt
         | 
| 54 | 
            +
                  ].each do |m|
         | 
| 55 | 
            +
                    define_method m do |*args|
         | 
| 56 | 
            +
                      EwktSerializer.send m, *args
         | 
| 57 | 
            +
                    end
         | 
| 170 58 | 
             
                  end
         | 
| 171 59 | 
             
                end
         | 
| 172 60 | 
             
              end
         | 
    
        data/lib/charta/geometry.rb
    CHANGED
    
    | @@ -2,6 +2,7 @@ require 'json' | |
| 2 2 | 
             
            require 'rgeo/geo_json'
         | 
| 3 3 | 
             
            require 'rgeo/svg' # integrated lib for now
         | 
| 4 4 | 
             
            require 'active_support/core_ext/module/delegation'
         | 
| 5 | 
            +
            require 'victor' # for SVG
         | 
| 5 6 |  | 
| 6 7 | 
             
            module Charta
         | 
| 7 8 | 
             
              # Represents a Geometry with SRID
         | 
| @@ -63,16 +64,36 @@ module Charta | |
| 63 64 |  | 
| 64 65 | 
             
                alias to_ewkb to_binary
         | 
| 65 66 |  | 
| 66 | 
            -
                #  | 
| 67 | 
            +
                # Generate SVG from geometry
         | 
| 68 | 
            +
                # @param [Hash] options , the options for SVG object.
         | 
| 69 | 
            +
                # @option options [Hash] :mode could be :stroke or :fill
         | 
| 70 | 
            +
                # @option options [Hash] :color could be "orange", "red", "blue" or HTML color "#14TF15"
         | 
| 71 | 
            +
                # @option options [Hash] :fill_opacity could be '0' to '100'
         | 
| 72 | 
            +
                # @option options [Hash] :stroke_linecap could be 'round', 'square', 'butt'
         | 
| 73 | 
            +
                # @option options [Hash] :stroke_linejoin default 'round'
         | 
| 74 | 
            +
                # @option options [Hash] :stroke_width default '5%'
         | 
| 75 | 
            +
                # @note more informations on https://developer.mozilla.org/fr/docs/Web/SVG/Tutorial/Fills_and_Strokes
         | 
| 76 | 
            +
                # @return [String] the SVG image
         | 
| 67 77 | 
             
                def to_svg(options = {})
         | 
| 68 | 
            -
                   | 
| 69 | 
            -
                   | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 78 | 
            +
                  # set default options if not present
         | 
| 79 | 
            +
                  options[:mode] ||= :stroke
         | 
| 80 | 
            +
                  options[:color] ||= 'black'
         | 
| 81 | 
            +
                  options[:fill_opacity] ||= '100' # 0 to 100
         | 
| 82 | 
            +
                  options[:stroke_linecap] ||= 'butt' # round, square, butt
         | 
| 83 | 
            +
                  options[:stroke_linejoin] ||= 'round' #
         | 
| 84 | 
            +
                  options[:stroke_width] ||= '5%'
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  svg = Victor::SVG.new template: :html
         | 
| 87 | 
            +
                  svg.setup width: 180, height: 180, viewBox: bounding_box.svg_view_box.join(' ')
         | 
| 88 | 
            +
                  # return a stroke SVG with options
         | 
| 89 | 
            +
                  if options[:mode] == :stroke
         | 
| 90 | 
            +
                    svg.path d: to_svg_path, fill: 'none', stroke: options[:color], stroke_linecap: options[:stroke_linecap],
         | 
| 91 | 
            +
            stroke_linejoin: options[:stroke_linejoin], stroke_width: options[:stroke_width]
         | 
| 92 | 
            +
                  # return a fill SVG with options
         | 
| 93 | 
            +
                  elsif options[:mode] == :fill
         | 
| 94 | 
            +
                    svg.path d: to_svg_path, fill: options[:color], fill_opacity: options[:fill_opacity]
         | 
| 73 95 | 
             
                  end
         | 
| 74 | 
            -
                  svg | 
| 75 | 
            -
                  svg
         | 
| 96 | 
            +
                  svg.render
         | 
| 76 97 | 
             
                end
         | 
| 77 98 |  | 
| 78 99 | 
             
                # Return the geometry as Scalar Vector Graphics (SVG) path data.
         | 
| @@ -97,6 +118,7 @@ module Charta | |
| 97 118 | 
             
                  other_geometry = Charta.new_geometry(other).transform(srid)
         | 
| 98 119 | 
             
                  return true if empty? && other_geometry.empty?
         | 
| 99 120 | 
             
                  return inspect == other_geometry.inspect if collection? && other_geometry.collection?
         | 
| 121 | 
            +
             | 
| 100 122 | 
             
                  feature.equals?(other_geometry.feature)
         | 
| 101 123 | 
             
                end
         | 
| 102 124 |  | 
| @@ -105,17 +127,30 @@ module Charta | |
| 105 127 | 
             
                  other_geometry = Charta.new_geometry(other).transform(srid)
         | 
| 106 128 | 
             
                  return true if empty? && other_geometry.empty?
         | 
| 107 129 | 
             
                  return inspect == other_geometry.inspect if collection? && other_geometry.collection?
         | 
| 130 | 
            +
             | 
| 108 131 | 
             
                  !feature.equals?(other_geometry.feature)
         | 
| 109 132 | 
             
                end
         | 
| 110 133 |  | 
| 111 134 | 
             
                # Returns true if Geometry is a Surface
         | 
| 112 135 | 
             
                def surface?
         | 
| 113 | 
            -
                   | 
| 136 | 
            +
                  if collection?
         | 
| 137 | 
            +
                    feature.any? { |geometry| Charta.new_geometry(geometry).surface? }
         | 
| 138 | 
            +
                  else
         | 
| 139 | 
            +
                    [RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? feature.geometry_type
         | 
| 140 | 
            +
                  end
         | 
| 114 141 | 
             
                end
         | 
| 115 142 |  | 
| 116 143 | 
             
                # Returns area in unit corresponding to the SRS
         | 
| 117 144 | 
             
                def area
         | 
| 118 | 
            -
                  surface? | 
| 145 | 
            +
                  if surface?
         | 
| 146 | 
            +
                    if collection?
         | 
| 147 | 
            +
                      feature.sum { |geometry| Charta.new_geometry(geometry).area }
         | 
| 148 | 
            +
                    else
         | 
| 149 | 
            +
                      feature.area
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
                  else
         | 
| 152 | 
            +
                    0
         | 
| 153 | 
            +
                  end
         | 
| 119 154 | 
             
                end
         | 
| 120 155 |  | 
| 121 156 | 
             
                # Returns true if this Geometry is an empty geometrycollection, polygon,
         | 
| @@ -130,6 +165,7 @@ module Charta | |
| 130 165 | 
             
                # of mass of the geometry as a POINT.
         | 
| 131 166 | 
             
                def centroid
         | 
| 132 167 | 
             
                  return nil unless surface? && !feature.is_empty?
         | 
| 168 | 
            +
             | 
| 133 169 | 
             
                  point = feature.centroid
         | 
| 134 170 | 
             
                  [point.y, point.x]
         | 
| 135 171 | 
             
                end
         | 
| @@ -137,16 +173,23 @@ module Charta | |
| 137 173 | 
             
                # Returns a POINT guaranteed to lie on the surface.
         | 
| 138 174 | 
             
                def point_on_surface
         | 
| 139 175 | 
             
                  return nil unless surface?
         | 
| 176 | 
            +
             | 
| 140 177 | 
             
                  point = feature.point_on_surface
         | 
| 141 178 | 
             
                  [point.y, point.x]
         | 
| 142 179 | 
             
                end
         | 
| 143 180 |  | 
| 144 181 | 
             
                def convert_to(new_type)
         | 
| 145 182 | 
             
                  case new_type
         | 
| 146 | 
            -
                  when type | 
| 147 | 
            -
             | 
| 148 | 
            -
                  when : | 
| 149 | 
            -
             | 
| 183 | 
            +
                  when type
         | 
| 184 | 
            +
                    self
         | 
| 185 | 
            +
                  when :multi_point
         | 
| 186 | 
            +
                    flatten_multi(:point)
         | 
| 187 | 
            +
                  when :multi_line_string
         | 
| 188 | 
            +
                    flatten_multi(:line_string)
         | 
| 189 | 
            +
                  when :multi_polygon
         | 
| 190 | 
            +
                    flatten_multi(:polygon)
         | 
| 191 | 
            +
                  else
         | 
| 192 | 
            +
                    self
         | 
| 150 193 | 
             
                  end
         | 
| 151 194 | 
             
                end
         | 
| 152 195 |  | 
| @@ -174,10 +217,12 @@ module Charta | |
| 174 217 | 
             
                def transform(new_srid)
         | 
| 175 218 | 
             
                  return self if new_srid == srid
         | 
| 176 219 | 
             
                  raise 'Proj is not supported. Cannot tranform' unless RGeo::CoordSys::Proj4.supported?
         | 
| 220 | 
            +
             | 
| 177 221 | 
             
                  new_srid = Charta::SRS[new_srid] || new_srid
         | 
| 178 222 | 
             
                  database = self.class.srs_database
         | 
| 179 223 | 
             
                  new_proj_entry = database.get(new_srid)
         | 
| 180 224 | 
             
                  raise "Cannot find proj for SRID: #{new_srid}" if new_proj_entry.nil?
         | 
| 225 | 
            +
             | 
| 181 226 | 
             
                  new_feature = RGeo::CoordSys::Proj4.transform(
         | 
| 182 227 | 
             
                    database.get(srid).proj4,
         | 
| 183 228 | 
             
                    feature,
         | 
| @@ -205,6 +250,11 @@ module Charta | |
| 205 250 | 
             
                  feature.intersection(other_geometry.feature)
         | 
| 206 251 | 
             
                end
         | 
| 207 252 |  | 
| 253 | 
            +
                def intersects?(other)
         | 
| 254 | 
            +
                  other_geometry = Charta.new_geometry(other).transform(srid)
         | 
| 255 | 
            +
                  feature.intersects?(other_geometry.feature)
         | 
| 256 | 
            +
                end
         | 
| 257 | 
            +
             | 
| 208 258 | 
             
                def difference(other)
         | 
| 209 259 | 
             
                  other_geometry = Charta.new_geometry(other).transform(srid)
         | 
| 210 260 | 
             
                  feature.difference(other_geometry.feature)
         | 
| @@ -241,7 +291,7 @@ module Charta | |
| 241 291 | 
             
                      @feature = ::Charta::Geometry.from_ewkt(@ewkt)
         | 
| 242 292 | 
             
                      @properties = @options.dup if @options
         | 
| 243 293 | 
             
                    else
         | 
| 244 | 
            -
                      raise StandardError | 
| 294 | 
            +
                      raise StandardError.new('Invalid geometry (no feature, no EWKT)')
         | 
| 245 295 | 
             
                    end
         | 
| 246 296 | 
             
                  end
         | 
| 247 297 | 
             
                  @feature.dup
         | 
| @@ -250,7 +300,8 @@ module Charta | |
| 250 300 | 
             
                alias to_rgeo feature
         | 
| 251 301 |  | 
| 252 302 | 
             
                def feature=(new_feature)
         | 
| 253 | 
            -
                  raise ArgumentError | 
| 303 | 
            +
                  raise ArgumentError.new("Feature can't be nil") if new_feature.nil?
         | 
| 304 | 
            +
             | 
| 254 305 | 
             
                  @feature = new_feature
         | 
| 255 306 | 
             
                end
         | 
| 256 307 |  | 
| @@ -269,6 +320,7 @@ module Charta | |
| 269 320 |  | 
| 270 321 | 
             
                def respond_to_missing?(name, include_private = false)
         | 
| 271 322 | 
             
                  return false if name == :init_with
         | 
| 323 | 
            +
             | 
| 272 324 | 
             
                  super
         | 
| 273 325 | 
             
                end
         | 
| 274 326 |  | 
| @@ -279,11 +331,13 @@ module Charta | |
| 279 331 |  | 
| 280 332 | 
             
                  def factory(srid = 4326)
         | 
| 281 333 | 
             
                    return projected_factory(srid) if srid.to_i == 4326
         | 
| 334 | 
            +
             | 
| 282 335 | 
             
                    geos_factory(srid)
         | 
| 283 336 | 
             
                  end
         | 
| 284 337 |  | 
| 285 338 | 
             
                  def feature(ewkt_or_rgeo)
         | 
| 286 339 | 
             
                    return from_rgeo(ewkt_or_rgeo) if ewkt_or_rgeo.is_a? RGeo::Feature::Instance
         | 
| 340 | 
            +
             | 
| 287 341 | 
             
                    from_ewkt(ewkt_or_rgeo)
         | 
| 288 342 | 
             
                  end
         | 
| 289 343 |  | 
| @@ -1,10 +1,12 @@ | |
| 1 1 | 
             
            module Charta
         | 
| 2 2 | 
             
              # Represent a Geometry with contains other geometries
         | 
| 3 3 | 
             
              class GeometryCollection < Geometry
         | 
| 4 | 
            -
                 | 
| 5 | 
            -
                  srid =  | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 4 | 
            +
                class << self
         | 
| 5 | 
            +
                  def empty(srid = nil)
         | 
| 6 | 
            +
                    srid = Charta.find_srid(srid.nil? ? :WGS84 : srid)
         | 
| 7 | 
            +
                    feature = Charta.new_feature('GEOMETRYCOLLECTION EMPTY', srid)
         | 
| 8 | 
            +
                    new(feature)
         | 
| 9 | 
            +
                  end
         | 
| 8 10 | 
             
                end
         | 
| 9 11 |  | 
| 10 12 | 
             
                def to_json_feature_collection(collection_properties = [])
         | 
    
        data/lib/charta/gml.rb
    CHANGED
    
    | @@ -83,6 +83,7 @@ module Charta | |
| 83 83 | 
             
                      'GEOMETRYCOLLECTION(' + gml.css("#{GML_PREFIX}|featureMember").collect do |feature|
         | 
| 84 84 | 
             
                        TAGS.collect do |tag|
         | 
| 85 85 | 
             
                          next if feature.css("#{GML_PREFIX}|#{tag}").empty?
         | 
| 86 | 
            +
             | 
| 86 87 | 
             
                          feature.css("#{GML_PREFIX}|#{tag}").collect do |fragment|
         | 
| 87 88 | 
             
                            object_to_ewkt(fragment, srid)
         | 
| 88 89 | 
             
                          end.compact.join(', ')
         | 
| @@ -90,6 +91,7 @@ module Charta | |
| 90 91 | 
             
                      end.compact.join(', ') + ')'
         | 
| 91 92 | 
             
                    end
         | 
| 92 93 | 
             
                  end
         | 
| 94 | 
            +
             | 
| 93 95 | 
             
                  alias geometry_collection_to_ewkt document_to_ewkt
         | 
| 94 96 |  | 
| 95 97 | 
             
                  def transform(data, from_srid, to_srid)
         | 
| @@ -101,8 +103,9 @@ module Charta | |
| 101 103 |  | 
| 102 104 | 
             
                    wkt = 'POLYGON(' + %w[outerBoundaryIs innerBoundaryIs].collect do |boundary|
         | 
| 103 105 | 
             
                      next if gml.css("#{GML_PREFIX}|#{boundary}").empty?
         | 
| 106 | 
            +
             | 
| 104 107 | 
             
                      gml.css("#{GML_PREFIX}|#{boundary}").collect do |hole|
         | 
| 105 | 
            -
                         | 
| 108 | 
            +
                        "(#{transform_coordinates(hole)})"
         | 
| 106 109 | 
             
                      end.join(', ')
         | 
| 107 110 | 
             
                    end.compact.join(', ') + ')'
         | 
| 108 111 |  | 
| @@ -115,6 +118,7 @@ module Charta | |
| 115 118 |  | 
| 116 119 | 
             
                  def point_to_ewkt(gml, srid)
         | 
| 117 120 | 
             
                    return 'POINT EMPTY' if gml.css("#{GML_PREFIX}|coordinates").nil?
         | 
| 121 | 
            +
             | 
| 118 122 | 
             
                    wkt = 'POINT(' + gml.css("#{GML_PREFIX}|coordinates").collect { |coords| coords.content.split ',' }.flatten.join(' ') + ')'
         | 
| 119 123 |  | 
| 120 124 | 
             
                    unless gml['srsName'].nil? || Charta.find_srid(gml['srsName']).to_s == srid.to_s
         | 
| @@ -127,7 +131,7 @@ module Charta | |
| 127 131 | 
             
                  def line_string_to_ewkt(gml, srid)
         | 
| 128 132 | 
             
                    return 'LINESTRING EMPTY' if gml.css("#{GML_PREFIX}|coordinates").nil?
         | 
| 129 133 |  | 
| 130 | 
            -
                    wkt =  | 
| 134 | 
            +
                    wkt = "LINESTRING(#{transform_coordinates(gml)})"
         | 
| 131 135 |  | 
| 132 136 | 
             
                    unless gml['srsName'].nil? || Charta.find_srid(gml['srsName']).to_s == srid.to_s
         | 
| 133 137 | 
             
                      wkt = transform(wkt, Charta.find_srid(gml['srsName']), srid)
         | 
| @@ -135,6 +139,18 @@ module Charta | |
| 135 139 |  | 
| 136 140 | 
             
                    wkt
         | 
| 137 141 | 
             
                  end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                  private
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                    def transform_coordinates(coordinates)
         | 
| 146 | 
            +
                      coordinates.css("#{GML_PREFIX}|coordinates")
         | 
| 147 | 
            +
                                 .collect { |coords| coords.content.split(/\r\n|\n| /) }
         | 
| 148 | 
            +
                                 .flatten
         | 
| 149 | 
            +
                                 .reject(&:empty?)
         | 
| 150 | 
            +
                                 .collect { |c| c.split ',' }
         | 
| 151 | 
            +
                                 .collect { |dimension| %(#{dimension.first} #{dimension[1]}) }
         | 
| 152 | 
            +
                                 .join(', ')
         | 
| 153 | 
            +
                    end
         | 
| 138 154 | 
             
                end
         | 
| 139 155 | 
             
              end
         | 
| 140 156 | 
             
            end
         | 
    
        data/lib/charta/gml_import.rb
    CHANGED
    
    | @@ -63,30 +63,30 @@ class GmlImport | |
| 63 63 |  | 
| 64 64 | 
             
              private
         | 
| 65 65 |  | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 69 | 
            -
             | 
| 70 | 
            -
             | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 76 | 
            -
             | 
| 77 | 
            -
             | 
| 78 | 
            -
             | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
             | 
| 88 | 
            -
             | 
| 66 | 
            +
                def featurize(node)
         | 
| 67 | 
            +
                  if node.element? && node.xpath('.//gml:Polygon')
         | 
| 68 | 
            +
                    geojson_feature = {}
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    geometry = node.xpath('.//gml:Polygon')
         | 
| 71 | 
            +
                    geometry.first['srsName'] = 'EPSG:2154'
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                    if ::Charta::GML.valid?(geometry)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                      # properties
         | 
| 76 | 
            +
                      id = (Time.zone.now.to_i.to_s + Time.zone.now.usec.to_s)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                      geojson_feature = {
         | 
| 79 | 
            +
                        type: 'Feature',
         | 
| 80 | 
            +
                        properties: {
         | 
| 81 | 
            +
                          internal_id: id
         | 
| 82 | 
            +
                        }.reject { |_, v| v.nil? },
         | 
| 83 | 
            +
                        geometry: ::Charta.new_geometry(geometry.to_xml, nil, 'gml').transform(:WGS84).to_geojson
         | 
| 84 | 
            +
                      }.reject { |_, v| v.nil? }
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                      return geojson_feature
         | 
| 87 | 
            +
                    else
         | 
| 88 | 
            +
                      return false
         | 
| 89 | 
            +
                    end
         | 
| 89 90 | 
             
                  end
         | 
| 90 91 | 
             
                end
         | 
| 91 | 
            -
              end
         | 
| 92 92 | 
             
            end
         | 
    
        data/lib/charta/kml.rb
    CHANGED
    
    | @@ -22,7 +22,9 @@ module Charta | |
| 22 22 | 
             
                end
         | 
| 23 23 |  | 
| 24 24 | 
             
                def to_ewkt
         | 
| 25 | 
            -
                  "SRID=#{@srid};" | 
| 25 | 
            +
                  srid_part = @srid.nil? ? '' : "SRID=#{@srid};"
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  srid_part + self.class.document_to_ewkt(@kml)
         | 
| 26 28 | 
             
                end
         | 
| 27 29 |  | 
| 28 30 | 
             
                def valid?
         | 
| @@ -46,15 +48,18 @@ module Charta | |
| 46 48 |  | 
| 47 49 | 
             
                  def document_to_ewkt(kml)
         | 
| 48 50 | 
             
                    return 'GEOMETRYCOLLECTION EMPTY' if kml.css('Document').nil?
         | 
| 51 | 
            +
             | 
| 49 52 | 
             
                    'GEOMETRYCOLLECTION(' + kml.css('Placemark').collect do |placemark|
         | 
| 50 53 | 
             
                      TAGS.collect do |tag|
         | 
| 51 54 | 
             
                        next if placemark.css(tag).empty?
         | 
| 55 | 
            +
             | 
| 52 56 | 
             
                        placemark.css(tag).collect do |fragment|
         | 
| 53 57 | 
             
                          object_to_ewkt(fragment)
         | 
| 54 58 | 
             
                        end.compact.join(', ')
         | 
| 55 59 | 
             
                      end.compact.join(', ')
         | 
| 56 60 | 
             
                    end.compact.join(', ') + ')'
         | 
| 57 61 | 
             
                  end
         | 
| 62 | 
            +
             | 
| 58 63 | 
             
                  alias geometry_collection_to_ewkt document_to_ewkt
         | 
| 59 64 |  | 
| 60 65 | 
             
                  def feature_to_ewkt(kml)
         | 
| @@ -63,13 +68,14 @@ module Charta | |
| 63 68 |  | 
| 64 69 | 
             
                  def point_to_ewkt(kml)
         | 
| 65 70 | 
             
                    return 'POINT EMPTY' if kml.css('coordinates').nil?
         | 
| 71 | 
            +
             | 
| 66 72 | 
             
                    'POINT(' + kml.css('coordinates').collect { |coords| coords.content.split ',' }.flatten.join(' ') + ')'
         | 
| 67 73 | 
             
                  end
         | 
| 68 74 |  | 
| 69 75 | 
             
                  def line_string_to_ewkt(kml)
         | 
| 70 76 | 
             
                    return 'LINESTRING EMPTY' if kml.css('coordinates').nil?
         | 
| 71 77 |  | 
| 72 | 
            -
                     | 
| 78 | 
            +
                    "LINESTRING(#{transform_coordinates(kml)})"
         | 
| 73 79 | 
             
                  end
         | 
| 74 80 |  | 
| 75 81 | 
             
                  def polygon_to_ewkt(kml)
         | 
| @@ -79,7 +85,7 @@ module Charta | |
| 79 85 | 
             
                      next if kml.css(boundary).empty?
         | 
| 80 86 |  | 
| 81 87 | 
             
                      kml.css(boundary).collect do |hole|
         | 
| 82 | 
            -
                         | 
| 88 | 
            +
                        "(#{transform_coordinates(hole)})"
         | 
| 83 89 | 
             
                      end.join(', ')
         | 
| 84 90 | 
             
                    end.compact.join(', ') + ')'
         | 
| 85 91 | 
             
                  end
         | 
| @@ -87,6 +93,18 @@ module Charta | |
| 87 93 | 
             
                  def multigeometry_to_ewkt(_kml)
         | 
| 88 94 | 
             
                    raise :not_implemented
         | 
| 89 95 | 
             
                  end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                  private
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                    def transform_coordinates(coordinates)
         | 
| 100 | 
            +
                      coordinates.css('coordinates')
         | 
| 101 | 
            +
                                 .collect { |coords| coords.content.split(/\r\n|\n| /) }
         | 
| 102 | 
            +
                                 .flatten
         | 
| 103 | 
            +
                                 .reject(&:empty?)
         | 
| 104 | 
            +
                                 .collect { |c| c.split ',' }
         | 
| 105 | 
            +
                                 .collect { |dimension| %(#{dimension.first} #{dimension[1]}) }
         | 
| 106 | 
            +
                                 .join(', ')
         | 
| 107 | 
            +
                    end
         | 
| 90 108 | 
             
                end
         | 
| 91 109 | 
             
              end
         | 
| 92 110 | 
             
            end
         | 
    
        data/lib/charta/multi_polygon.rb
    CHANGED
    
    
    
        data/lib/charta/point.rb
    CHANGED
    
    
    
        data/lib/charta/polygon.rb
    CHANGED
    
    
    
        data/lib/charta/version.rb
    CHANGED