-
Notifications
You must be signed in to change notification settings - Fork 500
Update specification #463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update specification #463
Changes from all commits
0414cd8
fef6352
bf50614
aec2a47
26352cb
618ad5b
d7a7a91
e05cd31
2ce7dca
8345cf4
aef4682
3e08100
6929a0c
d4ef272
89063bd
ffe0a3a
daa1c35
ce6bb6d
d7c6d25
a2b4168
33044f5
64ffd9c
fe29a44
f0a9771
2e8ac0a
a896494
5752d8d
362c8ec
79ca2c2
9a959bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Open Location Code API Reference Specification | ||
|
||
## Version history | ||
|
||
All substantial changes changes to this document are listed here. | ||
|
||
* Version 1.1.0 / 2021-06-04 / [William Entriken](https://github.com/fulldecent/) | ||
* Update to match nomenclature in [Plus Codes specification](./Plus%20Codes%20Specification.md) | ||
* Specify the number of significant digits that a short code may omit | ||
* `isFull`, `isShort`, `isValid` methods must now validate whether the input actually is a valid Plus Code ignoring case (breaking change, previously `true` could be returned for some invalid inputs) | ||
* Public methods are specified as REQUIRED or OPTIONAL (breaking change: previously it may have been unclear which methods were REQUIRED) | ||
|
||
- Version 1.0.0 / 2014-10-27 / [Doug Rinckes](https://github.com/drinckes), Google / Philipp Bunge, Google | ||
- Initial public release | ||
|
||
## REQUIRED public methods | ||
|
||
An implementation of the Open Location Code API SHALL implement these REQUIRED methods: | ||
|
||
| Method name | Input(s) | Output(s) | | ||
| -------------------- | ------------------------------- | ------------------------------------------------------------ | | ||
| `isValid` | Plus Code string | True if this is a Plus Code (full code or short code), false otherwise | | ||
| `isFull` | Plus Code string | True if this is a full code, false otherwise | | ||
| `encode` | Latitude, longitude | The Plus Code with code length 10 with area that contains the specified coordinates | | ||
| `decode` | Full code string with code length 10 | The southern parallel and western meridian for the Plus Code area | | ||
|
||
Implementations are RECOMMENDED to use the method names above. | ||
|
||
Note: it is possible to implement `isFull` using a Perl Compatible Regular Expression, see the Plus Code specification and use case-insensitive matching. | ||
|
||
## OPTIONAL public methods | ||
|
||
An implementation MAY implement these methods. | ||
|
||
| Method name | Input(s) | Output(s) | | ||
| ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | ||
| `isShort` | Plus Code string | True if this is a short code, false otherwise | | ||
| `encode` | Latitude, longitude, code length | The full code with specified code length with area that contains the specified coordinates | | ||
| `decode` | Full code string | The southern parallel and western meridian for the Plus Code area | | ||
| `shorten` | Full code, reference location latitude and longitude | The short code representing the input where all significant digits that are allowed to be omitted are omitted; or if no digits are allowed to be omitted then the input is returned | | ||
| `recoverNearest` | Short code, reference location latitude and longitude | The unique full code represented by the input | | ||
|
||
Implementations are RECOMMENDED to use the method names above. Note that the OPTIONAL `decode` public method overrides and tightens the specification for the REQUIRED `decode` public method. Note that The OPTIONAL `encode` public method adds a parameter. This MAY be implemented as an overloaded method or another way that is customary for the programming language. | ||
|
||
An implementation MAY implement `shorten` using separate `shortenBy4` and `shortenBy6` methods. | ||
|
||
Note: it is possible to implement `isValid` and `isShort` using a Perl Compatible Regular Expression, see the Plus Code specification and use case-insensitive matching. | ||
|
||
## REQUIREMENTS for all public methods | ||
|
||
Implementations MUST follow these REQUIREMENTS for all public methods: | ||
|
||
* Plus Code Inputs MUST treat non-upper-case inputs as if they were upper case. | ||
* Plus Code outputs MUST be uppercase and conform to the [Plus Codes Specification]. | ||
fulldecent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* Latitude inputs MUST treat a latitude greater than 90° N as if it were the North Pole (i.e. at 90° N). | ||
* Latitude inputs MUST treat a latitude lower than 90° S as if it were the South Pole (i.e. at 90° S). | ||
* Longitude inputs MUST treat values outside the range from (including) 180° W to (excluding) 180° E as if they were the equivalent longitude in this range. | ||
* Longitude inputs MUST NOT cause runtime performance linearly dependent on the longitude. E.g. use use a modulo operator, not a subtracting/adding while loop. | ||
|
||
## OPTIONAL notes for all public methods | ||
|
||
Implementations MAY follow these specifications for all public methods. | ||
|
||
* Every public method that returns a southern parallel and western meridian may also return the northern parallel, the eastern meridian as well as the center. See definition of center in the Plus Codes specification. | ||
|
||
## Implementation RECOMMENDATION | ||
|
||
An implementation MAY use the following RECOMMENDATIONS. | ||
|
||
- If latitude is 90° N or higher, directly return the Plus Code `C2X2X2X2+X2RRRRR`, truncated as necessary. | ||
- If latitude is 90° S or lower, directly return the Plus Code `22222222+2222222`, truncated as necessary. | ||
- If longitude is outside [180° W, 180° E), use a single modular calculation to enter the correct range. | ||
- If your platform supports floating point numbers with mantissa of at least 35 bits (e.g. IEEE 754 double precision or better), then: | ||
- Multiply the input latitude by 2.5e7 and the longitude by 8.192e7 one time. This prevents inaccurate floating point math resulting from repeated multiplications/divisions. All remaining calculations can be done using base-20, base-4 and base-5 math on this integer value. | ||
- If your platform only supports floating point numbers with mantissa up to 24 bits (e.g. IEEE 754 single precision) then your application will not produce accurate results in all cases for Plus Codes with code length greater than 12. This should produce a warning or error if greater than this precision is requested. | ||
|
||
## References | ||
|
||
- [Plus Codes specification](./Plus%20Codes%20Specification.md) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# Plus Codes Specification | ||
|
||
## Version history | ||
|
||
All substantial changes changes to this document are listed here. | ||
|
||
* Version 1.1.0 / 2021-06-04 / [William Entriken](https://github.com/fulldecent/) | ||
* Separate Plus Codes specification from [Open Location Code API specification](./Open Location Code API Specification.md) | ||
* Define one code for the North Pole at each code level | ||
* Define one code for the South Pole at each code level (breaking change, previously many codes included the South Pole) | ||
* Specify which code levels of full codes may be shortened to which code levels of short codes | ||
* Establish consistent wording/naming | ||
* Version 1.0.0 / 2019-04-29 / [Doug Rinckes](https://github.com/drinckes), Google / Philipp Bunge, Google | ||
* Initial public release | ||
|
||
## Area and bounds | ||
|
||
A **Plus Code** represents a locus of coordinates ("**area**") with **bounds** on northern & southern parallels and western & eastern meridians. This area includes exactly the coordinates: | ||
|
||
1. Inside (excluding) the bounds; | ||
2. On the western bound between (excluding) the northern and southern bounds; | ||
3. (If the northern bound is 90° N and the western bound is 0° W) the North Pole (i.e. the point at 90° N); | ||
4. (If the southern bound is 90° S and the western bound is 0° W) the South Pole (i.e. the point at 90° S); and | ||
5. (If the southern bound is not 90° S) on the southern bound from (including) the western bound to (excluding) the eastern bound. | ||
|
||
This specification references latitudes and longitudes on a sphere which MUST be agreed between the producer and consumer of a Plus Code. Typically Earth and the [WGS 84 geodetic](https://earth-info.nga.mil) are used, which is the standard used by the Global Positioning System. | ||
|
||
The **center** of a Plus Code is defined as the arithmetic mean of its bound's parallels and meridians. | ||
|
||
## Precision | ||
fulldecent marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Plus Codes are characterized by their **code length**. This specifies the distance between the northern & southern bounds and the western & eastern bounds. Plus codes MUST use one of these code lengths: | ||
|
||
| Code length | North-south distance | West-east distance | Longest edge | | ||
| :---------: | -------------------- | ------------------ | :----------: | | ||
| 2 | 20 degrees | 20 degrees | < 2300 km | | ||
| 4 | 1 degrees | 1 degrees | < 120 km | | ||
| 6 | 1/20 degrees | 1/20 degrees | < 5.6 km | | ||
| 8 | 1/400 degrees | 1/400 degrees | < 280 meters | | ||
| 10 | 1/8000 degrees | 1/8000 degrees | < 14 meters | | ||
| 11 | 1/40000 degrees | 1/32000 degrees | < 4 meters | | ||
| 12 | 1/200000 degrees | 1/128000 degrees | < 90 cm | | ||
| 13 | 1/1e6 degrees | 1/512000 degrees | < 22 cm | | ||
| 14 | 1/5e6 degrees | 1/2.048e6 degrees | < 6 cm | | ||
| 15 | 1/2.5e7 degrees | 1/8.192e7 degrees | < 14 mm | | ||
|
||
Longest edges above are provided for informational purposes only and are not normative, these assume a Plus Code over Earth with the WGS 84 geodetic. | ||
|
||
## Formatting | ||
|
||
A Plus Code consists of two or more **significant digits**, zero or more **padding characters** and exactly one **format separator**. Plus Code formatting has been selected to reduce writing errors and prevent spelling words. | ||
|
||
There are eight **digit places** to the left of the **format separator** and seven to the right: | ||
|
||
<kbd>1</kbd><kbd>2</kbd><kbd>3</kbd><kbd>4</kbd><kbd>5</kbd><kbd>6</kbd><kbd>7</kbd><kbd>8</kbd><kbd>+</kbd><kbd>9</kbd><kbd>10</kbd><kbd>11</kbd><kbd>12</kbd><kbd>13</kbd><kbd>14</kbd><kbd>15</kbd> | ||
|
||
Plus Codes SHALL NOT be formatted differently for right-to-left languages. This avoids ambiguity. | ||
|
||
A significant digit represents a numeric value as: | ||
|
||
| Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | | ||
| ----- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | ||
| Digit | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | C | F | G | H | J | M | P | Q | R | V | W | X | | ||
|
||
The padding character is defined as the zero ("0") character ([U+0030](http://unicode.org/charts/PDF/U0000.pdf)). | ||
|
||
The format separator is defined as the plus ("+") character ([U+002B](http://unicode.org/charts/PDF/U0000.pdf)). | ||
|
||
## Encoding | ||
|
||
A Plus Code uses significant digits to encode its southern and western bounds. The significant digits of a Plus Code represent latitude (north) and then longitude (east) offsets from the starting location 90° S, 180° W. | ||
|
||
A significant digit in digit places 1, 3, 5, 7 and 9 represents an offset north equal to the north-south distance for that code length (find the code length for one more than the digit place in the code length table above) multiplied by the significant digit value. | ||
|
||
A significant digit in digit places 2, 4, 6, 8 and 10 represents an offset east equal to the west-east distance for that code length multiplied by the significant digit value. | ||
|
||
A significant digit in places 11 and higher represents: | ||
|
||
* an offset north equal to the north-south distance for that code length multiplied by (the significant digit value divided by four and rounded down) | ||
* an offset east equal to the west-east distance for that code length multiplied by (the significant digit value modulo 4) | ||
|
||
<kbd>N</kbd><kbd>E</kbd><kbd>N</kbd><kbd>E</kbd><kbd>N</kbd><kbd>E</kbd><kbd>N</kbd><kbd>E</kbd><kbd>+</kbd><kbd>N</kbd><kbd>E</kbd><kbd>X</kbd><kbd>X</kbd><kbd>X</kbd><kbd>X</kbd><kbd>X</kbd> | ||
|
||
:information_source: Note that latitudes greater than 90° N do not exist and therefore the digit place 1 MUST only have values 0–8. Likewise, digit place 2 MUST only have values 0–17. | ||
|
||
## Full code | ||
|
||
A **full code** representation of a Plus Code is globally usable and requires no other reference to interpret. | ||
|
||
Every full code MUST include significant digits in digit places 1 up through the code length. If the code length is less than 8, then the padding character is placed in digit places after the last significant digit up to and including the 8th digit place. The format separator is added after the 8th digit place. | ||
|
||
Therefore, the set of full codes exactly matches the [Perl Compatible Regular Expression](http://pcre.org): | ||
|
||
````perl | ||
/^[2-9C][2-9CFGHJMPQRV](0{6}\+|[2-9CFGHJMPQRVWX]{2}(0000\+|[2-9CFGHJMPQRVWX]{2}(00\+|[2-9CFGHJMPQRVWX]{2}\+([2-9CFGHJMPQRVWX]{2,7})?)))$/ | ||
```` | ||
|
||
The full code representation is the default representation of a Plus Code. | ||
|
||
## Short code | ||
|
||
A **short code** representation of a Plus Code is meaningful only when the producer and consumer agree on the approximate latitude and longitude of a **reference location**. A short code can be easier to use and remember than a full code. | ||
|
||
Plus Codes with code length less than 8 SHALL NOT be represented as short codes. | ||
|
||
The **2-D rectilinear distance** between two latitude/longitude coordinates is defined as the sum of (the absolute difference of latitudes) and (the absolute difference of longitudes). | ||
|
||
The 2-D rectilinear distance distance between a Plus Code's center and a reference location determines which digit places can be omitted in the short code representation: | ||
|
||
* If both distances are less than 10 degrees, digit places 1–2 MAY be omitted. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implementations actually use a magic number of 0.3* the distances given here, and I believe I've also seen multiplying by 0.4 suggested somewhere (probably the Wiki). I agree that being mathematically exact is preferable to strange magic numbers, but should these be integrated here somehow at least as a suggestion for a safety margin? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! This is built into the spec under "Short codes" where it specifies the "if both distances..." part. These use half the distance as the precision amount for that code level. I believe this amounts to 50% margin. Is that correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's true that, with an exact reference location agreed upon between both parties, a short code can be recovered within one full code area for any given code level (e.g. within +/- 10° if the full code was shortened by two digits). However, often the reference locations aren't exact, so to make short codes more useful many parts of the current documentation warn about pushing the limits where this isn't necessary. For example, this wiki page mentions a safety margin of 20% (which I falsely remembered as a factor of 0.4 - should of course be 0.8): https://github.com/google/open-location-code/wiki/Guidance-for-shortening-codes That page, by the way, is referenced from this repo's README, which also states:
|
||
* If both distances are less than 0.5 degrees, digit places 1–2 or 1–4 MAY be omitted. | ||
* If both distances are less than 1/40 degrees, digit places 1–2, 1–4 or 1–6 MAY be omitted. | ||
|
||
A short code represents the unique full code Plus Code nearest (minimal 2-D rectilinear distance, prefer southernmost and westernmost if tied) to the reference location. | ||
|
||
:information_source: Note that omitted digits places of a short code will not necessarily be the same as the reference location. | ||
|
||
Therefore, the set of short code representations exactly matches the Perl Compatible Regular Expression: | ||
|
||
```perl | ||
/^([2-9CFGHJMPQRVWX]{2})?([2-9CFGHJMPQRVWX]{2})?[2-9CFGHJMPQRVWX]{2}\+([2-9CFGHJMPQRVWX]{2,7})?$/ | ||
``` |
Uh oh!
There was an error while loading. Please reload this page.