[geotk] Re: Get envelope for a scale

Martin Desruisseaux martin.desruisseaux at geomatys.fr
Fri Sep 4 05:14:24 EDT 2009

Hello Theuns

theuns a écrit :
> Can you give me some info on how to get the envelope for a certain
> scale?
> What i would like to do is provide a combobox to the user, with
> pre-defined scales. eg 1:50 000 , 1:100 000 etc.
> When the user select a scale then let the map refresh and display the
> map according to the selected scale.

Lets assume that we have an "objectiveToDisplay" affine transform which is the 
current state of your display. I presume that you want to keep the center of the 
display area unchanged (i.e. the pixel at the center doesn't move; everything 
move around that pixel). The following code alter the affine transform while 
preserving rotation (if any).

I'm writting this code just from my mind; it may contains errors, but the basic 
idea should be okay. Note that the "currentScale" and "scaleThatYouWant" are the 
multiplication factor from "real world" metre to pixel; you may need an 
additional factor for taking in account the pixel size.

AffineTransform objectiveToDisplay = ...;
Rectangle widgetBounds = theSwingComponent.getBounds();
Rectangle2D envelope = XAffineTransform.transform(
         objectiveToDisplay.createInverse(), widgetBounds, null);

double currentScale = XAffineTransform.getScale(objectiveToDisplay);
double scaleThatYouWant = ...
double scaleChange = currentScale / scaleThatYouWant;

objectiveToDisplay.translate(envelope.getCenterX(), envelope.getCenterY());
objectiveToDisplay.scale(scaleChange, scaleChange);
objectiveToDisplay.translate(-envelope.getCenterX(), -envelope.getCenterY());

// The new envelope
envelope = XAffineTransform.transform(
         objectiveToDisplay.createInverse(), widgetBounds, null);

Note that if you work with the GO2 renderer, it is probably possible to use a 
shorter path since this renderer should work natively with AffineTransform, not 
Envelope. Basically you should be able to give to the renderer the scale change 
as an AffineTransform (create a new AffineTransform initialized to the identity 
one and execute the 3 "objectiveToDisplay.xxx(...)" methods on it) and that it.


More information about the Geotoolkit mailing list