IanBicking (Talk | contribs) |
|||
| (18 intermediate revisions by 6 users not shown) | |||
| Line 1: | Line 1: | ||
| − | GeoWebDNS is a service | + | GeoWebDNS is a service inspired by DNS and reverse-geocoding. Given a lat/long, what is the URI of the standardized API, protocol, or file for a given service namespace (eg 311 services). The GeoWebDNS servers would be decentralized and redundant, automatically mirroring one-another and propagating out changes much like DNS servers. All that the client would need to do would be to send the lat/long and request the URI for a given namespace. The server would then have to look at the polygon that contains that lat/long for that service namespace and return the URI associated with it. |
| + | |||
| + | This model is meant to work in concert with a [[Service Discovery]] spec such as that being used with Open311. A good deal of other work is also occurring in the service discovery space for [http://spec.datacatalogs.org/ data catalogs] and [http://www.apievangelist.com/2013/02/02/one-api-discovery-definition-to-rule-them-all/ APIs]. | ||
| + | |||
| + | == Reference Implementation == | ||
| + | * https://github.com/open311/geowebdns | ||
| + | * See also https://github.com/SeeClickFix/open311-router | ||
== Protocol == | == Protocol == | ||
| Line 7: | Line 13: | ||
A query uses query string arguments: | A query uses query string arguments: | ||
| − | <code>lat</code>: The latitude. | + | <code>lat</code>: The latitude. (WGS84) |
| − | <code>long</code>: The longitude. | + | <code>long</code>: The longitude. (WGS84) |
'''Note''': should lat/long be one value? This makes it easier to add new query types. It might be like: <code>point=100.1234%2035.1234</code> (i.e., space-separated), or just comma-separated (which doesn't need to be quoted). | '''Note''': should lat/long be one value? This makes it easier to add new query types. It might be like: <code>point=100.1234%2035.1234</code> (i.e., space-separated), or just comma-separated (which doesn't need to be quoted). | ||
| Line 37: | Line 43: | ||
"name": "San Francisco 311", | "name": "San Francisco 311", | ||
"kml": "http://ns.geowebdns.org/kml/3940193" | "kml": "http://ns.geowebdns.org/kml/3940193" | ||
| + | } | ||
] | ] | ||
} | } | ||
| Line 61: | Line 68: | ||
== No results == | == No results == | ||
| − | If there are absolutely no results, it will return <code>{"results": []}</code> | + | If there are absolutely no results, it will return <code>{"results": []}</code> with a 404 status code. |
| − | + | ||
| − | + | ||
== Errors == | == Errors == | ||
| Line 72: | Line 77: | ||
'''Note''': are there any predictable errors? E.g., a lat/long that is impossible? | '''Note''': are there any predictable errors? E.g., a lat/long that is impossible? | ||
| + | |||
| + | == Source == | ||
| + | |||
| + | Source code for the reference implementation is at https://github.com/openplans/geowebdns | ||
| + | |||
| + | To get started, run: | ||
| + | |||
| + | $ wget https://github.com/openplans/geowebdns | ||
| + | $ chmod +x setup-layout.sh | ||
| + | $ ./setup-layout.sh geowebdns-app | ||
| + | |||
| + | This product uses [http://cloudsilverlining.org/ SilverLining] for deployment. The stack consists of PostGIS, GeoAlchemy, WebOb. | ||
| + | |||
| + | To bootstrap a database, you can run these scripts: | ||
| + | |||
| + | $ cd src/geowebdns/imports | ||
| + | $ mkdir data | ||
| + | $ ./getall.sh | ||
| + | $ export CONFIG_PG_SQLALCHEMY=postgres://postgres:password@localhost/geowebdns # use your postgres password here | ||
| + | $ ./importall.sh --commit | ||
| + | |||
| + | ==Related Technologies== | ||
| + | * [http://tools.ietf.org/html/rfc5222 LoST: A Location-to-Service Translation Protocol] | ||
GeoWebDNS is a service inspired by DNS and reverse-geocoding. Given a lat/long, what is the URI of the standardized API, protocol, or file for a given service namespace (eg 311 services). The GeoWebDNS servers would be decentralized and redundant, automatically mirroring one-another and propagating out changes much like DNS servers. All that the client would need to do would be to send the lat/long and request the URI for a given namespace. The server would then have to look at the polygon that contains that lat/long for that service namespace and return the URI associated with it.
This model is meant to work in concert with a Service Discovery spec such as that being used with Open311. A good deal of other work is also occurring in the service discovery space for data catalogs and APIs.
The service will use HTTP. It exists at one URL; in this document we will use the example http://ns.geowebdns.org/service as the API endpoint.
A query uses query string arguments:
lat: The latitude. (WGS84)
long: The longitude. (WGS84)
Note: should lat/long be one value? This makes it easier to add new query types. It might be like: point=100.1234%2035.1234 (i.e., space-separated), or just comma-separated (which doesn't need to be quoted).
type: The type of object to be returned; this will be a string/URI. This argument may be present multiple times, returning jurisdictions with any of the given types.
A query then looks like:
GET /service?lat=100.1234&long=35.1234&type=http://ns.geowebdns.org/311/jurisdiction
The only coordinate system supported is WGS 84 (latitude/longitude).
In this example http://ns.geowebdns.org/311/jurisdiction might be the URI identifying 311 jurisdictions. URIs act similar to how an XML namespace works; it is an opaque string, but by convention maps to a URL describing the type.
Note: should we accept a level of confidence, using the same scale as presented in the Google geocode API? A low confidence might mean we do a more fuzzy search.
The response is a JSON object like:
Content-type: application/json
{"results": [
{"type": "http://ns.geowebdns.org/311/jursidiction",
"uri": "http://sfgov.org/311/api",
"name": "San Francisco 311",
"kml": "http://ns.geowebdns.org/kml/3940193"
}
]
}
The return result JSON is an object with one key, "results" (other keys may be added later, for example to specifying caching semantics or paging). The "results" key has a value of a list of all results matching this location.
Each result is an object with several keys:
"type": The "type" of the jurisdiction. If you specify multiple type=... in your query, you can use this to determine which specific type this result is.
"uri": The destination URL.
Note: should there be a kind of "id URL" in addition to this more explicit URL? For instance, if there are multiple APIs, they might each have a different "type" but still represent the same basic entity. These could all have the same id URI (e.g., http://sfgov/311) but still different specific endpoints.
"name": The name of the entity, a readable string.
Note: should this be translated or translatable? E.g., {"en_US": "San Francisco 311 Information", "es": "San Fransisco 311 Informacion"} ?
"kml": This optional response value points to a KML document describing the entity.
Note: would it make sense to inline GeoJSON?
If there are absolutely no results, it will return {"results": []} with a 404 status code.
If the request is malformed, a 400 Bad Request response is given. The text of this response will be a readable description of the problem.
The readable format is defined by the Content-Type header, but will probably be HTML. Clients that cannot or do not want to present HTML can strip all tags and will get a description that is still readable.
Note: are there any predictable errors? E.g., a lat/long that is impossible?
Source code for the reference implementation is at https://github.com/openplans/geowebdns
To get started, run:
$ wget https://github.com/openplans/geowebdns $ chmod +x setup-layout.sh $ ./setup-layout.sh geowebdns-app
This product uses SilverLining for deployment. The stack consists of PostGIS, GeoAlchemy, WebOb.
To bootstrap a database, you can run these scripts:
$ cd src/geowebdns/imports $ mkdir data $ ./getall.sh $ export CONFIG_PG_SQLALCHEMY=postgres://postgres:password@localhost/geowebdns # use your postgres password here $ ./importall.sh --commit