Changeset 17896
- Timestamp:
- 05/03/09 17:55:52 (4 years ago)
- Files:
-
- plugins/sfEasyGMapPlugin/trunk/lib/GMap.class.php (modified) (5 diffs)
- plugins/sfEasyGMapPlugin/trunk/lib/GMapBounds.class.php (modified) (2 diffs)
- plugins/sfEasyGMapPlugin/trunk/lib/GMapCoord.class.php (modified) (5 diffs)
- plugins/sfEasyGMapPlugin/trunk/lib/GMapMarker.class.php (modified) (6 diffs)
- plugins/sfEasyGMapPlugin/trunk/package.xml (modified) (4 diffs)
- plugins/sfEasyGMapPlugin/trunk/test/unit/GMapBoundsTest.php (modified) (2 diffs)
- plugins/sfEasyGMapPlugin/trunk/test/unit/GMapCoordTest.php (modified) (2 diffs)
- plugins/sfEasyGMapPlugin/trunk/test/unit/GMapTest.php (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
plugins/sfEasyGMapPlugin/trunk/lib/GMap.class.php
r16320 r17896 38 38 // options 39 39 protected $options = array(); 40 41 protected $zoom = null; 42 protected $center_coord = null; 40 43 41 44 /** … … 111 114 { 112 115 $api_keys = sfConfig::get('app_google_maps_api_keys'); 116 if (is_null($api_keys)) 117 { 118 return ''; 119 } 120 113 121 if (is_array($api_keys) && array_key_exists($domain,$api_keys)) 114 122 { … … 459 467 public function setCenter($lat=null,$lng=null) 460 468 { 461 if (!is_null($lat)) 462 { 463 $this->center_lat = $lat; 464 } 465 if (!is_null($lng)) 466 { 467 $this->center_lng = $lng; 468 } 469 } 469 $this->center_coord = new GMapCoord($lat, $lng); 470 } 471 472 /** 473 * 474 * @return GMapCoord 475 * @author fabriceb 476 * @since 2009-05-02 477 */ 478 public function getCenterCoord() 479 { 480 481 return $this->center_coord; 482 } 483 /** 484 * 485 * @return float 486 * @author fabriceb 487 * @since 2009-05-02 488 */ 470 489 public function getCenterLat() 471 490 { 472 491 473 return $this->center_lat; 474 } 492 return $this->getCenterCoord()->getLatitude(); 493 } 494 /** 495 * 496 * @return float 497 * @author fabriceb 498 * @since 2009-05-02 499 */ 475 500 public function getCenterLng() 476 501 { 477 return $this-> center_lng;502 return $this->getCenterCoord()->getLongitude(); 478 503 } 479 504 public function getZoom() … … 482 507 return $this->zoom; 483 508 } 509 510 /** 511 * gets the width of the map in pixels according to container style 512 * @return integer 513 * @author fabriceb 514 * @since 2009-05-03 515 */ 516 public function getWidth() 517 { 518 519 return intval(substr($this->getContainerStyle('width'),0,-2)); 520 } 521 522 /** 523 * gets the width of the map in pixels according to container style 524 * @return integer 525 * @author fabriceb 526 * @since 2009-05-03 527 */ 528 public function getHeight() 529 { 530 531 return intval(substr($this->getContainerStyle('height'),0,-2)); 532 } 533 534 /** 535 * sets the width of the map in pixels 536 * 537 * @param integer 538 * @author fabriceb 539 * @since 2009-05-03 540 */ 541 public function setWidth($width) 542 { 543 $this->setContainerStyle('width',$width.'px'); 544 } 545 546 /** 547 * sets the width of the map in pixels 548 * 549 * @param integer 550 * @author fabriceb 551 * @since 2009-05-03 552 */ 553 public function setHeight($height) 554 { 555 $this->setContainerStyle('height',$height.'px'); 556 } 557 484 558 485 559 /** … … 526 600 return implode('|',$markers_code); 527 601 } 602 603 /** 604 * 605 * calculates the center of the markers linked to the map 606 * 607 * @return GMapCoord 608 * @author fabriceb 609 * @since 2009-05-02 610 */ 611 public function getMarkersCenterCoord() 612 { 613 614 return GMapMarker::getCenterCoord($this->markers); 615 } 616 617 /** 618 * sets the center of the map at the center of the markers 619 * 620 * @author fabriceb 621 * @since 2009-05-02 622 */ 623 public function centerOnMarkers() 624 { 625 $center = $this->getMarkersCenterCoord(); 626 627 $this->setCenter($center->getLatitude(), $center->getLongitude()); 628 } 629 630 /** 631 * 632 * calculates the zoom which fits the markers on the map 633 * 634 * @param integer $margin a scaling factor around the smallest bound 635 * @return integer $zoom 636 * @author fabriceb 637 * @since 2009-05-02 638 */ 639 public function getMarkersFittingZoom($margin = 0) 640 { 641 $bounds = GMapBounds::getBoundsContainingMarkers($this->markers, $margin); 642 643 return $bounds->getZoom(min($this->getWidth(),$this->getHeight())); 644 } 645 646 /** 647 * sets the zoom of the map to fit the markers (uses mercator projection to guess the size in pixels of the bounds) 648 * WARNING : this depends on the width in pixels of the resulting map 649 * 650 * @param integer $margin a scaling factor around the smallest bound 651 * @author fabriceb 652 * @since 2009-05-02 653 */ 654 public function zoomOnMarkers($margin = 0) 655 { 656 $this->setZoom($this->getMarkersFittingZoom($margin)); 657 } 658 659 /** 660 * sets the zoom and center of the map to fit the markers (uses mercator projection to guess the size in pixels of the bounds) 661 * 662 * @param integer $margin a scaling factor around the smallest bound 663 * @author fabriceb 664 * @since 2009-05-02 665 */ 666 public function centerAndZoomOnMarkers($margin = 0) 667 { 668 $this->zoomOnMarkers($margin); 669 $this->centerOnMarkers(); 670 } 528 671 529 672 } plugins/sfEasyGMapPlugin/trunk/lib/GMapBounds.class.php
r16301 r17896 223 223 224 224 /** 225 * Returns the most appropriate zoom to see the bounds on a map with m ax(width,height) = $max_w_h226 * 227 * @param integer $m ax_w_h width or height of the map in pixels225 * Returns the most appropriate zoom to see the bounds on a map with min(width,height) = $min_w_h 226 * 227 * @param integer $min_w_h width or height of the map in pixels 228 228 * @return integer 229 229 * @author fabriceb 230 230 * @since Feb 18, 2009 fabriceb 231 231 */ 232 public function getZoom($max_w_h) 233 { 234 $sw_lat_pix = GMapCoord::fromLatToPix($this->getSouthWest()->getLatitude(),1); 235 $ne_lat_pix = GMapCoord::fromLatToPix($this->getNorthEast()->getLatitude(),1); 232 public function getZoom($min_w_h) 233 { 234 /* 235 236 formula: the width of the bounds in "pixels" is pix_w * 2^z 237 We want pix_w * 2^z to fit in min_w_h so we are looking for 238 z = round ( log2 ( min_w_h / pix_w ) ) 239 */ 240 241 $sw_lat_pix = GMapCoord::fromLatToPix($this->getSouthWest()->getLatitude(),0); 242 $ne_lat_pix = GMapCoord::fromLatToPix($this->getNorthEast()->getLatitude(),0); 236 243 $pix_h = abs($sw_lat_pix-$ne_lat_pix); 237 $factor_h = $m ax_w_h / $pix_h;238 239 $sw_lng_pix = GMapCoord::fromLngToPix($this->getSouthWest()->getLongitude(), 1);240 $ne_lng_pix = GMapCoord::fromLngToPix($this->getNorthEast()->getLongitude(), 1);244 $factor_h = $min_w_h / $pix_h; 245 246 $sw_lng_pix = GMapCoord::fromLngToPix($this->getSouthWest()->getLongitude(),0); 247 $ne_lng_pix = GMapCoord::fromLngToPix($this->getNorthEast()->getLongitude(),0); 241 248 $pix_w = abs($sw_lng_pix-$ne_lng_pix); 242 $factor_w = $m ax_w_h / $pix_w;243 244 $factor = m ax($factor_w,$factor_h);245 246 return round(log($factor,2)) +1;249 $factor_w = $min_w_h / $pix_w; 250 251 $factor = min($factor_w,$factor_h); 252 253 return round(log($factor,2)); 247 254 } 248 255 … … 317 324 return $bounds; 318 325 } 326 327 328 /** 329 * 330 * @param GMapMarker[] $markers array of MArkers 331 * @param float $margin margin factor for the bounds 332 * @return GMapBounds 333 * @author fabriceb 334 * @since 2009-05-02 335 * 336 **/ 337 public static function getBoundsContainingMarkers($markers, $margin = 0) 338 { 339 $coords = array(); 340 foreach($markers as $marker) 341 { 342 array_push($coords, $marker->getGMapCoord()); 343 } 344 345 return GMapBounds::getBoundsContainingCoords($coords, $margin); 346 } 319 347 320 348 plugins/sfEasyGMapPlugin/trunk/lib/GMapCoord.class.php
r16301 r17896 22 22 protected $longitude; 23 23 24 const EARTH_RADIUS = 6380; 25 24 26 public function __construct($latitude = null, $longitude = null) 25 27 { … … 72 74 public static function fromLngToPix($lng,$zoom) 73 75 { 74 $lngrad = $lng / 180 * 3.14159;76 $lngrad = deg2rad($lng); 75 77 $mercx = $lngrad; 76 $cartx = $mercx + 3.14159;77 $pixelx = $cartx * 256/(2* 3.14159);78 $cartx = $mercx + pi(); 79 $pixelx = $cartx * 256/(2*pi()); 78 80 $pixelx_zoom = $pixelx * pow(2,$zoom); 79 81 … … 93 95 public static function fromLatToPix($lat,$zoom) 94 96 { 95 $latrad = $lat / 180 * 3.14159; 96 $mercy = log(tan($latrad)+1/cos($latrad)); 97 $carty = 3.14159 / 2 - $mercy; 98 $pixely = $carty * 256/(3.14159); 97 if ($lat == 90) 98 { 99 $pixely = 0; 100 } 101 else if ($lat == -90) 102 { 103 $pixely = 256; 104 } 105 else 106 { 107 $latrad = deg2rad($lat); 108 $mercy = log(tan(pi()/4+$latrad/2)); 109 $carty = pi() - $mercy; 110 $pixely = $carty * 256 / 2 / pi(); 111 $pixely = max(0, $pixely); // correct rounding errors near north and south poles 112 $pixely = min(256, $pixely); // correct rounding errors near north and south poles 113 } 99 114 $pixely_zoom = $pixely * pow(2,$zoom); 100 115 … … 115 130 { 116 131 $pixelx = $pixelx_zoom / pow(2,$zoom); 117 $cartx = $pixelx / 256 * 2 * 3.14159;118 $mercx = $cartx - 3.14159;132 $cartx = $pixelx / 256 * 2 * pi(); 133 $mercx = $cartx - pi(); 119 134 $lngrad = $mercx; 120 $lng = 180 * $lngrad / 3.14159;135 $lng = rad2deg($lngrad); 121 136 122 137 return $lng; … … 134 149 */ 135 150 public static function fromPixToLat($pixely_zoom,$zoom) 136 { 151 { 137 152 $pixely = $pixely_zoom / pow(2,$zoom); 138 $carty = $pixely / 256 * 3.14159; 139 $mercy = 3.14159 / 2 - $carty; 140 $latrad = 2 * atan(exp($mercy))-3.14159/2; 141 $lat = 180 * $latrad / 3.14159; 153 if ($pixely == 0) 154 { 155 $lat = 90; 156 } 157 else if ($pixely == 256) 158 { 159 $lat = -90; 160 } 161 else 162 { 163 $carty = $pixely / 256 * 2 * pi(); 164 $mercy = pi() - $carty; 165 $latrad = 2 * atan(exp($mercy))-pi()/2; 166 $lat = rad2deg($latrad); 167 } 142 168 143 169 return $lat; 144 170 } 171 172 /** 173 * Calculates the center of an array of coordiantes 174 * 175 * @param GMapCoord[] $coords 176 * @return GMapCoord 177 * @author fabriceb 178 * @since 2009-05-02 179 */ 180 public static function getCenterCoord($coords) 181 { 182 if (count($coords)==0) 183 { 184 185 return null; 186 } 187 $center_lat = 0; 188 $center_lng = 0; 189 foreach($coords as $coord) 190 { 191 /* @var $coord GMapCoord */ 192 $center_lat += $coord->getLatitude(); 193 $center_lng += $coord->getLongitude(); 194 } 195 196 return new GMapCoord($center_lat/count($coords),$center_lng/count($coords)); 197 } 198 199 /** 200 * toString method 201 * @return string 202 * @author fabriceb 203 * @since 2009-05-02 204 */ 205 public function __toString() 206 { 207 208 return $this->getLatitude().', '.$this->getLongitude(); 209 } 210 211 /** 212 * very approximate calculation of the distance in kilometers between two coordinates 213 * @param GMapCoord $coord2 214 * @return float 215 * @author fabriceb 216 * @since 2009-05-03 217 */ 218 public function distanceFrom($coord2) 219 { 220 $lat_dist = abs($this->getLatitude()-$coord2->getLatitude()); 221 $lng_dist = abs($this->getLongitude()-$coord2->getLongitude()); 222 223 $rad_dist = deg2rad(sqrt(pow($lat_dist,2)+pow($lng_dist,2))); 224 225 return $rad_dist * self::EARTH_RADIUS; 226 } 227 228 /** 229 * very approximate calculation of the distance in kilometers between two coordinates 230 * @param GMapCoord $coord1 231 * @param GMapCoord $coord2 232 * @return float 233 * @author fabriceb 234 * @since 2009-05-03 235 */ 236 public static function distance($coord1, $coord2) 237 { 238 239 return $coord1->distanceFrom($coord2); 240 } 145 241 } plugins/sfEasyGMapPlugin/trunk/lib/GMapMarker.class.php
r16320 r17896 9 9 class GMapMarker 10 10 { 11 /** 12 * javascript name of the marker 13 * 14 * @var string 15 */ 11 16 private $js_name = null; 17 /** 18 * Latitude - deprecated 19 * 20 * @var float 21 */ 12 22 private $lat = null; 23 /** 24 * Longitude - deprecated 25 * 26 * @var float 27 */ 13 28 private $lng = null; 29 /** 30 * Coordinates 31 * 32 * @var GMapCoord 33 */ 34 private $coord = null; 14 35 private $icon = null; 15 36 private $events = array(); … … 27 48 { 28 49 $this->js_name = $js_name; 29 $this->lat = $lat; 30 $this->lng = $lng; 50 $this->coord = new GMapCoord($lat,$lng); 31 51 $this->icon = $icon; 32 52 $this->events = $events; … … 65 85 return $this->icon; 66 86 } 87 88 /** 89 * returns the coordinates object of the marker 90 * 91 * @return GMapCoord 92 * @author fabriceb 93 * @since 2009-05-02 94 */ 95 public function getGMapCoord() 96 { 97 98 return $this->coord; 99 } 100 67 101 /** 68 102 * @return float $lat Javascript latitude … … 71 105 { 72 106 73 return $this-> lat;107 return $this->getGMapCoord()->getLatitude(); 74 108 } 75 109 /** … … 79 113 { 80 114 81 return $this-> lng;115 return $this->getGMapCoord()->getLongitude(); 82 116 } 83 117 … … 175 209 $this->custom_properties[$name] = $value; 176 210 } 211 212 /** 213 * 214 * @param GMapMarker[] $markers array of MArkers 215 * @return GMapCoord 216 * @author fabriceb 217 * @since 2009-05-02 218 * 219 **/ 220 public static function getCenterCoord($markers) 221 { 222 $coords = array(); 223 foreach($markers as $marker) 224 { 225 array_push($coords, $marker->getGMapCoord()); 226 } 227 228 return GMapCoord::getCenterCoord($coords); 229 } 177 230 178 231 } plugins/sfEasyGMapPlugin/trunk/package.xml
r16319 r17896 23 23 <active>yes</active> 24 24 </developer> 25 <date>2009-0 3-13</date>26 <time>1 6:00:00</time>25 <date>2009-05-03</date> 26 <time>17:50:00</time> 27 27 <version> 28 <release>1.0. 0</release>29 <api>1.0. 0</api>28 <release>1.0.2</release> 29 <api>1.0.2</api> 30 30 </version> 31 31 <stability> … … 108 108 <channel>pear.symfony-project.com</channel> 109 109 <min>1.0.0</min> 110 <max>1.2.0</max> 110 <max>1.3.0</max> 111 <exclude>1.3.0</exclude> 111 112 </package> 112 113 </required> … … 134 135 </version> 135 136 <stability> 136 <release> beta</release>137 <api> beta</api>137 <release>stable</release> 138 <api>stable</api> 138 139 </stability> 139 140 <license uri="http://www.symfony-project.org/license">MIT license</license> … … 145 146 * added some very interesting functions concerning coordinates : you can now transform lat/lng into Google Map' pixels coordinates system and vice-versa. This enables one to calculate the bounds around a coordinate for example, knowing only the Google Map's height/width in pixels 146 147 </notes> 147 </release> 148 </release> 149 <release> 150 <version> 151 <release>1.0.1</release> 152 <api>1.0.1</api> 153 </version> 154 <stability> 155 <release>stable</release> 156 <api>stable</api> 157 </stability> 158 <license uri="http://www.symfony-project.org/license">MIT license</license> 159 <notes> 160 * fabriceb: Corrected the package.xml to add all 1.2.x versions of symfony to the list of compatible versions 161 </notes> 162 </release> 163 <release> 164 <version> 165 <release>1.0.2</release> 166 <api>1.0.2</api> 167 </version> 168 <stability> 169 <release>stable</release> 170 <api>stable</api> 171 </stability> 172 <license uri="http://www.symfony-project.org/license">MIT license</license> 173 <notes> 174 * Corrected the Mercator projections for the GMapCoord::fromPixToLat and GMapCoord::fromLatToPix functions 175 * Used PHP pi() and deg2rad functions for better precision 176 * Created tests for the Mercator projections 177 * Added the GMapBounds::getBoundsContainingMarkers($markers) function 178 * Added the GMap::centerAndZoomOnMarkers() function which enables to guess zoom and center of the map to fit the markers. Center is easy to guess. Zoom uses width and height of smallest bound, pixel width and height of the map and Mercator projection 179 </notes> 180 </release> 148 181 </changelog> 149 182 </package> plugins/sfEasyGMapPlugin/trunk/test/unit/GMapBoundsTest.php
r16301 r17896 25 25 $bounds = new GMapBounds(new GMapCoord($sw_lat,$sw_lng),new GMapCoord($ne_lat,$ne_lng)); 26 26 27 $t = new lime_test(1 0, new lime_output_color());27 $t = new lime_test(13, new lime_output_color()); 28 28 29 29 $t->diag('GMapBounds test'); 30 30 31 31 $t->diag('->__toString Test'); 32 $t->is($bounds->__toString(),'((48.822717313, 2.23631017383), (48.8904837922, 2.44230382617))','On a déduit correctement les bounds à partir de la largeur de la carte, le centre et le zoom'); 33 34 $t->diag('->__toString Test'); 35 $t->is($bounds->__toString(),'((48.822717313, 2.23631017383), (48.8904837922, 2.44230382617))','On a déduit correctement les bounds à partir de la largeur de la carte, le centre et le zoom'); 32 $t->is($bounds->__toString(),'((48.7887237041, 2.23631017383), (48.9242565582, 2.44230382617))','On a déduit correctement les bounds à partir de la largeur de la carte, le centre et le zoom'); 36 33 37 34 $t->diag('->getZoom Test'); 38 $t->is($bounds->getZoom(300),11,'Pour voir Paris sur une largeur/hauteur de 300 pix, il faut un zoom 11'); 35 36 $bounds_world = GMapBounds::createFromString('((-90, -180), (90, 180))'); 37 $t->is($bounds_world->getZoom(256),0,'Pour voir le monde sur une largeur/hauteur de 256 pix, il faut un zoom 0'); 38 39 $bounds_world2 = GMapBounds::createFromString('((-86, -179), (86, 179))'); 40 $t->is($bounds_world2->getZoom(256),0,'Pour voir le monde sur une largeur/hauteur de 256 pix, il faut un zoom 0'); 41 42 $bounds_paris = GMapBounds::createFromString('((48.791033113791144, 2.2240447998046875), (48.926559723513435, 2.4300384521484375))'); 43 $t->is($bounds_paris->getZoom(300),11,'Pour voir Paris sur une largeur/hauteur de 300 pix, il faut un zoom 11'); 39 44 40 45 $t->diag('->createFromString Test'); 41 $bounds_france = GMapBounds::createFromString('((42.3 91008609205045, -4.833984375), (51.37178037591737, 8.349609375))');46 $bounds_france = GMapBounds::createFromString('((42.32606244456202, -4.921875), (51.31688050404585, 8.26171875))'); 42 47 $t->is($bounds_france->getZoom(300),5,'Pour voir la France sur une largeur/hauteur de 300 pix, il faut un zoom 5'); 43 48 … … 66 71 $t->is($bounds_123->__toString(),'((48.7887996681, 2.23631017383), (48.9243326339, 2.44230382617))', 'The minimal bounds containing the coords is the rectangle containing the three coords'); 67 72 73 74 $t->diag('->getBoundsContainingMarkers Test'); 75 $marker_1 = new GMapMarker(48.7887996681, 2.23631017383); 76 $marker_2 = new GMapMarker(48.9243326339, 2.44230382617); 77 $marker_3 = new GMapMarker(48.8, 2.4); 78 $bounds_12 = GMapBounds::getBoundsContainingMarkers(array($marker_1,$marker_2)); 79 $bounds_123 = GMapBounds::getBoundsContainingMarkers(array($marker_1,$marker_2,$marker_3)); 80 $t->is($bounds_12->__toString(),'((48.7887996681, 2.23631017383), (48.9243326339, 2.44230382617))', 'The minimal bounds containing the markers is the rectangle containing the two markers'); 81 $t->is($bounds_123->__toString(),'((48.7887996681, 2.23631017383), (48.9243326339, 2.44230382617))', 'The minimal bounds containing the markers is the rectangle containing the three markers'); 82 68 83 $t->diag('Fin du test'); plugins/sfEasyGMapPlugin/trunk/test/unit/GMapCoordTest.php
r16301 r17896 10 10 11 11 12 $t = new lime_test( 4, new lime_output_color());12 $t = new lime_test(286, new lime_output_color()); 13 13 14 14 $t->diag('GMapCoords Tests'); 15 16 for ($zoom=0; $zoom<15;$zoom += 3) 17 { 18 for($lat=90; $lat>=-90; $lat-=10) 19 { 20 $t->is(GMapCoord::fromPixToLat(GMapCoord::fromLatToPix($lat, $zoom),$zoom),(float)$lat,'les projections mercator sur les latitudes marchent'); 21 } 22 for($lng=-180; $lng<=180; $lng+=10) 23 { 24 $t->is(GMapCoord::fromPixToLng(GMapCoord::fromLngToPix($lng, $zoom),$zoom),(float)$lng,'les projections mercator sur les longitudes marchent'); 25 } 26 } 15 27 16 28 $lat = 0; 17 29 $lng = 0; 18 30 $zoom = 0; 31 19 32 $pix = GMapCoord::fromLatToPix($lat, $zoom); 20 33 $t->is($pix,128,'Latitude 0 is at the middle of the map for zoom 0'); … … 31 44 $t->is($pix,0,'Longitude -180 is at the left of the map whathever the zoom'); 32 45 46 47 $coord_paris = new GMapCoord(48.857939,2.346611); 48 $coord_le_mans = new GMapCoord(48.007381,0.202131); 49 $t->is(round(GMapCoord::distance($coord_le_mans, $coord_paris)),257,'Approximate distance between Le Mans and Paris is 257'); 50 51 $coord_luxembourg = new GMapCoord(48.846559,2.340689); 52 $coord_saint_michel = new GMapCoord(48.853717,2.344015); 53 $t->is(round(GMapCoord::distance($coord_luxembourg, $coord_saint_michel)*1000),879,'Approximate distance between RER Luxembourg and Saint-Michel is 879 meters');