Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

mapmanager/mapmanager.php

Go to the documentation of this file.
00001 <?
00002 
00181 require_once('map.php');
00182 
00183 // CLICK TYPES
00185 define ('MM_CLICK_MAIN', 1);
00187 define ('MM_CLICK_REF', 2);
00188 
00189 // ZOOM TYPES
00191 define('MM_ZOOM_NONE', 0);
00193 define('MM_ZOOM_IN', 1);
00195 define('MM_ZOOM_OUT', 2);
00197 define('MM_ZOOM_PAN', 3);
00199 define('MM_ZOOM_SCALE', 4);
00201 define('MM_ZOOM_EXTENT', 5);
00202 
00211 function imagePointToMapPoint($image_point, $map_extent, $image_width, $image_height) 
00212 {
00213     if (!$image_point)
00214         trigger_error('A point object must be specified', E_USER_ERROR);
00215 
00216     //Calculate the X coordinate
00217     $geo_x_diff = $map_extent->maxx - $map_extent->minx; // Get the difference between the geographical coordinates
00218     $x_ratio = $geo_x_diff / $image_width; // Get the ratio of the geographic coordinates to the image size
00219     $geo_x_delta = $image_point->x * $x_ratio; // Scale the clicked pixel to the geographic scale
00220     $geo_x = $map_extent->minx + $geo_x_delta; // Place this in the context of the map by adding it to the minimum extent
00221 
00222     //Calculate the Y coordinate
00223     $geo_y_diff = $map_extent->maxy - $map_extent->miny;
00224     $y_ratio = $geo_y_diff / $image_height;
00225     $pix_y_delta = $image_height - $image_point->y; // Everything is the same as for the X coordinate, except that here you have to compensate for image coordinates being upper left instead of lower right (as on a map)
00226     $geo_y_delta = $pix_y_delta * $y_ratio;
00227     $geo_y = $map_extent->miny + $geo_y_delta;
00228 
00229     $map_point = ms_newPointObj();
00230     $map_point->setXY($geo_x, $geo_y);
00231             
00232     return $map_point;
00233 }
00234 
00235 
00244 function mapPointToImagePoint($map_point, $map_extent, $image_width, $image_height) 
00245 {
00246     if (!$map_point)
00247         trigger_error('A point object must be specified', E_USER_ERROR);
00248     
00249     //Calculate the X coordinate
00250     $geo_x_diff = $map_extent->maxx - $map_extent->minx;// Get the difference between the geographical coordinates
00251     $x_ratio = $geo_x_diff / $image_width; // Get the ratio of the geographic coordinates to the image size
00252     $geo_x_image_diff = $map_point->x - $map_extent->minx; // get the distance of the coordinate from the x minimum
00253     $pix_x = round($geo_x_image_diff / $x_ratio); // Scale the geographic coordinate to the image scale in pixels
00254 
00255     //Calculate the Y coordinate
00256     $geo_y_diff = $map_extent->maxy - $map_extent->miny;
00257     $y_ratio = $geo_y_diff / $image_height;
00258     $geo_y_image_diff = $map_point->y - $map_extent->miny;
00259     $pix_y_delta = $geo_y_image_diff / $y_ratio;
00260     $pix_y = round($image_height - $pix_y_delta); // Everything is the same as for the X coordinate, except that here you have to compensate for image coordinates being upper left instead of lower right (as on a map)
00261 
00262     $image_point = ms_newPointObj();
00263     $image_point->setXY($pix_x, $pix_y);
00264             
00265     return $image_point;
00266 }
00267 
00275 function rectToString($rect)
00276 {
00277     return $rect->minx.' '.$rect->miny.' '.$rect->maxx.' '.$rect->maxy;
00278 }
00279 
00287 function stringToRect($string) 
00288 {
00289     $extents = explode(' ', $string);
00290     $rect = ms_newRectObj();
00291     $rect->setextent($extents[0], $extents[1], $extents[2], $extents[3]);
00292     return $rect;
00293 }
00294 
00295 
00302 function pointToString($point)
00303 {
00304     return $point->x.' '.$point->y.' '.$point->m;
00305 }
00306 
00314 function stringToPoint($string) 
00315 {
00316     $contents = explode(' ', $string);
00317     $point = ms_newPointObj();
00318     $point->setXY($contents[0], $contents[1], $contents[2]);
00319     return $point;
00320 }
00321 
00329 class MapManager extends Map
00330 {
00331     // SERIALISED VARS
00332 
00334     var $max_extent;
00336     var $zoom_level;
00338     var $layer_renderers;
00340     var $zoom_type;
00342     var $zoom_scale;
00344     var $zoom_extent;
00345 
00346     // NON SERIALISED VARS
00347 
00349     var $map_click;
00351     var $click_type;
00352 
00359     function MapManager($map_file, $new_map_path = null)
00360         {
00361             $this->Map($map_file, $new_map_path);
00362             $this->setMaxExtent($this->get('extent'));
00363             $this->setZoomLevel(1);
00364             $this->preparequery();
00365             $this->layer_renderers = array();
00366             $this->setZoomType(MM_ZOOM_PAN);
00367         }
00368 
00369     // ACCESSORS
00370 
00379     function getClickType() 
00380         {
00381             return $this->click_type;
00382         }
00383     
00389     function setZoomType($zoom_type) 
00390         {
00391             $this->zoom_type = $zoom_type;
00392         }
00393 
00398     function getZoomType() 
00399         {
00400             return $this->zoom_type;
00401         }
00402 
00407     function setZoomScale($zoom_scale) 
00408         {
00409             $this->zoom_scale = $zoom_scale;
00410         }
00411 
00416     function getZoomScale() 
00417         {
00418             return $this->zoom_scale;
00419         }
00420 
00425     function setZoomExtent($zoom_extent) 
00426         {
00427             $this->zoom_extent = $zoom_extent;
00428         }
00429 
00434     function getZoomExtent() 
00435         {
00436             return $this->zoom_extent;
00437         }
00438     
00448     function getMapClick($as_map_coords = true) 
00449         {
00450             if (!$this->map_click)
00451                 return null;
00452             
00453             if ($as_map_coords)
00454                 return $this->map_click;
00455 
00456             return $this->mapPointToImagePoint($this->map_click);
00457         }    
00458     
00467     function setMapClick($map_click, $click_type) 
00468         {            
00469             $this->map_click = $map_click;
00470             $this->click_type = $click_type;
00471         }
00472 
00478     function setZoomLevel($zoom_level)
00479         {
00480             if (!is_numeric($zoom_level))
00481                 trigger_error('The zoom level must be a numeric value: '.$zoom_level, E_USER_ERROR);
00482 
00483             if (is_float($zoom_level / 1))    // check to see if it's an integer
00484                 trigger_error('The zoom level must be an integer value', E_USER_ERROR);
00485             
00486             $this->zoom_level = $zoom_level;
00487         }
00488 
00493     function getZoomLevel() 
00494         {
00495             return $this->zoom_level;
00496         }
00497     
00502     function getMaxExtent() 
00503         {
00504             return $this->max_extent;
00505         }
00506 
00511     function setMaxExtent($extent) 
00512         {
00513             $this->max_extent = $extent;
00514         }    
00515 
00516     // LAYER RELATED METHODS
00517 
00523     function layerExists($layer_name) 
00524         {
00525             if ($layer = $this->getLayerByName($layer_name))
00526                 return true;
00527             return false;
00528         }
00529 
00537     function layerIsOn($layer_name) 
00538         {
00539             if (!$layer = $this->getLayerByName($layer_name))
00540                 return false;
00541 
00542             if ($layer->status == MS_ON)
00543                 return true;
00544 
00545             return false;
00546         }
00547 
00553     function turnLayerOn($layer_name, $toggle_group = false) 
00554         {
00555             if (!$this->layerExists($layer_name))
00556                 trigger_error("The layer '$layer_name' does not exist", E_USER_ERROR);
00557 
00558             $layer = $this->getLayerByName($layer_name);            
00559             if ($toggle_group and $this->isGroupLayer($layer_name)) {
00560                 $this->turnGroupOn($layer->group);
00561             } else {
00562                 $layer->set('status', MS_ON);
00563             }
00564         }
00565 
00571     function turnLayerOff($layer_name, $toggle_group = false) 
00572         {
00573             if (!$this->layerExists($layer_name))
00574                 trigger_error("The layer '$layer_name' does not exist", E_USER_ERROR);
00575 
00576             $layer = $this->getLayerByName($layer_name);
00577             if ($toggle_group and $this->isGroupLayer($layer_name)) {
00578                 $this->turnGroupOff($layer->group);
00579             } else {
00580                 $layer->set('status', MS_OFF);
00581             }
00582         }
00583 
00589     function isGroupLayer($layer_name) 
00590         {
00591             if (!$this->layerExists($layer_name))
00592                 return false;
00593 
00594             $layer = $this->getLayerByName($layer_name);
00595             return (strlen($layer->group) > 0) ? true : false;
00596         }
00597 
00603     function groupExists($group_name) 
00604         {
00605             return in_array($group_name, $this->getAllGroupNames());
00606         }
00607     
00612     function turnGroupOff($group_name) 
00613         {
00614             if (!$this->groupExists($group_name))
00615                 trigger_error("The group '$group_name' does not exist", E_USER_ERROR);
00616 
00617             foreach ($this->getLayersIndexByGroup($group_name) as $index) 
00618                 {
00619                     $layer = $this->getLayer($index);
00620                     $layer->set('status', MS_OFF);
00621                 }
00622         }
00623 
00628     function turnGroupOn($group_name) 
00629         {
00630             if (!$this->groupExists($group_name))
00631                 trigger_error("The group '$group_name' does not exist", E_USER_ERROR);
00632 
00633             foreach ($this->getLayersIndexByGroup($group_name) as $index) 
00634                 {
00635                     $layer = $this->getLayer($index);
00636                     $layer->set('status', MS_ON);
00637                 }
00638         }
00639     
00647     function layerIsQueryable($layer_name) 
00648         {
00649             $layer = $this->getLayerByName($layer_name);
00650             if (!$layer)
00651                 return false;
00652 
00653             if ($layer->template)
00654                 return true;
00655 
00656             for ($i = 0; $i < $layer->numclasses; $i++) {
00657                 $class = $layer->getClass($i);
00658                 if ($class->template)
00659                     return true;
00660             }
00661             
00662             return false;
00663         }
00664 
00672     function layerIsSelectable($layer_name) 
00673         {
00674             if (!$layer = $this->getLayerByName($layer_name))
00675                 return false;
00676 
00677             $selectable = $layer->getMetaData('SELECTABLE');
00678 
00679             if (strtoupper($selectable) == 'ON')
00680                 return true;
00681             
00682             return false;
00683         }
00684 
00695     function setLayerSelectable($layer_name, $selectable) 
00696         {
00697             if (!$layer = $this->getLayerByName($layer_name))
00698                 trigger_error("the layer '$layer_name' does not exist", E_USER_ERROR);
00699 
00700             if ($selectable)
00701                 $layer->setMetaData('SELECTABLE', 'ON');
00702             else
00703                 $layer->removeMetaData('SELECTABLE');
00704         }
00705 
00710     function getSelectableLayerNames() 
00711         {
00712             $layer_names = array();
00713             foreach ($this->getAllLayerNames() as $layer_name) 
00714                 {
00715                     if ($this->layerIsSelectable($layer_name))
00716                         $layer_names[] = $layer_name;
00717                 }
00718             return $layer_names;
00719         }
00720     
00730     function setLayerRenderer($layer_name, $renderer) 
00731         {
00732             if (!$this->layerExists($layer_name))
00733                 trigger_error("the layer '$layer_name' does not exist", E_USER_ERROR);
00734 
00735             if (!is_callable($renderer))
00736                 trigger_error("The callback function to render the layer '$layer_name' is not valid", E_USER_ERROR);
00737 
00738             $this->layer_renderers[$layer_name] = $renderer;
00739         }
00740 
00746     function getLayerRenderer($layer_name) 
00747         {
00748             if (!$this->layerRendererExists($layer_name))
00749                 trigger_error("no renderer is associated with layer '$layer_name'", E_USER_ERROR);
00750 
00751             return $this->layer_renderers[$layer_name];
00752         }
00753 
00761     function removeLayerRenderer($layer_name) 
00762         {
00763             if (!$this->layerRendererExists($layer_name))
00764                 trigger_error("no renderer to remove for layer '$layer_name'", E_USER_ERROR);
00765 
00766             unset($this->layer_renderers[$layer_name]);
00767         }
00768     
00774     function layerRendererExists($layer_name) 
00775         {
00776             return isset($this->layer_renderers[$layer_name]);
00777         }
00778 
00779     // UTILITY METHODS
00780 
00786     function imagePointToMapPoint($image_point) 
00787         {
00788             $extent =& $this->get('extent');
00789             $height = $this->get('height');
00790             $width = $this->get('width');
00791             
00792             return imagePointToMapPoint($image_point, $extent, $width, $height);
00793         }
00794 
00800     function mapPointToImagePoint($map_point) 
00801         {
00802             $extent =& $this->get('extent');
00803             $height = $this->get('height');
00804             $width = $this->get('width');
00805             
00806             return mapPointToImagePoint($map_point, $extent, $width, $height);
00807         }
00808     
00814     function imagePointToRefMapPoint($image_point) 
00815         {
00816             $reference =& $this->get('reference');
00817 
00818             $extent = $reference->extent;
00819             $height = $reference->height;
00820             $width = $reference->width;
00821             
00822             return imagePointToMapPoint($image_point, $extent, $width, $height);
00823         }
00824 
00830     function refMapPointToImagePoint($map_point) 
00831         {
00832             $reference =& $this->get('reference');
00833 
00834             $extent = $reference->extent;
00835             $height = $reference->height;
00836             $width = $reference->width;
00837             
00838             return mapPointToImagePoint($map_point, $extent, $width, $height);
00839         }
00840 
00841 
00842     // TESTS
00843     
00848     function zoomedToMinScale() 
00849         {
00850             $web =& $this->get('web');
00851 
00852             $minscale = $web->minscale;
00853 
00854             if ($minscale == -1)
00855                 return false;
00856             
00857             $scale = $this->get('scale');
00858 
00859             if ($scale != -1 and $scale <= $minscale)
00860                 return true;
00861             
00862             return false;
00863         }
00864     
00869     function zoomedToMaxScale() 
00870         {
00871             $web =& $this->get('web');
00872 
00873             $maxscale = $web->maxscale;
00874 
00875             if ($maxscale == -1)
00876                 return false;
00877             
00878             $scale = $this->get('scale');
00879 
00880             if ($scale != -1 and $scale >= $maxscale)
00881                 return true;
00882             
00883             return false;
00884         }
00885 
00890     function zoomedToMaxExtent() 
00891         {
00892             $max_extent = $this->getMaxExtent();
00893             $extent =& $this->get('extent');
00894 
00895             if (($extent->minx <= $max_extent->minx) and
00896                 ($extent->miny <= $max_extent->miny) and
00897                 ($extent->maxx >= $max_extent->maxx) and
00898                 ($extent->maxy >= $max_extent->maxy)) {
00899                 return true;
00900             }
00901 
00902             return false;
00903         }
00904     
00905 
00906     // ZOOM METHODS
00907 
00917     function zoom() 
00918         {
00919             $zoom_type = $this->getZoomType();
00920 
00921             switch($zoom_type) {
00922             case MM_ZOOM_NONE:
00923                 return false;
00924             case MM_ZOOM_IN:
00925                 $this->zoomInToMapClick();
00926                 break;
00927             case MM_ZOOM_OUT:
00928                 $this->zoomOutToMapClick();
00929                 break;
00930             case MM_ZOOM_PAN:
00931                 $this->panToMapClick();
00932                 break;
00933             case MM_ZOOM_SCALE:
00934                 if (!$zoom_scale = $this->getZoomScale())
00935                     trigger_error('No zoom scale has been set', E_USER_ERROR);                
00936                 $this->zoomToScale($zoom_scale);
00937                 break;
00938             case MM_ZOOM_EXTENT:
00939                 if (!$zoom_extent = $this->getZoomExtent())
00940                     trigger_error('No zoom extent has been set', E_USER_ERROR);
00941                 $this->zoomToExtent($zoom_extent);
00942                 break;
00943             default:
00944                 trigger_error('Unknown zoom type', E_USER_ERROR);
00945             }
00946 
00947             return true;
00948         }
00949 
00954     function zoomToExtent($extent) 
00955         {
00956             $width = $this->get('width');
00957             $height = $this->get('height');
00958             $pixel_extent = ms_newRectObj();
00959             $pixel_extent->setextent(0, $height, $width, 0);
00960             $max_extent = $this->getMaxExtent();
00961 
00962             $this->preparequery();
00963             $this->zoomrectangle($pixel_extent, $width, $height, $extent, $max_extent);
00964         }
00965 
00970     function zoomToScale($scale) 
00971         {
00972             $width = $this->get('width');
00973             $height = $this->get('height');
00974             $pixel_pos = ms_newPointObj();
00975             $x = round($width / 2);
00976             $y = round($height / 2);
00977             $pixel_pos->setXY($x, $y);
00978             $extent =& $this->get('extent');
00979             $max_extent = $this->getMaxExtent();
00980 
00981             $this->zoomscale($scale, $pixel_pos, $width, $height, $extent, $max_extent);
00982         }
00983 
00989     function zoomToPoint($map_point, $zoom_level) 
00990         {
00991             // check to ensure the zoom request is valid
00992             if (($zoom_level == 1) and $this->zoomedToMaxExtent()) // trying to pan at maximum extent
00993                 return;
00994             elseif (($zoom_level > 1) and $this->zoomedToMinScale()) // trying to zoom in further than the minimum scale
00995                 return;
00996             elseif (($zoom_level < 1) and ($this->zoomedToMaxScale() or $this->zoomedToMaxExtent()))    // trying to zoom out further than allowed
00997                 return;
00998 
00999             $image_point = $this->mapPointToImagePoint($map_point);
01000             
01001             $width = $this->get('width');
01002             $height = $this->get('height');
01003             $extent =& $this->get('extent');
01004             $max_extent = $this->getMaxExtent();
01005             
01006             $this->zoompoint($zoom_level, $image_point, $width, $height, $extent, $max_extent);
01007         }
01008 
01013     function panToPoint($map_point) 
01014         {
01015             $this->zoomToPoint($map_point, 1);
01016         }
01017 
01022     function zoomInToPoint($map_point) 
01023         {
01024             $zoom_level = $this->getZoomLevel();
01025             $this->zoomToPoint($map_point, $zoom_level);
01026         }
01027 
01032     function zoomOutToPoint($map_point) 
01033         {
01034             $zoom_level = $this->getZoomLevel();
01035             $this->zoomToPoint($map_point, -$zoom_level);
01036         }
01037 
01042     function zoomOutToMapClick() 
01043         {
01044             $map_click = $this->getMapClick();
01045 
01046             if (!$map_click)
01047                 return false;
01048 
01049             $this->zoomOutToPoint($map_click);
01050             return true;
01051         }
01052 
01057     function panToMapClick() 
01058         {
01059             $map_click = $this->getMapClick();
01060 
01061             if (!$map_click)
01062                 return false;
01063 
01064             $this->panToPoint($map_click);
01065             return true;
01066         }
01067     
01072     function zoomInToMapClick() 
01073         {
01074             $map_click = $this->getMapClick();
01075 
01076             if (!$map_click)
01077                 return false;
01078             
01079             $this->zoomInToPoint($map_click);
01080             return true;
01081         }
01082     
01083     // OVERRIDDEN METHODS
01084     
01091     function draw() 
01092         {
01093             $imageObj = $this->prepareImage();
01094             
01095             $postlabelcache = array();
01096 
01097             foreach ($this->getlayersdrawingorder() as $index) 
01098                 {
01099                     $layer = $this->getLayer($index);
01100 
01101                     if ($layer->postlabelcache != MS_TRUE)
01102                         $this->drawLayer($layer, $imageObj);
01103                     else
01104                         $postlabelcache[] = $layer;
01105                 }
01106 
01107             $legend =& $this->get('legend');
01108             if ($legend->status == MS_EMBED)
01109                 $this->embedlegend($imageObj);
01110 
01111             $scalebar =& $this->get('scalebar');
01112             if ($scalebar->status == MS_EMBED) 
01113                 $this->embedScalebar($imageObj);
01114 
01115             $this->drawLabelCache($imageObj);
01116 
01117             foreach ($postlabelcache as $layer)
01118                 {
01119                     $this->drawLayer($layer, $imageObj);
01120                 }
01121             
01122             return $imageObj;
01123         }
01124 
01133     function drawLayer($layer, &$imageObj) 
01134         {
01135             if ($layer->status == MS_OFF)
01136                 return;
01137             
01138             if (!$this->layerRendererExists($layer->name)) {
01139                 if (!$this->layerIsQueryable($layer->name)) {
01140                     $layer->draw($imageObj);
01141                 } else {
01142                     $layer->drawQuery($imageObj);
01143                 }
01144             } else {
01145                 $callback = $this->getLayerRenderer($layer->name);
01146                 call_user_func($callback, $imageObj);
01147             }
01148         }
01149 
01150     /***************************************************
01151      * Serialisation INTERFACE
01152      ***************************************************/
01153     
01154     function __wakeup() 
01155         {
01156             parent::__wakeup();
01157 
01158             if ($this->max_extent)
01159                 $this->setMaxExtent(stringToRect($this->max_extent));
01160 
01161             if ($this->zoom_extent)
01162                 $this->setZoomExtent(stringToRect($this->zoom_extent));
01163             
01164             // zoom to exactly the same place in order to properly initialise the map object (i.e. scale property)
01165             $this->zoomToExtent($this->get('extent'));
01166         }
01167     
01168     function __sleep() 
01169         {
01170             $sleep_vars = parent::__sleep();
01171 
01172             if ($max_extent = $this->getMaxExtent())
01173                 $this->max_extent = rectToString($max_extent);
01174 
01175             if ($zoom_extent = $this->getZoomExtent())
01176                 $this->zoom_extent = rectToString($zoom_extent);
01177             
01178             array_push($sleep_vars, 'max_extent', 'zoom_level', 'layer_renderers', 'zoom_type', 'zoom_scale', 'zoom_extent');
01179             return $sleep_vars;
01180         }
01181 }
01182 
01183 ?>

Generated on Mon Feb 14 11:40:06 2005 for MapManager by doxygen 1.3.5