// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.data.imagery;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
import org.openstreetmap.josm.gui.layer.ImageryLayer;
public class OffsetBookmark {
private static final List<OffsetBookmark> allBookmarks = new ArrayList<>();
public String projectionCode;
public String layerName;
public String name;
public double dx, dy;
public double centerX, centerY;
public boolean isUsable(ImageryLayer layer) {
if (projectionCode == null) return false;
if (!Main.getProjection().toCode().equals(projectionCode)) return false;
return layer.getInfo().getName().equals(layerName);
}
public OffsetBookmark(String projectionCode, String layerName, String name, double dx, double dy) {
this(projectionCode, layerName, name, dx, dy, 0, 0);
}
public OffsetBookmark(String projectionCode, String layerName, String name, double dx, double dy, double centerX, double centerY) {
this.projectionCode = projectionCode;
this.layerName = layerName;
this.name = name;
this.dx = dx;
this.dy = dy;
this.centerX = centerX;
this.centerY = centerY;
}
public OffsetBookmark(Collection<String> list) {
List<String> array = new ArrayList<>(list);
this.projectionCode = array.get(0);
this.layerName = array.get(1);
this.name = array.get(2);
this.dx = Double.parseDouble(array.get(3));
this.dy = Double.parseDouble(array.get(4));
if (array.size() >= 7) {
this.centerX = Double.parseDouble(array.get(5));
this.centerY = Double.parseDouble(array.get(6));
}
if (projectionCode == null) {
Main.error(tr("Projection ''{0}'' is not found, bookmark ''{1}'' is not usable", projectionCode, name));
}
}
public List<String> getInfoArray() {
List<String> res = new ArrayList<>(7);
if (projectionCode != null) {
res.add(projectionCode);
} else {
res.add("");
}
res.add(layerName);
res.add(name);
res.add(String.valueOf(dx));
res.add(String.valueOf(dy));
if (centerX != 0 || centerY != 0) {
res.add(String.valueOf(centerX));
res.add(String.valueOf(centerY));
}
return res;
}
public static void loadBookmarks() {
for (Collection<String> c : Main.pref.getArray("imagery.offsets",
Collections.<Collection<String>>emptySet())) {
allBookmarks.add(new OffsetBookmark(c));
}
}
public static void saveBookmarks() {
List<Collection<String>> coll = new LinkedList<>();
for (OffsetBookmark b : allBookmarks) {
coll.add(b.getInfoArray());
}
Main.pref.putArray("imagery.offsets", coll);
}
/**
* Returns all bookmarks.
* @return all bookmarks (unmodifiable collection)
* @since 11651
*/
public static List<OffsetBookmark> getBookmarks() {
return Collections.unmodifiableList(allBookmarks);
}
/**
* Returns the number of bookmarks.
* @return the number of bookmarks
* @since 11651
*/
public static int getBookmarksSize() {
return allBookmarks.size();
}
/**
* Adds a bookmark.
* @param ob bookmark to add
* @return {@code true}
* @since 11651
*/
public static boolean addBookmark(OffsetBookmark ob) {
return allBookmarks.add(ob);
}
/**
* Removes a bookmark.
* @param ob bookmark to remove
* @return {@code true} if this list contained the specified element
* @since 11651
*/
public static boolean removeBookmark(OffsetBookmark ob) {
return allBookmarks.remove(ob);
}
/**
* Returns the bookmark at the given index.
* @param index bookmark index
* @return the bookmark at the given index
* @throws IndexOutOfBoundsException if the index is out of range
* (<tt>index < 0 || index >= size()</tt>)
* @since 11651
*/
public static OffsetBookmark getBookmarkByIndex(int index) {
return allBookmarks.get(index);
}
public static OffsetBookmark getBookmarkByName(ImageryLayer layer, String name) {
for (OffsetBookmark b : allBookmarks) {
if (b.isUsable(layer) && name.equals(b.name))
return b;
}
return null;
}
public static void bookmarkOffset(String name, AbstractTileSourceLayer layer) {
LatLon center;
if (Main.isDisplayingMapView()) {
center = Main.getProjection().eastNorth2latlon(Main.map.mapView.getCenter());
} else {
center = LatLon.ZERO;
}
OffsetBookmark nb = new OffsetBookmark(
Main.getProjection().toCode(), layer.getInfo().getName(),
name, layer.getDisplaySettings().getDx(), layer.getDisplaySettings().getDy(), center.lon(), center.lat());
for (ListIterator<OffsetBookmark> it = allBookmarks.listIterator(); it.hasNext();) {
OffsetBookmark b = it.next();
if (b.isUsable(layer) && name.equals(b.name)) {
it.set(nb);
saveBookmarks();
return;
}
}
allBookmarks.add(nb);
saveBookmarks();
}
}