00001 <?
00002
00181 require_once('map.php');
00182
00183
00185 define ('MM_CLICK_MAIN', 1);
00187 define ('MM_CLICK_REF', 2);
00188
00189
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
00217 $geo_x_diff = $map_extent->maxx - $map_extent->minx;
00218 $x_ratio = $geo_x_diff / $image_width;
00219 $geo_x_delta = $image_point->x * $x_ratio;
00220 $geo_x = $map_extent->minx + $geo_x_delta;
00221
00222
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;
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
00250 $geo_x_diff = $map_extent->maxx - $map_extent->minx;
00251 $x_ratio = $geo_x_diff / $image_width;
00252 $geo_x_image_diff = $map_point->x - $map_extent->minx;
00253 $pix_x = round($geo_x_image_diff / $x_ratio);
00254
00255
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);
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
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
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
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))
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
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
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
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
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
00992 if (($zoom_level == 1) and $this->zoomedToMaxExtent())
00993 return;
00994 elseif (($zoom_level > 1) and $this->zoomedToMinScale())
00995 return;
00996 elseif (($zoom_level < 1) and ($this->zoomedToMaxScale() or $this->zoomedToMaxExtent()))
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
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
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
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 ?>