diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fdbf315 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +AJV_CLI_VERSION ?= 5.0.0 +JSON_DEREFERENCE_CLI_VERSION ?= 0.1.2 + +all: build validate checksum verify + +build: + @echo "Building spec bundle" + npx -y json-dereference-cli@$(JSON_DEREFERENCE_CLI_VERSION) -s src/geocodejson.schema.json -o draft/geocodejson.schema.json + +validate: + @echo "Validating spec bundle" + npx -y ajv-cli@$(AJV_CLI_VERSION) compile -s draft/geocodejson.schema.json + +checksum: + @echo "Computing spec checksum" + ./scripts/checksum + +verify: + ./scripts/verify && echo "Checksum ok" diff --git a/README.md b/README.md new file mode 100644 index 0000000..391a1dc --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# GeocodeJSON Specification + +An attempt to have standard geojson responses from geocoders. + +## How to use + +Please read the full spec at [master/draft/README.md](https://github.com/geocoders/geocodejson-spec/blob/master/draft/README.md). + +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. + +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). + +## How to contribute + +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). + +Please follow these steps: + +- Let the community knows you want to contribute [opening an issue](https://github.com/geocoders/geocodejson-spec/issues) +- Fork this repo, clone it locally and create a new branch +- Edit the [draft document]((https://github.com/geocoders/geocodejson-spec/blob/master/draft/README.md)) +- Update the [JSON schema](https://github.com/geocoders/geocodejson-spec/blob/master/draft/geocodejson.schema.json) in `src/` folder +- Run `make` +- If all is ok, commit your changes and push them +- Open a Pull Request on the main branch of this repo + +## Licence + +Public Domain, No Rights Reserved - Creative Commons Zero License ([CC0](https://creativecommons.org/public-domain/cc0/)). diff --git a/draft/geocodejson.schema.json b/draft/geocodejson.schema.json new file mode 100644 index 0000000..8a1b292 --- /dev/null +++ b/draft/geocodejson.schema.json @@ -0,0 +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"]}}}}}}]} \ No newline at end of file diff --git a/draft/geocodejson.schema.json.checksum b/draft/geocodejson.schema.json.checksum new file mode 100644 index 0000000..62250e2 --- /dev/null +++ b/draft/geocodejson.schema.json.checksum @@ -0,0 +1 @@ +sha512-9205cc1f149fe92799841a54e917e434d481404b9ccafed032b332b4bb3c5089619d64d66e3b277e3e542d8fe09752e6f30e825e5be45a2c25cb136625c86ff7 \ No newline at end of file diff --git a/scripts/checksum b/scripts/checksum new file mode 100755 index 0000000..a9fbdaf --- /dev/null +++ b/scripts/checksum @@ -0,0 +1,49 @@ +#!/bin/bash + +INPUT_DIR=src +OUTPUT_DIR=draft + +SCHEMA_FILE=geocodejson.schema.json + +SHA_CMD=shasum +SHA_VERSION=512 +SHA_PREFIX="sha$SHA_VERSION" + +NPX_CMD=npx +JSON_DEREFERENCE_CLI_VERSION="0.1.2" +BUNDLE_SCHEMA_CMD="$NPX_CMD -y json-dereference-cli@$JSON_DEREFERENCE_CLI_VERSION" + +# JSON schema file must exist +if [ ! -f "$INPUT_DIR/$SCHEMA_FILE" ] +then + echo "$SCHEMA_FILE file in $INPUT_DIR folder is missing, abort" + exit 1 +fi + +# npx must be installed +if ! command -v $NPX_CMD &> /dev/null +then + echo "$NPX_CMD could not be found, please install it" + exit 1 +fi + +# Create bundles +$BUNDLE_SCHEMA_CMD -s $INPUT_DIR/$SCHEMA_FILE -o $OUTPUT_DIR/$SCHEMA_FILE 2> /dev/null + +# shasum must be installed +if ! command -v $SHA_CMD &> /dev/null +then + echo "$SHA_CMD could not be found, please install it" + exit 1 +fi + +# Compute checksums +SHA_SCHEMA_CHECKSUM=`$SHA_CMD -a $SHA_VERSION $OUTPUT_DIR/$SCHEMA_FILE | cut -d" " -f 1` + +echo "Checksum ($OUTPUT_DIR/$SCHEMA_FILE.checksum): $SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" +echo -n "$SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" > $OUTPUT_DIR/$SCHEMA_FILE.checksum + +# Stage new checksums +git add $OUTPUT_DIR/$SCHEMA_FILE.checksum + +exit 0 diff --git a/scripts/verify b/scripts/verify new file mode 100755 index 0000000..6cd0e2c --- /dev/null +++ b/scripts/verify @@ -0,0 +1,44 @@ +#!/bin/bash + +INPUT_DIR=src +OUTPUT_DIR=draft + +SCHEMA_FILE=geocodejson.schema.json + +SHA_CMD=shasum +SHA_VERSION=512 +SHA_PREFIX="sha$SHA_VERSION" + +# JSON schema file must exist +if [ ! -f "$OUTPUT_DIR/$SCHEMA_FILE" ] +then + echo "$SCHEMA_FILE file in $INPUT_DIR folder is missing, abort" + exit 1 +fi + +# shasum must be installed +if ! command -v $SHA_CMD &> /dev/null +then + echo "$SHA_CMD could not be found, please install it" + exit 1 +fi + +# Checksums must exists +if [ ! -f "$OUTPUT_DIR/$SCHEMA_FILE.checksum" ] +then + echo "$SCHEMA_FILE.checksum file in $OUTPUT_DIR folder is missing, abort" + exit 1 +fi + +# Compute checksums +SHA_SCHEMA_CHECKSUM=`$SHA_CMD -a $SHA_VERSION $OUTPUT_DIR/$SCHEMA_FILE | cut -d" " -f 1` + +if ! grep "$SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" $OUTPUT_DIR/$SCHEMA_FILE.checksum &>/dev/null +then + echo "Wrong checksum for $OUTPUT_DIR/$SCHEMA_FILE, please verify" + exit 1 +else + echo "Checksum ($OUTPUT_DIR/$SCHEMA_FILE): $SHA_PREFIX-$SHA_SCHEMA_CHECKSUM" +fi + +exit 0 diff --git a/src/geocodejson.schema.json b/src/geocodejson.schema.json new file mode 100644 index 0000000..837893a --- /dev/null +++ b/src/geocodejson.schema.json @@ -0,0 +1,199 @@ +{ + "$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": [ + { + "$ref": "https://geojson.org/schema/GeoJSON.json" + }, + { + "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": { + "$ref": "semver.schema.json", + "description": "A semver.org compliant version number. Describes the version of the GeocodeJSON spec that is implemented by this instance." + }, + "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": { + "$ref": "geohash.schema.json", + "description": "OPTIONAL. Geohash encoding of coordinates (see http://geohash.org/site/tips.html)." + } + }, + "required": [ + "type" + ] + } + }, + "required": [ + "geocoding" + ] + } + } + } + } + } + } + ] +} \ No newline at end of file diff --git a/src/geohash.schema.json b/src/geohash.schema.json new file mode 100644 index 0000000..b0b1288 --- /dev/null +++ b/src/geohash.schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://geohash.org/geohash.schema.json", + "type": "string", + "description": "Geohash encoding of coordinates (see http://geohash.org and https://en.wikipedia.org/wiki/Geohash).", + "pattern": "^[0123456789bcdefghjkmnpqrstuvwxyz]+(:.+)?$", + "examples": [ + "6gkzmg1w", + "6gkzwgjzn820", + "c216ne:Mt_Hood" + ] +} \ No newline at end of file diff --git a/src/semver.schema.json b/src/semver.schema.json new file mode 100644 index 0000000..7322751 --- /dev/null +++ b/src/semver.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://semver.org/semver.schema.json", + "type": "string", + "description": "A semver.org compliant version number (see https://semver.org).", + "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" + ] +} \ No newline at end of file