/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package whitebox.cartographic;
import java.awt.Color;
import java.awt.Font;
import java.util.ArrayList;
import whitebox.geospatialfiles.RasterLayerInfo;
import whitebox.geospatialfiles.VectorLayerInfo;
import whitebox.geospatialfiles.WhiteboxRasterInfo;
import whitebox.interfaces.CartographicElement;
import whitebox.interfaces.MapLayer;
import whitebox.structures.BoundingBox;
import whitebox.structures.GridCell;
/**
*
* @author johnlindsay
*/
public class MapArea implements CartographicElement, Comparable<CartographicElement>, java.io.Serializable {
private String cartoElementType = "MapArea";
private transient MapLayer activeLayer = null;
private int activeLayerOverlayNumber = -1;
private int activeLayerIndex = -1;
private ArrayList<MapLayer> layers = new ArrayList<>();
private int numLayers = 0;
private BoundingBox currentExtent = null;
private int listOfExtentsIndex = -1;
private ArrayList<BoundingBox> listOfExtents = new ArrayList<>();
private BoundingBox fullExtent = null;
private transient boolean dirty = false;
private String XYUnits = "";
int upperLeftX = -32768;
int upperLeftY = -32768;
int height = -1; // in points
int width = -1; // in points
boolean visible = true;
boolean borderVisible = true;
boolean backgroundVisible = true;
boolean selected = false;
boolean referenceMarksVisible = true;
boolean neatlineVisible = false;
Color borderColour = Color.BLACK;
Color fontColour = Color.BLACK;
Color backgroundColour = Color.WHITE;
Font labelFont = new Font("SanSerif", Font.PLAIN, 10);
int number = -1;
String name = "MapArea";
float lineWidth = 0.75f;
private static double ppm = java.awt.Toolkit.getDefaultToolkit().getScreenResolution() * 39.3701;
private double scale = 0;
private int referenceMarkSize = 12;
private int selectedOffsetX;
private int selectedOffsetY;
private boolean maximumScreenSize = false;
private double rotation = 0;
public MapArea(String name) {
this.name = name;
}
@Override
public boolean isVisible() {
return visible;
}
@Override
public void setVisible(boolean visible) {
this.visible = visible;
}
@Override
public boolean isSelected() {
return selected;
}
@Override
public void setSelected(boolean selected) {
this.selected = selected;
}
@Override
public int getElementNumber() {
return number;
}
@Override
public void setElementNumber(int number) {
this.number = number;
}
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(CartographicElement other) {
final int BEFORE = -1;
final int EQUAL = 0;
final int AFTER = 1;
// compare them based on their element (overlay) numbers
if (this.number < other.getElementNumber()) {
return BEFORE;
} else if (this.number > other.getElementNumber()) {
return AFTER;
}
return EQUAL;
}
@Override
public int getUpperLeftX() {
return upperLeftX;
}
@Override
public void setUpperLeftX(int upperLeftX) {
this.upperLeftX = upperLeftX;
}
@Override
public int getUpperLeftY() {
return upperLeftY;
}
@Override
public void setUpperLeftY(int upperLeftY) {
this.upperLeftY = upperLeftY;
}
@Override
public int getLowerRightX() {
return upperLeftX + width;
}
@Override
public int getLowerRightY() {
return upperLeftY + height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Color getBorderColour() {
return borderColour;
}
public void setBorderColour(Color borderColour) {
this.borderColour = borderColour;
}
public boolean isBorderVisible() {
return borderVisible;
}
public void setBorderVisible(boolean borderVisible) {
this.borderVisible = borderVisible;
}
public Color getFontColour() {
return fontColour;
}
public void setFontColour(Color fontColour) {
this.fontColour = fontColour;
}
public Font getLabelFont() {
return labelFont;
}
public void setLabelFont(Font labelFont) {
this.labelFont = labelFont;
}
public boolean isReferenceMarksVisible() {
return referenceMarksVisible;
}
public void setReferenceMarksVisible(boolean referenceMarksVisible) {
this.referenceMarksVisible = referenceMarksVisible;
}
public boolean isNeatlineVisible() {
return neatlineVisible;
}
public void setNeatlineVisible(boolean neatlineVisible) {
this.neatlineVisible = neatlineVisible;
}
public float getLineWidth() {
return lineWidth;
}
public void setLineWidth(float lineWidth) {
this.lineWidth = lineWidth;
}
public Color getBackgroundColour() {
return backgroundColour;
}
public void setBackgroundColour(Color backgroundClour) {
this.backgroundColour = backgroundClour;
}
public boolean isBackgroundVisible() {
return backgroundVisible;
}
public void setBackgroundVisible(boolean backgroundVisible) {
this.backgroundVisible = backgroundVisible;
}
public boolean isSizeMaximizedToScreenSize() {
return maximumScreenSize;
}
public void setSizeMaximizedToScreenSize(boolean maximumScreenSize) {
this.maximumScreenSize = maximumScreenSize;
}
public int getNumLayers() {
return numLayers;
}
public String getXYUnits() {
return XYUnits;
}
public void setXYUnits(String XYUnits) {
if (XYUnits.toLowerCase().contains("deg")) {
XYUnits = "\u00b0";
}
this.XYUnits = XYUnits;
}
public int getReferenceMarksSize() {
return referenceMarkSize;
}
public void setReferenceMarksSize(int size) {
this.referenceMarkSize = size;
}
public double getRotation() {
return rotation;
}
public void setRotation(double rotation) {
this.rotation = rotation;
}
public double getScale() {
int viewAreaWidth = width - 2 * referenceMarkSize;
int viewAreaHeight = height - 2 * referenceMarkSize;
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
scale = 1 / Math.min(((viewAreaWidth / ppm) / xRange), ((viewAreaHeight / ppm) / yRange));
return scale;
}
public void setScale(double scale) {
// need to update the currentExtent to reflect the new scale
double viewAreaWidth = ((width - 2 * referenceMarkSize) / ppm);
double viewAreaHeight = ((height - 2 * referenceMarkSize) / ppm);
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double newXRange = scale * viewAreaWidth;
double deltaX = (newXRange - xRange) / 2;
currentExtent.setMinX(currentExtent.getMinX() - deltaX);
currentExtent.setMaxX(currentExtent.getMaxX() + deltaX);
double newYRange = scale * viewAreaHeight;
double deltaY = (newYRange - yRange) / 2;
currentExtent.setMinY(currentExtent.getMinY() - deltaY);
currentExtent.setMaxY(currentExtent.getMaxY() + deltaY);
}
public int getNumRasterLayers() {
int i = 0;
for (int a = 0; a < layers.size(); a++) {
if (layers.get(a).getLayerType() == MapLayer.MapLayerType.RASTER) {
i++;
}
}
return i;
}
@Override
public int getSelectedOffsetX() {
return selectedOffsetX;
}
@Override
public void setSelectedOffsetX(int selectedOffsetX) {
this.selectedOffsetX = selectedOffsetX;
}
@Override
public int getSelectedOffsetY() {
return selectedOffsetY;
}
@Override
public void setSelectedOffsetY(int selectedOffsetY) {
this.selectedOffsetY = selectedOffsetY;
}
public boolean isActiveLayerAVector() {
if (activeLayer != null) {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
return true;
}
}
return false;
}
// public int getSelectedFeatureFromActiveVector() {
// if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
// VectorLayerInfo vli = (VectorLayerInfo)activeLayer;
// return vli.getSelectedFeatureNumber();
// }
// return -1;
// }
public ArrayList<Integer> getSelectedFeaturesFromActiveVector() {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo)activeLayer;
//return vli.getSelectedFeatureNumber();
return vli.getSelectedFeatureNumbers();
}
return null;
}
public BoundingBox getFullExtent() {
return fullExtent = calculateFullExtent();
}
public BoundingBox getCurrentExtent() {
if (currentExtent == null) {
calculateFullExtent();
currentExtent = getFullExtent();
}
return currentExtent.clone();
}
public void setCurrentExtent(BoundingBox extent) {
currentExtent = extent.clone();
addToExtentHistory(extent);
}
BoundingBox currentMapExtent;
public BoundingBox getCurrentMapExtent() {
if (currentMapExtent == null) {
calculateFullExtent();
currentMapExtent = getFullExtent();
}
return currentMapExtent.clone();
}
public void setCurrentMapExtent(BoundingBox extent) {
currentMapExtent = extent.clone();
//addToExtentHistory(extent);
}
public int getActiveLayerOverlayNumber() {
if (activeLayer == null) {
return -1;
}
return activeLayer.getOverlayNumber();
}
public MapLayer getActiveLayer() {
return activeLayer;
}
public void setActiveLayer(int overlayNumber) {
this.activeLayerOverlayNumber = overlayNumber;
activeLayerIndex = findLayerIndexByOverlayNum(overlayNumber);
activeLayer = layers.get(activeLayerIndex);
dirty = true;
}
public double getActiveLayerNoDataValue() {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.RASTER) {
RasterLayerInfo rli = (RasterLayerInfo)activeLayer;
return rli.getNoDataValue();
} else {
return -32768;
}
}
public void deselectVectorFeatures() {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo)activeLayer;
//vli.setSelectedFeatureNumber(-1);
vli.clearSelectedFeatures();
}
}
public void selectVectorFeaturesByBox(BoundingBox box) {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo)activeLayer;
vli.selectFeaturesByBox(box);
}
}
public int selectVectorFeatures(double x, double y) {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo)activeLayer;
return vli.selectFeatureByLocation(x, y);
}
return -1; // it should not hit this point
}
public boolean isFitToData() {
if (numLayers > 0) {
calculateFullExtent();
double targetAspectRatio = fullExtent.getWidth() / fullExtent.getHeight();
double currentAspectRatio = (double)(width - 2 * referenceMarkSize) / (height - 2 * referenceMarkSize);
if (Math.abs(currentAspectRatio - targetAspectRatio) < 0.005) {
return true;
}
}
return false;
}
public void setFitToData() {
fitToData();
}
public void fitToData() {
if (numLayers > 0) {
calculateFullExtent();
double targetAspectRatio = fullExtent.getWidth() / fullExtent.getHeight();
double currentAspectRatio = (double)(width - 2 * referenceMarkSize) / (height - 2 * referenceMarkSize);
if (currentAspectRatio > targetAspectRatio) {
width = (int)((height - 2 * referenceMarkSize) * targetAspectRatio) + 2 * referenceMarkSize;
} else {
height = (int)((width - 2 * referenceMarkSize) / targetAspectRatio) + 2 * referenceMarkSize;
}
}
}
private void addToExtentHistory(BoundingBox extent) {
if (listOfExtentsIndex == listOfExtents.size() - 1) {
listOfExtents.add(extent.clone());
listOfExtentsIndex = listOfExtents.size() - 1;
} else {
// delete all forward extents.
for (int i = listOfExtents.size() - 1; i > listOfExtentsIndex; i--) {
listOfExtents.remove(i);
}
listOfExtents.add(extent.clone());
listOfExtentsIndex = listOfExtents.size() - 1;
}
if (listOfExtents.size() > 25) {
listOfExtents.remove(0);
listOfExtentsIndex--;
}
}
public boolean previousExtent() {
if (listOfExtentsIndex == 0) {
return false;
} else {
listOfExtentsIndex--;
currentExtent = listOfExtents.get(listOfExtentsIndex).clone();
return true;
}
}
public boolean nextExtent() {
if (listOfExtentsIndex == listOfExtents.size() - 1) {
return false;
} else {
listOfExtentsIndex++;
currentExtent = listOfExtents.get(listOfExtentsIndex).clone();
return true;
}
}
public double getXCoordinateFromColumn(int col) {
try {
RasterLayerInfo layer = new RasterLayerInfo();
if (activeLayer.getLayerType() == MapLayer.MapLayerType.RASTER) {
layer = (RasterLayerInfo) (activeLayer);
}
return layer.getXCoordinateFromColumn(col);
} catch (Exception e) {
return -1.0;
}
}
public double getYCoordinateFromRow(int row) {
try {
RasterLayerInfo layer = new RasterLayerInfo();
if (activeLayer.getLayerType() == MapLayer.MapLayerType.RASTER) {
layer = (RasterLayerInfo) (activeLayer);
}
return layer.getYCoordinateFromRow(row);
} catch (Exception e) {
return -1.0;
}
}
public GridCell getRowAndColumn(double easting, double northing) {
GridCell point = new GridCell(-1, -1, Double.NaN, Double.NaN, -1);
try {
if (activeLayer.getLayerType() == MapLayer.MapLayerType.RASTER) {
RasterLayerInfo layer = (RasterLayerInfo) (activeLayer);
// first see if this point is within the active layer.
BoundingBox db = layers.get(activeLayerIndex).getFullExtent();
double top = db.getMaxY();
double bottom = db.getMinY();
double left = db.getMinX();
double right = db.getMaxX();
double z;
boolean flag = false;
int rows = layer.getNumberRows();
int columns = layer.getNumberColumns();
if (((northing >= bottom) && (northing <= top))
|| ((northing <= bottom) && (northing >= top))) {
if (((easting >= left) && (easting <= right))
|| ((easting <= left) && (easting >= right))) {
flag = true;
}
}
if (flag) {
int row = (int) ((top - northing) / (top - bottom) * (rows));// - 0.5));
int col = (int) ((easting - left) / (right - left) * (columns));// - 0.5));
z = layer.getDataValue(row, col);
point = new GridCell(row, col, z, layer.getNoDataValue(), layer.getOverlayNumber());
if (layer.getDataScale() == WhiteboxRasterInfo.DataScale.RGB) {
point.isRGB = true;
}
} else {
// search from the top layer to the bottom for a layer in which this point resides.
for (int i = numLayers - 1; i >= 0; i--) {
if (getLayer(i) instanceof RasterLayerInfo) {
RasterLayerInfo rli = (RasterLayerInfo) getLayer(i);
db = rli.getFullExtent();
top = db.getMaxY();
bottom = db.getMinY();
left = db.getMinX();
right = db.getMaxX();
flag = false;
rows = rli.getNumberRows();
columns = rli.getNumberColumns();
if (((northing >= bottom) && (northing <= top))
|| ((northing <= bottom) && (northing >= top))) {
if (((easting >= left) && (easting <= right))
|| ((easting <= left) && (easting >= right))) {
flag = true;
}
}
if (flag) {
int row = (int) ((top - northing) / (top - bottom) * (rows)); // - 0.5));
int col = (int) ((easting - left) / (right - left) * (columns)); // - 0.5));
z = rli.getDataValue(row, col);
point = new GridCell(row, col, z, rli.getNoDataValue(), rli.getOverlayNumber());
if (rli.getDataScale() == WhiteboxRasterInfo.DataScale.RGB) {
point.isRGB = true;
}
return point;
}
}
}
}
}
} catch (Exception e) {
// do nothing
}
return point;
}
public BoundingBox calculateFullExtent() {
double top = -Double.MAX_VALUE;
double bottom = Double.MAX_VALUE;
double left = Double.MAX_VALUE;
double right = -Double.MAX_VALUE;
for (MapLayer rli: layers) {
BoundingBox db = rli.getFullExtent();
if (db.getMaxY() > top) { top = db.getMaxY(); }
if (db.getMinY() < bottom) { bottom = db.getMinY(); }
if (db.getMaxX() > right) { right = db.getMaxX(); }
if (db.getMinX() < left) { left = db.getMinX(); }
}
//fullExtent = new BoundingBox(top, right, bottom, left);
fullExtent = new BoundingBox(left, bottom, right, top);
return fullExtent.clone();
}
public void zoomIn() {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double z;
z = currentExtent.getMinY();
currentExtent.setMinY(z + rangeY * 0.1);
z = currentExtent.getMaxY();
currentExtent.setMaxY(z - rangeY * 0.1);
z = currentExtent.getMinX();
currentExtent.setMinX(z + rangeX * 0.1);
z = currentExtent.getMaxX();
currentExtent.setMaxX(z - rangeX * 0.1);
addToExtentHistory(currentExtent);
}
public void zoomIn(double x, double y) {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
currentExtent.setMinX(x - (rangeX * 0.85) / 2.0);
currentExtent.setMinY(y - (rangeY * 0.85) / 2.0);
currentExtent.setMaxX(x + (rangeX * 0.85) / 2.0);
currentExtent.setMaxY(y + (rangeY * 0.85) / 2.0);
addToExtentHistory(currentExtent);
}
public void zoomOut() {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double z;
z = currentExtent.getMinY();
currentExtent.setMinY(z - rangeY * 0.1);
z = currentExtent.getMaxY();
currentExtent.setMaxY(z + rangeY * 0.1);
z = currentExtent.getMinX();
currentExtent.setMinX(z - rangeX * 0.1);
z = currentExtent.getMaxX();
currentExtent.setMaxX(z + rangeX * 0.1);
addToExtentHistory(currentExtent);
}
public void zoomOut(double x, double y) {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
currentExtent.setMinX(x - (rangeX * 1.15) / 2.0);
currentExtent.setMinY(y - (rangeY * 1.15) / 2.0);
currentExtent.setMaxX(x + (rangeX * 1.15) / 2.0);
currentExtent.setMaxY(y + (rangeY * 1.15) / 2.0);
addToExtentHistory(currentExtent);
}
/**
* Performs a zoom and center operation
* @param x x-coordinate of center point
* @param y y-coordinate of center point
* @param factor zoom factor
*/
public void zoom(double x, double y, double factor) {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
currentExtent.setMinX(x - (rangeX * factor) / 2.0);
currentExtent.setMinY(y - (rangeY * factor) / 2.0);
currentExtent.setMaxX(x + (rangeX * factor) / 2.0);
currentExtent.setMaxY(y + (rangeY * factor) / 2.0);
addToExtentHistory(currentExtent);
}
/**
* Performs a zoom based on a point but does not re-center the extent.
* @param x x-coordinate of center point
* @param y y-coordinate of center point
* @param factor zoom factor
*/
public void naturalZoom(double x, double y, double factor) {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double relativePositionX = Math.abs(x - currentExtent.getMinX()) / rangeX;
double relativePositionY = Math.abs(y - currentExtent.getMinY()) / rangeY;
double newXRange = rangeX * factor;
double newYRange = rangeY * factor;
currentExtent.setMinX(x - newXRange * relativePositionX);
currentExtent.setMinY(y - newYRange * relativePositionY);
currentExtent.setMaxX(x + newXRange * (1.0 - relativePositionX));
currentExtent.setMaxY(y + newYRange * (1.0 - relativePositionY));
addToExtentHistory(currentExtent);
}
public void panUp() {
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double z;
z = currentExtent.getMinY();
currentExtent.setMinY(z + rangeY * 0.1);
z = currentExtent.getMaxY();
currentExtent.setMaxY(z + rangeY * 0.1);
addToExtentHistory(currentExtent);
}
public void panDown() {
double rangeY = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double z;
z = currentExtent.getMinY();
currentExtent.setMinY(z - rangeY * 0.1);
z = currentExtent.getMaxY();
currentExtent.setMaxY(z - rangeY * 0.1);
addToExtentHistory(currentExtent);
}
public void panLeft() {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double z;
z = currentExtent.getMinX();
currentExtent.setMinX(z - rangeX * 0.1);
z = currentExtent.getMaxX();
currentExtent.setMaxX(z - rangeX * 0.1);
addToExtentHistory(currentExtent);
}
public void panRight() {
double rangeX = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double z;
z = currentExtent.getMinX();
currentExtent.setMinX(z + rangeX * 0.1);
z = currentExtent.getMaxX();
currentExtent.setMaxX(z + rangeX * 0.1);
addToExtentHistory(currentExtent);
}
public void addLayer(MapLayer newLayer) {
layers.add(newLayer);
numLayers = layers.size();
if (currentExtent == null || currentExtent.getMinX() > currentExtent.getMaxX()) {
currentExtent = calculateFullExtent();
listOfExtents.add(currentExtent.clone());
listOfExtentsIndex = listOfExtents.size() - 1;
}
dirty = true;
}
public void removeLayer(int overlayNumber) {
try {
if (numLayers > 0) {
// which layer has an overlayNumber equal to layerNum?
int indexOfLayerToRemove = findLayerIndexByOverlayNum(overlayNumber);
if (indexOfLayerToRemove != -1) { // it exists
if (indexOfLayerToRemove == activeLayerIndex) {
// we're removing the active layer, so we'll need a new one.
// first, are there any other layers?
if (numLayers > 1) {
// if the active layer was the not the bottommost, set the active
// layer to the one currently beneath it, else the one above it.
if (activeLayerIndex > 0) {
activeLayerOverlayNumber--;
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
activeLayer = layers.get(activeLayerIndex);
} else {
activeLayerOverlayNumber++;
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
activeLayer = layers.get(activeLayerIndex);
}
layers.remove(indexOfLayerToRemove);
reorderLayers();
// what is the new overlay number and index of the active layer?
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
} else {
// we're removing the active and only layer.
layers.remove(indexOfLayerToRemove);
activeLayer = null;
activeLayerOverlayNumber = -1;
activeLayerIndex = -1;
}
} else {
// we're not removing the active layer. As a result,
// there must be at least one other layer.
layers.remove(indexOfLayerToRemove);
reorderLayers();
// what is the new overlay number and index of the active layer?
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
}
numLayers = layers.size();
}
if (numLayers == 0) {
currentExtent = null;
} else {
calculateFullExtent();
}
//currentExtent = calculateFullExtent();
//listOfExtents.add(currentExtent.clone());
}
} catch (Exception e) {
// do nothing.
}
}
private void reorderLayers() {
numLayers = layers.size();
if (numLayers == 0) { return; }
// find current highest value
int highestVal = 0;
int highestValIndex = 0;
for (int i = 0; i < numLayers; i++) {
int overlayNum = layers.get(i).getOverlayNumber();
if (overlayNum > highestVal) {
highestVal = overlayNum;
highestValIndex = i;
}
}
int currentLowest = -99;
int nextLowest;
int nextLowestIndex = 0;
int[] orderArray = new int[numLayers];
for (int i = 0; i < numLayers; i++) {
nextLowest = highestVal;
nextLowestIndex = highestValIndex;
for (int j = 0; j < numLayers; j++) {
int overlayNum = layers.get(j).getOverlayNumber();
if ((overlayNum > currentLowest) && (overlayNum < nextLowest)) {
nextLowest = overlayNum;
nextLowestIndex = j;
}
}
currentLowest = nextLowest;
orderArray[i] = nextLowestIndex;
}
for (int i = 0; i < numLayers; i++) {
layers.get(orderArray[i]).setOverlayNumber(i);
}
dirty = true;
}
public void promoteLayerToTop(int overlayNumber) {
if (overlayNumber == numLayers - 1) { // it's already topmost
return;
}
// which layer has an overlayNumber equal to overlayNumber?
int layerToMove = findLayerIndexByOverlayNum(overlayNumber);
layers.get(layerToMove).setOverlayNumber(numLayers);
reorderLayers();
// update the active layer overlay number and index.
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
dirty = true;
}
public void demoteLayerToBottom(int overlayNumber) {
if (overlayNumber == 0) { // it's already bottommost
return;
}
// which layer has an overlayNumber equal to overlayNumber?
int layerToMove = findLayerIndexByOverlayNum(overlayNumber);
layers.get(layerToMove).setOverlayNumber(-1);
reorderLayers();
// update the active layer overlay number and index.
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
dirty = true;
}
public void promoteLayer(int overlayNumber) {
if (overlayNumber == numLayers - 1) { // it's already topmost
return;
}
if (numLayers < 2) { // you need at least two layers to promote one
return;
}
int layerToPromote = findLayerIndexByOverlayNum(overlayNumber);
int layerToDemote = findLayerIndexByOverlayNum(overlayNumber + 1);
layers.get(layerToPromote).setOverlayNumber(overlayNumber + 1);
layers.get(layerToDemote).setOverlayNumber(overlayNumber);
// update the active layer overlay number and index.
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
dirty = true;
}
public void demoteLayer(int overlayNumber) {
if (overlayNumber == 0) {
return;
}
if (numLayers < 2) { // you need at least two layers to demote one
return;
}
int layerToDemote = findLayerIndexByOverlayNum(overlayNumber);
int layerToPromote = findLayerIndexByOverlayNum(overlayNumber - 1);
layers.get(layerToDemote).setOverlayNumber(overlayNumber - 1);
layers.get(layerToPromote).setOverlayNumber(overlayNumber);
// update the active layer overlay number and index.
activeLayerOverlayNumber = activeLayer.getOverlayNumber();
activeLayerIndex = findLayerIndexByOverlayNum(activeLayerOverlayNumber);
dirty = true;
}
public void toggleLayerVisibility(int overlayNumber) {
// which layer has an overlayNumber equal to overlayNumber?
int layerToToggle = findLayerIndexByOverlayNum(overlayNumber);
boolean value = layers.get(layerToToggle).isVisible();
if (value) {
layers.get(layerToToggle).setVisible(false);
} else {
layers.get(layerToToggle).setVisible(true);
}
}
public void toggleLayerVisibilityInLegend(int overlayNumber) {
// which layer has an overlayNumber equal to overlayNumber?
int layerToToggle = findLayerIndexByOverlayNum(overlayNumber);
boolean value = layers.get(layerToToggle).isVisibleInLegend();
if (value) {
layers.get(layerToToggle).setVisibleInLegend(false);
} else {
layers.get(layerToToggle).setVisibleInLegend(true);
}
}
public void reversePaletteOfLayer(int overlayNumber) {
// which layer has an overlayNumber equal to overlayNumber?
int layerToChange = findLayerIndexByOverlayNum(overlayNumber);
if (layers.get(layerToChange).getLayerType() == MapLayer.MapLayerType.RASTER) {
RasterLayerInfo rli = (RasterLayerInfo)layers.get(layerToChange);
boolean value = !rli.isPaletteReversed();
rli.setPaletteReversed(value);
}
}
public int findLayerIndexByOverlayNum(int overlayNumber) {
// which layer has an overlayNumber equal to layerNum?
int layerIndex = -1;
for (int i = 0; i < numLayers; i++) {
if (layers.get(i).getOverlayNumber() == overlayNumber) {
layerIndex = i;
break;
}
}
return layerIndex;
}
public MapLayer getLayer(int overlayNumber) {
try {
if (overlayNumber >= numLayers) { overlayNumber = numLayers - 1; }
int i = findLayerIndexByOverlayNum(overlayNumber);
return layers.get(i);
} catch (Exception e) {
return null;
}
}
public ArrayList<MapLayer> getLayersList() {
return layers;
}
@Override
public void resize(int x, int y, int resizeMode) {
int minSize = 50;
int deltaX = 0;
int deltaY = 0;
switch (resizeMode) {
case 0: // off the north edge
deltaY = y - upperLeftY;
if (height - deltaY >= minSize) {
upperLeftY = y;
height -= deltaY;
}
break;
case 1: // off the south edge
deltaY = y - (upperLeftY + height);
if (height + deltaY >= minSize) {
height += deltaY;
}
break;
case 2: // off the east edge
deltaX = x - (upperLeftX + width);
if (width + deltaX >= minSize) {
width += deltaX;
}
break;
case 3: // off the west edge
deltaX = x - upperLeftX;
if (width - deltaX >= minSize) {
upperLeftX = x;
width -= deltaX;
}
break;
case 4: // off the northeast edge
deltaY = y - upperLeftY;
if (height - deltaY >= minSize) {
upperLeftY = y;
height -= deltaY;
}
deltaX = x - (upperLeftX + width);
if (width + deltaX >= minSize) {
width += deltaX;
}
break;
case 5: // off the northwest edge
deltaY = y - upperLeftY;
if (height - deltaY >= minSize) {
upperLeftY = y;
height -= deltaY;
}
deltaX = x - upperLeftX;
if (width - deltaX >= minSize) {
upperLeftX = x;
width -= deltaX;
}
break;
case 6: // off the southeast edge
deltaY = y - (upperLeftY + height);
if (height + deltaY >= minSize) {
height += deltaY;
}
deltaX = x - (upperLeftX + width);
if (width + deltaX >= minSize) {
width += deltaX;
}
break;
case 7: // off the southwest edge
deltaY = y - (upperLeftY + height);
if (height + deltaY >= minSize) {
height += deltaY;
}
deltaX = x - upperLeftX;
if (width - deltaX >= minSize) {
upperLeftX = x;
width -= deltaX;
}
break;
}
}
@Override
public CartographicElementType getCartographicElementType() {
return CartographicElementType.MAP_AREA;
}
}