From bac0dd1c84e23cfe8c25dd826c47a07678fb5607 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Fri, 11 Jul 2014 12:38:57 +0200 Subject: [PATCH 01/16] whitespace: convert mixed case (tabs and spaces) to spaces --- src/Polyline.php | 405 ++++++++++++++++++++-------------------- tests/PolylineTest.php | 78 ++++---- tests/PrecisionTest.php | 32 ++-- tests/bootstrap.php | 8 +- 4 files changed, 261 insertions(+), 262 deletions(-) diff --git a/src/Polyline.php b/src/Polyline.php index 349a357..abb49b0 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -3,18 +3,18 @@ /** * Polyline * - * A simple class to handle polyline-encoding for Google Maps + * A simple class to handle polyline-encoding for Google Maps * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * @@ -29,12 +29,12 @@ //@NAMESPACE@ namespace emcconville { class Polyline { - - /** - * @var array $polylines - */ - private $polylines = array(); - + + /** + * @var array $polylines + */ + private $polylines = array(); + /** * Default precision level of 1e-5. * @@ -49,200 +49,199 @@ class Polyline { */ protected static $precision = 5; - /** - * @var Polyline $instance - */ - private static $instance; - - /** - * Private constructor. Initialize class through Polyline::Singleton - * - * @see Polyline::Singleton - */ - private function __construct() {} - - /** - * Static instance method - * - * @return Polyline - */ - public static function Singleton() { - return self::$instance instanceof self ? self::$instance : self::$instance = new self; - } - - - /** - * Magic method for supporting wildcard getters - * - * @let {Node} be the name of the polyline - * @method get{Node}Points( ) //=> array of points for polyline "Node" - * @method get{Node}Encoded( ) //=> encoded string for polyline "Node" - * @method getPoints( "{Node}") //=> array of points for polyline "Node" - * @method getEncoded("{Node}") //=> encoded string for polyline "Node" - */ - public function __call($method,$arguments) { - $return = null; - if (preg_match('/^get(.+?)(points|encoded)$/i',$method,$matches)) { - list($all,$node,$type) = $matches; - return $this->getPolyline(strtolower($node),strtolower($type)); - } elseif (preg_match('/^get(points|encoded)$/i',$method,$matches)) { - list($all,$type) = $matches; - $node = array_shift($arguments); - return $this->getPolyline(strtolower($node),strtolower($type)); - } else { - throw new BadMethodCallException(); - } - return $return; - } - - /** - * Polyline getter - * @param string $node - * @param string $type - * @return mixed - */ - public function getPolyline($node, $type) { - $node = strtolower($node); - $type = in_array($type,array('points','encoded')) ? $type : 'encoded'; - return isset($this->polylines[$node]) - ? $this->polylines[$node][$type] - : ($type =='points' ? array() : null); - } - - - /** - * General purpose data method - * - * @param string polyline name - * @param mixed [ string | array ] optional - * @return array - */ - public function polyline() { - $arguments = func_get_args(); - $return = null; - switch (count($arguments)) { - case 2 : - list($node,$value) = $arguments; - $isArray = is_array($value); - $return = $this->polylines[strtolower($node)] = array( - 'points' => $isArray ? self::Flatten($value) : self::Decode($value), - 'encoded' => $isArray ? self::Encode($value) : $value - ); - $return = $return[$isArray ? 'encoded' : 'points' ]; - break; - case 1 : - $node = strtolower((string)array_shift($arguments)); - $return = isset($this->polylines[$node]) - ? $this->polylines[$node] - : array( 'points' => null, 'encoded' => null ); - break; - } - return $return; - } - - /** - * Retrieve list of polyline within singleton - * - * @return array $polylines - */ - public function listPolylines() { - return $return = array_keys($this->polylines); - } - - /** - * Apply Google Polyline algorithm to list of points - * - * @param array $points - * @param integer $precision optional - * @return string $encoded_string - */ - final public static function Encode($points) { - $points = self::Flatten($points); - $encoded_string = ''; - $index = 0; - $previous = array(0,0); - foreach($points as $number) { - $number = (float)($number); - $number = floor($number * pow(10, static::$precision)); - $diff = $number - $previous[$index % 2]; - $previous[$index % 2] = $number; - $number = $diff; - $index++; - $number = ($number < 0) ? ~($number << 1) : ($number << 1); - $chunk = ''; - while($number >= 0x20) { - $chunk .= chr((0x20 | ($number & 0x1f)) + 63); - $number >>= 5; - } - $chunk .= chr($number + 63); - $encoded_string .= $chunk; - } - return $encoded_string; - } - - /** - * Reverse Google Polyline algorithm on encoded string - * - * @param string $string - * @param integer $precision optional - * @return array $points - */ - final public static function Decode($string) { - $points = array(); - $index = $i = 0; - $previous = array(0,0); - while( $i < strlen($string) ) { - $shift = $result = 0x00; - do { - $bit = ord(substr($string,$i++)) - 63; - $result |= ($bit & 0x1f) << $shift; - $shift += 5; - } while( $bit >= 0x20 ) ; - - $diff = ($result & 1) ? ~($result >> 1) : ($result >> 1); - $number = $previous[$index % 2] + $diff; - $previous[$index % 2] = $number; - $index++; - $points[] = $number * 1 / pow(10, static::$precision); - } - return $points; - } - - /** - * Reduce multi-dimensional to single list - * - * @param array $array - * @return array $flatten - */ - final public static function Flatten($array) { - $flatten = array(); - foreach(array_values($array) as $node) { - if (is_array($node)) { - $flatten = array_merge($flatten,self::Flatten($node)); - } else { - $flatten[] = $node; - } - } - return $flatten; - } - - /** - * Concat list into pairs of points - * - * @param array $list - * @return array $pairs - */ - final public static function Pair($list) { - $pairs = array(); - if(!is_array($list)) { return $pairs; } - do { - $pairs[] = array( - array_shift($list), - array_shift($list) - ); - } while (!empty($list)); - return $pairs; - } + /** + * @var Polyline $instance + */ + private static $instance; + + /** + * Private constructor. Initialize class through Polyline::Singleton + * + * @see Polyline::Singleton + */ + private function __construct() {} + + /** + * Static instance method + * + * @return Polyline + */ + public static function Singleton() { + return self::$instance instanceof self ? self::$instance : self::$instance = new self; + } + + + /** + * Magic method for supporting wildcard getters + * + * @let {Node} be the name of the polyline + * @method get{Node}Points( ) //=> array of points for polyline "Node" + * @method get{Node}Encoded( ) //=> encoded string for polyline "Node" + * @method getPoints( "{Node}") //=> array of points for polyline "Node" + * @method getEncoded("{Node}") //=> encoded string for polyline "Node" + */ + public function __call($method,$arguments) { + $return = null; + if (preg_match('/^get(.+?)(points|encoded)$/i',$method,$matches)) { + list($all,$node,$type) = $matches; + return $this->getPolyline(strtolower($node),strtolower($type)); + } elseif (preg_match('/^get(points|encoded)$/i',$method,$matches)) { + list($all,$type) = $matches; + $node = array_shift($arguments); + return $this->getPolyline(strtolower($node),strtolower($type)); + } else { + throw new BadMethodCallException(); + } + return $return; + } + + /** + * Polyline getter + * @param string $node + * @param string $type + * @return mixed + */ + public function getPolyline($node, $type) { + $node = strtolower($node); + $type = in_array($type,array('points','encoded')) ? $type : 'encoded'; + return isset($this->polylines[$node]) + ? $this->polylines[$node][$type] + : ($type =='points' ? array() : null); + } + + /** + * General purpose data method + * + * @param string polyline name + * @param mixed [ string | array ] optional + * @return array + */ + public function polyline() { + $arguments = func_get_args(); + $return = null; + switch (count($arguments)) { + case 2 : + list($node,$value) = $arguments; + $isArray = is_array($value); + $return = $this->polylines[strtolower($node)] = array( + 'points' => $isArray ? self::Flatten($value) : self::Decode($value), + 'encoded' => $isArray ? self::Encode($value) : $value + ); + $return = $return[$isArray ? 'encoded' : 'points' ]; + break; + case 1 : + $node = strtolower((string)array_shift($arguments)); + $return = isset($this->polylines[$node]) + ? $this->polylines[$node] + : array( 'points' => null, 'encoded' => null ); + break; + } + return $return; + } + + /** + * Retrieve list of polyline within singleton + * + * @return array $polylines + */ + public function listPolylines() { + return $return = array_keys($this->polylines); + } + + /** + * Apply Google Polyline algorithm to list of points + * + * @param array $points + * @param integer $precision optional + * @return string $encoded_string + */ + final public static function Encode($points) { + $points = self::Flatten($points); + $encoded_string = ''; + $index = 0; + $previous = array(0,0); + foreach($points as $number) { + $number = (float)($number); + $number = floor($number * pow(10, static::$precision)); + $diff = $number - $previous[$index % 2]; + $previous[$index % 2] = $number; + $number = $diff; + $index++; + $number = ($number < 0) ? ~($number << 1) : ($number << 1); + $chunk = ''; + while($number >= 0x20) { + $chunk .= chr((0x20 | ($number & 0x1f)) + 63); + $number >>= 5; + } + $chunk .= chr($number + 63); + $encoded_string .= $chunk; + } + return $encoded_string; + } + + /** + * Reverse Google Polyline algorithm on encoded string + * + * @param string $string + * @param integer $precision optional + * @return array $points + */ + final public static function Decode($string) { + $points = array(); + $index = $i = 0; + $previous = array(0,0); + while ($i < strlen($string)) { + $shift = $result = 0x00; + do { + $bit = ord(substr($string,$i++)) - 63; + $result |= ($bit & 0x1f) << $shift; + $shift += 5; + } while ($bit >= 0x20); + + $diff = ($result & 1) ? ~($result >> 1) : ($result >> 1); + $number = $previous[$index % 2] + $diff; + $previous[$index % 2] = $number; + $index++; + $points[] = $number * 1 / pow(10, static::$precision); + } + return $points; + } + + /** + * Reduce multi-dimensional to single list + * + * @param array $array + * @return array $flatten + */ + final public static function Flatten($array) { + $flatten = array(); + foreach(array_values($array) as $node) { + if (is_array($node)) { + $flatten = array_merge($flatten,self::Flatten($node)); + } else { + $flatten[] = $node; + } + } + return $flatten; + } + + /** + * Concat list into pairs of points + * + * @param array $list + * @return array $pairs + */ + final public static function Pair($list) { + $pairs = array(); + if(!is_array($list)) { return $pairs; } + do { + $pairs[] = array( + array_shift($list), + array_shift($list) + ); + } while (!empty($list)); + return $pairs; + } } //@NAMESPACE@ } diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 8508da6..3be2187 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -7,14 +7,14 @@ class PolylineTest extends PHPUnit_Framework_TestCase protected $polylineName = "HydeParkRecords"; protected $encoded = '}`c~FlyquOnAE?`B@|HBpGJ?@pI'; protected $points = array( - array(41.79999,-87.58695), - array(41.79959,-87.58692), - array(41.79959,-87.58741), - array(41.79958,-87.58900), - array(41.79956,-87.59037), - array(41.79950,-87.59037), - array(41.79949,-87.59206) - ); + array(41.79999,-87.58695), + array(41.79959,-87.58692), + array(41.79959,-87.58741), + array(41.79958,-87.58900), + array(41.79956,-87.59037), + array(41.79950,-87.59037), + array(41.79949,-87.59206) + ); /** * @covers Polyline::Singleton @@ -27,19 +27,19 @@ public function testSingleton() return $object; } - /** - * @covers Polyline::polyline - * @covers Polyline::Encode - * @covers Polyline::Flatten - * @depends testSingleton - */ - public function testPolyline(Polyline $object) { - $encoded = $object->polyline($this->polylineName,$this->points); - $this->assertEquals($encoded,$this->encoded); - $hash = $object->polyline($this->polylineName); - $this->assertEquals($encoded,$hash['encoded']); - return $object; - } + /** + * @covers Polyline::polyline + * @covers Polyline::Encode + * @covers Polyline::Flatten + * @depends testSingleton + */ + public function testPolyline(Polyline $object) { + $encoded = $object->polyline($this->polylineName,$this->points); + $this->assertEquals($encoded,$this->encoded); + $hash = $object->polyline($this->polylineName); + $this->assertEquals($encoded,$hash['encoded']); + return $object; + } /** * @covers Polyline::getPolyline @@ -47,31 +47,31 @@ public function testPolyline(Polyline $object) { */ public function testGetPolyline(Polyline $object) { - $this->assertEquals($this->encoded,$object->getPolyline($this->polylineName,'encoded')); - $this->assertNull($object->getPolyline('I_Dont_exsits','encoded')); - return $object; + $this->assertEquals($this->encoded,$object->getPolyline($this->polylineName,'encoded')); + $this->assertNull($object->getPolyline('I_Dont_exsits','encoded')); + return $object; } /** * @covers Polyline::__call - * @depends testGetPolyline + * @depends testGetPolyline */ public function testGetters(Polyline $object) { - $this->assertEquals($this->encoded,$object->getEncoded($this->polylineName)); - $this->assertEquals($this->encoded,$object->getHydeParkRecordsEncoded()); - return $object; + $this->assertEquals($this->encoded,$object->getEncoded($this->polylineName)); + $this->assertEquals($this->encoded,$object->getHydeParkRecordsEncoded()); + return $object; } - /** + /** * @covers Polyline::__call * @expectedException BadMethodCallException - * @depends testPolyline + * @depends testPolyline */ public function testGettersException(Polyline $object) { - $object->thisMethodFails(); - return $object; + $object->thisMethodFails(); + return $object; } /** @@ -81,7 +81,7 @@ public function testGettersException(Polyline $object) public function testListPolylines(Polyline $object) { $list = $object->listPolylines(); - $this->assertCount(1,$list); + $this->assertCount(1,$list); } /** @@ -110,9 +110,9 @@ public function testDecode() public function testFlatten() { $paired = array( - array(1,2), - array(3,4), - array(5,6) + array(1,2), + array(3,4), + array(5,6) ); $this->assertEquals(array(1,2,3,4,5,6),Polyline::Flatten($paired)); } @@ -123,9 +123,9 @@ public function testFlatten() public function testPair() { $paired = array( - array(1,2), - array(3,4), - array(5,6) + array(1,2), + array(3,4), + array(5,6) ); $this->assertEquals($paired,Polyline::Pair(array(1,2,3,4,5,6))); } diff --git a/tests/PrecisionTest.php b/tests/PrecisionTest.php index f01398d..91cacf9 100644 --- a/tests/PrecisionTest.php +++ b/tests/PrecisionTest.php @@ -7,13 +7,13 @@ class PrecisionTest extends PHPUnit_Framework_TestCase { protected $encoded = 'q}~~|AdshNkSsBid@eGqBlm@yKhj@bA?'; protected $points = array( - 49.283049, -0.250691, - 49.283375, -0.250633, - 49.283972, -0.250502, - 49.284029, -0.251245, - 49.284234, -0.251938, - 49.284200, -0.251938 - ); + 49.283049, -0.250691, + 49.283375, -0.250633, + 49.283972, -0.250502, + 49.284029, -0.251245, + 49.284234, -0.251938, + 49.284200, -0.251938 + ); /** * @covers Polyline::Encode @@ -21,10 +21,10 @@ class PrecisionTest extends PHPUnit_Framework_TestCase */ public function testEncodePrecision() { - $this->assertEquals( - $this->encoded, - PrecisionPolyline::Encode($this->points) - ); + $this->assertEquals( + $this->encoded, + PrecisionPolyline::Encode($this->points) + ); } /** @@ -32,9 +32,9 @@ public function testEncodePrecision() */ public function testDecodePrecision() { - $this->assertEquals( - $this->points, - PrecisionPolyline::Decode($this->encoded) - ); + $this->assertEquals( + $this->points, + PrecisionPolyline::Decode($this->encoded) + ); } -} \ No newline at end of file +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 517a80a..bc9a255 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,12 +1,12 @@ Date: Fri, 11 Jul 2014 13:43:30 +0200 Subject: [PATCH 02/16] ignore tags --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 782217c..d1c0971 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ dist vendor .idea +tags From a446d8c7f3e3c7af9e347a785281239af6f3f43e Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Fri, 11 Jul 2014 13:50:02 +0200 Subject: [PATCH 03/16] phpunit: generate code coverage report --- .gitignore | 1 + phpunit.xml.dist | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d1c0971..8014d65 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ dist vendor .idea tags +coverage-report-html diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a909508..94e8f1d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -8,7 +8,6 @@ convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" bootstrap="tests/bootstrap.php" > @@ -21,5 +20,10 @@ ./src/ + + + + + From 92f1f85f56ed68e40a1dfbf2c47c43c684194558 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Fri, 11 Jul 2014 13:52:38 +0200 Subject: [PATCH 04/16] phpunit: remove tab --- phpunit.xml.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 94e8f1d..e2ceb03 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,6 +9,7 @@ processIsolation="false" stopOnFailure="false" bootstrap="tests/bootstrap.php" > + ./tests/ @@ -22,8 +23,7 @@ - + - From 0a011437aa5f47c10eb30812a5a15c92f6f147b7 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 11:31:51 +0200 Subject: [PATCH 05/16] lint: add phpcs as a dev-requirement and a 'make lint' rule to Makefile' --- Makefile | 16 +++++++++------- composer.json | 3 +++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1b70c2d..4f47776 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,8 @@ PREFIX = . DIST_DIR = ${PREFIX}/dist PLY = Polyline.php -GMPET = ${DIST_DIR}/${PLY} -SRC_GMPET = ${SRC_DIR}/${PLY} +GMPET = ${DIST_DIR}/${PLY} +SRC_GMPET = ${SRC_DIR}/${PLY} NAMESPACE_GMPET = ${DIST_DIR}/emcconville/${PLY} GMPET_VER = $(shell git log -1 --pretty=format:%h\ %p\ %t) @@ -27,24 +27,26 @@ goodbye: polyline: ${SRC_GMPET} | ${DIST_DIR} @@echo "Building Polyline" - + @@cat ${SRC_GMPET} | \ sed 's/@VERSION@/'"${GMPET_VER}"'/' | \ sed 's/@DATE@/'"${GMPET_DATE}"'/' > ${GMPET}; - + namespace: polyline @@echo "Patching namespace" @@mkdir -p ${DIST_DIR}/emcconville @@cat ${GMPET} | \ sed 's/^\/\/@NAMESPACE@\s*//g' > ${NAMESPACE_GMPET} -test: +test: @@echo "Testing Polyline" @@if test ! -z ${PHPUNIT}; then \ ${PHPUNIT} --testdox ; \ else \ echo "PHPUnit not installed. Skipping build test."; \ fi - + +lint: + vendor/bin/phpcs --standard=tests/phpcs-ruleset.xml src tests + .PHONY: all clean goodbye polyline namespace test - \ No newline at end of file diff --git a/composer.json b/composer.json index 5d28bb5..dd74e3f 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,9 @@ "require": { "php": ">=5.3" }, + "require-dev": { + "squizlabs/php_codesniffer": "2.0.0a2" + }, "autoload": { "files": ["src/Polyline.php"] } From a838353acc522109c750ae08e03108bfc2340e35 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 11:32:31 +0200 Subject: [PATCH 06/16] ignore composer.lock --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8014d65..c51ddc6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ vendor .idea tags coverage-report-html +composer.lock From f13ead332b2a37d2f949beec2c1367a8e313b9d0 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 11:32:53 +0200 Subject: [PATCH 07/16] lint: add a phpcs ruleset --- tests/phpcs-ruleset.xml | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/phpcs-ruleset.xml diff --git a/tests/phpcs-ruleset.xml b/tests/phpcs-ruleset.xml new file mode 100644 index 0000000..987b76b --- /dev/null +++ b/tests/phpcs-ruleset.xml @@ -0,0 +1,50 @@ + + + custom code convention rules + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From eda8568c7a89d793e0d276449a1a68245c78e049 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 11:34:40 +0200 Subject: [PATCH 08/16] lint: opening brancket on new line (zend convention) --- src/Polyline.php | 29 ++++++++++++++++++----------- tests/PolylineTest.php | 5 ++--- tests/PrecisionTest.php | 1 + tests/bootstrap.php | 4 ++-- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/Polyline.php b/src/Polyline.php index abb49b0..22c7a46 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -28,8 +28,8 @@ //@NAMESPACE@ namespace emcconville { -class Polyline { - +class Polyline +{ /** * @var array $polylines */ @@ -70,7 +70,6 @@ public static function Singleton() { return self::$instance instanceof self ? self::$instance : self::$instance = new self; } - /** * Magic method for supporting wildcard getters * @@ -80,7 +79,8 @@ public static function Singleton() { * @method getPoints( "{Node}") //=> array of points for polyline "Node" * @method getEncoded("{Node}") //=> encoded string for polyline "Node" */ - public function __call($method,$arguments) { + public function __call($method,$arguments) + { $return = null; if (preg_match('/^get(.+?)(points|encoded)$/i',$method,$matches)) { list($all,$node,$type) = $matches; @@ -101,7 +101,8 @@ public function __call($method,$arguments) { * @param string $type * @return mixed */ - public function getPolyline($node, $type) { + public function getPolyline($node, $type) + { $node = strtolower($node); $type = in_array($type,array('points','encoded')) ? $type : 'encoded'; return isset($this->polylines[$node]) @@ -116,7 +117,8 @@ public function getPolyline($node, $type) { * @param mixed [ string | array ] optional * @return array */ - public function polyline() { + public function polyline() + { $arguments = func_get_args(); $return = null; switch (count($arguments)) { @@ -144,7 +146,8 @@ public function polyline() { * * @return array $polylines */ - public function listPolylines() { + public function listPolylines() + { return $return = array_keys($this->polylines); } @@ -155,7 +158,8 @@ public function listPolylines() { * @param integer $precision optional * @return string $encoded_string */ - final public static function Encode($points) { + final public static function Encode($points) + { $points = self::Flatten($points); $encoded_string = ''; $index = 0; @@ -186,7 +190,8 @@ final public static function Encode($points) { * @param integer $precision optional * @return array $points */ - final public static function Decode($string) { + final public static function Decode($string) + { $points = array(); $index = $i = 0; $previous = array(0,0); @@ -213,7 +218,8 @@ final public static function Decode($string) { * @param array $array * @return array $flatten */ - final public static function Flatten($array) { + final public static function Flatten($array) + { $flatten = array(); foreach(array_values($array) as $node) { if (is_array($node)) { @@ -231,7 +237,8 @@ final public static function Flatten($array) { * @param array $list * @return array $pairs */ - final public static function Pair($list) { + final public static function Pair($list) + { $pairs = array(); if(!is_array($list)) { return $pairs; } do { diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 3be2187..7a8046e 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -33,7 +33,8 @@ public function testSingleton() * @covers Polyline::Flatten * @depends testSingleton */ - public function testPolyline(Polyline $object) { + public function testPolyline(Polyline $object) + { $encoded = $object->polyline($this->polylineName,$this->points); $this->assertEquals($encoded,$this->encoded); $hash = $object->polyline($this->polylineName); @@ -94,7 +95,6 @@ public function testEncode() $this->assertEquals($this->encoded,Polyline::Encode($this->points)); } - /** * @covers Polyline::Decode */ @@ -103,7 +103,6 @@ public function testDecode() $this->assertCount(count($this->points) * 2, Polyline::Decode($this->encoded)); } - /** * @covers Polyline::Flatten */ diff --git a/tests/PrecisionTest.php b/tests/PrecisionTest.php index 91cacf9..2030511 100644 --- a/tests/PrecisionTest.php +++ b/tests/PrecisionTest.php @@ -3,6 +3,7 @@ class PrecisionPolyline extends Polyline { protected static $precision = 6; } + class PrecisionTest extends PHPUnit_Framework_TestCase { protected $encoded = 'q}~~|AdshNkSsBid@eGqBlm@yKhj@bA?'; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index bc9a255..7d8dadc 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,10 +1,10 @@ Date: Sat, 12 Jul 2014 11:40:01 +0200 Subject: [PATCH 09/16] lint: fix the following issues found by phpcs: 62 | ERROR | [x] Opening brace should be on a new line 62 | ERROR | [ ] Closing brace must be on a line by itself 69 | ERROR | [x] Opening brace should be on a new line 85 | ERROR | [x] No space found after comma in function call 85 | ERROR | [x] No space found after comma in function call 87 | ERROR | [x] No space found after comma in function call 88 | ERROR | [x] No space found after comma in function call 88 | ERROR | [x] No space found after comma in function call 91 | ERROR | [x] No space found after comma in function call 107 | ERROR | [x] No space found after comma in function call 164 | ERROR | [ ] Variable "encoded_string" is not in valid camel caps format 167 | ERROR | [ ] Expected "foreach (...) {\n"; found "foreach(...) {\n" 176 | ERROR | [ ] Expected "while (...) {\n"; found "while(...) {\n" 181 | ERROR | [ ] Variable "encoded_string" is not in valid camel caps format 183 | ERROR | [ ] Variable "encoded_string" is not in valid camel caps format 201 | ERROR | [x] No space found after comma in function call 224 | ERROR | [ ] Expected "foreach (...) {\n"; found "foreach(...) {\n" 226 | ERROR | [x] No space found after comma in function call 243 | ERROR | [ ] Expected "if (...) {\n"; found "if(...) { " 243 | ERROR | [ ] Closing brace must be on a line by itself --- src/Polyline.php | 51 ++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/Polyline.php b/src/Polyline.php index 22c7a46..170cf8e 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -59,14 +59,17 @@ class Polyline * * @see Polyline::Singleton */ - private function __construct() {} + private function __construct() + { + } /** * Static instance method * * @return Polyline */ - public static function Singleton() { + public static function Singleton() + { return self::$instance instanceof self ? self::$instance : self::$instance = new self; } @@ -82,13 +85,13 @@ public static function Singleton() { public function __call($method,$arguments) { $return = null; - if (preg_match('/^get(.+?)(points|encoded)$/i',$method,$matches)) { + if (preg_match('/^get(.+?)(points|encoded)$/i', $method, $matches)) { list($all,$node,$type) = $matches; - return $this->getPolyline(strtolower($node),strtolower($type)); - } elseif (preg_match('/^get(points|encoded)$/i',$method,$matches)) { + return $this->getPolyline(strtolower($node), strtolower($type)); + } elseif (preg_match('/^get(points|encoded)$/i', $method, $matches)) { list($all,$type) = $matches; $node = array_shift($arguments); - return $this->getPolyline(strtolower($node),strtolower($type)); + return $this->getPolyline(strtolower($node), strtolower($type)); } else { throw new BadMethodCallException(); } @@ -104,7 +107,7 @@ public function __call($method,$arguments) public function getPolyline($node, $type) { $node = strtolower($node); - $type = in_array($type,array('points','encoded')) ? $type : 'encoded'; + $type = in_array($type, array('points','encoded')) ? $type : 'encoded'; return isset($this->polylines[$node]) ? $this->polylines[$node][$type] : ($type =='points' ? array() : null); @@ -122,7 +125,7 @@ public function polyline() $arguments = func_get_args(); $return = null; switch (count($arguments)) { - case 2 : + case 2: list($node,$value) = $arguments; $isArray = is_array($value); $return = $this->polylines[strtolower($node)] = array( @@ -131,7 +134,7 @@ public function polyline() ); $return = $return[$isArray ? 'encoded' : 'points' ]; break; - case 1 : + case 1: $node = strtolower((string)array_shift($arguments)); $return = isset($this->polylines[$node]) ? $this->polylines[$node] @@ -144,7 +147,7 @@ public function polyline() /** * Retrieve list of polyline within singleton * - * @return array $polylines + * @return array polylines */ public function listPolylines() { @@ -156,15 +159,15 @@ public function listPolylines() * * @param array $points * @param integer $precision optional - * @return string $encoded_string + * @return string encoded string */ final public static function Encode($points) { $points = self::Flatten($points); - $encoded_string = ''; + $encodedString = ''; $index = 0; $previous = array(0,0); - foreach($points as $number) { + foreach ($points as $number) { $number = (float)($number); $number = floor($number * pow(10, static::$precision)); $diff = $number - $previous[$index % 2]; @@ -173,14 +176,14 @@ final public static function Encode($points) $index++; $number = ($number < 0) ? ~($number << 1) : ($number << 1); $chunk = ''; - while($number >= 0x20) { + while ($number >= 0x20) { $chunk .= chr((0x20 | ($number & 0x1f)) + 63); $number >>= 5; } $chunk .= chr($number + 63); - $encoded_string .= $chunk; + $encodedString .= $chunk; } - return $encoded_string; + return $encodedString; } /** @@ -188,7 +191,7 @@ final public static function Encode($points) * * @param string $string * @param integer $precision optional - * @return array $points + * @return array points */ final public static function Decode($string) { @@ -198,7 +201,7 @@ final public static function Decode($string) while ($i < strlen($string)) { $shift = $result = 0x00; do { - $bit = ord(substr($string,$i++)) - 63; + $bit = ord(substr($string, $i++)) - 63; $result |= ($bit & 0x1f) << $shift; $shift += 5; } while ($bit >= 0x20); @@ -216,14 +219,14 @@ final public static function Decode($string) * Reduce multi-dimensional to single list * * @param array $array - * @return array $flatten + * @return array flattened */ final public static function Flatten($array) { $flatten = array(); - foreach(array_values($array) as $node) { + foreach (array_values($array) as $node) { if (is_array($node)) { - $flatten = array_merge($flatten,self::Flatten($node)); + $flatten = array_merge($flatten, self::Flatten($node)); } else { $flatten[] = $node; } @@ -235,12 +238,14 @@ final public static function Flatten($array) * Concat list into pairs of points * * @param array $list - * @return array $pairs + * @return array pairs */ final public static function Pair($list) { $pairs = array(); - if(!is_array($list)) { return $pairs; } + if (!is_array($list)) { + return $pairs; + } do { $pairs[] = array( array_shift($list), From 26107b66186b46437a23b290390ec2523d7bb2c7 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 11:41:36 +0200 Subject: [PATCH 10/16] lint: fix the following found by phpcs: 26 | ERROR | [x] No space found after comma in function call 38 | ERROR | [x] No space found after comma in function call 39 | ERROR | [x] No space found after comma in function call 41 | ERROR | [x] No space found after comma in function call 51 | ERROR | [x] No space found after comma in function call 51 | ERROR | [x] No space found after comma in function call 52 | ERROR | [x] No space found after comma in function call 62 | ERROR | [x] No space found after comma in function call 63 | ERROR | [x] No space found after comma in function call 85 | ERROR | [x] No space found after comma in function call 95 | ERROR | [x] No space found after comma in function call 116 | ERROR | [x] No space found after comma in function call 129 | ERROR | [x] No space found after comma in function call --- tests/PolylineTest.php | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 7a8046e..5f7a53f 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -23,7 +23,7 @@ class PolylineTest extends PHPUnit_Framework_TestCase public function testSingleton() { $object = Polyline::Singleton(); - $this->assertInstanceOf('Polyline',$object); + $this->assertInstanceOf('Polyline', $object); return $object; } @@ -35,10 +35,10 @@ public function testSingleton() */ public function testPolyline(Polyline $object) { - $encoded = $object->polyline($this->polylineName,$this->points); - $this->assertEquals($encoded,$this->encoded); + $encoded = $object->polyline($this->polylineName, $this->points); + $this->assertEquals($encoded, $this->encoded); $hash = $object->polyline($this->polylineName); - $this->assertEquals($encoded,$hash['encoded']); + $this->assertEquals($encoded, $hash['encoded']); return $object; } @@ -48,8 +48,8 @@ public function testPolyline(Polyline $object) */ public function testGetPolyline(Polyline $object) { - $this->assertEquals($this->encoded,$object->getPolyline($this->polylineName,'encoded')); - $this->assertNull($object->getPolyline('I_Dont_exsits','encoded')); + $this->assertEquals($this->encoded, $object->getPolyline($this->polylineName, 'encoded')); + $this->assertNull($object->getPolyline('I_Dont_exsits', 'encoded')); return $object; } @@ -59,8 +59,8 @@ public function testGetPolyline(Polyline $object) */ public function testGetters(Polyline $object) { - $this->assertEquals($this->encoded,$object->getEncoded($this->polylineName)); - $this->assertEquals($this->encoded,$object->getHydeParkRecordsEncoded()); + $this->assertEquals($this->encoded, $object->getEncoded($this->polylineName)); + $this->assertEquals($this->encoded, $object->getHydeParkRecordsEncoded()); return $object; } @@ -82,7 +82,7 @@ public function testGettersException(Polyline $object) public function testListPolylines(Polyline $object) { $list = $object->listPolylines(); - $this->assertCount(1,$list); + $this->assertCount(1, $list); } /** @@ -92,7 +92,7 @@ public function testListPolylines(Polyline $object) public function testEncode() { // Remove the following lines when you implement this test. - $this->assertEquals($this->encoded,Polyline::Encode($this->points)); + $this->assertEquals($this->encoded, Polyline::Encode($this->points)); } /** @@ -113,7 +113,7 @@ public function testFlatten() array(3,4), array(5,6) ); - $this->assertEquals(array(1,2,3,4,5,6),Polyline::Flatten($paired)); + $this->assertEquals(array(1,2,3,4,5,6), Polyline::Flatten($paired)); } /** @@ -126,6 +126,6 @@ public function testPair() array(3,4), array(5,6) ); - $this->assertEquals($paired,Polyline::Pair(array(1,2,3,4,5,6))); + $this->assertEquals($paired, Polyline::Pair(array(1,2,3,4,5,6))); } } From 7c39dd6a85990a0ebc95ab5ab298723567ab5239 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 12:04:46 +0200 Subject: [PATCH 11/16] refactor polyline() --- src/Polyline.php | 81 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/Polyline.php b/src/Polyline.php index 170cf8e..aa4254b 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -120,28 +120,69 @@ public function getPolyline($node, $type) * @param mixed [ string | array ] optional * @return array */ - public function polyline() + public function polyline($node, $value = '') { - $arguments = func_get_args(); - $return = null; - switch (count($arguments)) { - case 2: - list($node,$value) = $arguments; - $isArray = is_array($value); - $return = $this->polylines[strtolower($node)] = array( - 'points' => $isArray ? self::Flatten($value) : self::Decode($value), - 'encoded' => $isArray ? self::Encode($value) : $value - ); - $return = $return[$isArray ? 'encoded' : 'points' ]; - break; - case 1: - $node = strtolower((string)array_shift($arguments)); - $return = isset($this->polylines[$node]) - ? $this->polylines[$node] - : array( 'points' => null, 'encoded' => null ); - break; + $node = strtolower($node); + + if (is_array($value)) { + return $this->importPolyArray($node, $value); + } else if ($value != '') { + return $this->importPolyString($node, $value); } - return $return; + + return $this->getNode($node); + } + + /** + * Imports a polyline specifed in an array of arrays + * + * @param string $node polyline name + * @param array $value + * @return string encoded polyline + */ + public function importPolyArray($node, $value) + { + if (!is_array($value)) { + throw new InvalidArgumentException(); + } + + $return = $this->polylines[strtolower($node)] = array( + 'points' => self::Flatten($value), + 'encoded' => self::Encode($value) + ); + return $return['encoded']; + } + + /** + * Imports a encoded polyline to the internal buffer + * @param string $node polyline name + * @param string $value + * @return decoded polyline + */ + public function importPolyString($node, $value) + { + if (!is_string($value)) { + throw new InvalidArgumentException(); + } + + $node = strtolower($node); + + $return = $this->polylines[$node] = array( + 'points' => self::Decode($value), + 'encoded' => $value + ); + return $return['points']; + } + + /** + * @return polyline at the specified $node + */ + public function getNode($node) + { + $node = strtolower($node); + return isset($this->polylines[$node]) + ? $this->polylines[$node] + : array('points' => null, 'encoded' => null); } /** From 93b7fdc4bd194f415320b5255b57e088de739607 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 12:11:32 +0200 Subject: [PATCH 12/16] test: add tests for new methods --- tests/PolylineTest.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 5f7a53f..c008912 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -42,6 +42,27 @@ public function testPolyline(Polyline $object) return $object; } + /** + * @depends testSingleton + */ + public function testGetNode(Polyline $object) + { + $encoded = $object->importPolyArray($this->polylineName, $this->points); + $this->assertEquals($encoded, $this->encoded); + $hash = $object->getNode($this->polylineName); + $this->assertEquals($encoded, $hash['encoded']); + return $object; + } + + /** + * @depends testSingleton + */ + public function testImportPolyString(Polyline $object) + { + $x = $object->importPolyString('nodeKey', $this->encoded); + $this->assertEquals(14, count($x)); + } + /** * @covers Polyline::getPolyline * @depends testPolyline @@ -82,7 +103,7 @@ public function testGettersException(Polyline $object) public function testListPolylines(Polyline $object) { $list = $object->listPolylines(); - $this->assertCount(1, $list); + $this->assertCount(2, $list); } /** From c14a48bf8796506bab3939375b495f243b4e4968 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Fri, 11 Jul 2014 13:17:56 +0200 Subject: [PATCH 13/16] tests: add a test based on the encoding example from Google Maps API docs at https://developers.google.com/maps/documentation/utilities/polylinealgorithm --- tests/PolylineTest.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index c008912..6af1014 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -1,4 +1,5 @@ polyline($this->polylineName, $points); + $this->assertEquals('_p~iF~ps|U_ulLnnqC_mqNvxq`@', $encoded); + } + /** * @covers Polyline::polyline * @covers Polyline::Encode From c860bca7f8f2847e8e09b07a099ccbbd57ae62b2 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 12:13:08 +0200 Subject: [PATCH 14/16] pass invalid name to exception --- src/Polyline.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Polyline.php b/src/Polyline.php index aa4254b..88df3f9 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -82,7 +82,7 @@ public static function Singleton() * @method getPoints( "{Node}") //=> array of points for polyline "Node" * @method getEncoded("{Node}") //=> encoded string for polyline "Node" */ - public function __call($method,$arguments) + public function __call($method, $arguments) { $return = null; if (preg_match('/^get(.+?)(points|encoded)$/i', $method, $matches)) { @@ -93,7 +93,7 @@ public function __call($method,$arguments) $node = array_shift($arguments); return $this->getPolyline(strtolower($node), strtolower($type)); } else { - throw new BadMethodCallException(); + throw new BadMethodCallException($method); } return $return; } From d8d3dffdd2d17b0436240e772426d748b88d3839 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 12:16:16 +0200 Subject: [PATCH 15/16] tests: test failure code paths --- tests/PolylineTest.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 6af1014..9d3eaff 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -31,7 +31,8 @@ public function testSingleton() /** * @depends testSingleton */ - public function testGooglePolyline(Polyline $object) { + public function testGooglePolyline(Polyline $object) + { // uses example from google maps api docs // at https://developers.google.com/maps/documentation/utilities/polylinealgorithm $points = array( @@ -80,6 +81,24 @@ public function testImportPolyString(Polyline $object) $this->assertEquals(14, count($x)); } + /** + * @depends testSingleton + * @expectedException InvalidArgumentException + */ + public function testImportPolyArrayBadInput(Polyline $object) + { + $encoded = $object->importPolyArray($this->polylineName, null); + } + + /** + * @depends testSingleton + * @expectedException InvalidArgumentException + */ + public function testImportPolyStringBadInput(Polyline $object) + { + $encoded = $object->importPolyString($this->polylineName, null); + } + /** * @covers Polyline::getPolyline * @depends testPolyline From d5064eaa655823026c6432e33e14a9d1b57ddfa9 Mon Sep 17 00:00:00 2001 From: Martin Lindhe Date: Sat, 12 Jul 2014 12:36:50 +0200 Subject: [PATCH 16/16] add importPolyObjects() --- src/Polyline.php | 27 +++++++++++++++++++++++++++ tests/PolylineTest.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/Polyline.php b/src/Polyline.php index 88df3f9..d944011 100755 --- a/src/Polyline.php +++ b/src/Polyline.php @@ -174,6 +174,33 @@ public function importPolyString($node, $value) return $return['points']; } + /** + * Imports a polyline specifed in an array of objects, + * extracting coordinates from latitude & longitude parameters + * of the objects + * + * @param string $node polyline name + * @param array $objs + * @return string encoded polyline + */ + public function importPolyObjects($node, $objs) + { + if (!is_array($objs)) { + throw new InvalidArgumentException(); + } + + $arr = array(); + + foreach ($objs as $obj) { + + if (property_exists($obj, 'latitude') && property_exists($obj, 'longitude')) { + $arr[] = array($obj->latitude, $obj->longitude); + } + } + + return $this->importPolyArray($node, $arr); + } + /** * @return polyline at the specified $node */ diff --git a/tests/PolylineTest.php b/tests/PolylineTest.php index 9d3eaff..a1d3a5c 100644 --- a/tests/PolylineTest.php +++ b/tests/PolylineTest.php @@ -1,5 +1,17 @@ latitude = $lat; + $this->longitude = $long; + } +} + /** * Generated by PHPUnit_SkeletonGenerator on 2012-02-17 at 14:08:49. */ @@ -81,6 +93,31 @@ public function testImportPolyString(Polyline $object) $this->assertEquals(14, count($x)); } + /** + * @depends testSingleton + */ + public function testImportPolyObjects(Polyline $object) + { + $objs = array(); + foreach ($this->points as $point) { + $objs[] = new MyCoord($point[0], $point[1]); + } + + $this->assertEquals( + $this->encoded, + $object->importPolyObjects($this->polylineName, $objs) + ); + } + + /** + * @depends testSingleton + * @expectedException InvalidArgumentException + */ + public function testImportPolyObjectsBadInput(Polyline $object) + { + $encoded = $object->importPolyObjects($this->polylineName, null); + } + /** * @depends testSingleton * @expectedException InvalidArgumentException