geoscript 0.1.0.pre-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +35 -0
- data/lib/geoscript.rb +38 -0
- data/lib/geoscript/datastore.rb +1 -0
- data/lib/geoscript/datastore/memory.rb +11 -0
- data/lib/geoscript/feature.rb +3 -0
- data/lib/geoscript/feature/feature.rb +63 -0
- data/lib/geoscript/feature/field.rb +19 -0
- data/lib/geoscript/feature/schema.rb +95 -0
- data/lib/geoscript/geom.rb +9 -0
- data/lib/geoscript/geom/bounds.rb +84 -0
- data/lib/geoscript/geom/geom.rb +56 -0
- data/lib/geoscript/geom/linearring.rb +37 -0
- data/lib/geoscript/geom/linestring.rb +62 -0
- data/lib/geoscript/geom/multilinestring.rb +49 -0
- data/lib/geoscript/geom/multipoint.rb +49 -0
- data/lib/geoscript/geom/multipolygon.rb +47 -0
- data/lib/geoscript/geom/point.rb +44 -0
- data/lib/geoscript/geom/polygon.rb +56 -0
- data/lib/geoscript/io.rb +4 -0
- data/lib/geoscript/io/feature/json.rb +15 -0
- data/lib/geoscript/io/geom/json.rb +15 -0
- data/lib/geoscript/io/geom/wkb.rb +27 -0
- data/lib/geoscript/io/geom/wkt.rb +16 -0
- data/lib/geoscript/layer/layer.rb +0 -0
- data/lib/geoscript/layer/shapefile.rb +0 -0
- data/lib/geoscript/projection.rb +84 -0
- data/lib/geoscript/util.rb +1 -0
- data/lib/geoscript/util/bytes.rb +30 -0
- data/lib/geoscript/version.rb +3 -0
- data/lib/geoscript/workspace.rb +21 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 445d8baccf38f5d7554210741b7c0ea4c7d82a12
|
4
|
+
data.tar.gz: a725311f99daa2b3c18bade8dc85b4e316d8fb3c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6864c3bfc0e262ec1b4deda2de33b426bc2d3f4923d47ee71ba6ce811d388deb5be32fb6d90be976e3bf506bfbb811979f633048671b9cca569a3101453a9351
|
7
|
+
data.tar.gz: 506594ffbc7bbc166dc05bfdd9bdf34fc921b58f6b2bd975b3770e33e59f451130df33787043930c93893d50c90e14774ab82fad5b0580c91766f16fbff86c29
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
geoscript-ruby
|
2
|
+
|
3
|
+
GeoScript for JRuby
|
4
|
+
|
5
|
+
If in development, run `mvn install` to get GeoTools dependencies
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
# installed gem
|
9
|
+
# %> geoscript
|
10
|
+
|
11
|
+
# development
|
12
|
+
# %> rake console
|
13
|
+
# or
|
14
|
+
# %> bin/geoscript
|
15
|
+
|
16
|
+
require 'geoscript'
|
17
|
+
# => true
|
18
|
+
include GeoScript::Geom
|
19
|
+
# => Object
|
20
|
+
|
21
|
+
p = Point.new -111.0, 45.7
|
22
|
+
# => #<GeoScript::Geom::Point:0x636c4fcb>
|
23
|
+
p.to_wkt
|
24
|
+
# => "POINT (-111 45.7)"
|
25
|
+
|
26
|
+
p2 = GeoScript::Projection.reproject p, 'epsg:4326', 'epsg:26912'
|
27
|
+
# => #<GeoScript::Geom::Point:0x6a55c240>
|
28
|
+
p2.to_wkt
|
29
|
+
# => "POINT (500000 5060716.313515949)"
|
30
|
+
|
31
|
+
poly = p2.buffer 100
|
32
|
+
# => #<GeoScript::Geom::Polygon:0x7b32aba9>
|
33
|
+
poly.get_area
|
34
|
+
# => 31214.451522458345
|
35
|
+
```
|
data/lib/geoscript.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
$: << File.expand_path(File.dirname(__FILE__))
|
2
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'geoscript'))
|
3
|
+
|
4
|
+
if defined? JRUBY_VERSION
|
5
|
+
require 'geotools-jars'
|
6
|
+
|
7
|
+
require 'geoscript/version'
|
8
|
+
require 'geoscript/util'
|
9
|
+
require 'geoscript/io'
|
10
|
+
require 'geoscript/projection'
|
11
|
+
require 'geoscript/geom'
|
12
|
+
require 'geoscript/feature'
|
13
|
+
require 'geoscript/datastore'
|
14
|
+
require 'geoscript/workspace'
|
15
|
+
else
|
16
|
+
abort "GeoScript requires JRuby (http://jruby.org)"
|
17
|
+
end
|
18
|
+
|
19
|
+
java_import org.geotools.factory.Hints
|
20
|
+
|
21
|
+
unless java.lang.System.get_property('org.geotools.referencing.forceXY') == 'true'
|
22
|
+
java.lang.System.set_property 'org.geotools.referencing.forceXY', 'true'
|
23
|
+
end
|
24
|
+
|
25
|
+
Hints.put_system_default Hints::FORCE_LONGITUDE_FIRST_AXIS_ORDER, java.lang.Boolean.new(true)
|
26
|
+
|
27
|
+
module GeoScript
|
28
|
+
class << self
|
29
|
+
def version
|
30
|
+
VERSION
|
31
|
+
end
|
32
|
+
|
33
|
+
def geotools_version
|
34
|
+
::Java::OrgGeotoolsFactory::GeoTools.version.to_string
|
35
|
+
end
|
36
|
+
alias_method :gt_version, :geotools_version
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'datastore/memory'
|
@@ -0,0 +1,63 @@
|
|
1
|
+
java_import org.geotools.feature.simple.SimpleFeatureBuilder
|
2
|
+
ogFeature = org.opengis.feature.Feature
|
3
|
+
|
4
|
+
module GeoScript
|
5
|
+
class Feature
|
6
|
+
def initialize(attrs=nil, id=nil, schema=nil)
|
7
|
+
raise 'No attributes specified for feature' unless attrs
|
8
|
+
|
9
|
+
unless attrs.kind_of? GeoScript::Feature
|
10
|
+
unless schema
|
11
|
+
if attrs.instance_of? Hash
|
12
|
+
schema_attrs = []
|
13
|
+
attrs.each do |k, v|
|
14
|
+
schema_attrs << {name: k.to_s, type: v.to_java.java_class}
|
15
|
+
end
|
16
|
+
@schema = GeoScript::Schema.new('feature', schema_attrs)
|
17
|
+
elsif attrs.instance_of? Array
|
18
|
+
raise 'Attributes may only be given as Array if schema is specified'
|
19
|
+
end
|
20
|
+
else
|
21
|
+
@schema = schema
|
22
|
+
end
|
23
|
+
|
24
|
+
if attrs.instance_of? Array
|
25
|
+
attrs_hash = {}
|
26
|
+
attrs.each_with_index {|v, i| attrs_hash[@schema.fields[i].name] = v}
|
27
|
+
attrs = attrs_hash
|
28
|
+
end
|
29
|
+
|
30
|
+
sfb = SimpleFeatureBuilder.new @schema.feature_type
|
31
|
+
attrs.each {|k, v| sfb.set(k.to_s, v)}
|
32
|
+
@feature = sfb.build_feature id
|
33
|
+
else
|
34
|
+
@feature = attrs
|
35
|
+
@schema = schema ? schema : GeoScript::Schema.new(@feature.feature_type)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def id
|
40
|
+
@feature.identifier.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_geom
|
44
|
+
@feature.default_geometry
|
45
|
+
end
|
46
|
+
alias_method :geom, :get_geom
|
47
|
+
|
48
|
+
def set_geom(geom)
|
49
|
+
@feature.default_geometry = geom
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_attributes
|
53
|
+
attributes = {}
|
54
|
+
|
55
|
+
@schema.fields.each do |field|
|
56
|
+
attributes[field] = @feature.get_attribute(field)
|
57
|
+
end
|
58
|
+
|
59
|
+
attributes
|
60
|
+
end
|
61
|
+
alias_method :attributes, :get_attributes
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module GeoScript
|
2
|
+
class Field
|
3
|
+
attr_accessor :name, :type, :proj
|
4
|
+
|
5
|
+
def initialize(name, type, proj=nil)
|
6
|
+
@name = name
|
7
|
+
@type = type
|
8
|
+
@proj = proj
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"#{@name}: #{@type}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def ==(other)
|
16
|
+
other.name == @name && other.type == @type && other.proj == @proj
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
java_import org.opengis.feature.type.FeatureType
|
2
|
+
java_import org.opengis.feature.type.GeometryDescriptor
|
3
|
+
java_import org.geotools.feature.NameImpl
|
4
|
+
java_import org.geotools.feature.simple.SimpleFeatureTypeBuilder
|
5
|
+
|
6
|
+
module GeoScript
|
7
|
+
class Schema
|
8
|
+
attr_accessor :feature_type
|
9
|
+
|
10
|
+
def initialize(name=nil, fields=[], type=nil, uri='http://geoscript.org/feature')
|
11
|
+
if name && !fields.empty?
|
12
|
+
type_builder = SimpleFeatureTypeBuilder.new
|
13
|
+
type_builder.set_name NameImpl.new(name)
|
14
|
+
type_builder.setNamespaceURI uri
|
15
|
+
fields.each do |field|
|
16
|
+
if field.instance_of? GeoScript::Field
|
17
|
+
name, type, proj = field.name, field.type, field.proj
|
18
|
+
elsif field.instance_of? Hash
|
19
|
+
if field[:name] && field[:type]
|
20
|
+
name, type = field[:name], field[:type]
|
21
|
+
else
|
22
|
+
name, type = field.keys.first, field.values.first
|
23
|
+
end
|
24
|
+
|
25
|
+
if type.name.match /GeoScript::Geom/
|
26
|
+
proj = GeoScript::Projection.new(field[:proj]) if field[:proj]
|
27
|
+
end
|
28
|
+
elsif field.instance_of? Array
|
29
|
+
name, type = field[0], field[1]
|
30
|
+
|
31
|
+
if type.name.match /GeoScript::Geom/
|
32
|
+
proj = GeoScript::Projection.new(field[2]) if field[2]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
type_builder.crs proj if proj
|
36
|
+
|
37
|
+
if type.name.match /GeoScript::Geom/
|
38
|
+
type = type.superclass.java_class
|
39
|
+
else
|
40
|
+
type = type.to_java.java_class
|
41
|
+
end
|
42
|
+
|
43
|
+
type_builder.add name, type
|
44
|
+
end
|
45
|
+
@feature_type = type_builder.build_feature_type
|
46
|
+
else
|
47
|
+
if !name && fields.empty?
|
48
|
+
raise "No name specified & No fields specified for type: #{type}"
|
49
|
+
elsif fields.empty?
|
50
|
+
raise "No fields specified for type: #{type}" if fields.empty?
|
51
|
+
elsif !name
|
52
|
+
raise 'No name specified'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def get_name
|
58
|
+
@feature_type.name.local_part
|
59
|
+
end
|
60
|
+
alias_method :name, :get_name
|
61
|
+
|
62
|
+
def get_geom
|
63
|
+
@feature_type.geometry_descriptor.local_name
|
64
|
+
end
|
65
|
+
alias_method :geom, :get_geom
|
66
|
+
|
67
|
+
def uri
|
68
|
+
@feature_type.name.namespaceURI
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_proj
|
72
|
+
crs = @feature_type.coordinate_reference_system
|
73
|
+
GeoScript::Projection.new crs if crs
|
74
|
+
end
|
75
|
+
alias_method :proj, :get_proj
|
76
|
+
|
77
|
+
def get_fields
|
78
|
+
fields = []
|
79
|
+
|
80
|
+
@feature_type.attribute_descriptors.each do |ad|
|
81
|
+
fields << self.get(ad.local_name)
|
82
|
+
end
|
83
|
+
|
84
|
+
fields
|
85
|
+
end
|
86
|
+
alias_method :fields, :get_fields
|
87
|
+
|
88
|
+
def get(name)
|
89
|
+
ad = @feature_type.get_descriptor name
|
90
|
+
GeoScript::Field.new(ad.local_name, ad.type.binding, ad.coordinate_reference_system)
|
91
|
+
rescue NoMethodError
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
java_import com.vividsolutions.jts.geom.Envelope
|
4
|
+
java_import org.geotools.geometry.jts.ReferencedEnvelope
|
5
|
+
|
6
|
+
class Bounds < ReferencedEnvelope
|
7
|
+
include GeoScript::Geom
|
8
|
+
|
9
|
+
def initialize(env, proj = nil)
|
10
|
+
projection = GeoScript::Projection.new proj if proj
|
11
|
+
|
12
|
+
if env.kind_of? Envelope
|
13
|
+
if projection
|
14
|
+
super(env, projection)
|
15
|
+
elsif env.respond_to? :crs
|
16
|
+
if env.crs
|
17
|
+
super(env, env.crs)
|
18
|
+
else
|
19
|
+
super(env, nil)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
super(env, nil)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
if env.kind_of? Hash
|
26
|
+
if projection
|
27
|
+
super(env[:x_min], env[:x_max], env[:y_min], env[:y_max], projection)
|
28
|
+
else
|
29
|
+
super(env[:x_min], env[:x_max], env[:y_min], env[:y_max], nil)
|
30
|
+
end
|
31
|
+
elsif env.kind_of? Array
|
32
|
+
if projection
|
33
|
+
super(env[0], env[1], env[2], env[3], projection)
|
34
|
+
else
|
35
|
+
super(env[0], env[1], env[2], env[3])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
super()
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_west
|
44
|
+
self.min_x
|
45
|
+
end
|
46
|
+
|
47
|
+
def get_south
|
48
|
+
self.min_y
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_east
|
52
|
+
self.max_x
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_north
|
56
|
+
self.max_y
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_projection
|
60
|
+
crs = self.coordinate_reference_system
|
61
|
+
GeoScript::Projection.new crs if crs
|
62
|
+
end
|
63
|
+
|
64
|
+
def get_aspect
|
65
|
+
self.width / self.height
|
66
|
+
end
|
67
|
+
|
68
|
+
def scale(factor)
|
69
|
+
width = self.width * (factor - 1) / 2
|
70
|
+
height = self.height * (factor - 1) / 2
|
71
|
+
|
72
|
+
Bounds.new self.west - width, self.south - height, self.east + width, self.north + height
|
73
|
+
end
|
74
|
+
|
75
|
+
def expand(other)
|
76
|
+
self.expand_to_include(other)
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_polygon;end
|
80
|
+
|
81
|
+
def tile(resolution);end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
java_import java.awt.geom.AffineTransform
|
4
|
+
java_import com.vividsolutions.jts.geom.GeometryFactory
|
5
|
+
java_import com.vividsolutions.jts.geom.Geometry
|
6
|
+
java_import com.vividsolutions.jts.geom.prep.PreparedGeometryFactory
|
7
|
+
java_import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier
|
8
|
+
java_import com.vividsolutions.jts.triangulate.DelaunayTriangulationBuilder
|
9
|
+
java_import com.vividsolutions.jts.triangulate.VoronoiDiagramBuilder
|
10
|
+
java_import com.vividsolutions.jts.operation.buffer.BufferParameters
|
11
|
+
java_import com.vividsolutions.jts.operation.buffer.BufferOp
|
12
|
+
java_import org.geotools.geometry.jts.JTS
|
13
|
+
java_import org.geotools.referencing.operation.transform.AffineTransform2D
|
14
|
+
|
15
|
+
GEOM_FACTORY = GeometryFactory.new
|
16
|
+
PREP_FACTORY = PreparedGeometryFactory.new
|
17
|
+
|
18
|
+
def self.prepare(geom)
|
19
|
+
PREP_FACTORY.create(geom)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.simplify(geom, tolerance)
|
23
|
+
DouglasPeuckerSimplifier.simplify(geom, tolerance)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.buffer(geom, distance, single_sided = false)
|
27
|
+
buffer_params = BufferParameters.new
|
28
|
+
buffer_params.set_single_sided(single_sided)
|
29
|
+
BufferOp.buffer_op(geom, distance, buffer_params)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.get_bounds(geom)
|
33
|
+
Bounds.new geom.get_envelope_internal
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.enhance(geom)
|
37
|
+
geom.bounds = get_bounds(geom)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.to_geoscript_geom(geom)
|
41
|
+
const_get(geom.geometry_type).new(geom)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.from_json(json)
|
45
|
+
to_geoscript_geom(GeoScript::IO::Geom.read_json(json))
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.from_wkt(wkt)
|
49
|
+
to_geoscript_geom(GeoScript::IO::Geom.read_wkt(wkt))
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.from_wkb(wkb)
|
53
|
+
to_geoscript_geom(GeoScript::IO::Geom.read_wkb(wkb))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
java_import com.vividsolutions.jts.geom.Coordinate
|
4
|
+
JTSLinearRing = com.vividsolutions.jts.geom.LinearRing
|
5
|
+
|
6
|
+
class LinearRing < JTSLinearRing
|
7
|
+
include GeoScript::Geom
|
8
|
+
|
9
|
+
attr_accessor :bounds
|
10
|
+
|
11
|
+
def initialize(*coords)
|
12
|
+
if coords.size == 1
|
13
|
+
super(coords.first.coordinate_sequence) if coords.first.kind_of? LinearRing
|
14
|
+
else
|
15
|
+
line_string = LineString.new *coords
|
16
|
+
super(line_string.coordinate_sequence, GEOM_FACTORY)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def buffer(dist)
|
21
|
+
Polygon.new super
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_wkt
|
25
|
+
GeoScript::IO::Geom.write_wkt self
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_wkb
|
29
|
+
GeoScript::IO::Geom.write_wkb self
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json
|
33
|
+
GeoScript::IO::Geom.write_json self
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
java_import com.vividsolutions.jts.geom.Coordinate
|
4
|
+
JTSLineString = com.vividsolutions.jts.geom.LineString
|
5
|
+
|
6
|
+
class LineString < JTSLineString
|
7
|
+
include GeoScript::Geom
|
8
|
+
|
9
|
+
attr_accessor :bounds
|
10
|
+
|
11
|
+
def initialize(*coords)
|
12
|
+
if coords.size == 1
|
13
|
+
if coords.first.kind_of? JTSLineString
|
14
|
+
ls = coords.first
|
15
|
+
elsif coords.kind_of? Array
|
16
|
+
if coords.first.kind_of? Array
|
17
|
+
l = []
|
18
|
+
coords.first.each do |coord|
|
19
|
+
l << Coordinate.new(coord[0], coord[1])
|
20
|
+
l.last.z = coord[2] if coord[2]
|
21
|
+
end
|
22
|
+
if l.size > 0
|
23
|
+
ls = GEOM_FACTORY.create_line_string l.to_java(com.vividsolutions.jts.geom.Coordinate)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
else
|
28
|
+
l = []
|
29
|
+
coords.each do |coord|
|
30
|
+
l << Coordinate.new(coord[0], coord[1])
|
31
|
+
l.last.z = coord[2] if coord[2]
|
32
|
+
end
|
33
|
+
if l.size > 0
|
34
|
+
ls = GEOM_FACTORY.create_line_string l.to_java(com.vividsolutions.jts.geom.Coordinate)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
if ls
|
39
|
+
super(ls.coordinate_sequence, GEOM_FACTORY)
|
40
|
+
else
|
41
|
+
raise 'LineString could not be created. Check inputs.'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def buffer(dist)
|
46
|
+
Polygon.new super
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_wkt
|
50
|
+
GeoScript::IO::Geom.write_wkt self
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_wkb
|
54
|
+
GeoScript::IO::Geom.write_wkb self
|
55
|
+
end
|
56
|
+
|
57
|
+
def to_json
|
58
|
+
GeoScript::IO::Geom.write_json self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
JTSMultiLineString = com.vividsolutions.jts.geom.MultiLineString
|
4
|
+
|
5
|
+
class MultiLineString < JTSMultiLineString
|
6
|
+
include GeoScript::Geom
|
7
|
+
|
8
|
+
attr_accessor :bounds
|
9
|
+
|
10
|
+
def initialize(*line_strings)
|
11
|
+
strings = []
|
12
|
+
|
13
|
+
if line_strings.first.kind_of? JTSMultiLineString
|
14
|
+
multi_line_string_geom = line_strings.first
|
15
|
+
|
16
|
+
for i in (0...multi_line_string_geom.num_geometries)
|
17
|
+
strings << multi_line_string_geom.get_geometry_n(i)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
line_strings.each do |line_string|
|
21
|
+
if line_string.kind_of? LineString
|
22
|
+
strings << line_string
|
23
|
+
else
|
24
|
+
strings << LineString.new(*line_string)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
super(strings.to_java(com.vividsolutions.jts.geom.LineString), GEOM_FACTORY)
|
30
|
+
end
|
31
|
+
|
32
|
+
def buffer(dist)
|
33
|
+
Polygon.new super
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_wkt
|
37
|
+
GeoScript::IO::Geom.write_wkt self
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_wkb
|
41
|
+
GeoScript::IO::Geom.write_wkb self
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_json
|
45
|
+
GeoScript::IO::Geom.write_json self
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
JTSMultiPoint = com.vividsolutions.jts.geom.MultiPoint
|
4
|
+
|
5
|
+
class MultiPoint < JTSMultiPoint
|
6
|
+
include GeoScript::Geom
|
7
|
+
|
8
|
+
attr_accessor :bounds
|
9
|
+
|
10
|
+
def initialize(*points)
|
11
|
+
feature_points = []
|
12
|
+
|
13
|
+
if points.first.kind_of? JTSMultiPoint
|
14
|
+
mp_geom = points.first
|
15
|
+
|
16
|
+
for i in (0...mp_geom.num_geometries)
|
17
|
+
feature_points << mp_geom.get_geometry_n(i)
|
18
|
+
end
|
19
|
+
else
|
20
|
+
points.each do |point|
|
21
|
+
if point.kind_of? Point
|
22
|
+
feature_points << point
|
23
|
+
else
|
24
|
+
feature_points << Point.new(*point)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
super(feature_points.to_java(com.vividsolutions.jts.geom.Point), GEOM_FACTORY)
|
30
|
+
end
|
31
|
+
|
32
|
+
def buffer(dist)
|
33
|
+
Polygon.new super
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_wkt
|
37
|
+
GeoScript::IO::Geom.write_wkt self
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_wkb
|
41
|
+
GeoScript::IO::Geom.write_wkb self
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_json
|
45
|
+
GeoScript::IO::Geom.write_json self
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
JTSMultiPolygon = com.vividsolutions.jts.geom.MultiPolygon
|
4
|
+
|
5
|
+
class MultiPolygon < JTSMultiPolygon
|
6
|
+
include GeoScript::Geom
|
7
|
+
|
8
|
+
attr_accessor :bounds
|
9
|
+
|
10
|
+
def initialize(*polygons)
|
11
|
+
polys = []
|
12
|
+
|
13
|
+
if polygons.first.kind_of? JTSMultiPolygon
|
14
|
+
multi_polygon = polygons.first
|
15
|
+
for i in range(0...multi_polygon.num_geometries)
|
16
|
+
polys << multi_polygon.get_geometry_n(i)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
polygons.each do |polygon|
|
20
|
+
if polygon.kind_of? Java::ComVividsolutionsJtsGeom::Polygon
|
21
|
+
polys << polygon
|
22
|
+
else
|
23
|
+
polys << Polygon.new(*polygon)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
super(polys.to_java(com.vividsolutions.jts.geom.Polygon), GEOM_FACTORY)
|
28
|
+
end
|
29
|
+
|
30
|
+
def buffer(dist)
|
31
|
+
Polygon.new super
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_wkt
|
35
|
+
GeoScript::IO::Geom.write_wkt self
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_wkb
|
39
|
+
GeoScript::IO::Geom.write_wkb self
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_json
|
43
|
+
GeoScript::IO::Geom.write_json self
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
java_import com.vividsolutions.jts.geom.Coordinate
|
4
|
+
JTSPoint = com.vividsolutions.jts.geom.Point
|
5
|
+
|
6
|
+
class Point < JTSPoint
|
7
|
+
include GeoScript::Geom
|
8
|
+
|
9
|
+
attr_accessor :bounds
|
10
|
+
|
11
|
+
def initialize(*coords)
|
12
|
+
if coords.first.kind_of? JTSPoint
|
13
|
+
p = coords.first
|
14
|
+
else
|
15
|
+
if coords.empty?
|
16
|
+
c = Coordinate.new 0, 0
|
17
|
+
else
|
18
|
+
c = Coordinate.new coords[0], coords[1]
|
19
|
+
c.z = coords[2] if coords[2]
|
20
|
+
end
|
21
|
+
|
22
|
+
p = GEOM_FACTORY.create_point c
|
23
|
+
end
|
24
|
+
super p.coordinate_sequence, GEOM_FACTORY
|
25
|
+
end
|
26
|
+
|
27
|
+
def buffer(dist)
|
28
|
+
Polygon.new super
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_wkt
|
32
|
+
GeoScript::IO::Geom.write_wkt self
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_wkb
|
36
|
+
GeoScript::IO::Geom.write_wkb self
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_json
|
40
|
+
GeoScript::IO::Geom.write_json self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module GeoScript
|
2
|
+
module Geom
|
3
|
+
JTSPolygon = com.vividsolutions.jts.geom.Polygon
|
4
|
+
|
5
|
+
class Polygon < JTSPolygon
|
6
|
+
include GeoScript::Geom
|
7
|
+
|
8
|
+
attr_accessor :bounds
|
9
|
+
|
10
|
+
def initialize(*rings)
|
11
|
+
if rings.first.kind_of? JTSPolygon
|
12
|
+
interior_rings = []
|
13
|
+
num_rings = rings.first.num_interior_ring
|
14
|
+
for i in (0...num_rings)
|
15
|
+
interior_rings << rings.first.get_interior_ring_n(i)
|
16
|
+
end
|
17
|
+
shell = rings.first.exterior_ring
|
18
|
+
holes = interior_rings.to_java(com.vividsolutions.jts.geom.LinearRing)
|
19
|
+
else
|
20
|
+
linear_rings = []
|
21
|
+
rings.each do |ring|
|
22
|
+
if ring.kind_of? LinearRing
|
23
|
+
linear_rings << ring
|
24
|
+
else
|
25
|
+
linear_rings << LinearRing.new(*ring)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
shell = linear_rings.first
|
30
|
+
holes = linear_rings[1..linear_rings.size].to_java(com.vividsolutions.jts.geom.LinearRing)
|
31
|
+
end
|
32
|
+
super(shell, holes, GEOM_FACTORY)
|
33
|
+
end
|
34
|
+
|
35
|
+
def buffer(dist)
|
36
|
+
Polygon.new super
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_wkt
|
40
|
+
GeoScript::IO::Geom.write_wkt self
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_wkb
|
44
|
+
GeoScript::IO::Geom.write_wkb self
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_json
|
48
|
+
GeoScript::IO::Geom.write_json self
|
49
|
+
end
|
50
|
+
|
51
|
+
def bounds
|
52
|
+
Bounds.new self.get_envelope_internal
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/geoscript/io.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
java_import org.geotools.geojson.feature.FeatureJSON
|
2
|
+
|
3
|
+
module GeoScript
|
4
|
+
module IO
|
5
|
+
module Feature
|
6
|
+
def self.write_json(feature)
|
7
|
+
FeatureJSON.new.to_string feature
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.read_json(json)
|
11
|
+
GeoScript::Feature.new(FeatureJSON.new.read_feature(json))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
java_import org.geotools.geojson.geom.GeometryJSON
|
2
|
+
|
3
|
+
module GeoScript
|
4
|
+
module IO
|
5
|
+
module Geom
|
6
|
+
def self.write_json(geom)
|
7
|
+
GeometryJSON.new.to_string geom
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.read_json(json)
|
11
|
+
GeometryJSON.new.read json.to_java
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
java_import com.vividsolutions.jts.io.WKBReader
|
2
|
+
java_import com.vividsolutions.jts.io.WKBWriter
|
3
|
+
|
4
|
+
module GeoScript
|
5
|
+
module IO
|
6
|
+
module Geom
|
7
|
+
include GeoScript::Util
|
8
|
+
|
9
|
+
def self.write_wkb(geom)
|
10
|
+
wkb = WKBWriter.new.write geom
|
11
|
+
WKBWriter.bytes_to_hex wkb
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.read_wkb(wkb)
|
15
|
+
if wkb.kind_of? String
|
16
|
+
wkb = WKBReader.hex_to_bytes wkb
|
17
|
+
elsif wkb.kind_of? Array
|
18
|
+
# .to_java(java.lang.Byte) does not seem to work
|
19
|
+
# this is very hacky
|
20
|
+
wkb = WKBWriter.bytes_to_hex wkb
|
21
|
+
wkb = WKBReader.hex_to_bytes wkb
|
22
|
+
end
|
23
|
+
WKBReader.new.read wkb
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
java_import com.vividsolutions.jts.io.WKTReader
|
2
|
+
java_import com.vividsolutions.jts.io.WKTWriter
|
3
|
+
|
4
|
+
module GeoScript
|
5
|
+
module IO
|
6
|
+
module Geom
|
7
|
+
def self.read_wkt(wkt)
|
8
|
+
WKTReader.new.read wkt
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.write_wkt(geom)
|
12
|
+
WKTWriter.new.write geom
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,84 @@
|
|
1
|
+
java_import org.geotools.geometry.jts.GeometryCoordinateSequenceTransformer
|
2
|
+
java_import org.geotools.referencing.CRS
|
3
|
+
java_import org.opengis.referencing.crs.CoordinateReferenceSystem
|
4
|
+
java_import org.geotools.factory.Hints
|
5
|
+
|
6
|
+
module GeoScript
|
7
|
+
class Projection
|
8
|
+
attr_accessor :crs
|
9
|
+
|
10
|
+
def initialize(proj)
|
11
|
+
if proj.kind_of? CoordinateReferenceSystem
|
12
|
+
@crs = proj
|
13
|
+
elsif proj.kind_of? GeoScript::Projection
|
14
|
+
@crs = proj.crs
|
15
|
+
elsif proj.kind_of? String
|
16
|
+
@crs = CRS.decode proj
|
17
|
+
|
18
|
+
if @crs.nil?
|
19
|
+
@crs = CRS.parseWKT proj
|
20
|
+
|
21
|
+
if @crs.nil?
|
22
|
+
raise "Unable to determine projection from #{proj}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_id
|
29
|
+
CRS.lookup_identifier(@crs, true).to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_wkt
|
33
|
+
@crs.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_bounds
|
37
|
+
env = CRS.get_envelope @crs
|
38
|
+
if env
|
39
|
+
min = env.get_minimum
|
40
|
+
max = env.get_maximum
|
41
|
+
GeoScript::Geom::Bounds.create min.first, min.last, max.first, max.last
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_geobounds
|
46
|
+
box = CRS.get_geographic_bounding_box @crs
|
47
|
+
if box
|
48
|
+
GeoScript::Geom::Bounds.create box.west_bound_longitude, box.south_bound_latitude, box.east_bound_longitude, box.north_bound_latitude, 'epsg:4326'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def transform(obj, dest)
|
53
|
+
from_crs = @crs
|
54
|
+
to_crs = Projection.new(dest).crs
|
55
|
+
transform = CRS.find_math_transform(from_crs, to_crs)
|
56
|
+
|
57
|
+
if obj.kind_of? Array
|
58
|
+
else
|
59
|
+
geometry_transform = GeometryCoordinateSequenceTransformer.new
|
60
|
+
geometry_transform.math_transform = transform
|
61
|
+
new_geom = geometry_transform.transform obj
|
62
|
+
geom_type = new_geom.class.to_s.split('::').last
|
63
|
+
klass = ['GeoScript', 'Geom', geom_type].inject(Module) {|acc, val| acc.const_get(val)}
|
64
|
+
klass.new(new_geom)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.reproject(obj, from_crs, to_crs)
|
69
|
+
Projection.new(from_crs).transform obj, to_crs
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.projections
|
73
|
+
CRS.get_supported_codes('epsg').each do |code|
|
74
|
+
begin
|
75
|
+
Projection.new "epsg:#{code}"
|
76
|
+
rescue Java::OrgOpengisReferencing::NoSuchAuthorityCodeException
|
77
|
+
p "code: #{code} -> no such authority"
|
78
|
+
rescue Java::OrgOpengisReferencing::FactoryException => e
|
79
|
+
p "exception: #{e}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'util/bytes.rb'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
JInt = java.lang.Integer
|
2
|
+
|
3
|
+
module GeoScript
|
4
|
+
module Util
|
5
|
+
class Bytes
|
6
|
+
def self.decode(str, base)
|
7
|
+
str.to_java_bytes
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.encode(bytes, base)
|
11
|
+
bytes.from_java_bytes
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.byte_to_string(byte, base)
|
15
|
+
n = Math.log(256, base).ceil
|
16
|
+
s = byte < 0 ? java.lang.Integer.to_string(((b.abs ^ 0xff) + 0x01), base) : java.lang.Integer.to_string(b, base)
|
17
|
+
"%0#{n}d" % s
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.string_to_byte(string, base)
|
21
|
+
int = string.to_i(base)
|
22
|
+
if int > 128
|
23
|
+
-1 * ((int ^ 0xff) + 0x01)
|
24
|
+
else
|
25
|
+
int
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
java_import org.geotools.data.DataStore
|
2
|
+
|
3
|
+
module GeoScript
|
4
|
+
class Workspace
|
5
|
+
DS_TYPES = {
|
6
|
+
'memory' => GeoScript::DataStore::Memory
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_accessor :store
|
10
|
+
|
11
|
+
def initialize(store = nil, params = nil)
|
12
|
+
unless store
|
13
|
+
@store = GeoScript::DataStore::Memory.new(params)
|
14
|
+
else
|
15
|
+
if DS_TYPES[store]
|
16
|
+
@store = DS_TYPES[store].new(params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: geoscript
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0.pre
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Scooter Wadsworth
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: geotools-jars
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '8.0'
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '8.0'
|
25
|
+
prerelease: false
|
26
|
+
type: :runtime
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
prerelease: false
|
40
|
+
type: :development
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
prerelease: false
|
54
|
+
type: :development
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
prerelease: false
|
68
|
+
type: :development
|
69
|
+
description: GeoScript for JRuby - makes using GeoTools from JRuby easier and more fun.
|
70
|
+
email:
|
71
|
+
- scooterwadsworth@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- lib/geoscript.rb
|
78
|
+
- lib/geoscript/datastore.rb
|
79
|
+
- lib/geoscript/feature.rb
|
80
|
+
- lib/geoscript/geom.rb
|
81
|
+
- lib/geoscript/io.rb
|
82
|
+
- lib/geoscript/projection.rb
|
83
|
+
- lib/geoscript/util.rb
|
84
|
+
- lib/geoscript/version.rb
|
85
|
+
- lib/geoscript/workspace.rb
|
86
|
+
- lib/geoscript/datastore/memory.rb
|
87
|
+
- lib/geoscript/feature/feature.rb
|
88
|
+
- lib/geoscript/feature/field.rb
|
89
|
+
- lib/geoscript/feature/schema.rb
|
90
|
+
- lib/geoscript/geom/bounds.rb
|
91
|
+
- lib/geoscript/geom/geom.rb
|
92
|
+
- lib/geoscript/geom/linearring.rb
|
93
|
+
- lib/geoscript/geom/linestring.rb
|
94
|
+
- lib/geoscript/geom/multilinestring.rb
|
95
|
+
- lib/geoscript/geom/multipoint.rb
|
96
|
+
- lib/geoscript/geom/multipolygon.rb
|
97
|
+
- lib/geoscript/geom/point.rb
|
98
|
+
- lib/geoscript/geom/polygon.rb
|
99
|
+
- lib/geoscript/io/feature/json.rb
|
100
|
+
- lib/geoscript/io/geom/json.rb
|
101
|
+
- lib/geoscript/io/geom/wkb.rb
|
102
|
+
- lib/geoscript/io/geom/wkt.rb
|
103
|
+
- lib/geoscript/layer/layer.rb
|
104
|
+
- lib/geoscript/layer/shapefile.rb
|
105
|
+
- lib/geoscript/util/bytes.rb
|
106
|
+
homepage: https://github.com/scooterw/geoscript-ruby
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>'
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 1.3.1
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.1.9
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: GeoScript is a library for making use of GeoTools from JRuby easier and more fun.
|
130
|
+
test_files: []
|