Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions cpp/openlocationcode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ std::string encodeIntegers(int64_t lat_val, int64_t lng_val,
// Add the separator character.
code[internal::kSeparatorPosition] = internal::kSeparator;

// Limit the maximum number of digits in the code.
code_length = std::min(code_length, internal::kMaximumDigitCount);
// Ensure the length is valid.
code_length = std::max(code_length, internal::kMinimumDigitCount);
// Compute the grid part of the code if necessary.
if (code_length > internal::kPairCodeLength) {
for (size_t i = internal::kGridCodeLength; i >= 1; i--) {
Expand All @@ -89,6 +93,9 @@ std::string encodeIntegers(int64_t lat_val, int64_t lng_val,
lng_val /= internal::kGridColumns;
}
} else {
if (code_length % 2 == 1) {
code_length++;
}
lat_val /= pow(internal::kGridRows, internal::kGridCodeLength);
lng_val /= pow(internal::kGridColumns, internal::kGridCodeLength);
}
Expand Down Expand Up @@ -193,13 +200,6 @@ std::string clean_code_chars(const std::string &code) {
} // anonymous namespace

std::string Encode(const LatLng &location, size_t code_length) {
// Limit the maximum number of digits in the code.
code_length = std::min(code_length, internal::kMaximumDigitCount);
// Ensure the length is valid.
code_length = std::max(code_length, internal::kMinimumDigitCount);
if (code_length < internal::kPairCodeLength && code_length % 2 == 1) {
code_length = code_length + 1;
}
// Convert latitude and longitude into integer values.
int64_t lat_val = internal::latitudeToInteger(location.latitude);
int64_t lng_val = internal::longitudeToInteger(location.longitude);
Expand Down
3 changes: 0 additions & 3 deletions go/olc.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ func CheckFull(code string) error {
if firstLat := strings.IndexByte(Alphabet, upper(code[0])) * int(encBase); firstLat >= latMax*2 {
return errors.New("latitude outside range")
}
if len(code) == 1 {
return nil
}
if firstLong := strings.IndexByte(Alphabet, upper(code[1])) * int(encBase); firstLong >= lngMax*2 {
return errors.New("longitude outside range")
}
Expand Down
30 changes: 30 additions & 0 deletions go/olc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,36 @@ func TestCheck(t *testing.T) {
}
}

func TestCheckShort(t *testing.T) {
for i, elt := range validity {
err := CheckShort(elt.code)
got := err == nil
if got != elt.isShort {
t.Errorf("%d. %q validity is %t (err=%v), wanted %t.", i, elt.code, got, err, elt.isShort)
}
}
}

func TestCheckFull(t *testing.T) {
for i, elt := range validity {
err := CheckFull(elt.code)
got := err == nil
if got != elt.isFull {
t.Errorf("%d. %q validity is %t (err=%v), wanted %t.", i, elt.code, got, err, elt.isFull)
}
}
}

func TestDecodeValidity(t *testing.T) {
for i, elt := range validity {
_, err := Decode(elt.code)
got := err == nil
if got != elt.isFull {
t.Errorf("%d. %q validity is %t (err=%v), wanted %t.", i, elt.code, got, err, elt.isValid)
}
}
}

func TestEncodeDegrees(t *testing.T) {
const allowedErrRate float64 = 0.05
var badCodes int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,12 @@ public OpenLocationCode(double latitude, double longitude, int codeLength) {
static String encodeIntegers(long lat, long lng, int codeLength) {
// Limit the maximum number of digits in the code.
codeLength = Math.min(codeLength, MAX_DIGIT_COUNT);
// Automatically increase code length if odd and below pair code length.
if ((codeLength < PAIR_CODE_LENGTH) && codeLength % 2 == 1) {
codeLength += 1;
}
// Check that the code length requested is valid.
if (codeLength < PAIR_CODE_LENGTH && codeLength % 2 == 1 || codeLength < MIN_DIGIT_COUNT) {
if (codeLength < MIN_DIGIT_COUNT) {
throw new IllegalArgumentException("Illegal code length " + codeLength);
}

Expand Down Expand Up @@ -359,6 +363,15 @@ public static CodeArea decode(String code) throws IllegalArgumentException {
* @return True if it is a full code.
*/
public boolean isFull() {
// First latitude character can only have first 9 values.
if (CODE_ALPHABET.indexOf(code.charAt(0)) > 8) {
return false;
}

// First longitude character can only have first 18 values.
if (CODE_ALPHABET.indexOf(code.charAt(1)) > 17) {
return false;
}
return code.indexOf(SEPARATOR) == SEPARATOR_POSITION;
}

Expand Down Expand Up @@ -569,19 +582,6 @@ public static boolean isValidCode(String code) {
return false;
}

// Check first two characters: only some values from the alphabet are permitted.
if (separatorPosition == SEPARATOR_POSITION) {
// First latitude character can only have first 9 values.
if (CODE_ALPHABET.indexOf(code.charAt(0)) > 8) {
return false;
}

// First longitude character can only have first 18 values.
if (CODE_ALPHABET.indexOf(code.charAt(1)) > 17) {
return false;
}
}

// Check the characters before the separator.
boolean paddingStarted = false;
for (int i = 0; i < separatorPosition; i++) {
Expand Down
9 changes: 5 additions & 4 deletions js/closure/openlocationcode.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,11 @@ function _encodeIntegers(latInt, lngInt, codeLength) {
if (typeof codeLength == 'undefined') {
codeLength = PAIR_CODE_LENGTH;
}
if (
codeLength < MIN_CODE_LEN ||
(codeLength < PAIR_CODE_LENGTH && codeLength % 2 == 1)
) {
// Increment length if short and not even.
if (codeLength < PAIR_CODE_LENGTH && codeLength % 2 === 1) {
codeLength++;
}
if (codeLength < MIN_CODE_LEN) {
throw new Error('IllegalArgumentException: Invalid Plus Code length');
}
codeLength = Math.min(codeLength, MAX_CODE_LEN);
Expand Down
6 changes: 4 additions & 2 deletions python/openlocationcode/openlocationcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,10 @@ def encodeIntegers(latVal, lngVal, codeLength):
This function is exposed for testing purposes and should not be called
directly.
"""
if codeLength < MIN_DIGIT_COUNT_ or (codeLength < PAIR_CODE_LENGTH_ and
codeLength % 2 == 1):
if codeLength < PAIR_CODE_LENGTH_ and codeLength % 2 == 1:
# Automatically increment short lengths to be even.
codeLength+=1
if codeLength < MIN_DIGIT_COUNT_:
raise ValueError('Invalid Open Location Code length - ' +
str(codeLength))
codeLength = min(codeLength, MAX_DIGIT_COUNT_)
Expand Down
1 change: 1 addition & 0 deletions test_data/encoding.csv
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
20.5,2.5,2762500000,1495040000,4,7FG40000+
-89.9999375,-179.9999375,1562,512,10,22222222+22
0.5,179.5,2262500000,2945024000,4,6VGX0000+
0.5,179.5,2262500000,2945024000,3,6VGX0000+
1,1,2275000000,1482752000,11,6FH32222+222
################################################################################
#
Expand Down
12 changes: 12 additions & 0 deletions test_data/validityTests.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
8fwc2345+,true,false,true
8FWCX400+,true,false,true
84000000+,true,false,true
C2000000+,true,false,true
2V000000+,true,false,true
################################################################################
#
# Valid short codes:
Expand All @@ -29,7 +31,9 @@ WC2345+G6g,true,true,false
#
################################################################################
G+,false,false,false
G,false,false,false
+,false,false,false
45CC+0+,false,false,false
8FWC2345+G,false,false,false
8FWC2_45+G6,false,false,false
8FWC2η45+G6,false,false,false
Expand All @@ -40,6 +44,14 @@ WC2300+G6g,false,false,false
WC2345+G,false,false,false
WC2300+,false,false,false
84900000+,false,false,false
# Cannot start with padding
049VGJQF+VX7Q,false,false,false
# Missing separator
849VGJQFVX7Q,false,false,false
# Latitude outside range
F2000000+,true,false,false
# Longitude outside range
2W000000+,true,false,false
################################################################################
#
# Validate that codes at and exceeding 15 digits are still valid when all their
Expand Down