[MapServer-users] zoomRectangle error image rectangle maxy >= miny

Seth G sethg at geographika.co.uk
Tue May 7 07:40:56 PDT 2024


Hi Fernando,

There is a test case for this at:

https://github.com/MapServer/MapServer/blob/0cb56232d4ca0e64d747efa1db602ff08e0ea42f/src/mapscript/python/tests/cases/zoom_test.py#L99

This test has the MaxY < MinY. It looks like the rectObj represents an image rather than a map, and so the maxy and miny need to be reversed as in your original PHP code for SWIG MapScript too. 

The error message is:

> Exception: mapscript::mapObj::zoomRectangle(): General error message. 
> image rectangle maxy >= miny in 

And is raised at https://github.com/MapServer/MapServer/blob/0cb56232d4ca0e64d747efa1db602ff08e0ea42f/src/mapscript/swiginc/mapzoom.i#L239

There is a comment in the source code where this error is thrown (I think it applies to maxy too):

        /* This is not a typo: "maxx >= minx". For historical reason, we
         * keep this as it is. See documentation for more info about this check. */
        if (poPixRect->maxy >= poPixRect->miny) {
            msSetError(MS_MISCERR, "image rectangle maxy >= miny", "mapscript::mapObj::zoomRectangle()");
            return MS_FAILURE;
        }

See https://github.com/MapServer/MapServer/issues/3286
So you'll need to reverse the Y values below (likely as it did in the old code). The API docs should also include this note.

> $this->geoext0->minx -334.31761006289
> $this->geoext0->miny -22
> $this->geoext0->maxx 525.31761006289
> $this->geoext0->maxy 342


Seth

--
web:https://geographika.net & https://mapserverstudio.net
twitter: @geographika

On Tue, May 7, 2024, at 10:43 AM, Fernando Sánchez García via MapServer-users wrote:
> Dear users, my name is Fernando and I work at the University of Córdoba 
> in Spain. I have been using mapserver for several years as a user at the 
> University together with pmapper. Our old virtual machine has Ubuntu 
> Server 18.04 LTS + mapserver 7.2.1 + PHP 5.6.40 + postgres/postgis with 
> pmapper 4.3.2. and locally on my computer I have MS4W 3.2.3 with pmapper 
> 4.3.2. Unfortunately pmapper was discontinued a few years ago and 
> although I don't have much programming knowledge, I have started trying 
> to make some small changes to the pmapper code to adapt it to PHP 7/8 
> (although I know other more up-to-date alternatives such as Openlayers).
> I have reached the "Zoom to rectangle" function where Armin implemented 
> it like this:
>
>
>      /************************************************
>       * ZOOM&PAN FUNCTIONS
>       ************************************************/
>      /**
>       * Zoom to rectangle
>       */
>      protected function pmap_zoomrect()
>      {
>          if (isset($_REQUEST["imgbox"])) {
>              $imgbox_str = $_REQUEST["imgbox"];
>              //error_log($imgbox_str);
>              if ($imgbox_str != "") {
>                  $imgbox_arr = explode(" ", $imgbox_str);
>                  // New map extent in image pixel ((0,0) top-left)
>                  $pix_minx = $imgbox_arr[0];
>                  $pix_miny = $imgbox_arr[1];
>                  $pix_maxx = $imgbox_arr[2];
>                  $pix_maxy = $imgbox_arr[3];
>
>                  if ($pix_minx == $pix_maxx) $pix_maxx = $pix_maxx + 3;  
> ## increase max extent if min==max
>                  if ($pix_miny == $pix_maxy) $pix_maxy = $pix_maxy - 3;  ##
>
>                  $pixext = ms_newrectObj();
>
>                  // Modified by Thomas RAFFIN (SIRAP)
>                  // If the rectangle is not in the same proportions as 
> the map,
>                  // To leave the coeff Y / X unghanged, we need to made 
> $geoNewCoeff = $geo0Coeff...
>                  $geo0Coeff = $this->mapheight / $this->mapwidth;
>                  $geoNewDeltaX = $pix_maxx - $pix_minx;
>                  $geoNewDeltaY = $pix_maxy - $pix_miny;
>                  $geoNewCoeff = $geoNewDeltaY / $geoNewDeltaX;
>                  if ($geoNewCoeff < $geo0Coeff) {
>                      $newDeltaYCorrected = $geo0Coeff * $geoNewDeltaX;
>                      $newDeltaYToAdd = ($newDeltaYCorrected - 
> $geoNewDeltaY) / 2;
>                      $pix_miny -= $newDeltaYToAdd;
>                      $pix_maxy += $newDeltaYToAdd;
>                  } else {
>                      $newDeltaXCorrected = $geoNewDeltaY / $geo0Coeff;
>                      $newDeltaXToAdd = ($newDeltaXCorrected - 
> $geoNewDeltaX) / 2;
>                      $pix_minx -= $newDeltaXToAdd;
>                      $pix_maxx += $newDeltaXToAdd;
>                  }
>
> $pixext->setExtent($pix_minx,$pix_miny,$pix_maxx,$pix_maxy);
>              }
>
>          // Zoom to full extent when starting
>          } else {
>              $pixext = ms_newrectObj();
>              $pixext->setExtent(0, 0, $this->mapwidth, $this->mapheight);
>          }
>
>          $this->map->zoomrectangle($pixext, $this->mapwidth, 
> $this->mapheight, $this->geoext0);
>          PMCommon::freeMsObj($pixext);
>      }
>
> In this function Mapscript zoomrectangle is called, which according to 
> the old PHP Mapscript documentation 
> (https://mapserver.org/mapscript/php/index-5.6.html#mapobj) is like this:
>
> void zoomrectangle(rectObj oPixelExt, int nImageWidth, int nImageHeight, 
> rectObj oGeorefExt)
>      Set the map extents to a given extents.
>      Parameters are :
>              oPixelExt (rect object) : Pixel Extents, with (0,0) at the 
> top-left The rectangle contains the coordinates of the LL and UR 
> coordinates in pixel. (the maxy in the rect object should be < miny value)
>
>              ------- UR (values in the rect object : maxx, maxy)
>              |     |
>              |     |
>              |     |
>              ------
>              LL (values in the rectobject minx, miny)
>
>              Width : width in pixel of the current image.
>              Height : Height in pixel of the current image.
>              Georef extent (rectObj) : current georef extents.
>
> The pmapper log file shows me the following values when I zoom without 
> any problem and the result is satisfactory, that is, it zooms in on my 
> map correctly:
>
> P.MAPPER debug info en la función pmap_zoomrect de map.php
> $pix_minx 551.97186827847
> $pix_miny 86.08332824707031
> $pix_maxx 632.19478821567
> $pix_maxy 120.08332824707031
> $this->geoext0->minx -334.31761006289
> $this->geoext0->miny -22
> $this->geoext0->maxx 525.31761006289
> $this->geoext0->maxy 342
>
> My .map file has the following EXTENT -37 -22 228 334 and "wms_srs" 
> "epsg:3857".
>
> I have updated to MS4W 4.0.4 which has MapServer and MapScript 
> 7.7.0-dev, PHP to 7.2.31 and SWIG support. According to the current SWIG 
> MapScript API Reference:
>
> mapscript.mapObj
> class mapscript.mapObj(*args)
>
> Methods:
> zoomRectangle(poPixRect: rectObj, width: int, height: int, poGeorefExt: 
> rectObj, poMaxGeorefExt: rectObj) → int[source]
>      Set the map extents to a given extents. Returns MS_SUCCESS or 
> MS_FAILURE on error
>
> and I have adapted the code like this:
>
>      /************************************************
>       * ZOOM&PAN FUNCTIONS
>       ************************************************/
>      /**
>       * Zoom to rectangle
>       */
>      protected function pmap_zoomrect()
>      {
>          if (isset($_REQUEST["imgbox"])) {
>              $imgbox_str = $_REQUEST["imgbox"];
>
>              pm_logDebug(3, $imgbox_str, "\$imgbox_str en la función 
> pmap_zoomrect de map.php");
>              //  642.0833282470703 40.08332824707031 685.0833282470703 
> 68.08332824707031
>
>              //error_log($imgbox_str);
>              if ($imgbox_str != "") {
>                  $imgbox_arr = explode(" ", $imgbox_str);
>                  // New map extent in image pixel ((0,0) top-left)
>                  $pix_minx = $imgbox_arr[0];
>                  $pix_miny = $imgbox_arr[1];
>                  $pix_maxx = $imgbox_arr[2];
>                  $pix_maxy = $imgbox_arr[3];
>
>                  if ($pix_minx == $pix_maxx) $pix_maxx = $pix_maxx + 3;  
> ## increase max extent if min==max
>                  if ($pix_miny == $pix_maxy) $pix_maxy = $pix_maxy - 3;  ##
>
>                  // BEFORE:
>                  // $pixext = ms_newrectObj();
>
>                  // Modified by Thomas RAFFIN (SIRAP)
>                  // If the rectangle is not in the same proportions as 
> the map,
>                  // To leave the coeff Y / X unghanged, we need to made 
> $geoNewCoeff = $geo0Coeff...
>                  $geo0Coeff = $this->mapheight / $this->mapwidth;
>                  $geoNewDeltaX = $pix_maxx - $pix_minx;
>                  $geoNewDeltaY = $pix_maxy - $pix_miny;
>                  $geoNewCoeff = $geoNewDeltaY / $geoNewDeltaX;
>                  if ($geoNewCoeff < $geo0Coeff) {
>                      $newDeltaYCorrected = $geo0Coeff * $geoNewDeltaX;
>                      $newDeltaYToAdd = ($newDeltaYCorrected - 
> $geoNewDeltaY) / 2;
>                      $pix_miny -= $newDeltaYToAdd;
>                      $pix_maxy += $newDeltaYToAdd;
>                  } else {
>                      $newDeltaXCorrected = $geoNewDeltaY / $geo0Coeff;
>                      $newDeltaXToAdd = ($newDeltaXCorrected - 
> $geoNewDeltaX) / 2;
>                      $pix_minx -= $newDeltaXToAdd;
>                      $pix_maxx += $newDeltaXToAdd;
>                  }
>
>                  // BEFORE:
>                  // 
> $pixext->setExtent($pix_minx,$pix_miny,$pix_maxx,$pix_maxy);
>
>                  // NEW:
>                  $pixext = new rectObj($pix_minx, $pix_miny, $pix_maxx, 
> $pix_maxy);
>              }
>
>          // Zoom to full extent when starting
>          } else {
>              $pixext = ms_newrectObj();
>              $pixext->setExtent(0, 0, $this->mapwidth, $this->mapheight);
>          }
>
>          // BEFORE:
>          // $this->map->zoomrectangle($pixext, $this->mapwidth, 
> $this->mapheight, $this->geoext0);
>
>          // NEW:
>          $maxGeoExt = null; // Null o tu valor predeterminado para la 
> extensión geográfica máxima
>          $this->map->zoomRectangle($pixext, $this->mapwidth, 
> $this->mapheight, $this->geoext0, $maxGeoExt);
>
>          PMCommon::freeMsObj($pixext);
>      }
>
> but the following error is returned:
>
> [06-May-2024 12:49:32 Europe/Paris] PHP Fatal error:  Uncaught 
> Exception: mapscript::mapObj::zoomRectangle(): General error message. 
> image rectangle maxy >= miny in 
> C:\ms4w\apps\sig-uco\htdocs\phpmapscriptng-swig\include\mapscript.php:2908
> Stack trace:
> #0 
> C:\ms4w\apps\sig-uco\htdocs\phpmapscriptng-swig\include\mapscript.php(2908): 
> mapobj_zoomrectangle(Resource id #10, Object(rectObj), '1503.166666', 
> '351.16666599999...', Object(rectObj), NULL)
> #1 
> C:\ms4w\apps\sig-uco\htdocs\pmapper\pmapper-4.3.2\incphp\map\map.php(629): 
> mapObj->zoomRectangle(Object(rectObj), '1503.166666', 
> '351.16666599999...', Object(rectObj), NULL)
> #2 
> C:\ms4w\apps\sig-uco\htdocs\pmapper\pmapper-4.3.2\incphp\map\map.php(489): 
> PMap->pmap_zoomrect()
> #3 
> C:\ms4w\apps\sig-uco\htdocs\pmapper\pmapper-4.3.2\incphp\map\map.php(74): 
> PMap->pmap_createMap()
> #4 
> C:\ms4w\apps\sig-uco\htdocs\pmapper\pmapper-4.3.2\incphp\xajax\x_load.php(78): 
> PMap->pmap_create()
> #5 {main}
>    thrown in 
> C:\ms4w\apps\sig-uco\htdocs\phpmapscriptng-swig\include\mapscript.php on 
> line 2908
>
> I have also updated to MS4W 5.0.0 which has MapServer and MapScript 
> 8.2.0-dev and PHP to 8.2.11 and the error is the same.
>
> How should I solve the problem? Thanks.
>
> _______________________________________________
> MapServer-users mailing list
> MapServer-users at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/mapserver-users



More information about the MapServer-users mailing list