Skip to content

Commit

Permalink
Fix code to pass more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ben221199 committed Sep 21, 2022
1 parent d56565f commit 6409730
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 35 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"license": "GPL-3.0-or-later",
"require": {
"php": "^7||^8"
"php": "^7.1||^8"
},
"require-dev": {
"phpunit/phpunit": "^7||^8||^9"
Expand Down
70 changes: 37 additions & 33 deletions src/OpenLocationCode.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
namespace YOCLIB\OpenLocationCode;

use Exception;
use InvalidArgumentException;
use RuntimeException;

class OpenLocationCode{

Expand Down Expand Up @@ -46,16 +46,19 @@ class OpenLocationCode{
* @param double|string $latitudeOrCode
* @param ?double $longitude
* @param ?int $codeLength
* @throws InvalidArgumentException
*/
public function __construct($latitudeOrCode,$longitude=null,$codeLength=self::CODE_PRECISION_NORMAL){
if(func_num_args()===1 && is_string($latitudeOrCode)){
$code = $latitudeOrCode;
$code = (string) $latitudeOrCode;
if(!self::isValidCode(strtoupper($code))){
throw new InvalidArgumentException('The provided code \''.$code.'\' is not a valid Open Location Code.');
}
$this->code = strtoupper($code);
}elseif((func_num_args()==2 || func_num_args()==3) && is_numeric($latitudeOrCode) && is_numeric($longitude) && is_int($codeLength)){
$latitude = $latitudeOrCode;
$latitude = (double) $latitudeOrCode;
$longitude = (double) $longitude;
$codeLength = $codeLength ?? self::PAIR_CODE_LENGTH;

$codeLength = min($codeLength,self::MAX_DIGIT_COUNT);
if($codeLength<self::PAIR_CODE_LENGTH && $codeLength%2==1 || $codeLength<4){
Expand All @@ -70,28 +73,28 @@ public function __construct($latitudeOrCode,$longitude=null,$codeLength=self::CO

$revCode = '';

$latVal = (int) round(($latitude+self::LATITUDE_MAX)*self::LAT_INTEGER_MULTIPLIER*1e6)/1e6;
$lngVal = (int) round(($longitude+self::LONGITUDE_MAX)*self::LNG_INTEGER_MULTIPLIER*1e6)/1e6;
$latVal = self::floatToInt(round(($latitude+self::LATITUDE_MAX)*self::LAT_INTEGER_MULTIPLIER,6));
$lngVal = self::floatToInt(round(($longitude+self::LONGITUDE_MAX)*self::LNG_INTEGER_MULTIPLIER,6));

if($codeLength>self::PAIR_CODE_LENGTH){
for($i=0;$i<self::GRID_CODE_LENGTH;$i++){
$latDigit = $latVal%self::GRID_ROWS;
$lngDigit = $lngVal%self::GRID_COLUMNS;
$ndx = (int) ($latDigit*self::GRID_COLUMNS+$lngDigit);
$ndx = self::floatToInt($latDigit*self::GRID_COLUMNS+$lngDigit);
$revCode .= substr(self::CODE_ALPHABET,$ndx,1);
$latVal /= self::GRID_ROWS;
$lngVal /= self::GRID_COLUMNS;
$latVal = self::floatToInt($latVal/self::GRID_ROWS);
$lngVal = self::floatToInt($lngVal/self::GRID_COLUMNS);
}
}else{
$latVal = (int) ($latVal/pow(self::GRID_ROWS,self::GRID_CODE_LENGTH));
$lngVal = (int) ($lngVal/pow(self::GRID_COLUMNS,self::GRID_CODE_LENGTH));
$latVal = self::floatToInt($latVal/(self::GRID_ROWS ** self::GRID_CODE_LENGTH));
$lngVal = self::floatToInt($lngVal/(self::GRID_COLUMNS ** self::GRID_CODE_LENGTH));
}

for($i=0;$i<self::PAIR_CODE_LENGTH/2;$i++){
$revCode .= substr(self::CODE_ALPHABET,$lngVal%self::ENCODING_BASE,1);
$revCode .= substr(self::CODE_ALPHABET,$latVal%self::ENCODING_BASE,1);
$latVal /= self::ENCODING_BASE;
$lngVal /= self::ENCODING_BASE;
$latVal = self::floatToInt($latVal/self::ENCODING_BASE);
$lngVal = self::floatToInt($lngVal/self::ENCODING_BASE);
if($i===0){
$revCode .= self::SEPARATOR;
}
Expand Down Expand Up @@ -130,33 +133,32 @@ public static function encode($latitude,$longitude,$codeLength=self::CODE_PRECIS

/**
* @return CodeArea
* @throws Exception
*/
public function decode(){
if(!self::isFullCode($this->code)){
throw new Exception('Method decode() could only be called on valid full codes, code was '.$this->code.'.');
throw new RuntimeException('Method decode() could only be called on valid full codes, code was '.$this->code.'.');
}
$clean = str_replace(self::PADDING_CHARACTER,'',str_replace(self::SEPARATOR,'',$this->code));

$latVal = -self::LATITUDE_MAX * self::LAT_INTEGER_MULTIPLIER;
$lngVal = -self::LONGITUDE_MAX * self::LNG_INTEGER_MULTIPLIER;
$latVal = self::floatToInt(-self::LATITUDE_MAX * self::LAT_INTEGER_MULTIPLIER);
$lngVal = self::floatToInt(-self::LONGITUDE_MAX * self::LNG_INTEGER_MULTIPLIER);

$latPlaceVal = self::LAT_MSP_VALUE;
$lngPlaceVal = self::LNG_MSP_VALUE;
$latPlaceVal = self::floatToInt(self::LAT_MSP_VALUE);
$lngPlaceVal = self::floatToInt(self::LNG_MSP_VALUE);
for($i=0;$i<min(strlen($clean),self::PAIR_CODE_LENGTH);$i+=2){
$latPlaceVal /= self::ENCODING_BASE;
$lngPlaceVal /= self::ENCODING_BASE;
$latVal += self::indexOf(self::CODE_ALPHABET,substr($clean,$i,1)) * $latPlaceVal;
$lngVal += self::indexOf(self::CODE_ALPHABET,substr($clean,$i+1,1)) * $lngPlaceVal;
$latPlaceVal = self::floatToInt($latPlaceVal/self::ENCODING_BASE);
$lngPlaceVal = self::floatToInt($lngPlaceVal/self::ENCODING_BASE);
$latVal += self::floatToInt(self::indexOf(self::CODE_ALPHABET,substr($clean,$i,1)) * $latPlaceVal);
$lngVal += self::floatToInt(self::indexOf(self::CODE_ALPHABET,substr($clean,$i+1,1)) * $lngPlaceVal);
}
for($i=self::PAIR_CODE_LENGTH;$i<min(strlen($clean),self::MAX_DIGIT_COUNT);$i++){
$latPlaceVal /= self::GRID_ROWS;
$lngPlaceVal /= self::GRID_COLUMNS;
$latPlaceVal = self::floatToInt($latPlaceVal/self::GRID_ROWS);
$lngPlaceVal = self::floatToInt($lngPlaceVal/self::GRID_COLUMNS);
$digit = self::indexOf(self::CODE_ALPHABET,substr($clean,$i,1));
$row = $digit/self::GRID_COLUMNS;
$row = self::floatToInt($digit/self::GRID_COLUMNS);
$col = $digit%self::GRID_COLUMNS;
$latVal += $row*$latPlaceVal;
$lngVal += $col*$lngPlaceVal;
$latVal += self::floatToInt($row*$latPlaceVal);
$lngVal += self::floatToInt($col*$lngPlaceVal);
}
$latitudeLo = $latVal/self::LAT_INTEGER_MULTIPLIER;
$longitudeLo = $lngVal/self::LNG_INTEGER_MULTIPLIER;
Expand Down Expand Up @@ -232,7 +234,8 @@ public function shorten($referenceLatitude,$referenceLongitude){
}

$codeArea = $this->decode();
$range = max(abs($referenceLatitude - $codeArea->getCenterLatitude()),$referenceLongitude-$codeArea->getCenterLongitude());
var_dump($codeArea);
$range = max(abs($referenceLatitude - $codeArea->getCenterLatitude()),$referenceLongitude - $codeArea->getCenterLongitude());

for($i=4;$i>=1;$i--){
if($range<(self::computeLatitudePrecision($i*2)*0.3)){
Expand All @@ -255,7 +258,7 @@ public function recover($referenceLatitude,$referenceLongitude){
$referenceLongitude = self::normalizeLongitude($referenceLongitude);

$digitsToRecover = self::SEPARATOR_POSITION - self::indexOf($this->code,self::SEPARATOR);
$prefixPrecision = pow(self::ENCODING_BASE,2-($digitsToRecover/2));
$prefixPrecision = self::ENCODING_BASE ** (2-($digitsToRecover/2));

$recoveredPrefix = substr((new self($referenceLatitude,$referenceLongitude))->getCode(),0,$digitsToRecover);
$recovered = new self($recoveredPrefix.$this->code);
Expand Down Expand Up @@ -285,16 +288,13 @@ public function recover($referenceLatitude,$referenceLongitude){
* @param double $latitude
* @param double $longitude
* @return bool
* @throws Exception
*/
public function contains($latitude,$longitude){
$codeArea = $this->decode();

return $codeArea->getSouthLatitude()<=$latitude && $latitude<$codeArea->getNorthLatitude() && $codeArea->getWestLongitude()<=$longitude && $longitude<$codeArea->getEastLongitude();
}

//TODO equals

public function __toString(){
return $this->getCode();
}
Expand Down Expand Up @@ -405,7 +405,7 @@ private static function normalizeLongitude($longitude){
return $longitude;
}
$CIRCLE_DEG = 2 * self::LONGITUDE_MAX;
return ($longitude % $CIRCLE_DEG + $CIRCLE_DEG + self::LONGITUDE_MAX) % $CIRCLE_DEG - self::LONGITUDE_MAX;
return fmod((fmod($longitude,$CIRCLE_DEG) + $CIRCLE_DEG + self::LONGITUDE_MAX),$CIRCLE_DEG) - self::LONGITUDE_MAX;
}

/**
Expand All @@ -427,4 +427,8 @@ private static function indexOf($haystack,$needle,$offset=0){
return $pos;
}

private static function floatToInt($float){
return (intval(($float+0).''));
}

}
1 change: 1 addition & 0 deletions tests/ShorteningTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public function testShortening(){
if('B'!==$testData->testType && 'S'!==$testData->testType){
continue;
}
var_dump($testData);
$olc = new OpenLocationCode($testData->code);
$shortened = $olc->shorten($testData->referenceLatitude,$testData->referenceLongitude);
$this->assertEquals($testData->shortCode,$shortened->getCode(),'Wrong shortening of code '.$testData->code);
Expand Down
1 change: 0 additions & 1 deletion tests/ValidityTest_TestData.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ public function __construct($line){
$this->isValid = filter_var($parts[1],FILTER_VALIDATE_BOOLEAN);
$this->isShort = filter_var($parts[2],FILTER_VALIDATE_BOOLEAN);
$this->isFull = filter_var($parts[3],FILTER_VALIDATE_BOOLEAN);
// var_dump($this);
}

}

0 comments on commit 6409730

Please sign in to comment.