How to get the x,y values(in pixel) via mapscript?

mark.wilson at rohoel.at mark.wilson at rohoel.at
Fri Mar 9 00:11:13 PST 2001



Here are my perl subroutines to calculate the map extents and generate image map
html for each point. They come with the usual caveats and warnings. They may not
be the most elegant piece of coding, and there may be redundant calculations,
but they work fine for me. (At least they did before I cleaned them up by
deleting all my commented out code!!  Watch out for line wraps.

Bear in mind that I have three maps, one large image map, one small mapserver
map, with an identically sized keymap showing coverage. The small mapserver map
is what is used for navigation. It is exactly the same image but with reduced
dimensions. Since I don't use lines very heavily, this isn't a real problem. The
large map is for exploring the data.

Hope this is of use,
Mark

Here are the subroutines I use:
--------------------------------------------
# Set initial values

       $newminx = -180;
      $newmaxx = 180;
      $newminy = -90;
      $newmaxy = 90;



sub set_extent() {
    my ($zoom, @imgext);
    my ($x, $y);
    my ($cellsizex, $cellsizey);

    if($cgi->param('imgext')) { # if an interactive interface then
calculate a new extent
        @imgext = split(' ', $cgi->param('imgext'));
        $x = $cgi->param('img.x');
        $y = $cgi->param('img.y');
        # adjust x,y for small navigation map size
        $x = ($x * 100)/15;
        $y = ($y * 100)/15;
        $zoom_size = $cgi->param('zoomsize');
        $zoom_direction = $cgi->param('zoomdir');

        if($zoom_direction == 0) { # pan
            $zoom = 1;
        } else { # in or out
            $zoom = $zoom_size*$zoom_direction;
            $zoom = 1.0/abs($zoom) if $zoom < 0;
        }

        $cx = ($imgext[2]-$imgext[0])/($map->{width}-1); # calculate
cellsize in x and y
        $cy = ($imgext[3]-$imgext[1])/($map->{height}-1);

        $x = $imgext[0] + $cx*$x; # change x,y from image to map
coordinates, offset from UL corner of previous image
        $y = $imgext[3] - $cy*$y;

        $newminx = $x - .5*(($imgext[2] - $imgext[0])/$zoom); # calculate
new extent
        $newminy = $y - .5*(($imgext[3] - $imgext[1])/$zoom);
        $newmaxx = $x + .5*(($imgext[2] - $imgext[0])/$zoom);
        $newmaxy = $y + .5*(($imgext[3] - $imgext[1])/$zoom);

        # ensure map limits are never inside the image boundaries,
resulting in background showing
        if($newminx < -180) {
            $newmaxx = $newmaxx - (180 + $newminx);
            $newminx = -180;
        }


        if($newminx < -180) {
            $newmaxx = $newmaxx - (180 + $newminx);
            $newminx = -180;
        }
        if($newmaxx > 180) {
            $newminx = $newminx - ($newmaxx - 180);
            $newmaxx = 180;
        }

        if($newminy < -90) {
            $newmaxy = $newmaxy - (90 + $newminy);
            $newminy = -90;
        }
        if($newmaxy > 90) {
            $newminy = $newminy - ($newmaxy - 90);
            $newmaxy = 90;
        }

        if($newminx < -180) { # if this is true, we have zoomed out too
far, reset extents
            $newmaxx = 180;
            $newminx = -180;
            $newmaxy = 90;
            $newminy = -90;
        }


        $map->{extent}->{minx} = $newminx; # set new extent
        $map->{extent}->{miny} = $newminy;
        $map->{extent}->{maxx} = $newmaxx;
        $map->{extent}->{maxy} = $newmaxy;

   }
}


sub round {
    my $number = shift;
    # return int($number + .5);
    return int($number + .5 * ($number <=> 0));
}


# here is the bit that creates the image map "records" in HTML for use with
OverLib

sub create_imagemap {
    my $xvert;
    my $yvert;

    #Read image width and height from map file
    $imgwidth = $map->{width};
    $imgheight = $map->{height};


#loop through the list grabbing each x and y coordinate and
# converting
# the geo-coordinate to image coordinates

foreach $loop (1..$maxcount) {

        $id=$record_array[$loop][0];
        $xvert=$record_array[$loop][8];
        $yvert=$record_array[$loop][9];
        $country=$record_array[$loop][5];
        $location=$record_array[$loop][7];
        $title=$record_array[$loop][4];

         #convert x map coordinate to image coordinates
        $cellsizex = (($map->{extent}->{maxx} -
$map->{extent}->{minx})/($imgwidth - 1));
        $ximg = (($xvert - $map->{extent}->{minx})/$cellsizex);
        $ximg = round($ximg);

        #convert y map coordinate to image coordinates
        $cellsizey = (($map->{extent}->{maxy} -
$map->{extent}->{miny})/($imgheight - 1));
        $yimg = (($map->{extent}->{maxy} - $yvert)/$cellsizey);
        $yimg = round($yimg);
        #add image coord. to the new list

    print "\<area shape=\"circle\" coords=\"$ximg,$yimg,4\"
href=\"javascript:void(0);\" onMouseover=\"return overlib('$title <A
HREF='+\'#$id\'+'><small>more . . .</small>
</A>',STICKY,HAUTO,VAUTO,CAPTION,'$location, $country');\"
onMouseout=\"nd();\" \>\n";

       }

}


# ------------------------------ end of code snippet





"Hermann-Marcus Behrens" <hermi at citybeat.de> on 08.03.2001 10:14:42

To:   Mark H Wilson/RAG/AT at RAG
cc:

Subject:  AW: How to get the x,y values(in pixel) via mapscript?



Hello Mark,

Thanks for your reply.

>Unfortunately you have to do the calulations for the image map within perl,
but
>all the required input is available.

This is exactly, what i want to do. How to get the "required input"? Since i
set the map->extents in my perl-script, i dont know, where to get the
extents, mapserv calculates to display the correct map. The problem seems to
be, that i set different map->extents(minx, miny, maxx, maxy for all the
points, i add by hand). mapserv computes different extents, because the map
would be streched otherwise.

ciao, Hermi








More information about the MapServer-users mailing list