source: josm/trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java@ 13493

Last change on this file since 13493 was 13493, checked in by Don-vip, 6 years ago

see #11924, see #15560, see #16048 - tt HTML tag is deprecated in HTML5: use code instead

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.Collections;
9import java.util.List;
10import java.util.ListIterator;
11import java.util.Map;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.data.StructUtils;
15import org.openstreetmap.josm.data.StructUtils.StructEntry;
16import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
17import org.openstreetmap.josm.data.coor.EastNorth;
18import org.openstreetmap.josm.data.coor.ILatLon;
19import org.openstreetmap.josm.data.coor.LatLon;
20import org.openstreetmap.josm.data.projection.Projection;
21import org.openstreetmap.josm.data.projection.Projections;
22import org.openstreetmap.josm.gui.MainApplication;
23import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
24import org.openstreetmap.josm.gui.layer.ImageryLayer;
25import org.openstreetmap.josm.spi.preferences.Config;
26import org.openstreetmap.josm.tools.Logging;
27
28/**
29 * Class to save a displacement of background imagery as a bookmark.
30 *
31 * Known offset bookmarks will be stored in the preferences and can be
32 * restored by the user in later sessions.
33 */
34public class OffsetBookmark {
35 private static final List<OffsetBookmark> allBookmarks = new ArrayList<>();
36
37 @StructEntry private String projection_code;
38 @StructEntry private String imagery_name;
39 @StructEntry private String name;
40 @StructEntry @WriteExplicitly private double dx, dy;
41 @StructEntry private double center_lon, center_lat;
42
43 /**
44 * Test if an image is usable for the given imagery layer.
45 * @param layer The layer to use the image at
46 * @return <code>true</code> if it is usable on the projection of the layer and the imagery name matches.
47 */
48 public boolean isUsable(ImageryLayer layer) {
49 if (projection_code == null) return false;
50 if (!Main.getProjection().toCode().equals(projection_code) && !hasCenter()) return false;
51 return layer.getInfo().getName().equals(imagery_name);
52 }
53
54 /**
55 * Construct new empty OffsetBookmark.
56 *
57 * Only used for preferences handling.
58 */
59 public OffsetBookmark() {
60 // do nothing
61 }
62
63 /**
64 * Create a new {@link OffsetBookmark} object using (0, 0) as center
65 * <p>
66 * The use of the {@link #OffsetBookmark(String, String, String, EastNorth, ILatLon)} constructor is preferred.
67 * @param projectionCode The projection for which this object was created
68 * @param imageryName The name of the imagery on the layer
69 * @param name The name of the new bookmark
70 * @param dx The x displacement
71 * @param dy The y displacement
72 */
73 public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy) {
74 this(projectionCode, imageryName, name, dx, dy, 0, 0);
75 }
76
77 /**
78 * Create a new {@link OffsetBookmark} object
79 * @param projectionCode The projection for which this object was created
80 * @param imageryName The name of the imagery on the layer
81 * @param name The name of the new bookmark
82 * @param displacement The displacement in east/north space.
83 * @param center The point on earth that was used as reference to align the image.
84 * @since 13243
85 */
86 public OffsetBookmark(String projectionCode, String imageryName, String name, EastNorth displacement, ILatLon center) {
87 this(projectionCode, imageryName, name, displacement.east(), displacement.north(), center.lon(), center.lat());
88 }
89
90 /**
91 * Create a new {@link OffsetBookmark} by specifying all values.
92 * <p>
93 * The use of the {@link #OffsetBookmark(String, String, String, EastNorth, ILatLon)} constructor is preferred.
94 * @param projectionCode The projection for which this object was created
95 * @param imageryName The name of the imagery on the layer
96 * @param name The name of the new bookmark
97 * @param dx The x displacement
98 * @param dy The y displacement
99 * @param centerLon The point on earth that was used as reference to align the image.
100 * @param centerLat The point on earth that was used as reference to align the image.
101 */
102 public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy, double centerLon, double centerLat) {
103 this.projection_code = projectionCode;
104 this.imagery_name = imageryName;
105 this.name = name;
106 this.dx = dx;
107 this.dy = dy;
108 this.center_lon = centerLon;
109 this.center_lat = centerLat;
110 }
111
112 /**
113 * Loads an old bookmark. For backward compatibility with settings. Do not use.
114 * @param list The settings that were read
115 */
116 public OffsetBookmark(Collection<String> list) {
117 List<String> array = new ArrayList<>(list);
118 this.projection_code = array.get(0);
119 this.imagery_name = array.get(1);
120 this.name = array.get(2);
121 this.dx = Double.parseDouble(array.get(3));
122 this.dy = Double.parseDouble(array.get(4));
123 if (array.size() >= 7) {
124 this.center_lon = Double.parseDouble(array.get(5));
125 this.center_lat = Double.parseDouble(array.get(6));
126 }
127 if (projection_code == null) {
128 Logging.error(tr("Projection ''{0}'' is not found, bookmark ''{1}'' is not usable", projection_code, name));
129 }
130 }
131
132 /**
133 * Get the projection code for which this bookmark was created.
134 * @return The projection.
135 */
136 public String getProjectionCode() {
137 return projection_code;
138 }
139
140 /**
141 * Get the name of this bookmark. This name can e.g. be displayed in menus.
142 * @return The name
143 */
144 public String getName() {
145 return name;
146 }
147
148 /**
149 * Get the name of the imagery for which this bookmark was created. It is used to match the bookmark to the right layers.
150 * @return The name
151 */
152 public String getImageryName() {
153 return imagery_name;
154 }
155
156 /**
157 * Get displacement in EastNorth coordinates of the original projection.
158 *
159 * @return the displacement
160 * @see #getProjectionCode()
161 */
162 public EastNorth getDisplacement() {
163 return new EastNorth(dx, dy);
164 }
165
166 /**
167 * Get displacement in EastNorth coordinates of a given projection.
168 *
169 * Displacement will be converted to the given projection, with respect to the
170 * center (reference point) of this bookmark.
171 * @param proj the projection
172 * @return the displacement, converted to that projection
173 */
174 public EastNorth getDisplacement(Projection proj) {
175 if (proj.toCode().equals(projection_code)) {
176 return getDisplacement();
177 }
178 LatLon center = getCenter();
179 Projection offsetProj = Projections.getProjectionByCode(projection_code);
180 EastNorth centerEN = center.getEastNorth(offsetProj);
181 EastNorth shiftedEN = centerEN.add(getDisplacement());
182 LatLon shifted = offsetProj.eastNorth2latlon(shiftedEN);
183 EastNorth centerEN2 = center.getEastNorth(proj);
184 EastNorth shiftedEN2 = shifted.getEastNorth(proj);
185 return shiftedEN2.subtract(centerEN2);
186 }
187
188 /**
189 * Get center/reference point of the bookmark.
190 *
191 * Basically this is the place where it was created and is valid.
192 * The center may be unrecorded (see {@link #hasCenter()}, in which
193 * case a dummy center (0,0) will be returned.
194 * @return the center
195 */
196 public LatLon getCenter() {
197 return new LatLon(center_lat, center_lon);
198 }
199
200 /**
201 * Check if bookmark has a valid center.
202 * @return true if bookmark has a valid center
203 */
204 public boolean hasCenter() {
205 return center_lat != 0 || center_lon != 0;
206 }
207
208 /**
209 * Set the projection code for which this bookmark was created
210 * @param projectionCode The projection
211 */
212 public void setProjectionCode(String projectionCode) {
213 this.projection_code = projectionCode;
214 }
215
216 /**
217 * Set the name of the bookmark
218 * @param name The name
219 * @see #getName()
220 */
221 public void setName(String name) {
222 this.name = name;
223 }
224
225 /**
226 * Sets the name of the imagery
227 * @param imageryName The name
228 * @see #getImageryName()
229 */
230 public void setImageryName(String imageryName) {
231 this.imagery_name = imageryName;
232 }
233
234 /**
235 * Update the displacement of this imagery.
236 * @param displacement The displacement
237 */
238 public void setDisplacement(EastNorth displacement) {
239 this.dx = displacement.east();
240 this.dy = displacement.north();
241 }
242
243 /**
244 * Load the global list of bookmarks from preferences.
245 */
246 public static void loadBookmarks() {
247 List<OffsetBookmark> bookmarks = StructUtils.getListOfStructs(
248 Config.getPref(), "imagery.offsetbookmarks", null, OffsetBookmark.class);
249 if (bookmarks == null) {
250 loadBookmarksOld();
251 saveBookmarks();
252 } else {
253 allBookmarks.addAll(bookmarks);
254 }
255 }
256
257 // migration code - remove Nov. 2017
258 private static void loadBookmarksOld() {
259 for (Collection<String> c : Config.getPref().getListOfLists("imagery.offsets")) {
260 allBookmarks.add(new OffsetBookmark(c));
261 }
262 }
263
264 /**
265 * Stores the bookmakrs in the settings.
266 */
267 public static void saveBookmarks() {
268 StructUtils.putListOfStructs(Config.getPref(), "imagery.offsetbookmarks", allBookmarks, OffsetBookmark.class);
269 }
270
271 /**
272 * Returns all bookmarks.
273 * @return all bookmarks (unmodifiable collection)
274 * @since 11651
275 */
276 public static List<OffsetBookmark> getBookmarks() {
277 return Collections.unmodifiableList(allBookmarks);
278 }
279
280 /**
281 * Returns the number of bookmarks.
282 * @return the number of bookmarks
283 * @since 11651
284 */
285 public static int getBookmarksSize() {
286 return allBookmarks.size();
287 }
288
289 /**
290 * Adds a bookmark.
291 * @param ob bookmark to add
292 * @return {@code true}
293 * @since 11651
294 */
295 public static boolean addBookmark(OffsetBookmark ob) {
296 return allBookmarks.add(ob);
297 }
298
299 /**
300 * Removes a bookmark.
301 * @param ob bookmark to remove
302 * @return {@code true} if this list contained the specified element
303 * @since 11651
304 */
305 public static boolean removeBookmark(OffsetBookmark ob) {
306 return allBookmarks.remove(ob);
307 }
308
309 /**
310 * Returns the bookmark at the given index.
311 * @param index bookmark index
312 * @return the bookmark at the given index
313 * @throws IndexOutOfBoundsException if the index is out of range
314 * (<code>index &lt; 0 || index &gt;= size()</code>)
315 * @since 11651
316 */
317 public static OffsetBookmark getBookmarkByIndex(int index) {
318 return allBookmarks.get(index);
319 }
320
321 /**
322 * Gets a bookmark that is usable on the given layer by it's name.
323 * @param layer The layer to use the bookmark at
324 * @param name The name of the bookmark
325 * @return The bookmark if found, <code>null</code> if not.
326 */
327 public static OffsetBookmark getBookmarkByName(ImageryLayer layer, String name) {
328 for (OffsetBookmark b : allBookmarks) {
329 if (b.isUsable(layer) && name.equals(b.name))
330 return b;
331 }
332 return null;
333 }
334
335 /**
336 * Add a bookmark for the displacement of that layer
337 * @param name The bookmark name
338 * @param layer The layer to store the bookmark for
339 */
340 public static void bookmarkOffset(String name, AbstractTileSourceLayer<?> layer) {
341 LatLon center;
342 if (MainApplication.isDisplayingMapView()) {
343 center = Main.getProjection().eastNorth2latlon(MainApplication.getMap().mapView.getCenter());
344 } else {
345 center = LatLon.ZERO;
346 }
347 OffsetBookmark nb = new OffsetBookmark(
348 Main.getProjection().toCode(), layer.getInfo().getName(),
349 name, layer.getDisplaySettings().getDisplacement(), center);
350 for (ListIterator<OffsetBookmark> it = allBookmarks.listIterator(); it.hasNext();) {
351 OffsetBookmark b = it.next();
352 if (b.isUsable(layer) && name.equals(b.name)) {
353 it.set(nb);
354 saveBookmarks();
355 return;
356 }
357 }
358 allBookmarks.add(nb);
359 saveBookmarks();
360 }
361
362 /**
363 * Converts the offset bookmark to a properties map.
364 *
365 * The map contains all the information to restore the offset bookmark.
366 * @return properties map of all data
367 * @see #fromPropertiesMap(java.util.Map)
368 * @since 12134
369 */
370 public Map<String, String> toPropertiesMap() {
371 return StructUtils.serializeStruct(this, OffsetBookmark.class);
372 }
373
374 /**
375 * Creates an offset bookmark from a properties map.
376 * @param properties the properties map
377 * @return corresponding offset bookmark
378 * @see #toPropertiesMap()
379 * @since 12134
380 */
381 public static OffsetBookmark fromPropertiesMap(Map<String, String> properties) {
382 return StructUtils.deserializeStruct(properties, OffsetBookmark.class);
383 }
384}
Note: See TracBrowser for help on using the repository browser.