Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / ExtentHistory.java @ 44043

History | View | Annotate | Download (11.9 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18 40559 jjdelcerro
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 40435 jjdelcerro
 *
21 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.fmap.mapcontext;
25
26
import java.awt.geom.Rectangle2D;
27
28
import org.gvsig.tools.ToolsLocator;
29
import org.gvsig.tools.dynobject.DynStruct;
30
import org.gvsig.tools.persistence.PersistenceManager;
31
import org.gvsig.tools.persistence.Persistent;
32
import org.gvsig.tools.persistence.PersistentState;
33
import org.gvsig.tools.persistence.exception.PersistenceException;
34 41840 jjdelcerro
import org.gvsig.tools.util.Callable;
35 40435 jjdelcerro
36 42192 fdiaz
37 40435 jjdelcerro
/**
38 42170 mcompany
 * <p>
39
 * <code>ExtentHistory</code> is designed for managing a history of extents.
40
 * </p>
41
 * <p>
42
 * Note: An <i>extent</i> is a rectangular area, with information of its
43
 * top-left 2D corner.
44
 * </p>
45 40435 jjdelcerro
 *
46
 * @author Vicente Caballero Navarro
47
 */
48
public class ExtentHistory implements Persistent {
49
50 42192 fdiaz
  private static final String FIELD_CURRENT_EXTENT = "current";
51
  private static final String FIELD_NUM_PREVIOUS = "num";
52
  private static final String FIELD_NUM_NEXT = "numnext";
53
  private static final String FIELD_NUM_RECORDS = "numrec";
54
  private static final String FIELD_PREVIOUS_EXTENTS = "extents";
55
  private static final String FIELD_NEXT_EXTENTS = "extentsNext";
56 43279 fdiaz
57 42170 mcompany
  /**
58
   * <p>
59
   * Maximum number of extents that can store.
60
   * </p>
61
   */
62
  private int NUMREC;
63 40435 jjdelcerro
64 42170 mcompany
  /**
65
   * <p>
66 42192 fdiaz
   * Array with the previous extents.
67 42170 mcompany
   * </p>
68
   *
69
   * @see #hasPrevious()
70
   * @see #put(Rectangle2D)
71 42192 fdiaz
   * @see #getPrev()
72
   * @see #popPrev()
73 42170 mcompany
   */
74 42192 fdiaz
  private Rectangle2D[] extentsPrev;
75 40435 jjdelcerro
76 42192 fdiaz
  /**
77
   * <p>
78
   * Array with the next extents.
79
   * </p>
80
   *
81
   * @see #hasNext()
82
   * @see #putNext(Rectangle2D)
83
   * @see #getNext()
84
   * @see #popNext()
85
   */
86 42170 mcompany
  private Rectangle2D[] extentsNext;
87 40435 jjdelcerro
88 42170 mcompany
  /**
89
   * <p>
90 42192 fdiaz
   * The current extent of the viewport.
91
   * </p>
92
   */
93
  private Rectangle2D currentExtent;
94
95
  /**
96
   * <p>
97 42177 mcompany
   * Number of previous extents stored.
98 42170 mcompany
   * </p>
99
   *
100
   * @see #hasPrevious()
101
   * @see #put(Rectangle2D)
102 42192 fdiaz
   * @see #getPrev()
103
   * @see #popPrev()
104 42170 mcompany
   */
105 42192 fdiaz
  private int numPrev = 0;
106 40435 jjdelcerro
107 42177 mcompany
  /**
108
   * <p>
109
   * Number of next extents stored.
110
   * </p>
111
   *
112
   * @see #hasNext()
113
   * @see #putNext(Rectangle2D)
114
   * @see #getNext()
115 42192 fdiaz
   * @see #popNext()
116 42177 mcompany
   */
117 42170 mcompany
  private int numNext = 0;
118 40435 jjdelcerro
119 42170 mcompany
  /**
120
   * <p>
121
   * Creates a new instance of <code>ExtentsHistory</code> with an history of 10
122
   * extents.
123
   * </p>
124
   */
125
  public ExtentHistory() {
126
    this(10);
127
  }
128 40435 jjdelcerro
129 42170 mcompany
  /**
130
   * <p>
131
   * Creates a new instance of <code>ExtentsHistory</code> with an history of
132
   * <code>numEntries</code> extents.
133
   * </p>
134
   *
135
   * @param numEntries the maximum number of extents that will store the
136
   *          instance
137
   */
138
  public ExtentHistory(int numEntries) {
139
    NUMREC = numEntries;
140 42192 fdiaz
    extentsPrev = new Rectangle2D[NUMREC];
141 42170 mcompany
    extentsNext = new Rectangle2D[NUMREC];
142
  }
143 40435 jjdelcerro
144 42170 mcompany
  /**
145
   * <p>
146 42177 mcompany
   * Appends the specified extent at the end of the array of previous zooms.
147 42170 mcompany
   * </p>
148
   *
149
   * @param ext the new extent
150
   */
151
  public void put(Rectangle2D ext) {
152 43279 fdiaz
153 42192 fdiaz
    // Si al cargar de la persistencia currentExtent es null ViewPort nos dar? su extent
154
    if(currentExtent == null) {
155
      this.currentExtent = ext;
156
      return;
157 42170 mcompany
    }
158 43279 fdiaz
159 42192 fdiaz
    if ( !ext.equals(getPrev()) && !ext.equals(getNext()) ) {
160
      clearNumNext();
161
    }
162 42177 mcompany
163 42192 fdiaz
    pushPrevious(currentExtent);
164
165
    this.currentExtent = ext;
166 42173 mcompany
  }
167 40435 jjdelcerro
168 42170 mcompany
  /**
169
   * <p>
170 42177 mcompany
   * Returns <code>true</code> if there are previous extents registered.
171 42170 mcompany
   * </p>
172
   *
173 42177 mcompany
   * @return <code>true</code> if there are previous extents registered;
174 42170 mcompany
   *         <code>false</code> otherwise
175
   */
176
  public boolean hasPrevious() {
177 42192 fdiaz
    return numPrev > 0;
178 42170 mcompany
  }
179 40435 jjdelcerro
180 42177 mcompany
  /**
181
   * <p>
182
   * Returns <code>true</code> if there are next extents registered.
183
   * </p>
184
   *
185
   * @return <code>true</code> if there are next extents registered;
186
   *         <code>false</code> otherwise
187
   */
188 42170 mcompany
  public boolean hasNext() {
189
    return numNext > 0;
190
  }
191 40435 jjdelcerro
192 42170 mcompany
  /**
193
   * <p>
194 42198 mcompany
   * Returns the last previous extent from the history.
195 42170 mcompany
   * </p>
196
   *
197 42198 mcompany
   * @return the last previous extent from the history
198 42170 mcompany
   */
199 42192 fdiaz
  public Rectangle2D getPrev() {
200
    if (numPrev <= 0) {
201 42170 mcompany
      return null;
202
    }
203 42192 fdiaz
    Rectangle2D ext = extentsPrev[numPrev - 1];
204 40435 jjdelcerro
205 42170 mcompany
    return ext;
206
  }
207 42173 mcompany
208 42177 mcompany
  /**
209
   * <p>
210 42198 mcompany
   * Returns the last next extent from the history.
211 42177 mcompany
   * </p>
212
   *
213 42198 mcompany
   * @return the last next extent from the history
214 42177 mcompany
   */
215 42170 mcompany
  public Rectangle2D getNext() {
216
    if (numNext <= 0) {
217
      return null;
218
    }
219 42173 mcompany
220 42170 mcompany
    Rectangle2D ext = extentsNext[numNext - 1];
221
    return ext;
222
  }
223 40435 jjdelcerro
224 42170 mcompany
  /**
225
   * <p>
226 42177 mcompany
   * Extracts (removing) the last previous extent from the history.
227 42170 mcompany
   * </p>
228
   *
229 42198 mcompany
   * @return last previous extent from the history
230 42170 mcompany
   */
231 42192 fdiaz
  private Rectangle2D popPrev() {
232
    if (numPrev <= 0) {
233 42170 mcompany
      return null;
234
    }
235 40435 jjdelcerro
236 42192 fdiaz
    Rectangle2D ext = extentsPrev[--numPrev];
237 42170 mcompany
    return ext;
238
  }
239 41840 jjdelcerro
240 42170 mcompany
  /**
241
   * <p>
242 42177 mcompany
   * Extracts (removing) the last next extent from the history.
243 42170 mcompany
   * </p>
244
   *
245 42198 mcompany
   * @return last next extent from the history
246 42170 mcompany
   */
247 42192 fdiaz
  private Rectangle2D popNext() {
248 42170 mcompany
    if (numNext <= 0) {
249
      return null;
250 41840 jjdelcerro
    }
251 42170 mcompany
252
    Rectangle2D ext = extentsNext[--numNext];
253
    return ext;
254
  }
255
256 42177 mcompany
  /**
257
   * <p>
258 42192 fdiaz
   * Sets to zero the number of previous extents from the history.
259
   * </p>
260
   */
261
  private void clearNumPrev() {
262
    numPrev = 0;
263
  }
264
265
  /**
266
   * <p>
267 42177 mcompany
   * Sets to zero the number of next extents from the history.
268
   * </p>
269
   */
270 42192 fdiaz
  private void clearNumNext() {
271 42170 mcompany
    numNext = 0;
272
  }
273
274 42192 fdiaz
  /**
275
   * <p>
276 42198 mcompany
   * Adds the current extent to the next extent history and sets the last
277 42192 fdiaz
   * previous extent as the new current extent.
278
   * </p>
279
   *
280
   * @return the last previous extent as the new current extent
281
   */
282
  public Rectangle2D setPreviousExtent() {
283 43279 fdiaz
284 42192 fdiaz
    if (currentExtent != null) {
285
      pushNext(currentExtent);
286
    }
287
    currentExtent = popPrev();
288
    return currentExtent;
289
  }
290 43279 fdiaz
291 42198 mcompany
  /**
292
   * <p>
293
   * Adds the specified extent to the next extent history.
294
   * If the array of next extents is complete, loses the
295
   * first extent of the array and adds the new one at the end.
296
   * </p>
297 43279 fdiaz
   *
298 42198 mcompany
   */
299 42192 fdiaz
  private void pushNext(Rectangle2D ext) {
300
    if (numNext < (NUMREC)) {
301
      extentsNext[numNext] = ext;
302
      numNext = numNext + 1;
303
    }
304
    else {
305
      for (int i = 0; i < (NUMREC - 1); i++) {
306
        extentsNext[i] = extentsNext[i + 1];
307
      }
308
      extentsNext[numNext - 1] = ext;
309
    }
310
  }
311
312
  /**
313
   * <p>
314 42198 mcompany
   * Adds the current extent to the previous extent history and sets the last
315 42192 fdiaz
   * next extent as the new current extent.
316
   * </p>
317 43279 fdiaz
   *
318 42192 fdiaz
   * @return the last next extent as the new current extent
319
   */
320
  public Rectangle2D setNextExtent() {
321
322
    if (currentExtent != null) {
323
      pushPrevious(currentExtent);
324 43279 fdiaz
325 42192 fdiaz
    }
326
    currentExtent = popNext();
327
    return currentExtent;
328
  }
329
330 42198 mcompany
  /**
331
   * <p>
332
   * Adds the specified extent to the previous extent history.
333
   * If the array of previous extents is complete, loses the
334
   * first extent of the array and adds the new one at the end.
335
   * </p>
336 43279 fdiaz
   *
337 42198 mcompany
   */
338 42192 fdiaz
  private void pushPrevious(Rectangle2D ext) {
339
    if (numPrev < (NUMREC)) {
340
      extentsPrev[numPrev] = ext;
341
      numPrev++;
342
    } else {
343
      for (int i = 0; i < (NUMREC - 1); i++) {
344
        extentsPrev[i] = extentsPrev[i + 1];
345
      }
346
      extentsPrev[numPrev - 1] = ext;
347
    }
348
  }
349 43279 fdiaz
350 42198 mcompany
  /**
351
   * <p>
352
   * Returns the current extent.
353
   * </p>
354 43279 fdiaz
   *
355 42198 mcompany
   * @return the current extent
356
   */
357 42192 fdiaz
  public Rectangle2D getCurrent() {
358
    return currentExtent;
359
  }
360
361 43279 fdiaz
    public void loadFromState(PersistentState state) throws PersistenceException {
362 42170 mcompany
363 43279 fdiaz
        if (state.hasValue("num")) {
364
            numPrev = state.getInt("num");
365
        } else {
366
            clearNumPrev();
367
        }
368 42192 fdiaz
369 43279 fdiaz
        if (state.hasValue("numnext")) {
370
            numNext = state.getInt("numnext");
371
        } else {
372
            clearNumNext();
373
        }
374 42192 fdiaz
375 43279 fdiaz
        if (state.hasValue("numrec")) {
376
            NUMREC = state.getInt("numrec");
377
        } else {
378
            NUMREC = 10;
379
        }
380 42192 fdiaz
381 43279 fdiaz
        extentsPrev = new Rectangle2D[NUMREC];
382
        clearNumPrev();
383
        if (state.hasValue("extents")) {
384
            Rectangle2D[] storedExtentPrev = (Rectangle2D[]) state.getArray("extents", Rectangle2D.class);
385
            if (storedExtentPrev.length >= NUMREC) {
386
                extentsPrev = storedExtentPrev;
387
                NUMREC = storedExtentPrev.length;
388
            } else {
389
                for (int i = 0; i < storedExtentPrev.length; i++) {
390
                    extentsPrev[i] = storedExtentPrev[i];
391
                }
392
            }
393
        }
394 42192 fdiaz
395 43279 fdiaz
        extentsNext = new Rectangle2D[NUMREC];
396
        clearNumNext();
397
        if (state.hasValue("extentsNext")) {
398
            Rectangle2D[] storedExtentsNext = (Rectangle2D[]) state.getArray("extentsNext", Rectangle2D.class);
399
            if (storedExtentsNext.length >= NUMREC) {
400
                extentsNext = storedExtentsNext;
401
                NUMREC = storedExtentsNext.length;
402
            } else {
403
                for (int i = 0; i < storedExtentsNext.length; i++) {
404
                    extentsNext[i] = storedExtentsNext[i];
405
                }
406
            }
407
        }
408
409
        if (state.hasValue("current")) {
410
            currentExtent = (Rectangle2D) state.get("current");
411
        } else {
412
            currentExtent = null;
413
        }
414 42192 fdiaz
    }
415 42170 mcompany
416
  /**
417
   * <p>
418
   * Returns information of this object. All information is stored as
419
   * properties:<br>
420
   * </p>
421
   * <p>
422
   * <b>Properties:</b>
423
   * <ul>
424
   * <li><i>className</i>: name of this class.
425
   * <li><i>num</i>: number of extents registered.
426
   * <li><i>numrec</i>: maximum number of extents that can register.
427
   * <li><i>extents</i>: .
428
   * </ul>
429
   * </p>
430
   */
431
  public void saveToState(PersistentState state) throws PersistenceException {
432
433 42192 fdiaz
    state.set(FIELD_NUM_PREVIOUS, numPrev);
434
    state.set(FIELD_NUM_NEXT, numNext);
435
    state.set(FIELD_NUM_RECORDS, NUMREC);
436
    state.set(FIELD_PREVIOUS_EXTENTS, extentsPrev);
437
    state.set(FIELD_NEXT_EXTENTS, extentsNext);
438
    state.set(FIELD_CURRENT_EXTENT, currentExtent);
439 42170 mcompany
  }
440
441
  public static class RegisterPersistence implements Callable {
442
443
    public Object call() {
444
      PersistenceManager manager = ToolsLocator.getPersistenceManager();
445
      DynStruct definition = manager.addDefinition(ExtentHistory.class,
446
          "ExtentHistory", "ExtentHistory Persistence definition", null, null);
447 42192 fdiaz
      definition.addDynFieldInt(FIELD_NUM_PREVIOUS).setMandatory(true);
448
      definition.addDynFieldInt(FIELD_NUM_NEXT).setMandatory(true);
449
      definition.addDynFieldInt(FIELD_NUM_RECORDS).setMandatory(true);
450
      definition.addDynFieldArray(FIELD_PREVIOUS_EXTENTS).setClassOfItems(Rectangle2D.class)
451 42170 mcompany
          .setMandatory(true);
452 42192 fdiaz
      definition.addDynFieldArray(FIELD_NEXT_EXTENTS)
453 42170 mcompany
          .setClassOfItems(Rectangle2D.class).setMandatory(true);
454 42192 fdiaz
      definition.addDynFieldObject(FIELD_CURRENT_EXTENT)
455
      .setClassOfValue(Rectangle2D.class).setMandatory(false);
456
457 42170 mcompany
      return Boolean.TRUE;
458
    }
459
  }
460 40435 jjdelcerro
}