jsontableschema 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +13 -0
  5. data/CHANGELOG.md +17 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +233 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/etc/schemas/geojson.json +209 -0
  14. data/etc/schemas/json-table-schema.json +102 -0
  15. data/jsontableschema.gemspec +32 -0
  16. data/lib/jsontableschema.rb +41 -0
  17. data/lib/jsontableschema/constraints/constraints.rb +76 -0
  18. data/lib/jsontableschema/constraints/enum.rb +14 -0
  19. data/lib/jsontableschema/constraints/max_length.rb +15 -0
  20. data/lib/jsontableschema/constraints/maximum.rb +14 -0
  21. data/lib/jsontableschema/constraints/min_length.rb +15 -0
  22. data/lib/jsontableschema/constraints/minimum.rb +14 -0
  23. data/lib/jsontableschema/constraints/pattern.rb +14 -0
  24. data/lib/jsontableschema/constraints/required.rb +32 -0
  25. data/lib/jsontableschema/data.rb +57 -0
  26. data/lib/jsontableschema/exceptions.rb +28 -0
  27. data/lib/jsontableschema/helpers.rb +48 -0
  28. data/lib/jsontableschema/infer.rb +142 -0
  29. data/lib/jsontableschema/model.rb +73 -0
  30. data/lib/jsontableschema/schema.rb +35 -0
  31. data/lib/jsontableschema/table.rb +50 -0
  32. data/lib/jsontableschema/types/any.rb +23 -0
  33. data/lib/jsontableschema/types/array.rb +37 -0
  34. data/lib/jsontableschema/types/base.rb +54 -0
  35. data/lib/jsontableschema/types/boolean.rb +35 -0
  36. data/lib/jsontableschema/types/date.rb +56 -0
  37. data/lib/jsontableschema/types/datetime.rb +63 -0
  38. data/lib/jsontableschema/types/geojson.rb +38 -0
  39. data/lib/jsontableschema/types/geopoint.rb +56 -0
  40. data/lib/jsontableschema/types/integer.rb +35 -0
  41. data/lib/jsontableschema/types/null.rb +37 -0
  42. data/lib/jsontableschema/types/number.rb +60 -0
  43. data/lib/jsontableschema/types/object.rb +37 -0
  44. data/lib/jsontableschema/types/string.rb +64 -0
  45. data/lib/jsontableschema/types/time.rb +55 -0
  46. data/lib/jsontableschema/validate.rb +54 -0
  47. data/lib/jsontableschema/version.rb +3 -0
  48. metadata +230 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1cf851281ccf698eb2f50ce29916e8b2632e841a
4
+ data.tar.gz: 253a669fbee44572cb3af3e9ed68592f444f08a1
5
+ SHA512:
6
+ metadata.gz: 3215fdb1aa97951f83dc9f69484fc054befe9c9f0e9c8441692c011659fb5035bb8d41c42cd01863d8d474fd6f899caa48513d264872443e77961dd66f696635
7
+ data.tar.gz: 2cc35932e7a71d369e75c5818e979d2a6db0c0ad26217f856b98f663dba9bafc2f8fbb2a8516324dbd6209764bb5dce6a0f0e7a348077e31cf6c8c146b0fbee7
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,13 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.11.2
6
+ deploy:
7
+ provider: rubygems
8
+ api_key:
9
+ secure: wH1kuoIanHWL0ohGKyFtcXDusgR5T5qD2QnaQS9vjIG6a//ClpYpDZ3iSxHG9CkkrbaKJDVhcGsKJOECcQRnLQ2/g9PC84c4tMzfgp3q5w7FdWfxe86diS3sXN4gw6+Xb+KhueOhO6RaghG1BJPBd2kj2G8uw6f/KT+8qOMaS+IRpuW8FkO7x8CZvUSLbzai21kYaneDglb5j/AY/sF2s+jGO/3VPmMjaJCJ7pU84Wqby6PixPMiP2EKVyhx1fD8m8CcPTAfPhiwxq1AkxxFJIkty730ECzwDVfrF9Ph5dcoR57jPliCSctNVREele2Q4ItBxi5Da5U3PiqHYu6AZR4pARoPMaO8m/ZwfvRftzwNDd7jnnkxLgWRRKDofU6wuxB+Jg8V7CbThTXyPFgn8RXYsL4tshOCCmicT8fbKO/f+S21gSQtQI1fZc6dc0WZqRCCY50NLnRH0eAJzXKfQxQ7iuKsF/nfGmZiAmVCZRKWVlGjQ+v5q5erXr+nS9prWotg/CrWiGhPkhHuEj8izBXxclzAuQHGE0H+IRwZFT/7Ym1KUKKhMx5mFRpf4EqLQ+mzIe8+4Ogn8YQclVP/3j14FtGCFiRegqy8SSfsKxTunF6i76Nbdj8v5Pkb0NZzvRjaBkbhvYKIAmLK1GaYC0lQS7gaqXqCRS64XjvAOGQ=
10
+ gem: jsontableschema
11
+ true:
12
+ tags: true
13
+ repo: theodi/jsontableschema.rb
@@ -0,0 +1,17 @@
1
+ # Change Log
2
+
3
+ ## [v0.1.0](https://github.com/theodi/jsontableschema.rb/tree/v0.1.0) (2016-09-19)
4
+ **Merged pull requests:**
5
+
6
+ - Deploy stuff [\#8](https://github.com/theodi/jsontableschema.rb/pull/8) ([pezholio](https://github.com/pezholio))
7
+ - Infer schema [\#7](https://github.com/theodi/jsontableschema.rb/pull/7) ([pezholio](https://github.com/pezholio))
8
+ - Work with a table [\#6](https://github.com/theodi/jsontableschema.rb/pull/6) ([pezholio](https://github.com/pezholio))
9
+ - Data conversion [\#5](https://github.com/theodi/jsontableschema.rb/pull/5) ([pezholio](https://github.com/pezholio))
10
+ - Add constraints [\#4](https://github.com/theodi/jsontableschema.rb/pull/4) ([pezholio](https://github.com/pezholio))
11
+ - Cast and validate types [\#3](https://github.com/theodi/jsontableschema.rb/pull/3) ([pezholio](https://github.com/pezholio))
12
+ - Schema model [\#2](https://github.com/theodi/jsontableschema.rb/pull/2) ([pezholio](https://github.com/pezholio))
13
+ - Validate a schema [\#1](https://github.com/theodi/jsontableschema.rb/pull/1) ([pezholio](https://github.com/pezholio))
14
+
15
+
16
+
17
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at pezholio@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jsontableschema.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 pezholio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,233 @@
1
+ [![Build Status](http://img.shields.io/travis/theodi/jsontableschema.rb.svg?style=flat-square)](https://travis-ci.org/theodi/jsontableschema.rb)
2
+ [![Dependency Status](http://img.shields.io/gemnasium/theodi/jsontableschema.rb.svg?style=flat-square)](https://gemnasium.com/theodi/jsontableschema.rb)
3
+ [![Coverage Status](https://coveralls.io/repos/github/theodi/jsontableschema.rb/badge.svg)](https://coveralls.io/github/theodi/jsontableschema.rb)
4
+ [![Code Climate](http://img.shields.io/codeclimate/github/theodi/jsontableschema.rb.svg?style=flat-square)](https://codeclimate.com/github/theodi/jsontableschema.rb)
5
+ [![Gem Version](http://img.shields.io/gem/v/jsontableschema.svg?style=flat-square)](https://rubygems.org/gems/jsontableschema)
6
+ [![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://theodi.mit-license.org)
7
+
8
+ # JSON Table Schema
9
+
10
+ A utility library for working with [JSON Table Schema](http://dataprotocols.org/json-table-schema/) in Ruby.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'jsontableschema'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install jsontableschema
27
+
28
+ ## Usage
29
+
30
+ ### Parse a CSV
31
+
32
+ Validate and cast data from a CSV as described by a schema.
33
+
34
+ ```ruby
35
+ schema = {
36
+ "fields": [
37
+ {
38
+ "name" => "id",
39
+ "title" => "Identifier",
40
+ "type" => "integer"
41
+ },
42
+ {
43
+ "name" => "title",
44
+ "title" => "Title",
45
+ "type" => "string"
46
+ }
47
+ ]
48
+ } # Can also be a URL or a path
49
+
50
+ csv = 'https://github.com/theodi/jsontableschema.rb/raw/master/spec/fixtures/simple_data.csv' # Can also be a url or array of arrays
51
+
52
+ table = JsonTableSchema::Table.new(csv, schema)
53
+ table.rows
54
+ #=> [[1,'foo'],[2,'bar'],[3,'baz']]
55
+ ```
56
+
57
+ ### Infer a schema
58
+
59
+ If you don't have a schema for a CSV, and want to generate one, you can infer a schema like so:
60
+
61
+ ```ruby
62
+ csv = 'https://github.com/theodi/jsontableschema.rb/raw/master/spec/fixtures/simple_data.csv' # Can also be a url or array of arrays
63
+
64
+ table = JsonTableSchema::Table.infer_schema(csv)
65
+ table.schema
66
+ #=> {"fields"=>[{"name"=>"id", "title"=>"", "description"=>"", "type"=>"string", "format"=>"default"}, {"name"=>"title", "title"=>"", "description"=>"", "type"=>"string", "format"=>"default"}]}
67
+ ```
68
+
69
+ ### Validate a schema
70
+
71
+ To validate that a schema meets the JSON Table Schema spec, you can pass a schema to the initializer like so:
72
+
73
+ ```ruby
74
+ schema_hash = {
75
+ "fields" => [
76
+ {
77
+ "name" => "id"
78
+ },
79
+ {
80
+ "name" => "height"
81
+ }
82
+ ]
83
+ }
84
+
85
+ schema = JsonTableSchema::Schema.new(schema_hash)
86
+ schema.valid?
87
+ #=> true
88
+ ```
89
+
90
+ You can also pass a file path or URL to the initializer:
91
+
92
+ ```ruby
93
+ schema = JsonTableSchema::Schema.new('http://example.org/schema.json')
94
+ schema.valid?
95
+ #=> true
96
+ ```
97
+
98
+ If the schema is invalid, you can access the errors via the `messages` attribute
99
+
100
+ ```ruby
101
+ schema_hash = {
102
+ "fields" => [
103
+ {
104
+ "name"=>"id",
105
+ "title"=>"Identifier",
106
+ "type"=>"integer"
107
+ },
108
+ {
109
+ "name"=>"title",
110
+ "title"=>"Title",
111
+ "type"=>"string"
112
+ }
113
+ ],
114
+ "primaryKey"=>"identifier"
115
+ }
116
+
117
+ schema.valid?
118
+ #=> false
119
+ schema.messages
120
+ #=> ["The JSON Table Schema primaryKey value `identifier` is not found in any of the schema's field names"]
121
+ ```
122
+
123
+ ## Schema Model
124
+
125
+ You can also access the schema via a Ruby model, with some useful methods for interaction:
126
+
127
+ ```ruby
128
+ schema_hash = {
129
+ "fields" => [
130
+ {
131
+ "name" => "id",
132
+ "type" => "string",
133
+ "constraints" => {
134
+ "required" => true,
135
+ }
136
+ },
137
+ {
138
+ "name" => "height",
139
+ "type" => "number"
140
+ }
141
+ ],
142
+ "primaryKey" => "id",
143
+ "foreignKeys" => [
144
+ {
145
+ "fields" => "state",
146
+ "reference" => {
147
+ "datapackage" => "http://data.okfn.org/data/mydatapackage/",
148
+ "resource" => "the-resource",
149
+ "fields" => "state_id"
150
+ }
151
+ }
152
+ ]
153
+ }
154
+
155
+ schema = JsonTableSchema::Schema.new(schema_hash)
156
+
157
+ schema.headers
158
+ #=> ["id", "height"]
159
+ schema.required_headers
160
+ #=> ["id"]
161
+ schema.fields
162
+ #=> [{"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}, {"name"=>"height", "type"=>"number", "format"=>"default"}]
163
+ schema.primary_keys
164
+ #=> ["id"]
165
+ schema.foreign_keys
166
+ #=> [{"fields" => "state", "reference" => { "datapackage" => "http://data.okfn.org/data/mydatapackage/", "resource" => "the-resource", "fields" => "state_id" } } ]
167
+ schema.cast('height', '10')
168
+ #=> 10.0
169
+ schema.get_field('id')
170
+ #=> {"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}
171
+ schema.has_field?('foo')
172
+ #=> false
173
+ schema.get_type('id')
174
+ #=> 'string'
175
+ schema.get_fields_by_type('string')
176
+ #=> [{"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}, {"name"=>"height", "type"=>"string", "format"=>"default"}]
177
+ schema.get_constraints('id')
178
+ #=> {"required" => true}
179
+ schema.convert_row(['string', '10.0'])
180
+ #=> ['string', 10.0]
181
+ schema.convert([['foo', '12.0'],['bar', '10.0']])
182
+ #=> [['foo', 12.0],['bar', 10.0]]
183
+ ```
184
+
185
+ When converting a row (using `convert_row`), or a number of rows (using `convert`), by default the converter will fail on the first error it finds. If you pass `false` as the second argument, the errors will be collected into a `errors` attribute for you to review later. For example:
186
+
187
+ ```ruby
188
+ schema_hash = {
189
+ "fields" => [
190
+ {
191
+ "name" => "id",
192
+ "type" => "string",
193
+ "constraints" => {
194
+ "required" => true,
195
+ }
196
+ },
197
+ {
198
+ "name" => "height",
199
+ "type" => "number"
200
+ }
201
+ ]
202
+ }
203
+
204
+ schema = JsonTableSchema::Schema.new(schema_hash)
205
+
206
+ rows = [
207
+ ['foo', 'notanumber'],
208
+ ['bar', 'notanumber'],
209
+ ['wrong column count']
210
+ ]
211
+
212
+ schema.convert(rows)
213
+ #=> JsonTableSchema::InvalidCast: notanumber is not a number
214
+ schema.convert(rows, false)
215
+ #=> JsonTableSchema::MultipleInvalid
216
+ schema.errors
217
+ #=> [#<JsonTableSchema::InvalidCast: notanumber is not a number>, #<JsonTableSchema::InvalidCast: notanumber is not a number>, #<JsonTableSchema::ConversionError: The number of items to convert (1) does not match the number of headers in the schema (2)>]
218
+ ```
219
+
220
+ ## Development
221
+
222
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
223
+
224
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
225
+
226
+ ## Contributing
227
+
228
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/jsontableschema. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
229
+
230
+
231
+ ## License
232
+
233
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jsontableschema"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,209 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "id": "https://raw.githubusercontent.com/fge/sample-json-schemas/master/geojson/geojson.json#",
4
+ "title": "Geo JSON object",
5
+ "description": "Schema for a Geo JSON object",
6
+ "type": "object",
7
+ "required": [ "type" ],
8
+ "properties": {
9
+ "crs": { "$ref": "#/definitions/crs" },
10
+ "bbox": { "$ref": "#/definitions/bbox" }
11
+ },
12
+ "oneOf": [
13
+ { "$ref": "#/definitions/geometry" },
14
+ { "$ref": "#/definitions/geometryCollection" },
15
+ { "$ref": "#/definitions/feature" },
16
+ { "$ref": "#/definitions/featureCollection" }
17
+ ],
18
+ "definitions": {
19
+ "geometryCollection": {
20
+ "title": "GeometryCollection",
21
+ "description": "A collection of geometry objects",
22
+ "required": [ "geometries" ],
23
+ "properties": {
24
+ "type": { "enum": [ "GeometryCollection" ] },
25
+ "geometries": {
26
+ "type": "array",
27
+ "items": { "$ref": "#/definitions/geometry" }
28
+ }
29
+ }
30
+ },
31
+ "feature": {
32
+ "title": "Feature",
33
+ "description": "A Geo JSON feature object",
34
+ "required": [ "geometry", "properties" ],
35
+ "properties": {
36
+ "type": { "enum": [ "Feature" ] },
37
+ "geometry": {
38
+ "oneOf": [
39
+ { "type": "null" },
40
+ { "$ref": "#/definitions/geometry" }
41
+ ]
42
+ },
43
+ "properties": { "type": [ "object", "null" ] },
44
+ "id": { "FIXME": "may be there, type not known (string? number?)" }
45
+ }
46
+ },
47
+ "featureCollection": {
48
+ "title": "FeatureCollection",
49
+ "description": "A Geo JSON feature collection",
50
+ "required": [ "features" ],
51
+ "properties": {
52
+ "type": { "enum": [ "FeatureCollection" ] },
53
+ "features": {
54
+ "type": "array",
55
+ "items": { "$ref": "#/definitions/feature" }
56
+ }
57
+ }
58
+ },
59
+ "geometry": {
60
+ "title": "geometry",
61
+ "description": "One geometry as defined by GeoJSON",
62
+ "type": "object",
63
+ "required": [ "type", "coordinates" ],
64
+ "oneOf": [
65
+ {
66
+ "title": "Point",
67
+ "properties": {
68
+ "type": { "enum": [ "Point" ] },
69
+ "coordinates": { "$ref": "#/definitions/geometry/definitions/position" }
70
+ }
71
+ },
72
+ {
73
+ "title": "MultiPoint",
74
+ "properties": {
75
+ "type": { "enum": [ "MultiPoint" ] },
76
+ "coordinates": { "$ref": "#/definitions/geometry/definitions/positionArray" }
77
+ }
78
+ },
79
+ {
80
+ "title": "LineString",
81
+ "properties": {
82
+ "type": { "enum": [ "LineString" ] },
83
+ "coordinates": { "$ref": "#/definitions/geometry/definitions/lineString" }
84
+ }
85
+ },
86
+ {
87
+ "title": "MultiLineString",
88
+ "properties": {
89
+ "type": { "enum": [ "MultiLineString" ] },
90
+ "coordinates": {
91
+ "type": "array",
92
+ "items": { "$ref": "#/definitions/geometry/definitions/lineString" }
93
+ }
94
+ }
95
+ },
96
+ {
97
+ "title": "Polygon",
98
+ "properties": {
99
+ "type": { "enum": [ "Polygon" ] },
100
+ "coordinates": { "$ref": "#/definitions/geometry/definitions/polygon" }
101
+ }
102
+ },
103
+ {
104
+ "title": "MultiPolygon",
105
+ "properties": {
106
+ "type": { "enum": [ "MultiPolygon" ] },
107
+ "coordinates": {
108
+ "type": "array",
109
+ "items": { "$ref": "#/definitions/geometry/definitions/polygon" }
110
+ }
111
+ }
112
+ }
113
+ ],
114
+ "definitions": {
115
+ "position": {
116
+ "description": "A single position",
117
+ "type": "array",
118
+ "minItems": 2,
119
+ "items": [ { "type": "number" }, { "type": "number" } ],
120
+ "additionalItems": false
121
+ },
122
+ "positionArray": {
123
+ "description": "An array of positions",
124
+ "type": "array",
125
+ "items": { "$ref": "#/definitions/geometry/definitions/position" }
126
+ },
127
+ "lineString": {
128
+ "description": "An array of two or more positions",
129
+ "allOf": [
130
+ { "$ref": "#/definitions/geometry/definitions/positionArray" },
131
+ { "minItems": 2 }
132
+ ]
133
+ },
134
+ "linearRing": {
135
+ "description": "An array of four positions where the first equals the last",
136
+ "allOf": [
137
+ { "$ref": "#/definitions/geometry/definitions/positionArray" },
138
+ { "minItems": 4 }
139
+ ]
140
+ },
141
+ "polygon": {
142
+ "description": "An array of linear rings",
143
+ "type": "array",
144
+ "items": { "$ref": "#/definitions/geometry/definitions/linearRing" }
145
+ }
146
+ }
147
+ },
148
+ "crs": {
149
+ "title": "crs",
150
+ "description": "a Coordinate Reference System object",
151
+ "type": [ "object", "null" ],
152
+ "required": [ "type", "properties" ],
153
+ "properties": {
154
+ "type": { "type": "string" },
155
+ "properties": { "type": "object" }
156
+ },
157
+ "additionalProperties": false,
158
+ "oneOf": [
159
+ { "$ref": "#/definitions/crs/definitions/namedCrs" },
160
+ { "$ref": "#/definitions/crs/definitions/linkedCrs" }
161
+ ],
162
+ "definitions": {
163
+ "namedCrs": {
164
+ "properties": {
165
+ "type": { "enum": [ "name" ] },
166
+ "properties": {
167
+ "required": [ "name" ],
168
+ "additionalProperties": false,
169
+ "properties": {
170
+ "name": {
171
+ "type": "string",
172
+ "FIXME": "semantic validation necessary"
173
+ }
174
+ }
175
+ }
176
+ }
177
+ },
178
+ "linkedObject": {
179
+ "type": "object",
180
+ "required": [ "href" ],
181
+ "properties": {
182
+ "href": {
183
+ "type": "string",
184
+ "format": "uri",
185
+ "FIXME": "spec says \"dereferenceable\", cannot enforce that"
186
+ },
187
+ "type": {
188
+ "type": "string",
189
+ "description": "Suggested values: proj4, ogjwkt, esriwkt"
190
+ }
191
+ }
192
+ },
193
+ "linkedCrs": {
194
+ "properties": {
195
+ "type": { "enum": [ "link" ] },
196
+ "properties": { "$ref": "#/definitions/crs/definitions/linkedObject" }
197
+ }
198
+ }
199
+ }
200
+ },
201
+ "bbox": {
202
+ "description": "A bounding box as defined by GeoJSON",
203
+ "FIXME": "unenforceable constraint: even number of elements in array",
204
+ "type": "array",
205
+ "items": { "type": "number" }
206
+ }
207
+ }
208
+ }
209
+