Giter Club home page Giter Club logo

georuby's Introduction

GeoRuby

This is intended as a holder for geometric data. The data model roughly follows the OGC "Simple Features for SQL" specification, so it should play nice with data returned from PostGIS or any Spatial Extensions (MongoDB, MySQL...). It also supports various output and input formats (GeoRSS, KML, Shapefile). GeoRuby is written in pure Ruby.

OGC:"http://www.opengis.org/docs/99-049.pdf"

If you are looking for Proj/Geos (geometric operators or reprojections) rubygem checkout: (C extension) rgeo:"https://github.com/dazuma/rgeo"

Gem Version Dependency Status Build Status Code Climate Coverage Status

Gitter

Available data types

The following geometric data types are provided :

  • Point
  • Line String
  • Linear Ring
  • Polygon
  • Multi Point
  • Multi Line String
  • Multi Polygon
  • Geometry Collection

They can be in 2D, 3DZ, 3DM, and 4D.

On top of this an Envelope class is available, to contain the bounding box of a geometry.

Installation

To install the latest version, just type:

gem install georuby

Or include on your projects`s Gemfile:

gem 'georuby'

Optional, require if you need the functionality:

require 'georuby'
require 'geo_ruby/ewk'        # EWKT/EWKB
require 'geo_ruby/shp'        # Shapefile
require 'geo_ruby/gpx'        # GPX data
require 'geo_ruby/kml'        # KML data
require 'geo_ruby/georss'     # GeoRSS
require 'geo_ruby/geojson'    # GeoJSON

TODO: https://github.com/AnalyticalGraphicsInc/czml-writer

Use

Simple Examples

Creating a 3D Point:

include GeoRuby::SimpleFeatures
Point.from_x_y_z(10.0, 20.0, 5.0)

Creating a LineString:

LineString.from_coordinates([[1,1],[2,2]],4326)

Creating a Polygon:

coordinates = [[0,0],[0,1],[1,1],[1,0]]
outer_ring = LinearRing.from_coordinates(coordinates, 4326)
rings = [outer_ring]
Polygon.from_linear_rings(rings)

Checking if a Point is inside a Polygon:

point   = Point.from_x_y(0.5, 0.5)
polygon = Polygon.from_coordinates([[[0,0],[0,1],[1,1],[1,0]]],4326)
polygon.contains_point?(point)

Input and output

These geometries can be input and output in WKB/EWKB/WKT/EWKT format as well as the related HexWKB and HexEWKB formats. HexEWKB and WKB are the default form under which geometric data is returned respectively from PostGIS and MySql.

GeoRSS Simple, GeoRSS W3CGeo, GeoRSS GML can also be input and output. Note that they will not output valid RSS, but just the part strictly concerning the geometry as outlined in http://www.georss.org/1/ . Since the model does not allow multiple geometries, for geometry collections, only the first geometry will be output. Similarly, for polygons, the GeoRSS output will only contain the outer ring. As for W3CGeo output, only points can be output, so the first point of the geometry is chosen. By default the Simple format is output. Envelope can also be output in these formats: The box geometric type is chosen (except for W3CGeo, where the center of the envelope is chose). These formats can also be input and a GeoRuby geometry will be created. Note that it will not read a valid RSS file, only a geometry string.

On top of that, there is now support for KML output and input. As for GeoRSS, a valid KML file will not be output, but only the geometric data. Options :id, :extrude, :tesselate and :altitude_mode can be given. Note that if the :altitude_mode option is not passed or set to clampToGround, the altitude data will not be output even if present. Envelopes output a LatLonAltBox instead of a geometry. For the output, the following geometric types are supported : Point, LineString, Polygon.

SHP reading and writing

Georuby has support for reading ESRI shapefiles (http://www.esri.com/library/whitepapers/pdfs/shapefile.pdf). A tool called shp2sql.rb is also provided: it shows how to use the SHP reading functionality together with the spatial adapter plugin for Rails to import spatial features into MySQL and PostGIS.

Here is an example of Shapefile reading, that goes through all the geometries in a file and disaply the values of the attributes :

  require 'geo_ruby/shp'

  GeoRuby::Shp4r::ShpFile.open(shpfile) do |shp|
    shp.each do |shape|
      geom = shape.geometry #a GeoRuby SimpleFeature
      att_data = shape.data #a Hash
      shp.fields.each do |field|
        puts att_data[field.name]
      end
    end
  end

Support for ESRI shapefile creation and modification has been added as well. New shapefiles can be created given a geometry type and specifications for the DBF fields. Data can be added and removed from an existing shapefile. An update operation is also provided for convenience: it just performs a 'delete' and an 'add', which means the index of the modified record will change. Note that once a shapefile has been created, GeoRuby does not allow the modification of the schema (it will probably be done in a subsequent version).

Here is an example of how to create a new Shapefile with 2 fields :

  shpfile = GeoRuby::Shp4r::ShpFile.create('hello.shp', ShpType::POINT, [DBF::Field.new("Hoyoyo", "C", 10), DBF::Field.new("Boyoul","N",10,0)])

The file is then open for reading and writing.

Here is an example of how to write to a shapefile (created or not with GeoRuby) :

  shpfile = GeoRuby::Shp4r::ShpFile.open('places.shp')
  shpfile.transaction do |tr|
    tr.add(ShpRecord.new(Point.from_x_y(123.4, 123.4), 'Hoyoyo' => "AEZ",'Bouyoul' => 45))
    tr.update(4, ShpRecord.new(Point.from_x_y(-16.67, 16.41), 'Hoyoyo' => "EatMe",'Bouyoul' => 42))
    tr.delete(1)
  end
  shpfile.close

Note the transaction is just there so the operations on the files can be buffered. Nothing happens on the original files until the block has finished executing. Calling tr.rollback at anytime during the execution will prevent the modifications.

Also currently, error reporting is minimal and it has not been tested that thoroughly so caveat emptor and backup before performing any destructive operation.

Shapefile names and extensions (dbf, shp, gpx) must be lowercased!

GPX Reading

You can read and convert GPX Files to LineString/Polygon:

 gpxfile = GpxFile.open('tour.gpx')
 gpxfile.as_line_string
 => GeoRuby::SimpleFeatures::LineString..

GeoJSON Support

Basic GeoJSON support has been implemented per v1.0 of the {spec}[http://geojson.org/geojson-spec.html].

USAGE:

input - GeoRuby::SimpleFeatures::Geometry.from_geojson(geojson_string) output - call #as_geojson or #to_json on any SimpleFeature Geometry instance

TODO:

  • Refactor to support extremely large GeoJSON input streams / files. Currently the entire GeoJSON representation must be loaded into memory as a String
  • Improve srid/crs support on input and add support on output
  • Implement bounding-box spport per spec on input/output?
  • Improved / more tests

GeoJSON support implemented by {Marcus Mateus}[http://github.com/marcusmateus] and released courtesy {SimpliTex}[http://simplitex.com].

Extra Features

  • Writing of ESRI shapefiles
  • Reading of ESRI shapefiles
  • Tool to import spatial features in MySQL and PostGIS from a SHP file

Acknowledgement

The SHP reading part uses the DBF library (http://rubyforge.org/projects/dbf/) by Keith Morrison (http://infused.org). Thanks also to Pramukta Kumar and Pete Schwamb for their contributions.

Support (Original GeoRuby gem)

Any questions, enhancement proposals, bug notifications or corrections can be sent to [email protected].

Coming in the next versions

  • Schema modification of existing shapefiles
  • More error reporting when writing shapefiles
  • More tests on writing shapefiles ; tests on real-world shapefiles
  • Better shp2sql import tool
  • Documentation

Bitdeli Badge

georuby's People

Contributors

bitdeli-chef avatar dougcole avatar ericduminil avatar gitter-badger avatar icco avatar kdelchev avatar kueda avatar lasssim avatar marcusmateus avatar nofxx avatar nolman avatar rossettistone avatar schleyfox avatar spone avatar tjdett avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

georuby's Issues

GeoRuby::SimpleFeatures::EWKBFormatError errors

When my model refreshes, I'm getting this error sometimes:

Screen Shot 2021-01-16 at 8 12 33 PM

      def read_point
        i = @position
        @position += 16
        fail EWKBFormatError.new('Truncated data') if @ewkb.length < @position
        @ewkb.unpack("@#{i}#{@double_mark}#{@double_mark}@*")
      end

I'm getting this in my production and I also get it in my test cases intermittently. My testcases are threaded which is why I thought they were happening.

But... they are also happening on production which is not using threading and it is just normal Rails / Puma. It seems like there is some kind of race condition being hit when the database records are being refresh.

I'm using Sequel orm which might be the source, but I don't think that is causing it.

Can someone give me some insight why this might be happening intermittently?

*.SHP, *.SHX *.DBF files not supported (File extensions are capitalized)

if you have Shapefiles that have file extensions that are capitalized (i.e. shape_file.SHP instead of shape_file.shp), it throws a MalformedShpException despite the file(s) actually existing and being valid.

@file_root = file.gsub(/.shp$/i, '')

works as to pulling the correct root file because you are ignoring case.

However

unless File.exist?(@file_root + '.shp') && File.exist?(@file_root + '.dbf') && File.exist?(@file_root + '.shx')

fails to pick up the files because you are looking for files with the lower cased extensions.

Renaming all files from *.SHP to *.shp (etc) resolves the issue now, but would be nice if the code could figure this out.

Empty attribute table

The code

` require 'geo_ruby/shp'

GeoRuby::Shp4r::ShpFile.open(shpfile) do |shp|
shp.each do |shape|
geom = shape.geometry #a GeoRuby SimpleFeature
att_data = shape.data #a Hash
shp.fields.each do |field|
puts att_data[field.name]
end
end
end`

Does seem to get the geometry nicely, but the att_data is completely empty (nil values all over)

Redirection to RGeo

Hi,

It looks like the project has been stale for some time now. As a maintainer of RGeo, I understand that these kind of gems need great support and we'd love to have more of the community involved.

What do we say we explicitely redirect to rgeo and/or ffi-geos from this gem, and mark it as deprecated so community efforts are more likely to be focused?

As part of this, of course, any feature that is present here, missing in rgeo, and wanted by anyone could be asked for in rgeo.

Cheers,
Ulysse

can't convert String into Float

Since you were so quick to help before, i hope you dont mind another issue :). ive looked at the GeoRuby code in the backtrace and i'm a bit lost. I also hope this is enough information to be useful.
`

Location.create({:user_id=>51,"latitude"=>"45.51163136959076", "longitude"=>"-122.61863350868225", "altitude"=>"37.0", "accuracy"=>"16.0", "heading"=>"0.0", "velocity"=>"0.0", "timestamp"=>"2010-10-12T21:53:07+0000", "batterylevel"=>"43"}).errors.full_messages
TypeError: can't convert String into Float
from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/GeoRuby-1.3.4/lib/geo_ruby/simple_features/point.rb:133:in pack' from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/GeoRuby-1.3.4/lib/geo_ruby/simple_features/point.rb:133:inbinary_representation'
from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/GeoRuby-1.3.4/lib/geo_ruby/simple_features/geometry.rb:66:in as_ewkb' from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/GeoRuby-1.3.4/lib/geo_ruby/simple_features/geometry.rb:76:inas_hex_ewkb'
from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/postgis_adapter-0.7.8/lib/postgis_adapter.rb:114:in quote' from /usr/local/ruby-1.9.2-p0/lib/ruby/gems/1.9.1/gems/activerecord-2.3.8/lib/active_record/base.rb:3033:inblock in attributes_with_quotes'
`

kml_spec.rb failure

I get the following error message when running the tests:

Failures:

  1) GeoRuby::KmlParser should parse a GeoRuby::SimpleFeatures::LineString correctly
     Failure/Error: g.as_kml.gsub(/\n/,'').should eql(LINEARRING)
     SystemStackError:
       stack level too deep
     # ./lib/geo_ruby/simple_features/linear_ring.rb:18:in `orig_kml_representation'
     # ./lib/geo_ruby/simple_features/linear_ring.rb:18:in `orig_kml_representation'
     # ./lib/geo_ruby/simple_features/linear_ring.rb:18:in `kml_representation'
     # ./lib/geo_ruby/simple_features/geometry.rb:139:in `as_kml'
     # ./spec/geo_ruby/kml_spec.rb:40

How to output a GeoJSONFeatureCollection?

Edit: Now I found out this is due to a conflict between Rail's ActiveSupport to_json and the json gem. Usage outside Rails environment works as intended. How to get around this?

I'm not sure if I'm using this functionality correctly or not, but I'm having trouble outputting a valid GeoJSON collection.

Example:
GeoJSONFeature.new(point1).to_json

Output:

{  
   "type":"Feature",
   "geometry":{  
      "type":"Point",
      "coordinates":[  
         121.4412656998513,
         31.2108137285587
      ]
   },
   "properties":{  
   }
}

But when a GeoJSONFeature is inside an array, it skips over its own GeoJSONFeature#to_json method (double checked with byebug) and is missing the "type": "Feature" attribute.

Example:
[GeoJSONFeature.new(point1)].to_json

Output:

[  
   {  
      "geometry":{  
         "type":"Point",
         "coordinates":[  
            121.4412656998513,
            31.2108137285587
         ]
      },
      "properties":{  
      },
      "id":null
   }
]

Finally putting it together with a FeatureCollection:

    features = [
      GeoJSONFeature.new(start_point),
      GeoJSONFeature.new(end_point)
    ]
    GeoJSONFeatureCollection.new(features)

Output (not valid GeoJSON):

{  
   "type":"FeatureCollection",
   "features":[  
      {  
         "geometry":{  
            "type":"Point",
            "coordinates":[  
               121.4412656998513,
               31.2108137285587
            ]
         },
         "properties":{  
         },
         "id":null
      },
      {  
         "geometry":{  
            "type":"Point",
            "coordinates":[  
               121.4569708797648,
               31.219778491221284
            ]
         },
         "properties":{  
         },
         "id":null
      }
   ]
}

Not able to access Dbf

Hi,

I have georuby 2.5.2 loaded and DBF 2.0.7. When I require 'geo_ruby/shp', the constant that I see loaded if DBF (all caps) and there is no Field function available. Any ideas on what I can try to get access to the Dbf method to allow access to the custom functions?

Thanks,

Scott

gem fails to load?

I've done all the diagnosis I know how to do, but can't get any of the georuby classes to become available. What am I missing?

$ uname -a
Linux linux 3.13.0-20-generic #42-Ubuntu SMP Fri Mar 28 09:56:33 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]

$ irb
irb(main):001:0> require 'georuby'
=> true
irb(main):002:0> p = Point.new
NameError: uninitialized constant Point
from (irb):2
from /usr/bin/irb:12:in `

'
irb(main):003:0>

On Ruby 2.1.0 the HexEWKBParser fails to give correct results

h = "01010000207B000000CDCCCCCCCCCC28406666666666A64640"

f2 = GeometryFactory::new
ep = EWKBParser::new(f2)
e = [h].pack("H*")
ep.parse(e)
f2.geometry.x
=> 12.4

f1 = GeometryFactory::new
hp = HexEWKBParser::new(f1)
hp.parse(h)
f1.geometry.x
=> -3.495080594483092e-247

Unable to connect to postgres without postGIS installed

My app connects to multiple databases via activerecord, some of which have postGIS and some do not.

When I use an AR class which connects to a db without postGIS,
I get a PG::Error (relation "geometry_columns" does not exist)
at spatial_adapter/postgresql.rb:216 in column_spatial_info.

I've been getting past this by including the following module in my AR objects, but would prefer a real fix.

module SupressSpatialCalculation # Since we dont have postGIS installed on this DB def column_spatial_info(column_name) {} end end

Would it make sense to handle this error within GeoRuby? (and maybe even disable the extra georuby features for that class when it's encountered)

undefined method `as_json' for Hash

Irked by this when using GeoRuby standalone to modify GeoJSON files.

/Users/parker/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/georuby-2.2.1/lib/geo_ruby/geojson.rb:40:in `as_json': undefined method `as_json' for #<Hash:0x007fb57a945958> (NoMethodError)
    from /Users/parker/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/georuby-2.2.1/lib/geo_ruby/geojson.rb:44:in `to_json'
    from /Users/parker/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/georuby-2.2.1/lib/geo_ruby/geojson.rb:70:in `to_json'
    from /Users/parker/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/georuby-2.2.1/lib/geo_ruby/geojson.rb:70:in `to_json'

Do I need ActiveSupport? ActiveModel? If so, how can I avoid it?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.