├── Makefile ├── README.md ├── draft ├── README.md ├── geocodejson.schema.json └── geocodejson.schema.json.checksum ├── scripts ├── checksum └── verify └── src ├── geocodejson.schema.json ├── geohash.schema.json └── semver.schema.json /Makefile: -------------------------------------------------------------------------------- 1 | AJV_CLI_VERSION ?= 5.0.0 2 | JSON_DEREFERENCE_CLI_VERSION ?= 0.1.2 3 | 4 | all: build validate checksum verify 5 | 6 | build: 7 | @echo "Building spec bundle" 8 | npx -y json-dereference-cli@$(JSON_DEREFERENCE_CLI_VERSION) -s src/geocodejson.schema.json -o draft/geocodejson.schema.json 9 | 10 | validate: 11 | @echo "Validating spec bundle" 12 | npx -y ajv-cli@$(AJV_CLI_VERSION) compile -s draft/geocodejson.schema.json 13 | 14 | checksum: 15 | @echo "Computing spec checksum" 16 | ./scripts/checksum 17 | 18 | verify: 19 | ./scripts/verify && echo "Checksum ok" 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GeocodeJSON Specification 2 | 3 | An attempt to have standard geojson responses from geocoders. 4 | 5 | ## How to use 6 | 7 | Please read the full spec at [master/draft/README.md](https://github.com/geocoders/geocodejson-spec/blob/master/draft/README.md). 8 | 9 | You can validate a geocoding service response against this GeocodeJSON spec using the JSON schema provided: [master/draft/geocodejson.schema.json](https://github.com/geocoders/geocodejson-spec/blob/master/draft/geocodejson.schema.json). Refer to [JSON Schema official website](https://json-schema.org/) for further informations. 10 | 11 | Please verify the integrity of the JSON schema using the SHA-512 checksum provided: [master/draft/geocodejson.schema.json.checksum](https://github.com/geocoders/geocodejson-spec/blob/master/draft/geocodejson.schema.json.checksum). 12 | 13 | ## How to contribute 14 | 15 | Pre-requisites: [git](https://git-scm.com/), [make](https://www.gnu.org/software/make/), [shasum](https://www.commandlinux.com/man-page/man1/shasum.1.html), [npx](https://www.npmjs.com/package/npx) (node and npm). 16 | 17 | Please follow these steps: 18 | 19 | - Let the community knows you want to contribute [opening an issue](https://github.com/geocoders/geocodejson-spec/issues) 20 | - Fork this repo, clone it locally and create a new branch 21 | - Edit the [draft document]((https://github.com/geocoders/geocodejson-spec/blob/master/draft/README.md)) 22 | - Update the [JSON schema](https://github.com/geocoders/geocodejson-spec/blob/master/draft/geocodejson.schema.json) in `src/` folder 23 | - Run `make` 24 | - If all is ok, commit your changes and push them 25 | - Open a Pull Request on the main branch of this repo 26 | 27 | ## Licence 28 | 29 | Public Domain, No Rights Reserved - Creative Commons Zero License ([CC0](https://creativecommons.org/public-domain/cc0/)). 30 | -------------------------------------------------------------------------------- /draft/README.md: -------------------------------------------------------------------------------- 1 | # GeocodeJSON-spec 2 | 3 | **Revision** 0.1 4 | 5 | **Copyright** This work is licensed under a [Creative Commons Attribution License (CC0)](https://creativecommons.org/about/cc0) 6 | 7 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 8 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in 9 | this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt). 10 | 11 | ## 1. Purpose 12 | 13 | This specification attempts to create a standard for handling geocoding results. 14 | 15 | ## 2. File format 16 | 17 | `GeocodeJSON` is a an extension of the [GeoJSON](http://geojson.org/) standard 18 | that aim to define places results. As such, files implementing `GeocodeJSON` 19 | MUST be valid GeoJSON and valid [JSON](http://json.org/) files. The JSON 20 | keys described here are not exclusive. 21 | 22 | 23 | ### Main object 24 | 25 | ```javascript 26 | { 27 | 28 | // REQUIRED. GeocodeJSON result is a FeatureCollection. 29 | "type": "FeatureCollection", 30 | 31 | // REQUIRED. Namespace. 32 | "geocoding": { 33 | 34 | // REQUIRED. A semver.org compliant version number. Describes the version of 35 | // the GeocodeJSON spec that is implemented by this instance. 36 | "version": "0.1.0", 37 | 38 | // OPTIONAL. Default: null. The licence of the data. In case of multiple sources, 39 | // and then multiple licences, can be an object with one key by source. 40 | "licence": "ODbL", 41 | 42 | // OPTIONAL. Default: null. The attribution of the data. In case of multiple sources, 43 | // and then multiple attributions, can be an object with one key by source. 44 | "attribution": "OpenStreetMap Contributors", 45 | 46 | // OPTIONAL. Default: null. The query that has been issued to trigger the 47 | // search. 48 | "query": "24 allée de Bercy 75012 Paris", 49 | 50 | }, 51 | 52 | // REQUIRED. As per GeoJSON spec. 53 | "features": [ 54 | // OPTIONAL. An array of feature objects. See below. 55 | ] 56 | } 57 | ``` 58 | 59 | ### Feature object 60 | 61 | ```javascript 62 | { 63 | 64 | // REQUIRED. As per GeoJSON spec. 65 | "properties": { 66 | 67 | // REQUIRED. Namespace. 68 | "geocoding": { 69 | 70 | // REQUIRED. One of "house", "street", "locality", "city", "region", "country". 71 | // TODO: make a clean list of common cases, plus make clear that the list 72 | // isn't meant to be closed. 73 | "type": "house", 74 | 75 | // OPTIONAL. Result accuracy, in meters. 76 | "accuracy": 20, 77 | 78 | // RECOMMENDED. Suggested label for the result. 79 | "label": "My Shoes Shop, 64 rue de Metz 59280 Armentières", 80 | 81 | // OPTIONAL. Name of the place. 82 | "name": "My Shoes Shop", 83 | 84 | // OPTIONAL. Housenumber of the place. 85 | // TODO: what about the suffix (64A, 64 bis, etc.)? 86 | "housenumber": "64", 87 | 88 | // OPTIONAL. Street of the place. 89 | "street": "Rue de Metz", 90 | 91 | // OPTIONAL. Locality of the place. 92 | "locality": "Les Clarons", 93 | 94 | // OPTIONAL. Postcode of the place. 95 | "postcode": "59280", 96 | 97 | // OPTIONAL. City of the place. 98 | "city": "Armentières", 99 | 100 | // OPTIONAL. District of the place. 101 | "district": null, 102 | 103 | // OPTIONAL. County of the place. 104 | "county": null, 105 | 106 | // OPTIONAL. State of the place. 107 | "state": null, 108 | 109 | // OPTIONAL. Country of the place. 110 | "country": "France", 111 | 112 | // OPTIONAL. Administratives boundaries the feature is included in, 113 | // as defined in http://wiki.osm.org/wiki/Key:admin_level#admin_level 114 | // TODO is there some still generic but less OSMish scheme? 115 | "admin": { 116 | "level2": "France", 117 | "level4": "Nord-Pas-de-Calais", 118 | "level6": "Nord" 119 | }, 120 | 121 | // OPTIONAL. Geohash encoding of coordinates (see http://geohash.org/site/tips.html). 122 | "geohash" : "Ehugh5oofiToh9aWe3heemu7ighee8", 123 | } 124 | 125 | }, 126 | 127 | // REQUIRED. As per GeoJSON spec. 128 | "type": "Feature", 129 | 130 | // REQUIRED. As per GeoJSON spec. 131 | "geometry": { 132 | "coordinates": [ 133 | 2.889957, 134 | 50.687328 135 | ], 136 | "type": "Point" 137 | } 138 | } 139 | ``` 140 | -------------------------------------------------------------------------------- /draft/geocodejson.schema.json: -------------------------------------------------------------------------------- 1 | {"$schema":"http://json-schema.org/draft-07/schema#","$id":"https://geocoders.github.io/geocodejson-spec/draft/geocodejson.schema.json","title":"GeocodeJSON Schema","description":"GeocodeJSON is an extension of the GeoJSON format and it is an attempt to create a standard for handling geocoding results.","allOf":[{"$schema":"http://json-schema.org/draft-07/schema#","$id":"https://geojson.org/schema/GeoJSON.json","title":"GeoJSON","oneOf":[{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON GeometryCollection","type":"object","required":["type","geometries"],"properties":{"type":{"type":"string","enum":["GeometryCollection"]},"geometries":{"type":"array","items":{"oneOf":[{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Feature","type":"object","required":["type","properties","geometry"],"properties":{"type":{"type":"string","enum":["Feature"]},"id":{"oneOf":[{"type":"number"},{"type":"string"}]},"properties":{"oneOf":[{"type":"null"},{"type":"object"}]},"geometry":{"oneOf":[{"type":"null"},{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON GeometryCollection","type":"object","required":["type","geometries"],"properties":{"type":{"type":"string","enum":["GeometryCollection"]},"geometries":{"type":"array","items":{"oneOf":[{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON FeatureCollection","type":"object","required":["type","features"],"properties":{"type":{"type":"string","enum":["FeatureCollection"]},"features":{"type":"array","items":{"title":"GeoJSON Feature","type":"object","required":["type","properties","geometry"],"properties":{"type":{"type":"string","enum":["Feature"]},"id":{"oneOf":[{"type":"number"},{"type":"string"}]},"properties":{"oneOf":[{"type":"null"},{"type":"object"}]},"geometry":{"oneOf":[{"type":"null"},{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON GeometryCollection","type":"object","required":["type","geometries"],"properties":{"type":{"type":"string","enum":["GeometryCollection"]},"geometries":{"type":"array","items":{"oneOf":[{"title":"GeoJSON Point","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"number"}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON LineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["LineString"]},"coordinates":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON Polygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Polygon"]},"coordinates":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPoint","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPoint"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"number"}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiLineString","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiLineString"]},"coordinates":{"type":"array","items":{"type":"array","minItems":2,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}},{"title":"GeoJSON MultiPolygon","type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["MultiPolygon"]},"coordinates":{"type":"array","items":{"type":"array","items":{"type":"array","minItems":4,"items":{"type":"array","minItems":2,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}},"bbox":{"type":"array","minItems":4,"items":{"type":"number"}}}}]},{"type":"object","description":"GeocodeJSON extension of GeoJSON Feature Collection","properties":{"type":{"const":"FeatureCollection","description":"REQUIRED. GeocodeJSON result is a FeatureCollection."},"geocoding":{"type":"object","description":"REQUIRED. Namespace.","properties":{"version":{"description":"A semver.org compliant version number. Describes the version of the GeocodeJSON spec that is implemented by this instance.","$schema":"http://json-schema.org/draft-07/schema#","$id":"https://semver.org/semver.schema.json","type":"string","pattern":"^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$","minLength":5,"maxLength":256,"examples":["0.1.0","1.0.0-beta.1","1.0.0-0.3.7","2.2.4"]},"licence":{"type":"string","description":"OPTIONAL. The licence of the data. In case of multiple sources, and then multiple licences, can be an object with one key by source.","examples":["ODbL"]},"attribution":{"type":"string","description":"OPTIONAL. The attribution of the data. In case of multiple sources, and then multiple attributions, can be an object with one key by source.","examples":["OpenStreetMap Contributors"]},"query":{"type":"string","description":"OPTIONAL. The query that has been issued to trigger the search.","examples":["24 allée de Bercy 75012 Paris"]}},"required":["version"]}},"required":["geocoding"]},{"type":"object","description":"GeocodeJSON extension of GeoJSON Feature","properties":{"features":{"type":"array","description":"REQUIRED. As per GeoJSON spec.","items":{"type":"object","description":"OPTIONAL. An array of feature objects.","properties":{"type":{"const":"Feature","description":"REQUIRED. As per GeoJSON spec."},"properties":{"type":"object","description":"REQUIRED. As per GeoJSON spec.","properties":{"geocoding":{"type":"object","description":"REQUIRED. Namespace.","properties":{"type":{"type":"string","description":"REQUIRED. One of house, street, locality, city, region, country.","examples":["house","street","district","city","county","state","country","locality"]},"accuracy":{"type":"number","minimum":0,"description":"OPTIONAL. Result accuracy, in meters.","examples":[20]},"label":{"type":"string","description":"RECOMMENDED. Suggested label for the result.","examples":["My Shoes Shop, 64 rue de Metz 59280 Armentières"]},"name":{"type":"string","description":"OPTIONAL. Name of the place.","examples":["My Shoes Shop"]},"housenumber":{"type":"string","description":"OPTIONAL. Housenumber of the place.","examples":["64"]},"street":{"type":"string","description":"OPTIONAL. Street of the place.","examples":["Rue de Metz"]},"locality":{"type":"string","description":"OPTIONAL. Locality of the place.","examples":["Les Clarons"]},"postcode":{"type":"string","description":"OPTIONAL. Postcode of the place.","examples":["59280"]},"city":{"type":"string","description":"OPTIONAL. City of the place.","examples":["Armentières"]},"district":{"type":"string","description":"OPTIONAL. District of the place."},"county":{"type":"string","description":"OPTIONAL. County of the place."},"state":{"type":"string","description":"OPTIONAL. State of the place."},"country":{"type":"string","description":"OPTIONAL. Country of the place.","examples":["France"]},"admin":{"type":"object","description":"OPTIONAL. Administratives boundaries the feature is included in, as defined in http://wiki.osm.org/wiki/Key:admin_level#admin_level.","patternProperties":{"^level[0-9]+$":{"type":"string"}}},"geohash":{"description":"OPTIONAL. Geohash encoding of coordinates (see http://geohash.org/site/tips.html).","$schema":"http://json-schema.org/draft-07/schema#","$id":"http://geohash.org/geohash.schema.json","type":"string","pattern":"^[0123456789bcdefghjkmnpqrstuvwxyz]+(:.+)?$","examples":["6gkzmg1w","6gkzwgjzn820","c216ne:Mt_Hood"]}},"required":["type"]}},"required":["geocoding"]}}}}}}]} -------------------------------------------------------------------------------- /draft/geocodejson.schema.json.checksum: -------------------------------------------------------------------------------- 1 | sha512-9205cc1f149fe92799841a54e917e434d481404b9ccafed032b332b4bb3c5089619d64d66e3b277e3e542d8fe09752e6f30e825e5be45a2c25cb136625c86ff7 -------------------------------------------------------------------------------- /scripts/checksum: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | INPUT_DIR=src 4 | OUTPUT_DIR=draft 5 | 6 | SCHEMA_FILE=geocodejson.schema.json 7 | 8 | SHA_CMD=shasum 9 | SHA_VERSION=512 10 | SHA_PREFIX="sha$SHA_VERSION" 11 | 12 | NPX_CMD=npx 13 | JSON_DEREFERENCE_CLI_VERSION="0.1.2" 14 | BUNDLE_SCHEMA_CMD="$NPX_CMD -y json-dereference-cli@$JSON_DEREFERENCE_CLI_VERSION" 15 | 16 | # JSON schema file must exist 17 | if [ ! -f "$INPUT_DIR/$SCHEMA_FILE" ] 18 | then 19 | echo "$SCHEMA_FILE file in $INPUT_DIR folder is missing, abort" 20 | exit 1 21 | fi 22 | 23 | # npx must be installed 24 | if ! command -v $NPX_CMD &> /dev/null 25 | then 26 | echo "$NPX_CMD could not be found, please install it" 27 | exit 1 28 | fi 29 | 30 | # Create bundles 31 | $BUNDLE_SCHEMA_CMD -s $INPUT_DIR/$SCHEMA_FILE -o $OUTPUT_DIR/$SCHEMA_FILE 2> /dev/null 32 | 33 | # shasum must be installed 34 | if ! command -v $SHA_CMD &> /dev/null 35 | then 36 | echo "$SHA_CMD could not be found, please install it" 37 | exit 1 38 | fi 39 | 40 | # Compute checksums 41 | SHA_SCHEMA_CHECKSUM=`$SHA_CMD -a $SHA_VERSION $OUTPUT_DIR/$SCHEMA_FILE | cut -d" " -f 1` 42 | 43 | echo "Checksum ($OUTPUT_DIR/$SCHEMA_FILE.checksum): $SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" 44 | echo -n "$SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" > $OUTPUT_DIR/$SCHEMA_FILE.checksum 45 | 46 | # Stage new checksums 47 | git add $OUTPUT_DIR/$SCHEMA_FILE.checksum 48 | 49 | exit 0 50 | -------------------------------------------------------------------------------- /scripts/verify: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | INPUT_DIR=src 4 | OUTPUT_DIR=draft 5 | 6 | SCHEMA_FILE=geocodejson.schema.json 7 | 8 | SHA_CMD=shasum 9 | SHA_VERSION=512 10 | SHA_PREFIX="sha$SHA_VERSION" 11 | 12 | # JSON schema file must exist 13 | if [ ! -f "$OUTPUT_DIR/$SCHEMA_FILE" ] 14 | then 15 | echo "$SCHEMA_FILE file in $INPUT_DIR folder is missing, abort" 16 | exit 1 17 | fi 18 | 19 | # shasum must be installed 20 | if ! command -v $SHA_CMD &> /dev/null 21 | then 22 | echo "$SHA_CMD could not be found, please install it" 23 | exit 1 24 | fi 25 | 26 | # Checksums must exists 27 | if [ ! -f "$OUTPUT_DIR/$SCHEMA_FILE.checksum" ] 28 | then 29 | echo "$SCHEMA_FILE.checksum file in $OUTPUT_DIR folder is missing, abort" 30 | exit 1 31 | fi 32 | 33 | # Compute checksums 34 | SHA_SCHEMA_CHECKSUM=`$SHA_CMD -a $SHA_VERSION $OUTPUT_DIR/$SCHEMA_FILE | cut -d" " -f 1` 35 | 36 | if ! grep "$SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" $OUTPUT_DIR/$SCHEMA_FILE.checksum &>/dev/null 37 | then 38 | echo "Wrong checksum for $OUTPUT_DIR/$SCHEMA_FILE, please verify" 39 | exit 1 40 | else 41 | echo "Checksum ($OUTPUT_DIR/$SCHEMA_FILE): $SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" 42 | fi 43 | 44 | exit 0 45 | -------------------------------------------------------------------------------- /src/geocodejson.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://geocoders.github.io/geocodejson-spec/draft/geocodejson.schema.json", 4 | "title": "GeocodeJSON Schema", 5 | "description": "GeocodeJSON is an extension of the GeoJSON format and it is an attempt to create a standard for handling geocoding results.", 6 | "allOf": [ 7 | { 8 | "$ref": "https://geojson.org/schema/GeoJSON.json" 9 | }, 10 | { 11 | "type": "object", 12 | "description": "GeocodeJSON extension of GeoJSON Feature Collection", 13 | "properties": { 14 | "type": { 15 | "const": "FeatureCollection", 16 | "description": "REQUIRED. GeocodeJSON result is a FeatureCollection." 17 | }, 18 | "geocoding": { 19 | "type": "object", 20 | "description": "REQUIRED. Namespace.", 21 | "properties": { 22 | "version": { 23 | "$ref": "semver.schema.json", 24 | "description": "A semver.org compliant version number. Describes the version of the GeocodeJSON spec that is implemented by this instance." 25 | }, 26 | "licence": { 27 | "type": "string", 28 | "description": "OPTIONAL. The licence of the data. In case of multiple sources, and then multiple licences, can be an object with one key by source.", 29 | "examples": [ 30 | "ODbL" 31 | ] 32 | }, 33 | "attribution": { 34 | "type": "string", 35 | "description": "OPTIONAL. The attribution of the data. In case of multiple sources, and then multiple attributions, can be an object with one key by source.", 36 | "examples": [ 37 | "OpenStreetMap Contributors" 38 | ] 39 | }, 40 | "query": { 41 | "type": "string", 42 | "description": "OPTIONAL. The query that has been issued to trigger the search.", 43 | "examples": [ 44 | "24 allée de Bercy 75012 Paris" 45 | ] 46 | } 47 | }, 48 | "required": [ 49 | "version" 50 | ] 51 | } 52 | }, 53 | "required": [ 54 | "geocoding" 55 | ] 56 | }, 57 | { 58 | "type": "object", 59 | "description": "GeocodeJSON extension of GeoJSON Feature", 60 | "properties": { 61 | "features": { 62 | "type": "array", 63 | "description": "REQUIRED. As per GeoJSON spec.", 64 | "items": { 65 | "type": "object", 66 | "description": "OPTIONAL. An array of feature objects.", 67 | "properties": { 68 | "type": { 69 | "const": "Feature", 70 | "description": "REQUIRED. As per GeoJSON spec." 71 | }, 72 | "properties": { 73 | "type": "object", 74 | "description": "REQUIRED. As per GeoJSON spec.", 75 | "properties": { 76 | "geocoding": { 77 | "type": "object", 78 | "description": "REQUIRED. Namespace.", 79 | "properties": { 80 | "type": { 81 | "type": "string", 82 | "description": "REQUIRED. One of house, street, locality, city, region, country.", 83 | "examples": [ 84 | "house", 85 | "street", 86 | "district", 87 | "city", 88 | "county", 89 | "state", 90 | "country", 91 | "locality" 92 | ] 93 | }, 94 | "accuracy": { 95 | "type": "number", 96 | "minimum": 0, 97 | "description": "OPTIONAL. Result accuracy, in meters.", 98 | "examples": [ 99 | 20 100 | ] 101 | }, 102 | "label": { 103 | "type": "string", 104 | "description": "RECOMMENDED. Suggested label for the result.", 105 | "examples": [ 106 | "My Shoes Shop, 64 rue de Metz 59280 Armentières" 107 | ] 108 | }, 109 | "name": { 110 | "type": "string", 111 | "description": "OPTIONAL. Name of the place.", 112 | "examples": [ 113 | "My Shoes Shop" 114 | ] 115 | }, 116 | "housenumber": { 117 | "type": "string", 118 | "description": "OPTIONAL. Housenumber of the place.", 119 | "examples": [ 120 | "64" 121 | ] 122 | }, 123 | "street": { 124 | "type": "string", 125 | "description": "OPTIONAL. Street of the place.", 126 | "examples": [ 127 | "Rue de Metz" 128 | ] 129 | }, 130 | "locality": { 131 | "type": "string", 132 | "description": "OPTIONAL. Locality of the place.", 133 | "examples": [ 134 | "Les Clarons" 135 | ] 136 | }, 137 | "postcode": { 138 | "type": "string", 139 | "description": "OPTIONAL. Postcode of the place.", 140 | "examples": [ 141 | "59280" 142 | ] 143 | }, 144 | "city": { 145 | "type": "string", 146 | "description": "OPTIONAL. City of the place.", 147 | "examples": [ 148 | "Armentières" 149 | ] 150 | }, 151 | "district": { 152 | "type": "string", 153 | "description": "OPTIONAL. District of the place." 154 | }, 155 | "county": { 156 | "type": "string", 157 | "description": "OPTIONAL. County of the place." 158 | }, 159 | "state": { 160 | "type": "string", 161 | "description": "OPTIONAL. State of the place." 162 | }, 163 | "country": { 164 | "type": "string", 165 | "description": "OPTIONAL. Country of the place.", 166 | "examples": [ 167 | "France" 168 | ] 169 | }, 170 | "admin": { 171 | "type": "object", 172 | "description": "OPTIONAL. Administratives boundaries the feature is included in, as defined in http://wiki.osm.org/wiki/Key:admin_level#admin_level.", 173 | "patternProperties": { 174 | "^level[0-9]+$": { 175 | "type": "string" 176 | } 177 | } 178 | }, 179 | "geohash": { 180 | "$ref": "geohash.schema.json", 181 | "description": "OPTIONAL. Geohash encoding of coordinates (see http://geohash.org/site/tips.html)." 182 | } 183 | }, 184 | "required": [ 185 | "type" 186 | ] 187 | } 188 | }, 189 | "required": [ 190 | "geocoding" 191 | ] 192 | } 193 | } 194 | } 195 | } 196 | } 197 | } 198 | ] 199 | } -------------------------------------------------------------------------------- /src/geohash.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "http://geohash.org/geohash.schema.json", 4 | "type": "string", 5 | "description": "Geohash encoding of coordinates (see http://geohash.org and https://en.wikipedia.org/wiki/Geohash).", 6 | "pattern": "^[0123456789bcdefghjkmnpqrstuvwxyz]+(:.+)?$", 7 | "examples": [ 8 | "6gkzmg1w", 9 | "6gkzwgjzn820", 10 | "c216ne:Mt_Hood" 11 | ] 12 | } -------------------------------------------------------------------------------- /src/semver.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-07/schema#", 3 | "$id": "https://semver.org/semver.schema.json", 4 | "type": "string", 5 | "description": "A semver.org compliant version number (see https://semver.org).", 6 | "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$", 7 | "minLength": 5, 8 | "maxLength": 256, 9 | "examples": [ 10 | "0.1.0", 11 | "1.0.0-beta.1", 12 | "1.0.0-0.3.7", 13 | "2.2.4" 14 | ] 15 | } --------------------------------------------------------------------------------