source: TI04-geosplat/trunk/web_extras/map_applet/tmap/map/MapGrid.new @ 798

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI04-geosplat/trunk/web_extras/map_applet/tmap/map/MapGrid.new@798
Revision 798, 15.0 KB checked in by astephen, 14 years ago (diff)

Latest working version with install method.
Can accept more than one file but doesn't combine variables yet.

  • Property svn:executable set to *
Line 
1/*
2 * @(#)MapGrid.java
3 *
4 */
5
6package tmap.map;
7
8import java.awt.*;
9
10/**
11 * A grid for use with the MapCanvas.
12 * <p>
13 * A MapGrid contains all the information for the conversion of pixels
14 * to user values and vice versa.  Associating a grid with a map also
15 * allows MapTools to work in snap-to-grid mode.
16 *
17 * @version     2.0, 23 Jan 1997
18 * @author      Jonathan Callahan (NOAA/OAR/ERL/PMEL/TMAP)
19 */
20
21public class MapGrid extends Object {
22 
23  /*
24   * Predefined constants for this tool.
25   */
26  static final int PIXEL_VALUES = 0;
27  static final int USER_VALUES = 1;
28
29  /**
30   * "user" value of the leftmost pixel in the base image.
31   */
32  public double x_start=0.0;
33
34  /**
35   * "user" value of the topmost pixel in the base image.
36   */
37  public double y_start=0.0;
38
39  /**
40   * Full "user" range of x in the base image.
41   */
42  public double x_factor=1.0;
43
44  /**
45   * Full "user" range of y in the base image.
46   */
47  public double y_factor=1.0;
48       
49  /**
50   * The offset of the grid center (in "user" coordinates) relative to x_start.
51   */
52  public double x_offset=0.0;
53
54  /**
55   * The offset of the grid center (in "user" coordinates) relative to y_start.
56   */
57  public double y_offset=0.0;
58
59  /**
60   * The grid spacing (in "user" coordinates) in the x dimension.
61   */
62  public double x_spacing=1.0;
63
64  /**
65   * The grid spacing (in "user" coordinates) in the y dimension.
66   */
67  public double y_spacing=1.0;
68
69  /**
70   * The rectangle (in pixels) of the  base image.
71   * This is a duplicate of the img_rect in the MapCanvas and
72   * will be updated by zoom/pan/scrolling.
73   * <p>
74   * (I'm implementing this img_rect as a reference to the img_rect
75   * in the MapCanvas.  That way I won't have to worry about updating
76   * it seperately every time some scrolling happens.  This means
77   * that I'd better not create any "new Rectangle" anywhere inside the MapGrid.
78   * <p>
79   * In fact, I'll do the assignment in MapCanvas so nothing at
80   * all need be done inside MapTool except for using the .x and .y
81   * values of img_rect.)
82   */
83  public Rectangle img_rect;
84
85  /**
86   * The bounding rectangle in which the grid will be drawn.
87   * This is a subset of the full MapCanvas area.
88   */
89  private Rectangle boundary;
90
91  /**
92   * The style of the grid (PIXEL_VALUES or USER_VALUES).
93   */
94  private int grid_style = USER_VALUES;
95
96  /**
97   * The color the grid should be drawn in.
98   */
99  private Color color;
100
101  /**
102   * Constructs a new MapGrid.
103   */
104  public MapGrid() {
105  }
106 
107  /**
108   * Constructs and initializes a MapGrid with the specified parameters.
109   * @param x_start the "user" value of the leftmost pixel in the base image.
110   * @param y_start the "user" value of the topmost pixel in the base image.
111   * @param x_factor the full "user" range of x in the base image.
112   * @param y_factor the full "user" range of y in the base image.
113   */
114  public MapGrid(double x_start, double y_start, double x_factor, double y_factor) {
115    this.x_start = x_start;
116    this.y_start = y_start;
117    this.x_factor = x_factor;
118    this.y_factor = y_factor;
119  }
120
121
122  /**
123   * Returns the String representation of the grid's values.
124   */
125  /*
126  public String toString() {
127    StringBuffer sbuf = new StringBuffer("");
128    sbuf.append("MapGrid: [" + x + ", " + y + ", " + x_spacing + ", " + y_spacing + "]");
129    sbuf.append(", boundary = " + boundary.toString());
130    if (grid_style == PIXEL_VALUES)
131      sbuf.append(", by pixel values");
132    else
133      sbuf.append(", by user values");
134    sbuf.append(", color = " + color.toString());
135    return sbuf.toString();
136  }
137*/
138
139  /**
140   * Sets the color of the grid.
141   */
142  public void setColor(Color new_color) {
143    color = new_color;
144  }
145
146  /**
147   * Sets the gridding style to grid to user values.
148   */
149  public void grid_to_user_values() {
150    grid_style = USER_VALUES;
151  }
152
153  /**
154   * Sets the gridding style to grid to pixels.
155   */
156  public void grid_to_pixel_values() {
157    grid_style = PIXEL_VALUES;
158  }
159
160
161  /**
162   * Sets the bounding rectangle for the grid.
163   * @param x the x coordinate of the boundary
164   * @param y the y coordinate of the boundary
165   * @param width the width of the boundary.
166   * @param height the height of the boundary.
167   */
168  public void set_boundary(int x, int y, int width, int height) {
169    boundary = new Rectangle(x, y, width-1, height-1);
170  }
171
172
173  /**
174   * Sets the spacing of the grid (in "user" coordinates).
175   * @param x_spacing the spacing along X.
176   * @param y_spacing the spacing along Y.
177   */
178  public void set_spacing(double x_spacing, double y_spacing) {
179    this.x_spacing = x_spacing;
180    this.y_spacing = y_spacing;
181  }
182
183
184  /**
185   * Sets the "user" coordinates for the grid.
186   * @param x_start the "user" value of the leftmost pixel in the base image.
187   * @param y_start the "user" value of the topmost pixel in the base image.
188   * @param x_factor the full "user" range of x in the base image.
189   * @param y_factor the full "user" range of y in the base image.
190   */
191  public void set_user_coords(double x_start, double y_start, double x_factor, double y_factor) {
192    this.x_start = x_start;
193    this.y_start = y_start;
194    this.x_factor = x_factor;
195    this.y_factor = y_factor;
196  }
197 
198
199  /**
200   * Converts a pixel value into a "user" value.
201   * @param pixel_x the pixel's x value.
202   * @return a "user" X value associated with the input.
203   */
204  public double pixelX_to_user(int pixel_x) {
205    double user_x=0.0;
206
207    /*
208     * We need to take special care when the image is scrolling and
209     * pixel_x is beyond the edge of the initial image.
210     *
211     * In that case we need to subtract "img_rect.width" from the number of pixels
212     * we calculate before we apply "x_factor".
213     */
214
215    if ( pixel_x > (img_rect.x+img_rect.width) )
216      user_x = (double)(pixel_x-img_rect.x -img_rect.width) * (x_factor/(double)img_rect.width) + x_start;
217    else
218      user_x = (double)(pixel_x-img_rect.x) * (x_factor/(double)img_rect.width) + x_start;
219
220    return(user_x);
221  }
222 
223
224  /**
225   * Converts a "user" value into a pixel value.
226   * @param user_x the "user" x value.
227   * @return a pixel X value associated with the input.
228   */
229  public int user_to_pixelX(double user_x) {
230    int pixel_x=0;
231
232    pixel_x = (int)( (user_x - x_start) * ((double)img_rect.width/x_factor) + (double)img_rect.x );
233
234    /*
235     * We need to make sure pixel_x is in the MapCanvas area.
236     * This means it may need to be drawn on the first or second image
237     * depending on the value of img_rect.x when scrolling is in effect.
238     */
239    if ( pixel_x < 0 )
240      pixel_x += img_rect.width;
241
242    return(pixel_x);
243  }
244
245
246  /**
247   * Converts a pixel value into a "user" value.<p>
248   * (Note that pixel values increase from top to bottom, whereas
249   * user values increase from bottom to top.)
250   * @param pixel_y the pixel's y value.
251   * @return a "user" Y value associated with the input.
252   */
253  public double pixelY_to_user(int pixel_y) {
254    double user_y=0.0;
255
256    /*
257     * We need to "invert" the user_y values because the tools consider
258     * the top of the screen to be "y=0" and we want to make the bottom
259     * of the map to be "y=0"
260     */
261    user_y = ((img_rect.height-1)/*HERE*/-(pixel_y-img_rect.y)) * (y_factor/(img_rect.height-1)/*HERE*/) + y_start;
262
263    return(user_y);
264  }
265
266
267  /**
268   * Converts a "user" value into a pixel value.<p>
269   * (Note that pixel values increase from top to bottom, whereas
270   * user values increase from bottom to top.)
271   * @param user_y the "user" y value.
272   * @return a pixel Y value associated with the input.
273   */
274  public int user_to_pixelY(double user_y) {
275    int pixel_y=0;
276
277    /*
278     * We need to "invert" the user_y values because the tools consider
279     * the top of the screen to be "y=0" and we want to make the bottom
280     * of the map to be "y=0"
281     */
282    pixel_y = (int)( img_rect.y - ( (user_y - y_start) * ((img_rect.height-1)/*HERE*//y_factor) - (img_rect.height-1)/*HERE*/) );
283
284    return(pixel_y);
285  }
286
287
288  /**
289   * Returns an X pixel value nearest the closest X grid point.
290   * @param mouse_x the current mouse X position.
291   * @return a new value for mouse_x.
292   */
293  public int snapX(int mouse_x) {
294    double test_val=0.0, user_val=0.0, return_val=0.0;
295
296    /*
297     * Note that we cannot use the pixelX_to_user() or user_to_pixelX()
298     * methods because we NEED to know whether the "special care" mentioned
299     * below is taken in order to undo the calculation properly.
300     * This problem doesn't happen with snapY().
301     *
302     * Using the pixelX_to_user() and user_to_pixelX() methods results in
303     * the tool jumping from the right edge to the left of the image depending
304     * on how far past the MapCanvas boundary the mouse is positioned.
305     */
306
307    /*
308     * We need to take special care when the image is scrolling and
309     * mouse_x is beyond the edge of the initial image.
310     *
311     * In that case we need to subtract "img_rect.width" from the number of pixels
312     * we calculate before we apply "x_factor".
313     */
314   
315    if ( mouse_x > (img_rect.x+img_rect.width) )
316      user_val = (double)(mouse_x-img_rect.x -img_rect.width) * (x_factor/(double)img_rect.width) + x_start;
317    else
318      user_val = (double)(mouse_x-img_rect.x) * (x_factor/(double)img_rect.width) + x_start;
319
320    // Snap to the nearest grid point.
321    //
322    return_val = snap_userX(user_val);
323 
324    // Undo the top calculation
325    //
326    if ( mouse_x > (img_rect.x + img_rect.width) )
327      return_val = (return_val - x_start) * ((double)img_rect.width/x_factor) + (double)(img_rect.x + img_rect.width);
328    else
329      return_val = (return_val - x_start) * ((double)img_rect.width/x_factor) + (double)img_rect.x;
330     
331    return ( (int)return_val );
332
333  }
334
335
336  /**
337   * Returns an X pixel value nearest the closest X grid midpoint.
338   * @param mouse_x the current mouse X position.
339   * @return a new value for mouse_x.
340   */
341  public int snap_mid_X(int mouse_x) {
342    double test_val=0.0, user_val=0.0, return_val=0.0;
343
344    /*
345     * Note that we cannot use the pixelX_to_user() or user_to_pixelX()
346     * methods because we NEED to know whether the "special care" mentioned
347     * below is taken in order to undo the calculation properly.
348     * This problem doesn't happen with snapY().
349     *
350     * Using the pixelX_to_user() and user_to_pixelX() methods results in
351     * the tool jumping from the right edge to the left of the image depending
352     * on how far past the MapCanvas boundary the mouse is positioned.
353     */
354
355    /*
356     * We need to take special care when the image is scrolling and
357     * mouse_x is beyond the edge of the initial image.
358     *
359     * In that case we need to subtract "img_rect.width" from the number of pixels
360     * we calculate before we apply "x_factor".
361     */
362   
363    if ( mouse_x > (img_rect.x+img_rect.width) )
364      user_val = (double)(mouse_x-img_rect.x -img_rect.width) * (x_factor/(double)img_rect.width) + x_start;
365    else
366      user_val = (double)(mouse_x-img_rect.x) * (x_factor/(double)img_rect.width) + x_start;
367
368    // Snap to the nearest grid point.
369    //
370    return_val = snap_mid_userX(user_val);
371 
372    // Undo the top calculation
373    //
374    if ( mouse_x > (img_rect.x + img_rect.width) )
375      return_val = (return_val - x_start) * ((double)img_rect.width/x_factor) + (double)(img_rect.x + img_rect.width);
376    else
377      return_val = (return_val - x_start) * ((double)img_rect.width/x_factor) + (double)img_rect.x;
378     
379    return ( (int)return_val );
380
381  }
382
383
384  /**
385   * Returns the X "user" value nearest the closest X grid point.
386   * @param user_x the "user" X position.
387   * @return a new value for user_x.
388   */
389  public double snap_userX(double user_x) {
390    double test_val=0.0, return_val=0.0;
391
392    // Test for the nearest grid point
393    //
394    test_val = user_x / x_spacing;
395
396    if ( test_val >= 0 ) {
397
398      if ( (test_val - (int)test_val) < 0.5 )
399        return_val = (int)(test_val) * x_spacing;
400      else
401        return_val = ((int)(test_val)+1) * x_spacing;
402 
403    } else {
404
405      if ( ((int)test_val - test_val) < 0.5 )
406        return_val = (int)(test_val) * x_spacing;
407      else
408        return_val = ((int)(test_val)-1) * x_spacing;
409
410    }
411
412    return ( return_val );
413  }
414
415
416  /**
417   * Returns the X "user" value nearest the closest X grid midpoint.
418   * @param user_x the "user" X position.
419   * @return a new value for user_x.
420   */
421  public double snap_mid_userX(double user_x) {
422    double test_val=0.0, return_val=0.0;
423
424    // Test for the nearest grid point
425    //
426    test_val = user_x / x_spacing;
427
428    if ( test_val >= 0 ) {
429
430      if ( (test_val - (int)test_val) < 1.0 )
431        return_val = (int)(test_val) * x_spacing + x_spacing/2.0;
432      else
433        return_val = ((int)(test_val)+1) * x_spacing + x_spacing/2.0;
434 
435    } else {
436
437      if ( ((int)test_val - test_val) < 1.0 )
438        return_val = (int)(test_val) * x_spacing - x_spacing/2.0;
439      else
440        return_val = ((int)(test_val)-1) * x_spacing - x_spacing/2.0;
441
442    }
443
444    return ( return_val );
445  }
446
447
448  /**
449   * Returns the Y pixel value nearest the closest Y grid point.
450   * @param mouse_y the current mouse Y position.
451   * @return a new value for mouse_y.
452   */
453  public int snapY(int mouse_y) {
454    double return_val=0.0, user_val=0.0;
455
456    user_val = this.pixelY_to_user(mouse_y);
457    return_val = snap_userY(user_val);
458 
459    return ( this.user_to_pixelY(return_val) );
460
461  }
462
463
464  /**
465   * Returns the Y pixel value nearest the closest Y grid midpoint.
466   * @param mouse_y the current mouse Y position.
467   * @return a new value for mouse_y.
468   */
469  public int snap_mid_Y(int mouse_y) {
470    double return_val=0.0, user_val=0.0;
471
472    user_val = this.pixelY_to_user(mouse_y);
473    return_val = snap_mid_userY(user_val);
474 
475    return ( this.user_to_pixelY(return_val) );
476
477  }
478
479
480  /**
481   * Returns the Y "user" value nearest the closest Y grid point.
482   * @param user_y the "user" Y position.
483   * @return a new value for user_y.
484   */
485  public double snap_userY(double user_y) {
486    double test_val=0.0, return_val=0.0;
487
488    // Test for the nearest grid point
489    //
490    test_val = user_y / y_spacing;
491
492    if ( test_val >= 0 ) {
493
494      if ( (test_val - (int)test_val) < 0.5 )
495        return_val = (int)(test_val) * y_spacing;
496      else
497        return_val = ((int)(test_val)+1) * y_spacing;
498 
499    } else {
500
501      if ( ((int)test_val - test_val) < 0.5 )
502        return_val = (int)(test_val) * y_spacing;
503      else
504        return_val = ((int)(test_val)-1) * y_spacing;
505
506    }
507
508    return ( return_val );
509  }
510
511
512  /**
513   * Returns the Y "user" value nearest the closest Y grid midpoint.
514   * @param user_y the "user" Y position.
515   * @return a new value for user_y.
516   */
517  public double snap_mid_userY(double user_y) {
518    double test_val=0.0, return_val=0.0;
519
520    /*
521     * Test for the nearest grid point.
522     * Note that we compare for < 1.0 because we are going to add
523     * half the grid spacing when we return the value.
524     */
525
526    test_val = user_y / y_spacing;
527
528    if ( test_val >= 0 ) {
529
530      if ( (test_val - (int)test_val) < 1.0 )
531        return_val = (int)(test_val) * y_spacing + y_spacing/2.0;
532      else
533        return_val = ((int)(test_val)+1) * y_spacing + y_spacing/2.0;
534 
535    } else {
536
537      if ( ((int)test_val - test_val) < 1.0 )
538        return_val = (int)(test_val) * y_spacing - y_spacing/2.0;
539      else
540        return_val = ((int)(test_val)-1) * y_spacing - y_spacing/2.0;
541
542    }
543
544    return ( return_val );
545  }
546
547
548}
Note: See TracBrowser for help on using the repository browser.