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

Last change on this file since 12867 was 12851, checked in by bastiK, 7 years ago

see #15229 - extract "struct" handling from Preference to StructUtils

  • Property svn:eol-style set to native
File size: 9.6 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.LatLon;
19import org.openstreetmap.josm.data.projection.Projection;
20import org.openstreetmap.josm.data.projection.Projections;
21import org.openstreetmap.josm.gui.MainApplication;
22import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
23import org.openstreetmap.josm.gui.layer.ImageryLayer;
24import org.openstreetmap.josm.spi.preferences.Config;
25import org.openstreetmap.josm.tools.Logging;
26
27/**
28 * Class to save a displacement of background imagery as a bookmark.
29 *
30 * Known offset bookmarks will be stored in the preferences and can be
31 * restored by the user in later sessions.
32 */
33public class OffsetBookmark {
34 private static final List<OffsetBookmark> allBookmarks = new ArrayList<>();
35
36 @StructEntry private String projection_code;
37 @StructEntry private String imagery_name;
38 @StructEntry private String name;
39 @StructEntry @WriteExplicitly private double dx, dy;
40 @StructEntry private double center_lon, center_lat;
41
42 public boolean isUsable(ImageryLayer layer) {
43 if (projection_code == null) return false;
44 if (!Main.getProjection().toCode().equals(projection_code) && !hasCenter()) return false;
45 return layer.getInfo().getName().equals(imagery_name);
46 }
47
48 /**
49 * Construct new empty OffsetBookmark.
50 *
51 * Only used for preferences handling.
52 */
53 public OffsetBookmark() {
54 // do nothing
55 }
56
57 public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy) {
58 this(projectionCode, imageryName, name, dx, dy, 0, 0);
59 }
60
61 public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy, double centerLon, double centerLat) {
62 this.projection_code = projectionCode;
63 this.imagery_name = imageryName;
64 this.name = name;
65 this.dx = dx;
66 this.dy = dy;
67 this.center_lon = centerLon;
68 this.center_lat = centerLat;
69 }
70
71 public OffsetBookmark(Collection<String> list) {
72 List<String> array = new ArrayList<>(list);
73 this.projection_code = array.get(0);
74 this.imagery_name = array.get(1);
75 this.name = array.get(2);
76 this.dx = Double.parseDouble(array.get(3));
77 this.dy = Double.parseDouble(array.get(4));
78 if (array.size() >= 7) {
79 this.center_lon = Double.parseDouble(array.get(5));
80 this.center_lat = Double.parseDouble(array.get(6));
81 }
82 if (projection_code == null) {
83 Logging.error(tr("Projection ''{0}'' is not found, bookmark ''{1}'' is not usable", projection_code, name));
84 }
85 }
86
87 public String getProjectionCode() {
88 return projection_code;
89 }
90
91 public String getName() {
92 return name;
93 }
94
95 public String getImageryName() {
96 return imagery_name;
97 }
98
99 /**
100 * Get displacement in EastNorth coordinates of the original projection.
101 *
102 * @return the displacement
103 * @see #getProjectionCode()
104 */
105 public EastNorth getDisplacement() {
106 return new EastNorth(dx, dy);
107 }
108
109 /**
110 * Get displacement in EastNorth coordinates of a given projection.
111 *
112 * Displacement will be converted to the given projection, with respect to the
113 * center (reference point) of this bookmark.
114 * @param proj the projection
115 * @return the displacement, converted to that projection
116 */
117 public EastNorth getDisplacement(Projection proj) {
118 if (proj.toCode().equals(projection_code)) {
119 return getDisplacement();
120 }
121 LatLon center = getCenter();
122 Projection offsetProj = Projections.getProjectionByCode(projection_code);
123 EastNorth centerEN = center.getEastNorth(offsetProj);
124 EastNorth shiftedEN = centerEN.add(getDisplacement());
125 LatLon shifted = offsetProj.eastNorth2latlon(shiftedEN);
126 EastNorth centerEN2 = center.getEastNorth(proj);
127 EastNorth shiftedEN2 = shifted.getEastNorth(proj);
128 return shiftedEN2.subtract(centerEN2);
129 }
130
131 /**
132 * Get center/reference point of the bookmark.
133 *
134 * Basically this is the place where it was created and is valid.
135 * The center may be unrecorded (see {@link #hasCenter()}, in which
136 * case a dummy center (0,0) will be returned.
137 * @return the center
138 */
139 public LatLon getCenter() {
140 return new LatLon(center_lat, center_lon);
141 }
142
143 /**
144 * Check if bookmark has a valid center.
145 * @return true if bookmark has a valid center
146 */
147 public boolean hasCenter() {
148 return center_lat != 0 || center_lon != 0;
149 }
150
151 public void setProjectionCode(String projectionCode) {
152 this.projection_code = projectionCode;
153 }
154
155 public void setName(String name) {
156 this.name = name;
157 }
158
159 public void setImageryName(String imageryName) {
160 this.imagery_name = imageryName;
161 }
162
163 public void setDisplacement(EastNorth displacement) {
164 this.dx = displacement.east();
165 this.dy = displacement.north();
166 }
167
168 public static void loadBookmarks() {
169 List<OffsetBookmark> bookmarks = StructUtils.getListOfStructs(
170 Config.getPref(), "imagery.offsetbookmarks", null, OffsetBookmark.class);
171 if (bookmarks == null) {
172 loadBookmarksOld();
173 saveBookmarks();
174 } else {
175 allBookmarks.addAll(bookmarks);
176 }
177 }
178
179 // migration code - remove Nov. 2017
180 private static void loadBookmarksOld() {
181 for (Collection<String> c : Config.getPref().getListOfLists("imagery.offsets")) {
182 allBookmarks.add(new OffsetBookmark(c));
183 }
184 }
185
186 public static void saveBookmarks() {
187 StructUtils.putListOfStructs(Config.getPref(), "imagery.offsetbookmarks", allBookmarks, OffsetBookmark.class);
188 }
189
190 /**
191 * Returns all bookmarks.
192 * @return all bookmarks (unmodifiable collection)
193 * @since 11651
194 */
195 public static List<OffsetBookmark> getBookmarks() {
196 return Collections.unmodifiableList(allBookmarks);
197 }
198
199 /**
200 * Returns the number of bookmarks.
201 * @return the number of bookmarks
202 * @since 11651
203 */
204 public static int getBookmarksSize() {
205 return allBookmarks.size();
206 }
207
208 /**
209 * Adds a bookmark.
210 * @param ob bookmark to add
211 * @return {@code true}
212 * @since 11651
213 */
214 public static boolean addBookmark(OffsetBookmark ob) {
215 return allBookmarks.add(ob);
216 }
217
218 /**
219 * Removes a bookmark.
220 * @param ob bookmark to remove
221 * @return {@code true} if this list contained the specified element
222 * @since 11651
223 */
224 public static boolean removeBookmark(OffsetBookmark ob) {
225 return allBookmarks.remove(ob);
226 }
227
228 /**
229 * Returns the bookmark at the given index.
230 * @param index bookmark index
231 * @return the bookmark at the given index
232 * @throws IndexOutOfBoundsException if the index is out of range
233 * (<tt>index &lt; 0 || index &gt;= size()</tt>)
234 * @since 11651
235 */
236 public static OffsetBookmark getBookmarkByIndex(int index) {
237 return allBookmarks.get(index);
238 }
239
240 public static OffsetBookmark getBookmarkByName(ImageryLayer layer, String name) {
241 for (OffsetBookmark b : allBookmarks) {
242 if (b.isUsable(layer) && name.equals(b.name))
243 return b;
244 }
245 return null;
246 }
247
248 public static void bookmarkOffset(String name, AbstractTileSourceLayer layer) {
249 LatLon center;
250 if (MainApplication.isDisplayingMapView()) {
251 center = Main.getProjection().eastNorth2latlon(MainApplication.getMap().mapView.getCenter());
252 } else {
253 center = LatLon.ZERO;
254 }
255 OffsetBookmark nb = new OffsetBookmark(
256 Main.getProjection().toCode(), layer.getInfo().getName(),
257 name, layer.getDisplaySettings().getDx(), layer.getDisplaySettings().getDy(), center.lon(), center.lat());
258 for (ListIterator<OffsetBookmark> it = allBookmarks.listIterator(); it.hasNext();) {
259 OffsetBookmark b = it.next();
260 if (b.isUsable(layer) && name.equals(b.name)) {
261 it.set(nb);
262 saveBookmarks();
263 return;
264 }
265 }
266 allBookmarks.add(nb);
267 saveBookmarks();
268 }
269
270 /**
271 * Converts the offset bookmark to a properties map.
272 *
273 * The map contains all the information to restore the offset bookmark.
274 * @return properties map of all data
275 * @see #fromPropertiesMap(java.util.Map)
276 * @since 12134
277 */
278 public Map<String, String> toPropertiesMap() {
279 return StructUtils.serializeStruct(this, OffsetBookmark.class);
280 }
281
282 /**
283 * Creates an offset bookmark from a properties map.
284 * @param properties the properties map
285 * @return corresponding offset bookmark
286 * @see #toPropertiesMap()
287 * @since 12134
288 */
289 public static OffsetBookmark fromPropertiesMap(Map<String, String> properties) {
290 return StructUtils.deserializeStruct(properties, OffsetBookmark.class);
291 }
292}
Note: See TracBrowser for help on using the repository browser.