geoq 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 370393af98fde48cdbf577971ac0024ef6c36dde
4
- data.tar.gz: 5ece21e4e719a0f601fe5a22560d1423d16189e0
3
+ metadata.gz: 65f99517f2c00af9dadaaebb0648a1b74ef265b5
4
+ data.tar.gz: c68af107652e020f66b2cb670f65bbc677d9f557
5
5
  SHA512:
6
- metadata.gz: ad791e2f4b9adc2f2056aa871e2bcda2c047b8c09ada892d5607c0aaff05bb060e5147ba7e38bd28ba54bd9841fec8197f1dd04fbf0d585d4eaa5975f7bf8fc8
7
- data.tar.gz: aa9d613c4ac743b2c0b32309cbfe60e226a1405f1b3227fe9b0302817a33c71a25c53c72410b0664b03fff90418eb39001c04810a84814fc169ea03218a5fcca
6
+ metadata.gz: a572ce5d989f3d7cbec851fc00a5e70646a357de19b44910cb892fc4bece21c1752abcb3bc3e1642b50c7a582ac0c167e21de97e16cc4d175f5a758c8b129976
7
+ data.tar.gz: 47dbb2f5207155b763ee5832c24dc6257787de7e9e656ece19cbc16d9bc42d0cc6424170452a7b46415a168bfb3e978612179c838d28ca41eb2e95b6fb65e6d5
@@ -1,3 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.2
3
+ - 2.2
4
+ before_install:
5
+ - sudo apt-get update
6
+ - sudo apt-get install -y jq
@@ -1,8 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- geoq (0.0.1)
4
+ geoq (0.0.2)
5
5
  gli (~> 2.17)
6
+ os (~> 1.0)
6
7
  pr_geohash (~> 1.0)
7
8
  rgeo (~> 1.0)
8
9
  rgeo-geojson (~> 2.0)
@@ -53,6 +54,7 @@ GEM
53
54
  ruby-progressbar
54
55
  multi_json (1.13.1)
55
56
  multi_test (0.1.2)
57
+ os (1.0.0)
56
58
  pr_geohash (1.0.0)
57
59
  pry (0.11.3)
58
60
  coderay (~> 1.1.0)
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2018 Horace Williams, http://worace.works
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rubygems/package_task'
4
4
  require 'rdoc/task'
5
5
  require 'cucumber'
6
6
  require 'cucumber/rake/task'
7
+ require "bundler/gem_tasks"
7
8
  Rake::RDocTask.new do |rd|
8
9
  rd.main = "README.rdoc"
9
10
  rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
data/bin/geoq CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gli'
3
+ require 'os'
3
4
  begin # XXX: Remove this begin/rescue before distributing your app
4
5
  require 'geoq'
5
6
  rescue LoadError
@@ -114,7 +115,29 @@ command :gh do |c|
114
115
  end
115
116
  end
116
117
  end
118
+ end
119
+
120
+ GEOJSON_IO_URL_LIMIT = 27000 # crudely derived via experimentation
121
+ map_desc = "
122
+ Plot input on geojson.io.
123
+
124
+ Input will be converted to a GeoJSON FeatureCollection, similarly to 'geoq gj fc'
125
+
126
+ We rely on url-encoding the desired GeoJSON to transfer it to geojson.io, so long inputs
127
+ over 27k characters will be rejected."
117
128
 
129
+ desc map_desc
130
+ command :map do |c|
131
+ c.action do |global_options,options,args|
132
+ entities = Geoq::GeomReader.new(STDIN)
133
+ geojson = Geoq::Commands::GeoJson::FeatureCollection.new(entities).output
134
+ if geojson.length > GEOJSON_IO_URL_LIMIT
135
+ raise ArgumentError.new("'geoq map' failed because provided geojson exceeds geojson.io limit")
136
+ end
137
+ url = "http://geojson.io#data=data:application/json,#{URI.encode(geojson)}"
138
+ open_command = OS.mac? ? 'open' : 'xdg-open'
139
+ exec("#{open_command} #{url}")
140
+ end
118
141
  end
119
142
 
120
143
  pre do |global,command,options,args|
@@ -26,4 +26,5 @@ spec = Gem::Specification.new do |s|
26
26
  s.add_runtime_dependency('rgeo', '~>1.0')
27
27
  s.add_runtime_dependency('rgeo-geojson', '~>2.0')
28
28
  s.add_runtime_dependency('pr_geohash', '~>1.0')
29
+ s.add_runtime_dependency('os', '~>1.0')
29
30
  end
@@ -22,7 +22,7 @@ module Geoq
22
22
 
23
23
  def each(&block)
24
24
  instream.each_line do |l|
25
- block.call(decode(l))
25
+ decode(l).each(&block)
26
26
  end
27
27
  end
28
28
 
@@ -32,13 +32,19 @@ module Geoq
32
32
  p1 = factory.point(lon1, lat1)
33
33
  p2 = factory.point(lon2, lat2)
34
34
  geom = RGeo::Cartesian::BoundingBox.create_from_points(p1, p2).to_geometry
35
- Geohash.new(geom, strip_whitespace(line))
35
+ [Geohash.new(geom, strip_whitespace(line))]
36
36
  elsif geojson?(line)
37
- GeoJson.new(RGeo::GeoJSON.decode(line), line)
37
+ decoded = RGeo::GeoJSON.decode(line)
38
+ case decoded
39
+ when RGeo::GeoJSON::FeatureCollection
40
+ decoded.map { |f| GeoJson.new(f, line) }
41
+ else
42
+ [GeoJson.new(decoded, line)]
43
+ end
38
44
  elsif latlon?(line)
39
- LatLon.new(factory.point(*strip_whitespace(line).split(",").map(&:to_f).reverse), line)
45
+ [LatLon.new(factory.point(*strip_whitespace(line).split(",").map(&:to_f).reverse), line)]
40
46
  else
41
- Wkt.new(wkt.parse(line), line)
47
+ [Wkt.new(wkt.parse(line), line)]
42
48
  end
43
49
  end
44
50
 
@@ -1,3 +1,3 @@
1
1
  module Geoq
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -9,19 +9,33 @@ module Geoq
9
9
  assert_equal "FeatureCollection", json["type"]
10
10
  assert_equal ["type", "features"].sort, json.keys.sort
11
11
  features = json["features"]
12
- assert_equal 5, features.count
12
+ assert_equal 6, features.count
13
13
 
14
+ assert_equal ["Polygon", "Point", "Point", "Point", "Point", "Point"], features.map { |f| f["geometry"]["type"] }
14
15
  # encodes properties
15
- assert_equal [{}, {}, {}, {"a" => "b"}, {}], features.map { |f| f["properties"] }
16
+ assert_equal [{}, {}, {}, {"a" => "b"}, {}, {"a" => "b"}], features.map { |f| f["properties"] }
16
17
  assert_equal Hash.new, features[0]["properties"]
17
18
  assert_equal Hash.new, features[1]["properties"]
18
19
  assert_equal Hash.new, features[2]["properties"]
19
20
  assert_equal({"a" => "b"}, features[3]["properties"])
20
21
 
21
- assert_equal ["Polygon", "Point", "Point", "Point", "Point"], features.map { |f| f["geometry"]["type"] }
22
22
 
23
23
  gh = [[[-119.53125, 33.75], [-118.125, 33.75], [-118.125, 35.15625], [-119.53125, 35.15625], [-119.53125, 33.75]]]
24
- assert_equal [gh, [0.0,1.0], [1.0, 2.0], [3.0, 4.0], [-118.3, 34.52]], features.map { |f| f["geometry"]["coordinates"] }
24
+ assert_equal [gh, [0.0,1.0], [1.0, 2.0], [3.0, 4.0], [-118.3, 34.52], [3.0, 4.0]], features.map { |f| f["geometry"]["coordinates"] }
25
+ end
26
+
27
+ def test_feature_collection_given_feature_collection
28
+ input = TestData.stream([TestData.fc.to_json])
29
+ fc = Geoq::Commands::GeoJson::FeatureCollection.new(input)
30
+ json = JSON.parse(fc.output)
31
+ assert_equal "FeatureCollection", json["type"]
32
+ assert_equal 2, json["features"].count
33
+
34
+ input = TestData.stream([TestData.fc.to_json, "9q"])
35
+ fc = Geoq::Commands::GeoJson::FeatureCollection.new(input)
36
+ json = JSON.parse(fc.output)
37
+ assert_equal "FeatureCollection", json["type"]
38
+ assert_equal 3, json["features"].count
25
39
  end
26
40
 
27
41
  def test_geohash_point
@@ -0,0 +1,21 @@
1
+ require "test_helper"
2
+ require "json"
3
+
4
+ module Geoq
5
+ class CommandsTest < Minitest::Test
6
+ def reader
7
+ i,o = IO.pipe
8
+ o.close
9
+ GeomReader.new(i)
10
+ end
11
+
12
+ def test_decoding_returns_list_of_features
13
+ gh = reader.decode("9q").first
14
+ assert_equal({"type"=>"Polygon", "coordinates"=>[[[-123.75, 33.75], [-112.5, 33.75], [-112.5, 39.375], [-123.75, 39.375], [-123.75, 33.75]]]}, gh.as_geojson)
15
+
16
+ assert_equal 1, reader.decode("9q").count
17
+ assert_equal 1, reader.decode("1,2").count
18
+ assert_equal 2, reader.decode(TestData.fc.to_json).count
19
+ end
20
+ end
21
+ end
@@ -52,5 +52,10 @@ module Geoq
52
52
  point = TestData.stream(["34, -118"]).first
53
53
  assert_equal "9qh1", point.gh_string(4)
54
54
  end
55
+
56
+ def test_gj_feature_collections_read_as_multiple
57
+ reader = TestData.stream([TestData.fc.to_json])
58
+ assert_equal 2, reader.count
59
+ end
55
60
  end
56
61
  end
@@ -8,6 +8,11 @@ require "minitest/spec"
8
8
  Minitest::Reporters.use! Minitest::Reporters::DefaultReporter.new
9
9
 
10
10
  module Geoq::TestData
11
+ def self.fc
12
+ {type: "FeatureCollection", features: [{type: "Feature", properties: {a: "b"}, geometry: {type: "Point", coordinates: [3,4]}},
13
+ {type: "Feature", properties: {a: "b"}, geometry: {type: "Point", coordinates: [5,6]}}]}
14
+ end
15
+
11
16
  def self.stream(strings)
12
17
  r,w = IO.pipe
13
18
  strings.each do |s|
@@ -22,7 +27,8 @@ module Geoq::TestData
22
27
  {type: "Point", coordinates: [0,1]}.to_json,
23
28
  "POINT (1.0 2.0)",
24
29
  {type: "Feature", properties: {a: "b"}, geometry: {type: "Point", coordinates: [3,4]}}.to_json,
25
- "34.52,-118.3"]
30
+ "34.52,-118.3",
31
+ {type: "FeatureCollection", features: [{type: "Feature", properties: {a: "b"}, geometry: {type: "Point", coordinates: [3,4]}}]}.to_json]
26
32
  stream(inputs)
27
33
  end
28
34
  end
@@ -2,22 +2,15 @@ require "test_helper"
2
2
 
3
3
  module Geoq
4
4
  class UsageTest < Minitest::Test
5
- def script_setup
5
+ def self.script_setup
6
6
  File.read("./usage.md").match(/```setup\n(.+)\n```/)[1]
7
7
  end
8
8
 
9
- def examples
9
+ def self.examples
10
10
  File.read("./usage.md").scan(/```example\n(.*?)```\n/m).to_a.flatten.map { |match| match.split("\n=> ") }
11
11
  end
12
12
 
13
- def setup
14
- end
15
-
16
- def test_reads_examples
17
- assert_equal 15, examples.count
18
- end
19
-
20
- def checked_command(command)
13
+ def self.checked_command(command)
21
14
  result = `#{command.gsub("geoq", "bundle exec bin/geoq")}`
22
15
  if $? != 0
23
16
  raise RuntimeError.new("Command #{command} exited with non-zero response code.")
@@ -25,11 +18,15 @@ module Geoq
25
18
  result
26
19
  end
27
20
 
28
- def test_run_examples
29
- examples.each do |command, expected_output|
30
- result = checked_command(command)
21
+ examples.each_with_index do |(command, expected_output), index|
22
+ define_method("test_#{index}") do
23
+ result = self.class.checked_command(command)
31
24
  assert_equal expected_output, result, "Checked example: #{command} failed"
32
25
  end
33
26
  end
27
+
28
+ def test_reads_examples
29
+ assert_equal 16, self.class.examples.count
30
+ end
34
31
  end
35
32
  end
data/usage.md CHANGED
@@ -23,6 +23,13 @@ printf "9q5\n9q4\n" | geoq gj fc
23
23
  => {"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-119.53125,33.75],[-118.125,33.75],[-118.125,35.15625],[-119.53125,35.15625],[-119.53125,33.75]]]}},{"type":"Feature","properties":{},"geometry":{"type":"Polygon","coordinates":[[[-120.9375,33.75],[-119.53125,33.75],[-119.53125,35.15625],[-120.9375,35.15625],[-120.9375,33.75]]]}}]}
24
24
  ```
25
25
 
26
+ Concat multiple GeoJSON Feature Collections into a single collection
27
+
28
+ ```example
29
+ printf "9q5\n{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-119.53125,33.75],[-118.125,33.75],[-118.125,35.15625],[-119.53125,35.15625],[-119.53125,33.75]]]}},{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-120.9375,33.75],[-119.53125,33.75],[-119.53125,35.15625],[-120.9375,35.15625],[-120.9375,33.75]]]}}]}" | geoq gj fc | jq ".features | length"
30
+ => 3
31
+ ```
32
+
26
33
  Converts Geohashes, WKTs, Lat/Lons, and GeoJSON into GeoJSON
27
34
 
28
35
  ```example
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geoq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Horace Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-28 00:00:00.000000000 Z
11
+ date: 2018-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '1.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: os
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.0'
139
153
  description:
140
154
  email: horace@worace.works
141
155
  executables:
@@ -147,6 +161,7 @@ files:
147
161
  - ".travis.yml"
148
162
  - Gemfile
149
163
  - Gemfile.lock
164
+ - LICENSE.txt
150
165
  - README.md
151
166
  - README.rdoc
152
167
  - Rakefile
@@ -161,6 +176,7 @@ files:
161
176
  - lib/geoq/geom_reader.rb
162
177
  - lib/geoq/version.rb
163
178
  - test/commands_test.rb
179
+ - test/entity_test.rb
164
180
  - test/geom_reader_test.rb
165
181
  - test/test_helper.rb
166
182
  - test/usage_test.rb