/*
* Copyright (C) 2011-2013 Dr. John Lindsay <jlindsay@uoguelph.ca>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package whiteboxgis;
import whitebox.cartographic.MapInfo;
import java.awt.Point;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.util.ArrayList;
import java.io.File;
import java.text.AttributedString;
import java.text.DecimalFormat;
import java.awt.font.TextAttribute;
import java.awt.font.LineBreakMeasurer;
import java.text.AttributedCharacterIterator;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.util.Collections;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JPopupMenu;
import java.awt.font.GlyphVector;
import javax.swing.SwingUtilities;
import whitebox.cartographic.MapArea;
import whitebox.cartographic.Neatline;
import whitebox.cartographic.*;
import whitebox.geospatialfiles.RasterLayerInfo;
import whitebox.geospatialfiles.VectorLayerInfo;
import whitebox.geospatialfiles.LasLayerInfo;
import whitebox.geospatialfiles.WhiteboxRasterBase;
import whitebox.geospatialfiles.shapefile.*;
import static whitebox.geospatialfiles.shapefile.ShapeType.MULTIPATCH;
import static whitebox.geospatialfiles.shapefile.ShapeType.MULTIPOINT;
import static whitebox.geospatialfiles.shapefile.ShapeType.MULTIPOINTM;
import static whitebox.geospatialfiles.shapefile.ShapeType.MULTIPOINTZ;
import static whitebox.geospatialfiles.shapefile.ShapeType.POINT;
import static whitebox.geospatialfiles.shapefile.ShapeType.POINTM;
import static whitebox.geospatialfiles.shapefile.ShapeType.POINTZ;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYGON;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYGONM;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYGONZ;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYLINE;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYLINEM;
import static whitebox.geospatialfiles.shapefile.ShapeType.POLYLINEZ;
import whitebox.interfaces.CartographicElement;
import whitebox.interfaces.MapLayer;
import whitebox.interfaces.WhiteboxPluginHost;
import whitebox.structures.BoundingBox;
import whitebox.structures.GridCell;
import whitebox.structures.XYPoint;
import whitebox.utilities.OSFinder;
import whiteboxgis.user_interfaces.ModifyPixel;
import whitebox.cartographic.MapScale.ScaleStyle;
/**
*
* @author johnlindsay
*/
public class MapRenderer2 extends JPanel implements Printable, MouseMotionListener,
MouseListener, MouseWheelListener {
public static final int MOUSE_MODE_ZOOM = 0;
public static final int MOUSE_MODE_PAN = 1;
public static final int MOUSE_MODE_GETINFO = 2;
public static final int MOUSE_MODE_SELECT = 3;
public static final int MOUSE_MODE_CARTO_ELEMENT = 4;
public static final int MOUSE_MODE_MAPAREA = 5;
public static final int MOUSE_MODE_RESIZE = 6;
public static final int MOUSE_MODE_DIGITIZE = 7;
public static final int MOUSE_MODE_ZOOMOUT = 8;
public static final int MOUSE_MODE_FEATURE_SELECT = 9;
private int myMode = 1;
public static final int RESIZE_MODE_N = 0;
public static final int RESIZE_MODE_S = 1;
public static final int RESIZE_MODE_E = 2;
public static final int RESIZE_MODE_W = 3;
public static final int RESIZE_MODE_NE = 4;
public static final int RESIZE_MODE_NW = 5;
public static final int RESIZE_MODE_SE = 6;
public static final int RESIZE_MODE_SW = 7;
private int myResizeMode = -1;
//private int mapElementX, mapElementY;
public MapInfo map = null;
private StatusBar status = null;
private JTextField scaleText = null;
private WhiteboxPluginHost host = null;
private Cursor zoomCursor = null;
private Cursor zoomOutCursor = null;
private Cursor panCursor = null;
private Cursor panClosedHandCursor = null;
private Cursor selectCursor = null;
private Cursor selectFeatureCursor = null;
private Cursor digitizeCursor = null;
private String graphicsDirectory;
private boolean modifyingPixels = false;
private double modifyPixelsX = -1;
private double modifyPixelsY = -1;
private boolean usingDistanceTool = false;
private int whichCartoElement = -1;
public static final int CARTO_ELEMENT_SCALE = 0;
public static final int CARTO_ELEMENT_NORTH_ARROW = 1;
public static final int CARTO_ELEMENT_LEGEND = 2;
public static final int CARTO_ELEMENT_TITLE = 3;
private boolean printingMap = false;
private BoundingBox mapExtent = new BoundingBox();
private Color selectedFeatureColour = Color.CYAN;
private Color selectionBoxColour = Color.GRAY;
private double ppm = java.awt.Toolkit.getDefaultToolkit().getScreenResolution() * 39.3701;
public MapRenderer2() {
init();
}
private void init() {
try {
String applicationDirectory = java.net.URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getPath(), "UTF-8");
if (applicationDirectory.endsWith(".exe") || applicationDirectory.endsWith(".jar")) {
applicationDirectory = new File(applicationDirectory).getParent();
} else {
// Add the path to the class files
applicationDirectory += getClass().getName().replace('.', File.separatorChar);
// Step one level up as we are only interested in the
// directory containing the class files
applicationDirectory = new File(applicationDirectory).getParent();
}
graphicsDirectory = applicationDirectory + File.separator
+ "resources" + File.separator + "Images" + File.separator;
Toolkit toolkit = Toolkit.getDefaultToolkit();
Point cursorHotSpot = new Point(0, 0);
if (!OSFinder.isWindows()) {
zoomCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "ZoomCursor.png"), new Point(8, 8), "zoomCursor");
zoomOutCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "ZoomOutCursor.png"), new Point(8, 8), "zoomCursor");
panCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "Pan3.png"), cursorHotSpot, "panCursor");
panClosedHandCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "Pan4.png"), cursorHotSpot, "panCursor");
selectCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "select.png"), cursorHotSpot, "selectCursor");
selectFeatureCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "SelectFeature.png"), cursorHotSpot, "selectFeatureCursor");
digitizeCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "DigitizeCursor2.png"), new Point(11, 11), "digitizeCursor");
} else {
// windows requires 32 x 32 cursors. Otherwise they look terrible.
zoomCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "ZoomCursorWin.png"), new Point(16, 16), "zoomCursor");
zoomOutCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "ZoomOutCursorWin.png"), new Point(16, 16), "zoomCursor");
panCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "Pan3Win.png"), cursorHotSpot, "panCursor");
panClosedHandCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "Pan4Win.png"), cursorHotSpot, "panCursor");
selectCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "selectWin.png"), cursorHotSpot, "selectCursor");
selectFeatureCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "SelectFeatureWin.png"), cursorHotSpot, "selectFeatureCursor");
digitizeCursor = toolkit.createCustomCursor(toolkit.getImage(graphicsDirectory + "DigitizeCursorWin.png"), new Point(16, 16), "digitizeCursor");
}
this.setCursor(panCursor);
panning = true;
this.addMouseMotionListener(this);
this.addMouseListener(this);
this.addMouseWheelListener(this);
this.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
boolean isActivelyEditedVector = false;
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea.getActiveLayer().getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo) mapArea.getActiveLayer();
if (vli.isActivelyEdited()) {
isActivelyEditedVector = true;
}
}
}
if (isActivelyEditedVector) {
host.deleteFeature();
} else {
removeSelectedMapElements();
host.refreshMap(true);
}
} else if (e.getKeyCode() == KeyEvent.VK_DOWN
|| e.getKeyCode() == KeyEvent.VK_KP_DOWN) {
map.getActiveMapArea().panDown();
host.refreshMap(true);
} else if (e.getKeyCode() == KeyEvent.VK_UP
|| e.getKeyCode() == KeyEvent.VK_KP_UP) {
map.getActiveMapArea().panUp();
host.refreshMap(true);
} else if (e.getKeyCode() == KeyEvent.VK_LEFT
|| e.getKeyCode() == KeyEvent.VK_KP_LEFT) {
map.getActiveMapArea().panLeft();
host.refreshMap(true);
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT
|| e.getKeyCode() == KeyEvent.VK_KP_RIGHT) {
map.getActiveMapArea().panRight();
host.refreshMap(true);
} else if (e.getKeyCode() == KeyEvent.VK_PLUS
|| e.getKeyCode() == KeyEvent.VK_EQUALS) {
map.getActiveMapArea().zoomIn();
host.refreshMap(true);
} else if (e.getKeyCode() == KeyEvent.VK_MINUS
|| e.getKeyCode() == KeyEvent.VK_UNDERSCORE) {
map.getActiveMapArea().zoomOut();
host.refreshMap(true);
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
});
} catch (Exception e) {
System.err.println(e);
}
}
public void setHost(WhiteboxPluginHost host) {
this.host = host;
}
public MapInfo getMapInfo() {
return map;
}
public void setMapInfo(MapInfo mapinfo) {
this.map = mapinfo;
}
public int getMouseMode() {
return backgroundMouseMode; //myMode;
}
private int backgroundMouseMode = MOUSE_MODE_SELECT;
public void setMouseMode(int mouseMode) {
myMode = mouseMode;
backgroundMouseMode = mouseMode;
switch (myMode) {
case MOUSE_MODE_ZOOM:
this.setCursor(zoomCursor);
break;
case MOUSE_MODE_ZOOMOUT:
this.setCursor(zoomOutCursor);
break;
case MOUSE_MODE_PAN:
this.setCursor(panCursor);
break;
case MOUSE_MODE_SELECT:
this.setCursor(selectCursor);
break;
case MOUSE_MODE_FEATURE_SELECT:
this.setCursor(selectFeatureCursor);
break;
}
}
boolean digitizing = false;
public void setUsingDistanceTool(boolean value) {
usingDistanceTool = value;
if (!usingDistanceTool) {
distPoints.clear();
if (!modifyingPixels) {
digitizing = false;
}
} else {
digitizing = true;
}
}
boolean digitizingNewFeature = false;
public void setDigitizingNewFeature(boolean value) {
digitizingNewFeature = value;
if (!digitizingNewFeature) {
if (!modifyingPixels && !usingDistanceTool) {
digitizing = false;
distPoints.clear();
}
} else {
digitizing = true;
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (map.getActiveMapAreaElementNumber() != mapArea.getElementNumber()) {
return;
}
if (mapArea.getActiveLayer().getLayerType() != MapLayer.MapLayerType.VECTOR) {
return;
}
// VectorLayerInfo vli = (VectorLayerInfo) mapArea.getActiveLayer();
// vli.openNewFeature();
}
}
}
public boolean isUsingDistanceTool() {
return usingDistanceTool;
}
public void setModifyingPixels(boolean val) {
modifyingPixels = val;
if (val) {
digitizing = true;
} else {
if (!usingDistanceTool) {
digitizing = false;
}
}
}
public boolean isModifyingPixels() {
return modifyingPixels;
}
public void setStatusBar(StatusBar status) {
this.status = status;
}
public void setScaleText(JTextField scaleText) {
this.scaleText = scaleText;
}
public void removeSelectedMapElements() {
try {
// remove any selected map elements
ArrayList<Integer> listOfSelectedElements = new ArrayList<>();
for (CartographicElement ce : map.getCartographicElementList()) {
if (ce.isSelected()) {
listOfSelectedElements.add(ce.getElementNumber());
}
}
Collections.sort(listOfSelectedElements);
for (int i = listOfSelectedElements.size() - 1; i >= 0; i--) {
map.removeCartographicElement(listOfSelectedElements.get(i));
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
@Override
public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
// host.showFeedback("Map printing has been temporarily disabled.");
// return -1;
try {
if (page > 0) {
return NO_SUCH_PAGE;
}
// int i = pf.getOrientation();
// get the size of the page
double pageWidth = pf.getImageableWidth();
double pageHeight = pf.getImageableHeight();
w = (int) (printResolution * pageWidth / 72);
h = (int) (printResolution * pageHeight / 72);
// double myWidth = this.getWidth();// - borderWidth * 2;
// double myHeight = this.getHeight();// - borderWidth * 2;
// double scaleX = pageWidth / w; //myWidth;
// double scaleY = pageHeight / h; //myHeight;
double minScale = 72d / printResolution; //Math.min(scaleX, scaleY);
// w = (int)
printingMap = true;
map.deslectAllCartographicElements();
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
g2d.scale(minScale, minScale);
drawMap(g);
printingMap = false;
return PAGE_EXISTS;
} catch (Exception e) {
throw new PrinterException("Something went wrong during printing.");
}
}
private int printResolution = 600;
public int getPrintResolution() {
return printResolution;
}
public void setPrintResolution(int resolution) {
this.printResolution = resolution;
}
public boolean saveToImage(String fileName) {
try {
// get the page size information
PageFormat pageFormat = map.getPageFormat();
double pageWidthInInches = pageFormat.getWidth() / 72;
double pageHeightInInches = pageFormat.getHeight() / 72;
w = (int) (printResolution * pageWidthInInches);
h = (int) (printResolution * pageHeightInInches);
// TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed
// into integer pixels
BufferedImage bi = new BufferedImage((int) w, (int) h, BufferedImage.TYPE_INT_ARGB);
Graphics ig = bi.createGraphics();
printingMap = true;
map.deslectAllCartographicElements();
drawMap(ig);
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();
if (!ImageIO.write(bi, extension, new File(fileName))) {
return false;
}
printingMap = false;
return true;
} catch (Exception e) {
return false;
}
}
@Override
public void paint(Graphics g) {
w = this.getWidth();
h = this.getHeight();
drawMap(g);
}
private double scale = 0;
private double pageTop = 0;
private double pageLeft = 0;
private double w = 0;
private double h = 0;
private int margin;
private void drawMap(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
try {
AffineTransform old = g2.getTransform();
// get the drawing area's width and height
Stroke oldStroke;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHints(rh);
rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(rh);
if (printingMap || !map.isPageVisible()) {
g2.setColor(Color.WHITE);
} else {
g2.setColor(new Color(160, 160, 160));
}
g2.fillRect(0, 0, (int) w, (int) h);
if (map != null && map.getNumberOfCartographicElements() > 0) {
// Font font = new Font("SanSerif", Font.PLAIN, 11);
int x, y;
// get the page size information
double pageWidth = map.getPageFormat().getWidth();
double pageHeight = map.getPageFormat().getHeight();
// set the page scale
BoundingBox pageExtent = map.getPageExtent();
int pageShadowSize;
if (!printingMap) {
pageShadowSize = 6;
if (pageExtent.getMaxY() == Float.NEGATIVE_INFINITY) {
// it hasn't yet been initialized
pageExtent.setMinX(-pageShadowSize);
pageExtent.setMinY(-pageShadowSize);
pageExtent.setMaxX(pageWidth + 1.25 * pageShadowSize);
pageExtent.setMaxY(pageHeight + 1.25 * pageShadowSize);
map.setPageExtent(pageExtent);
}
} else {
pageShadowSize = 0;
if (pageExtent.getMaxY() == Float.NEGATIVE_INFINITY) {
// it hasn't yet been initialized
pageExtent.setMinX(0);
pageExtent.setMinY(0);
pageExtent.setMaxX(pageWidth - 1);
pageExtent.setMaxY(pageHeight - 1);
map.setPageExtent(pageExtent);
}
}
scale = Math.min((w / pageExtent.getWidth()),
(h / pageExtent.getHeight()));
// what are the margins of the page on the drawing area?
//double pageWidthOnScreen = pageWidth * scale;
//double pageHeightOnScreen = pageHeight * scale;
pageTop = (h - pageExtent.getHeight() * scale) / 2.0 - pageExtent.getMinY() * scale; //(h - pageHeightOnScreen) / 2.0;
pageLeft = (w - pageExtent.getWidth() * scale) / 2.0 - pageExtent.getMinX() * scale; //(w - pageWidthOnScreen) / 2.0;
//double pageBottom = pageTop + pageHeightOnScreen;
//double pageRight = pageLeft + pageWidthOnScreen;
margin = (int) (map.getMargin() * 72);
g2.translate(pageLeft, pageTop);
g2.scale(scale, scale);
float miter = (float) (2.0 / scale);
miter = (miter < 1) ? 1 : miter;
float constantLineWidth = (float) (1 / scale);
if (constantLineWidth == 0) {
constantLineWidth = 0.5f;
}
float dash1[] = {constantLineWidth * 4};
BasicStroke dashed
= new BasicStroke(constantLineWidth,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
miter, dash1, 0.0f);
BasicStroke dashed2
= new BasicStroke(constantLineWidth,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
miter, dash1, constantLineWidth * 4);
// BoundingBox currentExtent; // = map.getCurrentExtent();
// double xRange; //= Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
// double yRange; //= Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
// draw the page on the drawing area if it is visible
if (map.isPageVisible() && !printingMap) {
g2.setColor(new Color(100, 100, 100)); //Color.GRAY);
g2.fillRect((int) (pageShadowSize),
(int) (pageShadowSize), (int) pageWidth,
(int) pageHeight);
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, (int) pageWidth,
(int) pageHeight);
g2.setColor(Color.DARK_GRAY);
g2.drawRect(0, 0, (int) pageWidth,
(int) pageHeight);
if (margin > 0) {
// draw page margin marks
g2.setColor(Color.LIGHT_GRAY);
int tickSize = 7; // in points
g2.drawLine(margin, margin, margin, margin - tickSize);
g2.drawLine(margin, margin, margin - tickSize, margin);
g2.drawLine((int) (pageWidth - margin), margin, (int) (pageWidth - margin), margin - tickSize);
g2.drawLine((int) (pageWidth - margin), margin, (int) (pageWidth - margin + tickSize), margin);
g2.drawLine(margin, (int) (pageHeight - margin), margin, (int) (pageHeight - margin + tickSize));
g2.drawLine(margin, (int) (pageHeight - margin), margin - tickSize, (int) (pageHeight - margin));
g2.drawLine((int) (pageWidth - margin), (int) (pageHeight - margin), (int) (pageWidth - margin), (int) (pageHeight - margin + tickSize));
g2.drawLine((int) (pageWidth - margin), (int) (pageHeight - margin), (int) (pageWidth - margin + tickSize), (int) (pageHeight - margin));
}
}
//***************************
// Draw cartographic elements
//***************************
// Color selectedColour = Color.BLACK;
// double ppm = java.awt.Toolkit.getDefaultToolkit().getScreenResolution() * 39.3701;
for (CartographicElement ce : map.getCartographicElementList()) {
if (ce instanceof MapScale) {
drawMapScale(g2, (MapScale) ce, dashed);
} else if (ce instanceof NorthArrow) {
drawNorthArrow(g2, (NorthArrow) ce, dashed);
} else if (ce instanceof MapTitle) {
drawMapTitle(g2, (MapTitle) ce, dashed);
} else if (ce instanceof MapTextArea) {
drawMapTextArea(g2, (MapTextArea) ce, dashed);
} else if (ce instanceof Neatline) {
drawNeatline(g2, (Neatline) ce, dashed);
} else if (ce instanceof Legend) {
drawLegend(g2, (Legend) ce, dashed);
} else if (ce instanceof MapArea) {
drawMapArea(g2, (MapArea) ce, dashed);
} else if (ce instanceof MapImage) {
drawMapImage(g2, (MapImage) ce, dashed);
} else if (ce instanceof CartographicElementGroup) {
drawCartographicElementGroup(g2,
(CartographicElementGroup) ce, dashed);
}
}
if (mouseDragged && (myMode == MOUSE_MODE_ZOOM
|| backgroundMouseMode == MOUSE_MODE_ZOOM
|| myMode == MOUSE_MODE_SELECT
|| backgroundMouseMode == MOUSE_MODE_SELECT
|| backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT)
&& !(myMode == MOUSE_MODE_RESIZE)) {
boolean drawLine = true;
if (myMode == MOUSE_MODE_CARTO_ELEMENT || myMode == MOUSE_MODE_MAPAREA) {
CartographicElement ce = map.getCartographicElement(whichCartoElement);
if (ce.isSelected()) {
drawLine = false;
}
}
if (drawLine) {
oldStroke = g2.getStroke();
g2.setStroke(dashed);
g2.setColor(Color.black);
int boxWidth = (int) (Math.abs(startCol - endCol));
int boxHeight = (int) (Math.abs(startRow - endRow));
x = Math.min(startCol, endCol);
y = Math.min(startRow, endRow);
g2.drawRect(x, y, boxWidth, boxHeight);
g2.setColor(Color.white);
g2.setStroke(dashed2);
g2.drawRect(x, y, boxWidth, boxHeight);
g2.setStroke(oldStroke);
}
}
g2.setTransform(old);
}
} catch (Exception e) {
host.logException("Error in MapRenderer", e);
host.showFeedback(e.getMessage());
} finally {
g.dispose();
g2.dispose();
}
}
private void drawCartographicElementGroup(Graphics2D g2, CartographicElementGroup group,
BasicStroke dashed) {
for (CartographicElement ce : group.getElementList()) {
if (ce instanceof MapScale) {
drawMapScale(g2, (MapScale) ce, dashed);
} else if (ce instanceof NorthArrow) {
drawNorthArrow(g2, (NorthArrow) ce, dashed);
} else if (ce instanceof MapTitle) {
drawMapTitle(g2, (MapTitle) ce, dashed);
} else if (ce instanceof MapTextArea) {
drawMapTextArea(g2, (MapTextArea) ce, dashed);
} else if (ce instanceof Neatline) {
drawNeatline(g2, (Neatline) ce, dashed);
} else if (ce instanceof Legend) {
drawLegend(g2, (Legend) ce, dashed);
} else if (ce instanceof MapArea) {
drawMapArea(g2, (MapArea) ce, dashed);
} else if (ce instanceof MapImage) {
drawMapImage(g2, (MapImage) ce, dashed);
} else if (ce instanceof CartographicElementGroup) {
drawCartographicElementGroup(g2,
(CartographicElementGroup) ce, dashed);
}
}
if (group.isSelected()) {
Color selectedColour = Color.BLACK;
PageFormat pageFormat = map.getPageFormat();
Stroke oldStroke;
oldStroke = g2.getStroke();
if (group.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
}
g2.drawRect(group.getUpperLeftX(),
group.getUpperLeftY(),
group.getWidth(),
group.getHeight());
g2.setStroke(oldStroke);
}
}
private void drawMapScale(Graphics2D g2, MapScale mapScale, BasicStroke dashed) {
if (mapScale.isVisible()) {
ScaleStyle styleType = mapScale.getScaleStyle();
if (mapScale.getMapArea() != null) {
mapScale.setScale();
}
if (map.getActiveMapArea().getXYUnits().toLowerCase().contains("deg")
&& !mapScale.getUnits().toLowerCase().contains("deg")) {
mapScale.setUnits("degrees");
}
Color selectedColour = Color.BLACK;
PageFormat pageFormat = map.getPageFormat();
double pageHeight = pageFormat.getHeight();
Stroke oldStroke;
FontMetrics metrics;
// set up the font
Font newfont = mapScale.getLabelFont();
g2.setFont(newfont);
metrics = g2.getFontMetrics(newfont);
String label;
float x, y;
int adv;
GeneralPath polyline;
// polyline.moveTo(xPoints[0], yPoints[0]);
//
// for (int index = 1; index < xPoints.length; index++) {
// polyline.lineTo(xPoints[index], yPoints[index]);
// }
// g2.draw(polyline);
double scale = mapScale.getScale();
if (scale > 0 && scale != Double.NaN && scale < Double.POSITIVE_INFINITY) {
if (mapScale.getUpperLeftY() == -32768) {
mapScale.setUpperLeftY((int) (pageHeight - margin - mapScale.getHeight()));
mapScale.setUpperLeftX((int) (margin));
}
// set the stroke
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(mapScale.getLineWidth()));
// draw the scale's box
if (mapScale.isBackgroundVisible()) {
g2.setColor(mapScale.getBackColour());
g2.fillRect(mapScale.getUpperLeftX(),
mapScale.getUpperLeftY(),
mapScale.getWidth(),
mapScale.getHeight());
}
g2.setColor(mapScale.getLegendColour());
if (mapScale.isBorderVisible() || mapScale.isSelected()) {
Stroke oldStroke2 = g2.getStroke();
if (mapScale.isSelected() && !printingMap) {
g2.setStroke(dashed);
g2.setColor(selectedColour);
} else {
g2.setColor(mapScale.getBorderColour());
}
g2.drawRect(mapScale.getUpperLeftX(),
mapScale.getUpperLeftY(),
mapScale.getWidth(),
mapScale.getHeight());
g2.setStroke(oldStroke2);
}
g2.setColor(mapScale.getOutlineColour());
// what is the content height?
float contentHeight = 0;
int spacingBetweenElements = 4;
float barHeight = 6f;
int spacingBetweenBarAndLabels = 3;
int fontHeight = metrics.getHeight() - metrics.getDescent();
if (mapScale.isRepresentativeFractionVisible()) {
contentHeight = fontHeight * 3
+ spacingBetweenElements * 2 + barHeight
+ spacingBetweenBarAndLabels;
} else {
contentHeight = fontHeight * 2
+ spacingBetweenElements + barHeight
+ spacingBetweenBarAndLabels;
}
// make sure that the scale box's height is large enough for the content
if (contentHeight > (mapScale.getHeight() + 2 * mapScale.getMargin())) {
mapScale.setHeight((int) (contentHeight + 2 * mapScale.getMargin()));
}
// calculate the bottom for all the content
int contentBottomY = (int) (mapScale.getUpperLeftY()
+ (mapScale.getHeight() - contentHeight) / 2.0
+ contentHeight);
if (mapScale.isGraphicalScaleVisible() && styleType != ScaleStyle.COMPACT) {
// draw the units label to the scale
label = mapScale.getUnits();
if (label.toLowerCase().contains("deg")) {
label = "km";
}
adv = metrics.stringWidth(label);
x = mapScale.getUpperLeftX() + ((mapScale.getWidth() - adv) / 2);
y = contentBottomY;
g2.drawString(label, x, y);
}
// draw the scale bar to the scale
double barLengthInMapUnits = mapScale.getBarLength() * mapScale.getConversionToMetres()
/ scale * ppm / mapScale.getNumberDivisions();
double barStartingX = mapScale.getUpperLeftX() + ((mapScale.getWidth() - (mapScale.getBarLength() * mapScale.getConversionToMetres()
/ scale * ppm)) / 2);
if (mapScale.isGraphicalScaleVisible()) {
g2.setStroke(new BasicStroke(0.5f));
float halfBarHeight = barHeight / 2.0f;
y = contentBottomY - fontHeight - spacingBetweenElements - barHeight;
switch (styleType) {
case STANDARD:
for (int k = 0; k < mapScale.getNumberDivisions(); k++) {
x = (float) (k * barLengthInMapUnits + barStartingX);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(x, y);
polyline.lineTo(x + barLengthInMapUnits, y);
polyline.lineTo(x + barLengthInMapUnits, y + barHeight);
polyline.lineTo(x, y + barHeight);
polyline.lineTo(x, y);
g2.draw(polyline);
if (k % 2.0 != 0.0) {
g2.fill(polyline);
}
}
break;
case SIMPLE:
for (int k = 0; k < mapScale.getNumberDivisions(); k++) {
x = (float) (k * barLengthInMapUnits + barStartingX);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(x, y);
polyline.lineTo(x, y + barHeight);
polyline.lineTo(x + barLengthInMapUnits, y + barHeight);
polyline.lineTo(x + barLengthInMapUnits, y);
g2.draw(polyline);
}
break;
case COMPLEX:
GeneralPath polyline2;
for (int k = 0; k < mapScale.getNumberDivisions(); k++) {
x = (float) (k * barLengthInMapUnits + barStartingX);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(x, y);
polyline.lineTo(x + barLengthInMapUnits, y);
polyline.lineTo(x + barLengthInMapUnits, y + halfBarHeight);
polyline.lineTo(x, y + halfBarHeight);
polyline.lineTo(x, y);
g2.draw(polyline);
polyline2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline2.moveTo(x, y + halfBarHeight);
polyline2.lineTo(x + barLengthInMapUnits, y + halfBarHeight);
polyline2.lineTo(x + barLengthInMapUnits, y + barHeight);
polyline2.lineTo(x, y + barHeight);
polyline2.lineTo(x, y + halfBarHeight);
g2.draw(polyline2);
if (k % 2.0 != 0.0) {
g2.fill(polyline);
} else {
g2.fill(polyline2);
}
}
break;
case COMPACT:
for (int k = 0; k < mapScale.getNumberDivisions(); k++) {
x = (float) (k * barLengthInMapUnits + barStartingX);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(x, y);
polyline.lineTo(x, y + barHeight);
polyline.lineTo(x + barLengthInMapUnits, y + barHeight);
polyline.lineTo(x + barLengthInMapUnits, y);
g2.draw(polyline);
}
break;
}
}
if (mapScale.isGraphicalScaleVisible()) {
// label the scale bar
adv = metrics.stringWidth(mapScale.getLowerLabel());
x = (int) (barStartingX - adv / 2.0);
y = contentBottomY - fontHeight - spacingBetweenElements
- barHeight - spacingBetweenBarAndLabels;
g2.drawString(mapScale.getLowerLabel(), x, y);
adv = metrics.stringWidth(mapScale.getUpperLabel());
x = (int) (barStartingX + barLengthInMapUnits * mapScale.getNumberDivisions() - adv / 2.0);
if (styleType != ScaleStyle.COMPACT) {
g2.drawString(mapScale.getUpperLabel(), x, y);
} else {
label = mapScale.getUnits();
if (label.toLowerCase().contains("deg")) {
label = "km";
}
g2.drawString(mapScale.getUpperLabel() + " " + label, x, y);
}
}
// label the representative fraction
if (mapScale.isRepresentativeFractionVisible()) {
label = mapScale.getRepresentativeFraction();
adv = metrics.stringWidth(label);
x = mapScale.getUpperLeftX() + ((mapScale.getWidth() - adv) / 2);
y = contentBottomY - fontHeight - spacingBetweenElements
- barHeight - spacingBetweenBarAndLabels - fontHeight
- spacingBetweenElements;
g2.drawString(label, x, y);
}
g2.setStroke(oldStroke);
// g2.setFont(font);
}
}
}
private void drawNorthArrow(Graphics2D g2, NorthArrow northArrow, BasicStroke dashed) {
if (northArrow.isVisible()) {
Color selectedColour = Color.BLACK;
PageFormat pageFormat = map.getPageFormat();
double pageWidth = pageFormat.getWidth();
double pageHeight = pageFormat.getHeight();
Stroke oldStroke;
if (northArrow.getX() == -32768) {
northArrow.setX((int) (pageWidth - margin - northArrow.getMarkerSize() / 2));
northArrow.setY((int) (pageHeight - margin - northArrow.getMarkerSize() / 2));
}
if (northArrow.isBackgroundVisible()) {
g2.setColor(northArrow.getBackColour());
g2.fillRect(northArrow.getUpperLeftX(),
northArrow.getUpperLeftY(),
northArrow.getWidth(),
northArrow.getHeight());
}
if (northArrow.isBorderVisible() || northArrow.isSelected()) {
oldStroke = g2.getStroke();
if (northArrow.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(northArrow.getBorderColour());
g2.setStroke(new BasicStroke(northArrow.getLineWidth()));
}
g2.drawRect(northArrow.getUpperLeftX(),
northArrow.getUpperLeftY(),
northArrow.getWidth(),
northArrow.getHeight());
g2.setStroke(oldStroke);
}
g2.setColor(northArrow.getOutlineColour());
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(northArrow.getLineWidth()));
ArrayList<GeneralPath> gpList = northArrow.getMarkerData();
ArrayList<Integer> gpInstructions = northArrow.getMarkerDrawingInstructions();
for (int a = 0; a < gpList.size(); a++) {
GeneralPath gp = gpList.get(a);
Integer instruction = gpInstructions.get(a);
if (instruction.equals(0)) {
g2.draw(gp);
} else {
g2.fill(gp);
g2.draw(gp);
}
}
g2.setStroke(oldStroke);
}
}
private void drawMapTitle(Graphics2D g2, MapTitle mapTitle, BasicStroke dashed) {
if (mapTitle.isVisible()) {
Color selectedColour = Color.BLACK;
FontMetrics metrics;
PageFormat pageFormat = map.getPageFormat();
double pageWidth = pageFormat.getWidth();
int x, y;
if (mapTitle.getWidth() < 0) {
Font newFont = mapTitle.getLabelFont();
g2.setFont(newFont);
metrics = g2.getFontMetrics(newFont);
int adv = metrics.stringWidth(mapTitle.getLabel());
mapTitle.setWidth(adv + 2 * mapTitle.getMargin());
mapTitle.setHeight(metrics.getHeight() + 2 * mapTitle.getMargin());
if (mapTitle.getUpperLeftX() == -32768) {
mapTitle.setUpperLeftX((int) ((pageWidth - mapTitle.getWidth()) / 2.0));
mapTitle.setUpperLeftY(margin);
}
}
if (mapTitle.isBackgroundVisible()) {
g2.setColor(mapTitle.getBackColour());
g2.fillRect(mapTitle.getUpperLeftX(),
mapTitle.getUpperLeftY(),
mapTitle.getWidth(),
mapTitle.getHeight());
}
if (mapTitle.isBorderVisible() || mapTitle.isSelected()) {
Stroke oldStroke = g2.getStroke();
if (mapTitle.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(mapTitle.getBorderColour());
g2.setStroke(new BasicStroke(mapTitle.getLineWidth()));
}
g2.drawRect(mapTitle.getUpperLeftX(),
mapTitle.getUpperLeftY(),
mapTitle.getWidth(),
mapTitle.getHeight());
g2.setStroke(oldStroke);
// g2.setFont(font);
}
Font newFont = mapTitle.getLabelFont();
g2.setColor(mapTitle.getFontColour());
Font oldFont = g2.getFont();
g2.setFont(newFont);
metrics = g2.getFontMetrics(newFont);
int fontHeight = metrics.getHeight() - metrics.getDescent();
x = mapTitle.getUpperLeftX() + mapTitle.getMargin();
y = (int) (mapTitle.getUpperLeftY() + mapTitle.getMargin() + fontHeight);
GlyphVector gv = newFont.createGlyphVector(g2.getFontRenderContext(), mapTitle.getLabel());
Shape sp = gv.getOutline();
g2.translate(x, y);
if (mapTitle.getRotation() == 0) {
g2.fill(sp);
} else {
// double xr = viewAreaLRX + ht;
// double yr = viewAreaLRY - 4;
// g2.translate(xr, yr);
g2.rotate(Math.toRadians(mapTitle.getRotation()), 0, 0);
g2.fill(sp);
g2.rotate(Math.toRadians(-mapTitle.getRotation()));
// g2.translate(-xr, -yr);
}
g2.translate(-x, -y);
if (mapTitle.isOutlineVisible()) {
g2.setColor(mapTitle.getOutlineColour());
g2.translate(x, y);
if (mapTitle.getRotation() == 0) {
g2.draw(sp);
} else {
g2.rotate(Math.toRadians(mapTitle.getRotation()), 0, 0);
g2.draw(sp);
g2.rotate(Math.toRadians(-mapTitle.getRotation()));
}
g2.translate(-x, -y);
}
g2.setFont(oldFont);
}
}
private void drawMapTextArea(Graphics2D g2, MapTextArea mapTextArea, BasicStroke dashed) {
if (mapTextArea.isVisible()) {
Color selectedColour = Color.BLACK;
int x1, y1, x2, y2;
int labelMargin = mapTextArea.getMargin();
float interlineSpace = mapTextArea.getInterlineSpace();
x1 = mapTextArea.getUpperLeftX() + labelMargin;
y1 = mapTextArea.getUpperLeftY() + labelMargin;
x2 = mapTextArea.getLowerRightX() - labelMargin;
y2 = mapTextArea.getLowerRightY() - labelMargin;
// double midX = (x2 - x1) / 2.0;
// double midY = (y2 - y1) / 2.0;
double rotation = Math.toRadians(mapTextArea.getRotation());
// g2.translate(midX, midY);
// g2.rotate(rotation, 0, 0);
if (mapTextArea.isBackgroundVisible()) {
g2.setColor(mapTextArea.getBackColour());
g2.fillRect(mapTextArea.getUpperLeftX(),
mapTextArea.getUpperLeftY(),
mapTextArea.getWidth(),
mapTextArea.getHeight());
}
if (mapTextArea.isBorderVisible() || mapTextArea.isSelected()) {
Stroke oldStroke = g2.getStroke();
if (mapTextArea.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(mapTextArea.getBorderColour());
g2.setStroke(new BasicStroke(mapTextArea.getLineWidth()));
}
g2.translate(mapTextArea.getUpperLeftX(), mapTextArea.getUpperLeftY());
g2.rotate(rotation);
g2.drawRect(0, 0,
mapTextArea.getWidth(),
mapTextArea.getHeight());
// g2.drawRect(mapTextArea.getUpperLeftX(),
// mapTextArea.getUpperLeftY(),
// mapTextArea.getWidth(),
// mapTextArea.getHeight());
g2.setStroke(oldStroke);
g2.rotate(-rotation);
g2.translate(-mapTextArea.getUpperLeftX(), -mapTextArea.getUpperLeftY());
}
Font newFont = mapTextArea.getLabelFont();
g2.setColor(mapTextArea.getFontColour());
Font oldFont = g2.getFont();
g2.setFont(newFont);
drawStringRect(g2, x1, y1, x2, y2, interlineSpace,
mapTextArea.getLabel(), rotation);
//g2.drawString(mapTextArea.getLabel(), 0, 0);
g2.setFont(oldFont);
g2.setFont(oldFont);
// xr = viewAreaULX - offset;
// yr = viewAreaLRY - 4;
// g2.drawString(label, 0, 0);
// g2.rotate(-rotation);
// g2.translate(-midX, -midY);
}
}
private void drawStringRect(Graphics2D graphics, int x1, int y1, int x2,
int y2, float interline, String txt, double rotation) {
if (txt.isEmpty()) {
return;
}
FontMetrics metrics = graphics.getFontMetrics(graphics.getFont());
int hgt = metrics.getAscent();
String[] stringArray = txt.split("\n");
for (String str : stringArray) {
if (str.isEmpty()) {
y1 += hgt;
} else {
AttributedString as = new AttributedString(str);
as.addAttribute(TextAttribute.FOREGROUND, graphics.getPaint());
as.addAttribute(TextAttribute.FONT, graphics.getFont());
AttributedCharacterIterator aci = as.getIterator();
FontRenderContext frc = new FontRenderContext(null, true, false);
LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
float width = x2 - x1;
TextLayout tl;
while (lbm.getPosition() < str.length()) {
tl = lbm.nextLayout(width);
y1 += tl.getAscent();
graphics.translate(x1, y1);
graphics.rotate(rotation, 0, 0);
tl.draw(graphics, 0, 0); //x1, y1);
graphics.rotate(-rotation, 0, 0);
graphics.translate(-x1, -y1);
y1 += tl.getDescent() + tl.getLeading() + (interline - 1.0f) * tl.getAscent();
if (y1 > y2) {
break;
}
}
}
}
}
private void drawNeatline(Graphics2D g2, Neatline neatLine, BasicStroke dashed) {
if (neatLine.isVisible()) {
Color selectedColour = Color.BLACK;
// get the page size information
PageFormat pageFormat = map.getPageFormat();
double pageWidth = pageFormat.getWidth();
double pageHeight = pageFormat.getHeight();
if (neatLine.getUpperLeftY() == -32768) {
neatLine.setWidth((int) (pageWidth - 2 * margin));
neatLine.setHeight((int) (pageHeight - 2 * margin));
neatLine.setUpperLeftX(margin);
neatLine.setUpperLeftY(margin);
}
int neatLineULX = neatLine.getUpperLeftX();
int neatLineULY = neatLine.getUpperLeftY();
int neatLineLRX = neatLine.getLowerRightX();
int neatLineLRY = neatLine.getLowerRightY();
int neatLineWidth = neatLineLRX - neatLineULX;
int neatLineHeight = neatLineLRY - neatLineULY;
int gap = neatLine.getDoubleLineGap();
boolean isDoubleLine = neatLine.isDoubleLine();
float innerLineWidth = neatLine.getInnerLineWidth();
float outerLineWidth = neatLine.getOuterLineWidth();
if (neatLine.isBackgroundVisible()) {
g2.setColor(neatLine.getBackgroundColour());
if (isDoubleLine) {
g2.fillRect(neatLineULX + gap,
neatLineULY + gap,
neatLineWidth - 2 * gap,
neatLineHeight - 2 * gap);
} else {
g2.fillRect(neatLineULX,
neatLineULY,
neatLineWidth,
neatLineHeight);
}
}
if (neatLine.isVisible() || neatLine.isSelected()) {
if (neatLine.isBorderVisible() || neatLine.isSelected()) {
Stroke oldStroke = g2.getStroke();
if (neatLine.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(neatLine.getBorderColour());
g2.setStroke(new BasicStroke(outerLineWidth));
}
if (isDoubleLine) {
// outer line
g2.drawRect(neatLineULX,
neatLineULY,
neatLineWidth,
neatLineHeight);
// inner line
g2.setStroke(new BasicStroke(innerLineWidth));
g2.drawRect(neatLineULX + gap,
neatLineULY + gap,
neatLineWidth - 2 * gap,
neatLineHeight - 2 * gap);
} else {
g2.drawRect(neatLineULX,
neatLineULY,
neatLineWidth,
neatLineHeight);
}
g2.setStroke(oldStroke);
}
}
}
}
private void drawMapImage(Graphics2D g2, MapImage mapImage, BasicStroke dashed) {
if (mapImage.isVisible()) {
Color selectedColour = Color.BLACK;
// get the page size information
PageFormat pageFormat = map.getPageFormat();
double pageWidth = pageFormat.getWidth();
double pageHeight = pageFormat.getHeight();
if (mapImage.getUpperLeftY() == -32768) {
mapImage.setWidth((int) (pageWidth - 2 * margin));
mapImage.setHeight((int) (pageHeight - 2 * margin));
mapImage.setUpperLeftX(margin);
mapImage.setUpperLeftY(margin);
}
int mapImageULX = mapImage.getUpperLeftX();
int mapImageULY = mapImage.getUpperLeftY();
int mapImageWidth = mapImage.getWidth();
int mapImageHeight = mapImage.getHeight();
try {
File imgSrc = new File(mapImage.getFileName());
if (imgSrc.exists()) {
BufferedImage bi = mapImage.getBufferedImage();
if (bi == null) {
Font oldFont = g2.getFont();
Font newFont = new Font("SanSerif", Font.BOLD, 11);
FontMetrics metrics = g2.getFontMetrics(newFont);
int hgt = metrics.getHeight();
String label = "Image unavailable";
if (mapImageWidth < 0) {
int adv = metrics.stringWidth(label);
mapImage.setHeight(hgt + 2);
mapImage.setWidth(adv + 2);
mapImageWidth = mapImage.getWidth();
mapImageHeight = mapImage.getHeight();
}
g2.setFont(newFont);
g2.drawString(label, mapImageULX + 1, mapImageULY + hgt - 1);
g2.setFont(oldFont);
} else {
if (!g2.drawImage(bi, mapImageULX, mapImageULY, mapImageWidth, mapImageHeight, this)) {
g2.drawImage(bi, mapImageULX, mapImageULY, mapImageWidth, mapImageHeight, this);
}
}
}
} catch (Exception e) {
Font oldFont = g2.getFont();
Font newFont = new Font("SanSerif", Font.BOLD, 11);
FontMetrics metrics = g2.getFontMetrics(newFont);
int hgt = metrics.getHeight();
String label = "Image unavailable";
if (mapImageWidth < 0) {
int adv = metrics.stringWidth(label);
mapImage.setHeight(hgt + 2);
mapImage.setWidth(adv + 2);
mapImageWidth = mapImage.getWidth();
mapImageHeight = mapImage.getHeight();
}
g2.setFont(newFont);
g2.drawString(label, mapImageULX + 1, mapImageULY + hgt - 1);
g2.setFont(oldFont);
}
float lineWidth = mapImage.getLineWidth();
if (mapImage.isBorderVisible() || mapImage.isSelected()) {
Stroke oldStroke = g2.getStroke();
if (mapImage.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(mapImage.getBorderColour());
g2.setStroke(new BasicStroke(lineWidth));
}
g2.drawRect(mapImageULX,
mapImageULY,
mapImageWidth,
mapImageHeight);
g2.setStroke(oldStroke);
}
}
}
private void drawLegend(Graphics2D g2, Legend legend, BasicStroke dashed) {
if (legend.isVisible()) {
Color selectedColour = Color.BLACK;
Stroke oldStroke;
FontMetrics metrics;
String label;
int adv;
Font font = new Font("SanSerif", Font.PLAIN, 11);
DecimalFormat df = new DecimalFormat("###,###,###.#");
int legendMargin = legend.getMargin();
if (legend.getUpperLeftY() == -32768) {
// initialize its size and location
legend.setWidth((int) (2 * legendMargin + 120));
legend.setHeight((int) (2 * legendMargin + legend.getNumberOfLegendEntries() * 60));
legend.setUpperLeftX(margin);
legend.setUpperLeftY(margin);
}
int legendULX = legend.getUpperLeftX();
int legendULY = legend.getUpperLeftY();
int legendLRX = legend.getLowerRightX();
int legendLRY = legend.getLowerRightY();
int legendWidth = legendLRX - legendULX;
int legendHeight = legendLRY - legendULY;
Rectangle2D rect = new Rectangle2D.Float();
rect.setRect(legendULX, legendULY, legendWidth, legendHeight);
Shape oldClip = g2.getClip();
Rectangle2D clipRect = new Rectangle2D.Float();
clipRect.setRect(legendULX - 1, legendULY - 1, legendWidth + 2, legendHeight + 2);
g2.setClip(clipRect);
if (legend.isBackgroundVisible()) {
g2.setColor(legend.getBackgroundColour());
g2.fill(rect);
}
g2.setColor(Color.BLACK);
int top = legendULY + legendMargin;
int left = legendULX + legendMargin;
Font newFont = legend.getLabelFont();
g2.setFont(newFont);
metrics = g2.getFontMetrics(newFont);
int fontHeight = metrics.getHeight() - metrics.getDescent();
int gap = 8;
int imageHeight = 35;
int imageWidth = 12;
label = legend.getLabel();
boolean noLabel = label.trim().isEmpty();
if (!noLabel) {
top += fontHeight;
adv = metrics.stringWidth(label);
g2.drawString(label, legendULX + (legendWidth - adv) / 2, top);
top += 4;
}
int legendNum = 1;
for (MapArea ma : legend.getMapAreasList()) {
for (int k = ma.getNumLayers() - 1; k >= 0; k--) {
MapLayer mapLayer = ma.getLayer(k);
//for (MapLayer mapLayer : ma.getLayersList()) {
if (mapLayer.isVisible() && mapLayer.isVisibleInLegend()) {
if (legendNum > 1 && !noLabel) {
top += gap;
}
// g2.setColor(ma.getFontColour());
// g2.drawString(mapLayer.getLayerTitle(), left, top);
// top += 4;
if (mapLayer.getLayerType() == MapLayer.MapLayerType.RASTER) {
top += 10;
g2.setColor(ma.getFontColour());
g2.drawString(mapLayer.getLayerTitle(), left, top);
top += 4;
RasterLayerInfo rli = (RasterLayerInfo) mapLayer;
PaletteImage paletteImage = new PaletteImage(18, 45, rli.getPaletteFile(), rli.isPaletteReversed(), PaletteImage.VERTICAL_ORIENTATION);
if (rli.getDataScale() == WhiteboxRasterBase.DataScale.CATEGORICAL) {
paletteImage.isCategorical(true, rli.getMinVal(), rli.getMaxVal());
}
if (rli.getNonlinearity() != 1) {
paletteImage.setNonlinearity(rli.getNonlinearity());
}
Image img = paletteImage.getPaletteImage();
if (!g2.drawImage(img, left, top, imageWidth, imageHeight, this)) {
// do nothing
}
BasicStroke myStroke = new BasicStroke(legend.getLineWidth());
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
g2.drawRect(left, top, imageWidth, imageHeight);
g2.setStroke(oldStroke2);
String maxVal = df.format(rli.getDisplayMaxVal());
String minVal = df.format(rli.getDisplayMinVal());
if (rli.getDisplayMaxVal() < rli.getMaxVal()) {
maxVal = ">" + df.format(rli.getDisplayMaxVal());
}
if (rli.getDisplayMinVal() > rli.getMinVal()) {
minVal = "<" + df.format(rli.getDisplayMinVal());
}
g2.drawString(maxVal, left + imageWidth + 4, top + fontHeight);
g2.drawString(minVal, left + imageWidth + 4, top + imageHeight);
top += 40;
} else if (mapLayer.getLayerType() == MapLayer.MapLayerType.VECTOR) {
VectorLayerInfo vli = (VectorLayerInfo) mapLayer;
ShapeType st = vli.getShapeType();
VectorLayerInfo.LegendEntry[] le = vli.getLegendEntries();
if (le != null && le[0].getLegendLabel().equals("continuous numerical variable") && le[0].getLegendColour().equals(Color.black)) {
// it's a continuous, scaled, numerical variable
top += 10;
g2.setColor(ma.getFontColour());
g2.drawString(mapLayer.getLayerTitle(), left, top);
top += 4;
PaletteImage paletteImage = new PaletteImage(18, 50, vli.getPaletteFile(), false, PaletteImage.VERTICAL_ORIENTATION);
Image img = paletteImage.getPaletteImage();
if (!g2.drawImage(img, left, top, imageWidth, imageHeight, this)) {
// do nothing
}
BasicStroke myStroke = new BasicStroke(legend.getLineWidth());
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
g2.drawRect(left, top, imageWidth, imageHeight);
g2.setStroke(oldStroke2);
String maxVal = df.format(vli.getMaximumValue());
String minVal = df.format(vli.getMinimumValue());
if (vli.getDisplayMaxValue() < vli.getMaximumValue()) {
maxVal = ">" + df.format(vli.getDisplayMaxValue());
}
if (vli.getDisplayMinValue() > vli.getMinimumValue()) {
minVal = "<" + df.format(vli.getDisplayMinValue());
}
g2.drawString(maxVal, left + imageWidth + 4, top + fontHeight);
g2.drawString(minVal, left + imageWidth + 4, top + imageHeight);
top += 40;
} else {
if (legendNum == 1 && !noLabel) {
top += 5;
}
Color fillColour = vli.getFillColour();
Color lineColour = vli.getLineColour();
float lineThickness = vli.getLineThickness();
//float markerSize = vli.getMarkerSize();
boolean isFilled = vli.isFilled();
boolean isOutlined = vli.isOutlined();
boolean bentLine = true;
double sqrSize = 16.0;
double spacing = 3.0;
/*
* figure out the width and
* height. This will depend on
* the fill method. If it is
* being filled using an
* attribute field then it may
* have a greater than normal
* height.
*/
boolean isFilledWithOneColour = vli.isFilledWithOneColour();
boolean isOutlinedWithOneColour = vli.isOutlinedWithOneColour();
int numEntries = 1;
if (!isFilledWithOneColour || !isOutlinedWithOneColour) {
g2.setColor(ma.getFontColour());
g2.drawString(mapLayer.getLayerTitle(), left, top);
//top += 4;
// how many legend entries are there?
le = vli.getLegendEntries();
numEntries = le.length;
}
int entryHeight = (int) sqrSize;
int entryWidth = (int) sqrSize;
//top += spacing;
double x1, y1;
//g2.setColor(legend.getBackgroundColour());
//g2.fillRect(0, 0, width, height);
if (st.getBaseType() == ShapeType.POLYGON) {
//double top = 7.0;
double vecSampleBottom = top + entryHeight; //- 7.0;
//double left = 15.0;
double right = left + entryWidth; // - 15.0;
GeneralPath polyline;
if (isFilled) {
if (isFilledWithOneColour) {
g2.setColor(fillColour);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(left, vecSampleBottom);
polyline.lineTo(left, top);
polyline.lineTo(right, top);
polyline.lineTo(right, vecSampleBottom);
polyline.closePath();
g2.fill(polyline);
} else {
double t, b;
double r = left + sqrSize;
for (int j = 0; j < numEntries; j++) {
t = top + j * (sqrSize + spacing);
b = t + sqrSize;
g2.setColor(le[j].legendColour);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(left, b);
polyline.lineTo(left, t);
polyline.lineTo(r, t);
polyline.lineTo(r, b);
polyline.closePath();
g2.fill(polyline);
}
}
}
if (isOutlined) {
BasicStroke myStroke = new BasicStroke(lineThickness);
if (vli.isDashed()) {
myStroke
= new BasicStroke(lineThickness,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
10.0f, vli.getDashArray(), 0.0f);
}
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
g2.setColor(lineColour);
if (isFilledWithOneColour) {
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(left, vecSampleBottom);
polyline.lineTo(left, top);
polyline.lineTo(right, top);
polyline.lineTo(right, vecSampleBottom);
polyline.closePath();
g2.draw(polyline);
} else {
double t, b;
double r = left + sqrSize;
for (int j = 0; j < numEntries; j++) {
t = top + j * (sqrSize + spacing);
b = t + sqrSize;
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(left, b);
polyline.lineTo(left, t);
polyline.lineTo(r, t);
polyline.lineTo(r, b);
polyline.closePath();
g2.draw(polyline);
}
}
g2.setStroke(oldStroke2);
}
if (!isFilledWithOneColour) {
//Font font = new Font("SanSerif", Font.PLAIN, 11);
//g2d.setFont(font);
//FontMetrics metrics = g.getFontMetrics(font);
double hgt = metrics.getHeight() / 4.0;
g2.setColor(legend.getFontColour());
double vOffset = (sqrSize / 2.0) - hgt;
double t, b;
double r = left + sqrSize + 6;
for (int j = 0; j < numEntries; j++) {
t = top + j * (sqrSize + spacing);
b = t + sqrSize;
label = le[j].getLegendLabel().trim();
g2.drawString(label, (float) (r), (float) (b - vOffset));
}
} else {
double hgt = metrics.getHeight() / 4.0;
g2.setColor(legend.getFontColour());
double vOffset = (sqrSize / 2.0) - hgt;
double r = left + sqrSize + 6;
g2.drawString(vli.getLayerTitle(), (float) (r), (float) (top + sqrSize - vOffset));
}
} else if (st.getBaseType() == ShapeType.POINT
|| st.getBaseType() == ShapeType.MULTIPOINT) {
double[][] xyData = PointMarkers.getMarkerData(vli.getMarkerStyle(), vli.getMarkerSize());
if (isFilledWithOneColour) {
x1 = left + entryWidth / 2.0;
y1 = top + entryHeight / 2.0;
GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
for (int a = 0; a < xyData.length; a++) {
if (xyData[a][0] == 0) { // moveTo
gp.moveTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 1) { // lineTo
gp.lineTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 2) { // elipse2D
Ellipse2D circle = new Ellipse2D.Double((x1 - xyData[a][1]), (y1 - xyData[a][1]), xyData[a][2], xyData[a][2]);
gp.append(circle, true);
}
}
if (isFilled) {
g2.setColor(fillColour);
g2.fill(gp);
}
if (isOutlined) {
BasicStroke myStroke = new BasicStroke(lineThickness);
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
g2.setColor(lineColour);
g2.draw(gp);
g2.setStroke(oldStroke2);
}
double hgt = metrics.getHeight() / 4.0;
g2.setColor(legend.getFontColour());
double vOffset = (sqrSize / 2.0) - hgt;
double r = left + sqrSize + 6;
g2.drawString(vli.getLayerTitle(), (float) (r), (float) (top + sqrSize - vOffset));
} else {
double t;
for (int j = 0; j < numEntries; j++) {
t = legendMargin + j * (sqrSize + spacing);
x1 = legendMargin + sqrSize / 2.0;
y1 = t + sqrSize / 2.0;
GeneralPath gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
for (int a = 0; a < xyData.length; a++) {
if (xyData[a][0] == 0) { // moveTo
gp.moveTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 1) { // lineTo
gp.lineTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 2) { // elipse2D
Ellipse2D circle = new Ellipse2D.Double((x1 - xyData[a][1]), (y1 - xyData[a][1]), xyData[a][2], xyData[a][2]);
gp.append(circle, true);
}
}
if (isFilled) {
g2.setColor(le[j].legendColour);
g2.fill(gp);
}
if (isOutlined) {
BasicStroke myStroke = new BasicStroke(lineThickness);
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
g2.setColor(lineColour);
g2.draw(gp);
g2.setStroke(oldStroke2);
}
}
//Font font = new Font("SanSerif", Font.PLAIN, 11);
//g2d.setFont(font);
//FontMetrics metrics = g.getFontMetrics(font);
double hgt = metrics.getHeight() / 4.0; // why a quarter rather than a half? I really can't figure it out either. But it works.
g2.setColor(Color.BLACK);
double vOffset = (sqrSize / 2.0) - hgt;
double b;
double r = legendMargin + sqrSize + 6;
for (int j = 0; j < numEntries; j++) {
t = margin + j * (sqrSize + spacing);
b = t + sqrSize;
label = le[j].getLegendLabel().trim();
g2.drawString(label, (float) (r), (float) (b - vOffset));
}
}
} else if (st.getBaseType() == ShapeType.POLYLINE) {
double vecSampleBottom = top + entryHeight;
double right = left + entryWidth;
double oneThirdWidth = (right - left) / 3.0;
if (isOutlinedWithOneColour) {
if (lineColour.equals(Color.white)) {
g2.setColor(Color.LIGHT_GRAY);
g2.fillRect(left, top, entryWidth, entryHeight);
}
g2.setColor(lineColour);
BasicStroke myStroke = new BasicStroke(lineThickness);
if (vli.isDashed()) {
myStroke
= new BasicStroke(lineThickness,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
10.0f, vli.getDashArray(), 0.0f);
}
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
if (bentLine) {
polyline.moveTo(left, vecSampleBottom);
polyline.lineTo(left + oneThirdWidth, top);
polyline.lineTo(left + oneThirdWidth * 2, vecSampleBottom);
polyline.lineTo(left + oneThirdWidth * 3, top);
} else {
double middle = entryHeight / 2.0;
polyline.moveTo(left, middle);
polyline.lineTo(right, middle);
}
g2.draw(polyline);
g2.setStroke(oldStroke2);
double hgt = metrics.getHeight() / 4.0;
g2.setColor(legend.getFontColour());
double vOffset = (sqrSize / 2.0) - hgt;
double r = left + sqrSize + 6;
g2.drawString(vli.getLayerTitle(), (float) (r), (float) (top + sqrSize - vOffset));
} else {
BasicStroke myStroke = new BasicStroke(lineThickness);
Stroke oldStroke2 = g2.getStroke();
g2.setStroke(myStroke);
double t, b;
double r = margin + 2 * sqrSize;
oneThirdWidth = (r - margin) / 3.0;
for (int j = 0; j < numEntries; j++) {
t = margin + j * (sqrSize + spacing);
b = t + sqrSize;
x1 = margin + sqrSize / 2.0;
y1 = t + sqrSize / 2.0;
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
if (bentLine) {
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline.moveTo(margin, b);
polyline.lineTo(margin + oneThirdWidth, t);
polyline.lineTo(margin + oneThirdWidth * 2, b);
polyline.lineTo(margin + oneThirdWidth * 3, t);
} else {
double middle = entryHeight / 2.0;
polyline.moveTo(left, middle);
polyline.lineTo(right, middle);
}
g2.setColor(le[j].legendColour);
g2.draw(polyline);
}
g2.setStroke(oldStroke2);
//Font font = new Font("SanSerif", Font.PLAIN, 11);
//g2d.setFont(font);
//FontMetrics metrics = g.getFontMetrics(font);
double hgt = metrics.getHeight() / 4.0; // why a quarter rather than a half? I really can't figure it out either. But it works.
g2.setColor(Color.BLACK);
double vOffset = (sqrSize / 2.0) - hgt;
r = margin + 2 * sqrSize + 6;
for (int j = 0; j < numEntries; j++) {
t = margin + j * (sqrSize + spacing);
b = t + sqrSize;
label = le[j].getLegendLabel().trim();
g2.drawString(label, (float) (r), (float) (b - vOffset));
}
}
}
entryHeight = (int) (numEntries * (sqrSize + spacing)); // + spacing);
top += entryHeight;
}
}
legendNum++;
}
}
}
g2.setClip(oldClip);
if (legend.isBorderVisible() || legend.isSelected()) {
oldStroke = g2.getStroke();
if (legend.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(legend.getBorderColour());
g2.setStroke(new BasicStroke(legend.getBorderWidth()));
}
g2.draw(rect);
g2.setStroke(oldStroke);
g2.setFont(font);
}
}
}
private void drawMapArea(Graphics2D g2, MapArea mapArea, BasicStroke dashed) {
if (mapArea.isVisible()) {
// if (mapArea.getRotation() > 0) {
// g2.rotate(mapArea.getRotation());
// }
Color selectedColour = Color.BLACK;
// get the page size information
PageFormat pageFormat = map.getPageFormat();
double pageWidth = pageFormat.getWidth();
double pageHeight = pageFormat.getHeight();
int x, y;
Stroke oldStroke;
FontMetrics metrics;
String label;
int adv;
// Font font = new Font("SanSerif", Font.PLAIN, 11);
DecimalFormat df = new DecimalFormat("###,###,###.#");
Font newFont = mapArea.getLabelFont();
g2.setColor(mapArea.getFontColour());
Font oldFont = g2.getFont();
g2.setFont(newFont);
metrics = g2.getFontMetrics(newFont);
int fontHeight = metrics.getHeight() - metrics.getDescent();
//boolean isActiveMap = map.getActiveMapAreaElementNumber() == mapArea.getElementNumber();
if (mapArea.getUpperLeftY() == -32768) {
// first set the reference marks size;
mapArea.setReferenceMarksSize(fontHeight + 2);
// now set the initial size
int mapAreaWidth = (int) (pageWidth - 2 * margin - 4);
int mapAreaHeight = (int) (pageHeight - 2 * margin - 4);
mapArea.setWidth(mapAreaWidth);
mapArea.setHeight(mapAreaHeight);
mapArea.setUpperLeftX((int) (margin + (pageWidth - 2 * margin - mapAreaWidth) / 2));
mapArea.setUpperLeftY((int) (margin + (pageHeight - 2 * margin - mapAreaHeight) / 2));
}
int referenceMarkSize = mapArea.getReferenceMarksSize();
int mapAreaULX = mapArea.getUpperLeftX();
int mapAreaULY = mapArea.getUpperLeftY();
int mapAreaLRX = mapArea.getLowerRightX();
int mapAreaLRY = mapArea.getLowerRightY();
// int mapAreaWidth = mapAreaLRX - mapAreaULX;
// int mapAreaHeight = mapAreaLRY - mapAreaULY;
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
int viewAreaWidth = viewAreaLRX - viewAreaULX;
int viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
mapAreaULX = (int) (-pageLeft / scale);
mapAreaULY = (int) (-pageTop / scale);
mapAreaLRX = (int) ((-pageLeft + w) / scale);
mapAreaLRY = (int) ((-pageTop + h) / scale);
// mapAreaWidth = mapAreaLRX - mapAreaULX;
// mapAreaHeight = mapAreaLRY - mapAreaULY;
viewAreaULX = mapAreaULX + referenceMarkSize;
viewAreaULY = mapAreaULY + referenceMarkSize;
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (mapArea.isBackgroundVisible()) {
g2.setColor(mapArea.getBackgroundColour());
g2.fillRect(viewAreaULX, viewAreaULY,
viewAreaWidth, viewAreaHeight);
}
String XYUnits = "";
double mapScale = 1;
int numLayers = mapArea.getNumLayers();
BoundingBox currentExtent = mapArea.getCurrentExtent();
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapScale = Math.min((viewAreaWidth / xRange), (viewAreaHeight / yRange));
// now draw the data into the MapArea
if (numLayers > 0) { // && (!mouseDragged || whichCartoElement != mapArea.getElementNumber())) {
if (scaleText != null && map.getActiveMapAreaElementNumber() == mapArea.getElementNumber()) {
scaleText.setText(df.format(mapArea.getScale()));
}
int width, height;
// what are the edge coordinates of the actual map area
mapExtent.setMinX(currentExtent.getMinX() - (viewAreaWidth / mapScale - xRange) / 2);
mapExtent.setMaxX(currentExtent.getMaxX() + (viewAreaWidth / mapScale - xRange) / 2);
mapExtent.setMinY(currentExtent.getMinY() - (viewAreaHeight / mapScale - yRange) / 2);
mapExtent.setMaxY(currentExtent.getMaxY() + (viewAreaHeight / mapScale - yRange) / 2);
mapArea.setCurrentMapExtent(mapExtent);
for (int i = 0; i < numLayers; i++) {
if (null != mapArea.getLayer(i).getLayerType()) {
switch (mapArea.getLayer(i).getLayerType()) {
case RASTER: {
RasterLayerInfo layer = (RasterLayerInfo) mapArea.getLayer(i);
if (mapArea.getXYUnits().trim().equals("")) {
if (layer.getXYUnits().toLowerCase().contains("met")) {
XYUnits = " m";
} else if (layer.getXYUnits().toLowerCase().contains("deg")) {
XYUnits = "\u00B0";
} else if (!layer.getXYUnits().toLowerCase().contains("not specified")) {
XYUnits = " " + layer.getXYUnits();
}
mapArea.setXYUnits(XYUnits);
}
if (layer.isVisible()) {
BoundingBox fe = layer.getFullExtent();
if (fe.overlaps(mapExtent)) {
BoundingBox layerCE = fe.intersect(mapExtent);
layer.setCurrentExtent(layerCE);
x = (int) (viewAreaULX + (layerCE.getMinX() - mapExtent.getMinX()) * mapScale);
y = (int) (viewAreaULY + (mapExtent.getMaxY() - layerCE.getMaxY()) * mapScale);
int layerWidth = (int) ((Math.abs(layerCE.getMaxX() - layerCE.getMinX())) * mapScale);
int layerHeight = (int) ((Math.abs(layerCE.getMaxY() - layerCE.getMinY())) * mapScale);
int startR = (int) (Math.abs(layer.fullExtent.getMaxY() - layerCE.getMaxY()) / layer.getCellSizeY());
int endR = (int) (layer.getNumberRows() - (Math.abs(layer.fullExtent.getMinY() - layerCE.getMinY()) / layer.getCellSizeY()));
int startC = (int) (Math.abs(layer.fullExtent.getMinX() - layerCE.getMinX()) / layer.getCellSizeX());
int endC = (int) (layer.getNumberColumns() - (Math.abs(layer.fullExtent.getMaxX() - layerCE.getMaxX()) / layer.getCellSizeX()));
int numRows = endR - startR;
int numCols = endC - startC;
//if (!printingMap) {
int cartoGeneralization = (int) layer.getCartographicGeneralizationLevel();
int res = (int) (Math.min(numRows / (double) layerHeight, numCols / (double) layerWidth));
if (res > cartoGeneralization) {
res = cartoGeneralization;
}
layer.setResolutionFactor(res);
//} else {
// layer.setResolutionFactor(1);
//}
if (layer.isDirty()) {
layer.createPixelData();
}
width = layer.getImageWidth();
height = layer.getImageHeight();
Image image = createImage(new MemoryImageSource(width, height, layer.getPixelData(), 0, width));
if (!g2.drawImage(image, x, y, layerWidth, layerHeight, this)) {
g2.drawImage(image, x, y, layerWidth, layerHeight, this);
}
}
}
break;
}
case VECTOR: {
Rectangle2D rect = new Rectangle2D.Float();
rect.setRect(viewAreaULX, viewAreaULY, viewAreaWidth, viewAreaHeight);
Shape oldClip = null;
VectorLayerInfo layer = (VectorLayerInfo) mapArea.getLayer(i);
if (mapArea.getXYUnits().trim().equals("")) {
if (layer.getXYUnits().toLowerCase().contains("met")) {
XYUnits = " m";
} else if (layer.getXYUnits().toLowerCase().contains("deg")) {
XYUnits = "\u00B0";
} else if (!layer.getXYUnits().toLowerCase().contains("not specified")) {
XYUnits = " " + layer.getXYUnits();
}
mapArea.setXYUnits(XYUnits);
} // is it the active layer?
//int selectedFeature = -1;
boolean activeLayerBool = false;
//if (backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT && mapArea.getActiveLayerOverlayNumber() == layer.getOverlayNumber()) {
if (mapArea.getActiveLayerOverlayNumber() == layer.getOverlayNumber()) {
//selectedFeature = layer.getSelectedFeatureNumber();
activeLayerBool = true;
} else { // if (layer.getSelectedFeatureNumber() >= 0) {
//layer.setSelectedFeatureNumber(-1);
layer.clearSelectedFeatures();
}
float xPoint, yPoint;
/*
* minDistinguishableLength is used to
* speed up the drawing of vectors. Any
* feature that is smaller than this
* value will be excluded from the map.
* This is an example of cartographic
* generalization.
*/
double minDistinguishableLength = layer.getCartographicGeneralizationLevel() / mapScale; //scale;
int r;
if (layer.isVisible()) {
BoundingBox fe = layer.getFullExtent();
if (fe.overlaps(mapExtent)) {
// only set the clip region if this layer's bounding box actually intersects the
// boundary of the mapExtent.
boolean isClipped = false;
if (!fe.entirelyContainedWithin(mapExtent)) {
oldClip = g2.getClip();
g2.setClip(rect);
isClipped = true;
}
BoundingBox layerCE = fe.intersect(mapExtent);
layer.setCurrentExtent(layerCE, minDistinguishableLength);
int a1 = layer.getAlpha();
//Color fillColour = new Color(r1, g1, b1, a1);
int r1 = layer.getLineColour().getRed();
int g1 = layer.getLineColour().getGreen();
int b1 = layer.getLineColour().getBlue();
Color lineColour = new Color(r1, g1, b1, a1);
ShapeType shapeType = layer.getShapeType();
//ShapeFileRecord[] records = layer.getGeometry();
ArrayList<ShapeFileRecord> records = layer.getData();
double x1, y1;
//int xInt, yInt, x2Int, y2Int;
double topCoord = mapExtent.getMaxY();
double bottomCoord = mapExtent.getMinY();
double leftCoord = mapExtent.getMinX();
double rightCoord = mapExtent.getMaxX();
double EWRange = rightCoord - leftCoord;
double NSRange = topCoord - bottomCoord;
double[][] xyData;
GeneralPath gp;
BasicStroke myStroke;
Color[] colours = layer.getColourData();
boolean isFilled = layer.isFilled();
boolean isOutlined = layer.isOutlined();
double[][] recPoints;
int[] partStart;
double[][] points;
int pointSt;
int pointEnd;
float xPoints[] = new float[0];
float yPoints[] = new float[0];
GeneralPath polyline;
boolean isActivelyEdited = layer.isActivelyEdited();
float markerSize;
int maxNumDisplayedPoints, skipVal;
switch (shapeType) {
case POINT:
case POINTZ:
case POINTM:
xyData = PointMarkers.getMarkerData(layer.getMarkerStyle(), layer.getMarkerSize());
myStroke = new BasicStroke(layer.getLineThickness());
oldStroke = g2.getStroke();
g2.setStroke(myStroke);
markerSize = layer.getMarkerSize();
maxNumDisplayedPoints = (int) ((viewAreaHeight / markerSize * viewAreaWidth / markerSize) * 1.25);
skipVal = (int) (Math.ceil(records.size() / maxNumDisplayedPoints));
if (skipVal < 1) {
skipVal = 1;
}
for (int q = 0; q < records.size(); q += skipVal) {
//for (ShapeFileRecord record : records) {
ShapeFileRecord record = records.get(q);
r = record.getRecordNumber() - 1;
if (record.getShapeType() != ShapeType.NULLSHAPE) {
// whitebox.geospatialfiles.shapefile.Point rec = (whitebox.geospatialfiles.shapefile.Point) (record.getGeometry());
// x1 = rec.getX();
// y1 = rec.getY();
recPoints = record.getGeometry().getPoints();
x1 = recPoints[0][0];
y1 = recPoints[0][1];
if (y1 < bottomCoord || x1 < leftCoord
|| y1 > topCoord || x1 > rightCoord) {
// It's not within the map area; do nothing.
} else {
x1 = (viewAreaULX + (x1 - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - y1) / NSRange * viewAreaHeight);
gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
for (int a = 0; a < xyData.length; a++) {
if (xyData[a][0] == 0) { // moveTo
gp.moveTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 1) { // lineTo
gp.lineTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 2) { // elipse2D
Ellipse2D circle = new Ellipse2D.Double((x1 - xyData[a][1]), (y1 - xyData[a][1]), xyData[a][2], xyData[a][2]);
gp.append(circle, true);
}
}
if (activeLayerBool && isActivelyEdited) {
g2.setColor(Color.RED);
GeneralPath polyline2;
float xSize = 2.5f;
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(0.5f));
polyline2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline2.moveTo(x1 - xSize, y1 - xSize);
polyline2.lineTo(x1 + xSize, y1 + xSize);
polyline2.moveTo(x1 + xSize, y1 - xSize);
polyline2.lineTo(x1 - xSize, y1 + xSize);
g2.draw(polyline2);
g2.setStroke(oldStroke);
} else {
if (isFilled) {
g2.setColor(colours[r]);
g2.fill(gp);
}
if (isOutlined) {
g2.setColor(lineColour);
g2.draw(gp);
}
if (activeLayerBool && layer.getNumSelectedFeatures() > 0
&& layer.isFeatureSelected(record.getRecordNumber())) { //record.getRecordNumber() == selectedFeature) {
g2.setColor(selectedFeatureColour);
g2.draw(gp);
}
}
}
}
}
g2.setStroke(oldStroke);
break;
case MULTIPOINT:
case MULTIPOINTZ:
case MULTIPOINTM:
markerSize = layer.getMarkerSize();
maxNumDisplayedPoints = (int) ((viewAreaHeight / markerSize * viewAreaWidth / markerSize) * 1.25);
xyData = PointMarkers.getMarkerData(layer.getMarkerStyle(), layer.getMarkerSize());
myStroke = new BasicStroke(layer.getLineThickness());
oldStroke = g2.getStroke();
g2.setStroke(myStroke);
int s = 0;
for (ShapeFileRecord record : records) {
//r = record.getRecordNumber() - 1;
if (record.getShapeType() != ShapeType.NULLSHAPE) {
//MultiPoint rec = (MultiPoint) (record.getGeometry());
recPoints = record.getGeometry().getPoints();
int numPointsInExtent = 0;
switch (shapeType) {
case MULTIPOINT:
numPointsInExtent = ((MultiPoint) (record.getGeometry())).numberOfPointsInExtent(layerCE);
break;
case MULTIPOINTM:
numPointsInExtent = ((MultiPointM) (record.getGeometry())).numberOfPointsInExtent(layerCE);
break;
case MULTIPOINTZ:
numPointsInExtent = ((MultiPointZ) (record.getGeometry())).numberOfPointsInExtent(layerCE);
break;
}
skipVal = (int) (Math.ceil(numPointsInExtent / maxNumDisplayedPoints));
if (skipVal < 1) {
skipVal = 1;
}
for (int p = 0; p < recPoints.length; p += skipVal) {
x1 = recPoints[p][0];
y1 = recPoints[p][1];
if (y1 < bottomCoord || x1 < leftCoord
|| y1 > topCoord || x1 > rightCoord) {
// It's not within the map area; do nothing.
} else {
x1 = (viewAreaULX + (x1 - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - y1) / NSRange * viewAreaHeight);
gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, xyData.length);
for (int a = 0; a < xyData.length; a++) {
if (xyData[a][0] == 0) { // moveTo
gp.moveTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 1) { // lineTo
gp.lineTo(x1 + xyData[a][1], y1 + xyData[a][2]);
} else if (xyData[a][0] == 2) { // elipse2D
Ellipse2D circle = new Ellipse2D.Double((x1 - xyData[a][1]), (y1 - xyData[a][1]), xyData[a][2], xyData[a][2]);
gp.append(circle, true);
}
}
if (activeLayerBool && isActivelyEdited) {
g2.setColor(Color.RED);
GeneralPath polyline2;
float xSize = 2.5f;
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(0.5f));
polyline2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline2.moveTo(x1 - xSize, y1 - xSize);
polyline2.lineTo(x1 + xSize, y1 + xSize);
polyline2.moveTo(x1 + xSize, y1 - xSize);
polyline2.lineTo(x1 - xSize, y1 + xSize);
g2.draw(polyline2);
g2.setStroke(oldStroke);
} else {
if (isFilled) {
g2.setColor(colours[p]); //s]);
g2.fill(gp);
}
if (isOutlined) {
g2.setColor(lineColour);
g2.draw(gp);
}
if (activeLayerBool && layer.getNumSelectedFeatures() > 0 && layer.isFeatureSelected(record.getRecordNumber())) { //record.getRecordNumber() == selectedFeature) {
g2.setColor(selectedFeatureColour);
g2.draw(gp);
}
}
}
//s++;
}
}
}
g2.setStroke(oldStroke);
break;
case POLYLINE:
case POLYLINEZ:
case POLYLINEM:
//g2.setColor(lineColour);
myStroke = new BasicStroke(layer.getLineThickness(), BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND);
if (layer.isDashed()) {
myStroke
= new BasicStroke(layer.getLineThickness(),
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND,
10.0f, layer.getDashArray(), 0.0f);
}
oldStroke = g2.getStroke();
g2.setStroke(myStroke);
for (ShapeFileRecord record : records) {
r = record.getRecordNumber() - 1;
if (record.getShapeType() != ShapeType.NULLSHAPE) {
partStart = record.getGeometry().getParts();
points = record.getGeometry().getPoints();
int numParts = partStart.length;
for (int p = 0; p < numParts; p++) {
pointSt = partStart[p];
if (p < numParts - 1) {
pointEnd = partStart[p + 1];
} else {
pointEnd = points.length;
}
xPoints = new float[pointEnd - pointSt];
yPoints = new float[pointEnd - pointSt];
for (int k = pointSt; k < pointEnd; k++) {
xPoint = (float) (viewAreaULX + (points[k][0] - leftCoord) / EWRange * viewAreaWidth);
yPoint = (float) (viewAreaULY + (topCoord - points[k][1]) / NSRange * viewAreaHeight);
xPoints[k - pointSt] = xPoint;
yPoints[k - pointSt] = yPoint;
}
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, xPoints.length);
polyline.moveTo(xPoints[0], yPoints[0]);
for (int index = 1; index < xPoints.length; index++) {
polyline.lineTo(xPoints[index], yPoints[index]);
}
if (activeLayerBool && isActivelyEdited) {
if (activeLayerBool && layer.isFeatureSelected(record.getRecordNumber())) {
g2.setColor(selectedFeatureColour);
} else {
g2.setColor(colours[r]);
}
g2.draw(polyline);
g2.setColor(Color.RED);
GeneralPath polyline2;
float xSize = 2.5f;
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(0.5f));
for (int index = 0; index < xPoints.length; index++) {
polyline2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline2.moveTo(xPoints[index] - xSize, yPoints[index] - xSize);
polyline2.lineTo(xPoints[index] + xSize, yPoints[index] + xSize);
polyline2.moveTo(xPoints[index] + xSize, yPoints[index] - xSize);
polyline2.lineTo(xPoints[index] - xSize, yPoints[index] + xSize);
g2.draw(polyline2);
}
g2.setStroke(oldStroke);
} else if ((activeLayerBool && layer.isFeatureSelected(record.getRecordNumber()))
&& !isActivelyEdited) { //record.getRecordNumber() == selectedFeature)
g2.setColor(selectedFeatureColour);
g2.draw(polyline);
} else {
g2.setColor(colours[r]);
g2.draw(polyline);
}
}
if (activeLayerBool && backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT) {
//&& layer.getNumSelectedFeatures() > 0) {
BoundingBox bb = record.getGeometry().getBox();
if (bb.isPointInBox(mapX, mapY)) {
g2.setColor(selectionBoxColour);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 5);
xPoint = (float) (viewAreaULX + (bb.getMinX() - leftCoord) / EWRange * viewAreaWidth);
yPoint = (float) (viewAreaULY + (topCoord - bb.getMinY()) / NSRange * viewAreaHeight);
float xPoint2 = (float) (viewAreaULX + (bb.getMaxX() - leftCoord) / EWRange * viewAreaWidth);
float yPoint2 = (float) (viewAreaULY + (topCoord - bb.getMaxY()) / NSRange * viewAreaHeight);
polyline.moveTo(xPoint, yPoint);
polyline.lineTo(xPoint, yPoint2);
polyline.lineTo(xPoint2, yPoint2);
polyline.lineTo(xPoint2, yPoint);
polyline.lineTo(xPoint, yPoint);
g2.draw(polyline);
Ellipse2D circle = new Ellipse2D.Double(xPoint + (xPoint2 - xPoint) / 2 - 2, yPoint + (yPoint2 - yPoint) / 2 - 2, 4, 4);
g2.fill(circle);
}
}
}
}
g2.setStroke(oldStroke);
break;
case POLYGON:
case POLYGONZ:
case POLYGONM:
colours = layer.getColourData();
for (ShapeFileRecord record : records) {
r = record.getRecordNumber() - 1;
if (record.getShapeType() != ShapeType.NULLSHAPE) {
partStart = record.getGeometry().getParts();
points = record.getGeometry().getPoints();
int numParts = partStart.length;
if (layer.isFilled()) {
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, points.length);
for (int p = 0; p < numParts; p++) {
pointSt = partStart[p];
if (p < numParts - 1) {
pointEnd = partStart[p + 1];
} else {
pointEnd = points.length;
}
xPoints = new float[pointEnd - pointSt];
yPoints = new float[pointEnd - pointSt];
for (int k = pointSt; k < pointEnd; k++) {
xPoints[k - pointSt] = (float) (viewAreaULX + (points[k][0] - leftCoord) / EWRange * viewAreaWidth);
yPoints[k - pointSt] = (float) (viewAreaULY + (topCoord - points[k][1]) / NSRange * viewAreaHeight);
}
//System.out.println(r + " " + p);
polyline.moveTo(xPoints[0], yPoints[0]);
for (int index = 1; index < xPoints.length; index++) {
polyline.lineTo(xPoints[index], yPoints[index]);
}
polyline.closePath();
}
g2.setColor(colours[r]);
g2.fill(polyline);
}
if ((layer.isOutlined() || (activeLayerBool && isActivelyEdited))
&& !(layer.isFeatureSelected(record.getRecordNumber()) & activeLayerBool)) {
g2.setColor(lineColour);
myStroke = new BasicStroke(layer.getLineThickness(), BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND);
if (layer.isDashed()) {
myStroke
= new BasicStroke(layer.getLineThickness(),
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND,
10.0f, layer.getDashArray(), 0.0f);
}
oldStroke = g2.getStroke();
g2.setStroke(myStroke);
for (int p = 0; p < numParts; p++) {
pointSt = partStart[p];
if (p < numParts - 1) {
pointEnd = partStart[p + 1];
} else {
pointEnd = points.length;
}
xPoints = new float[pointEnd - pointSt];
yPoints = new float[pointEnd - pointSt];
for (int k = pointSt; k < pointEnd; k++) {
xPoints[k - pointSt] = (float) (viewAreaULX + (points[k][0] - leftCoord) / EWRange * viewAreaWidth);
yPoints[k - pointSt] = (float) (viewAreaULY + (topCoord - points[k][1]) / NSRange * viewAreaHeight);
}
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, xPoints.length);
polyline.moveTo(xPoints[0], yPoints[0]);
for (int index = 1; index < xPoints.length; index++) {
polyline.lineTo(xPoints[index], yPoints[index]);
}
g2.draw(polyline);
}
if (activeLayerBool && isActivelyEdited) {
if (xPoints.length > 0) {
g2.setColor(Color.RED);
GeneralPath polyline2;
float xSize = 2.5f;
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(0.5f));
for (int index = 0; index < xPoints.length; index++) {
polyline2 = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 4);
polyline2.moveTo(xPoints[index] - xSize, yPoints[index] - xSize);
polyline2.lineTo(xPoints[index] + xSize, yPoints[index] + xSize);
polyline2.moveTo(xPoints[index] + xSize, yPoints[index] - xSize);
polyline2.lineTo(xPoints[index] - xSize, yPoints[index] + xSize);
g2.draw(polyline2);
}
g2.setStroke(oldStroke);
g2.setColor(lineColour);
}
}
g2.setStroke(oldStroke);
}
}
}
if (activeLayerBool) { // && layer.getNumSelectedFeatures() > 0) { //backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT &&
g2.setColor(selectedFeatureColour);
myStroke = new BasicStroke(layer.getLineThickness(), BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND);
oldStroke = g2.getStroke();
g2.setStroke(myStroke);
for (ShapeFileRecord record : records) {
if (layer.isFeatureSelected(record.getRecordNumber())) {
partStart = record.getGeometry().getParts();
points = record.getGeometry().getPoints();
int numParts = partStart.length;
for (int p = 0; p < numParts; p++) {
pointSt = partStart[p];
if (p < numParts - 1) {
pointEnd = partStart[p + 1];
} else {
pointEnd = points.length;
}
xPoints = new float[pointEnd - pointSt];
yPoints = new float[pointEnd - pointSt];
for (int k = pointSt; k < pointEnd; k++) {
xPoints[k - pointSt] = (float) (viewAreaULX + (points[k][0] - leftCoord) / EWRange * viewAreaWidth);
yPoints[k - pointSt] = (float) (viewAreaULY + (topCoord - points[k][1]) / NSRange * viewAreaHeight);
}
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, xPoints.length);
polyline.moveTo(xPoints[0], yPoints[0]);
for (int index = 1; index < xPoints.length; index++) {
polyline.lineTo(xPoints[index], yPoints[index]);
}
g2.draw(polyline);
}
}
if (backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT) {
BoundingBox bb = record.getGeometry().getBox();
if (bb.isPointInBox(mapX, mapY)) {
g2.setColor(selectionBoxColour);
polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 5);
xPoint = (float) (viewAreaULX + (bb.getMinX() - leftCoord) / EWRange * viewAreaWidth);
yPoint = (float) (viewAreaULY + (topCoord - bb.getMinY()) / NSRange * viewAreaHeight);
float xPoint2 = (float) (viewAreaULX + (bb.getMaxX() - leftCoord) / EWRange * viewAreaWidth);
float yPoint2 = (float) (viewAreaULY + (topCoord - bb.getMaxY()) / NSRange * viewAreaHeight);
polyline.moveTo(xPoint, yPoint);
polyline.lineTo(xPoint, yPoint2);
polyline.lineTo(xPoint2, yPoint2);
polyline.lineTo(xPoint2, yPoint);
polyline.lineTo(xPoint, yPoint);
g2.draw(polyline);
Ellipse2D circle = new Ellipse2D.Double(xPoint + (xPoint2 - xPoint) / 2 - 2, yPoint + (yPoint2 - yPoint) / 2 - 2, 4, 4);
g2.fill(circle);
g2.setColor(selectedFeatureColour);
}
}
}
g2.setStroke(oldStroke);
}
break;
case MULTIPATCH:
// this vector type is unsupported
break;
}
if (isClipped) {
g2.setClip(oldClip);
}
}
}
break;
}
case LAS: {
Rectangle2D rect = new Rectangle2D.Float();
rect.setRect(viewAreaULX, viewAreaULY, viewAreaWidth, viewAreaHeight);
Shape oldClip = null;
LasLayerInfo layer = (LasLayerInfo) mapArea.getLayer(i);
if (mapArea.getXYUnits().trim().equals("")) {
// if (layer.getXYUnits().toLowerCase().contains("met")) {
XYUnits = " m";
// } else if (layer.getXYUnits().toLowerCase().contains("deg")) {
// XYUnits = "\u00B0";
// } else if (!layer.getXYUnits().toLowerCase().contains("not specified")) {
// XYUnits = " " + layer.getXYUnits();
// }
mapArea.setXYUnits(XYUnits);
} // is it the active layer?
boolean activeLayerBool = false;
if (mapArea.getActiveLayerOverlayNumber() == layer.getOverlayNumber()) {
activeLayerBool = true;
} else {
layer.clearSelectedFeatures();
}
float markerSize = layer.getMarkerSize();
int maxNumDisplayedPoints = (int) ((viewAreaHeight / markerSize * viewAreaWidth / markerSize) * 1.25);
if (layer.isVisible()) {
BoundingBox fe = layer.getFullExtent();
if (fe.overlaps(mapExtent)) {
// only set the clip region if this layer's bounding box actually intersects the
// boundary of the mapExtent.
boolean isClipped = false;
if (!fe.entirelyContainedWithin(mapExtent)) {
oldClip = g2.getClip();
g2.setClip(rect);
isClipped = true;
}
BoundingBox layerCE = fe.intersect(mapExtent);
layer.setCurrentExtent(layerCE);
//int a1 = layer.getAlpha();
//Color fillColour = new Color(r1, g1, b1, a1);
ArrayList<XYPoint> records = layer.getPointXYData();
// skipVal is used to speed up the display of LAS points.
// If there are more points in the extent that can be displayed,
// some will be ignored when drawing.
int skipVal = (int) (Math.ceil(records.size() / maxNumDisplayedPoints));
if (skipVal < 1) {
skipVal = 1;
}
double x1, y1;
//int xInt, yInt, x2Int, y2Int;
double topCoord = mapExtent.getMaxY();
double bottomCoord = mapExtent.getMinY();
double leftCoord = mapExtent.getMinX();
double rightCoord = mapExtent.getMaxX();
double EWRange = rightCoord - leftCoord;
double NSRange = topCoord - bottomCoord;
GeneralPath gp;
XYPoint record;
ArrayList<Color> colours = layer.getColourData();
if (colours.size() == 1) {
Color fillColour = colours.get(0);
for (int r = 0; r < records.size(); r += skipVal) {
record = records.get(r);
x1 = record.x;
y1 = record.y;
if (y1 < bottomCoord || x1 < leftCoord
|| y1 > topCoord || x1 > rightCoord) {
// It's not within the map area; do nothing.
} else {
x1 = (viewAreaULX + (x1 - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - y1) / NSRange * viewAreaHeight);
gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
Ellipse2D circle = new Ellipse2D.Double((x1 - markerSize / 2f), (y1 - markerSize / 2f), markerSize, markerSize);
gp.append(circle, true);
g2.setColor(fillColour);
g2.fill(gp);
// if (activeLayerBool && layer.getNumSelectedFeatures() > 0
// && layer.isFeatureSelected(record.getRecordNumber())) {
// g2.setColor(selectedFeatureColour);
// g2.draw(gp);
// }
}
}
} else {
for (int r = 0; r < records.size(); r += skipVal) {
record = records.get(r);
x1 = record.x;
y1 = record.y;
if (y1 < bottomCoord || x1 < leftCoord
|| y1 > topCoord || x1 > rightCoord) {
// It's not within the map area; do nothing.
} else {
x1 = (viewAreaULX + (x1 - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - y1) / NSRange * viewAreaHeight);
gp = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 1);
Ellipse2D circle = new Ellipse2D.Double((x1 - markerSize / 2f), (y1 - markerSize / 2f), markerSize, markerSize);
gp.append(circle, true);
g2.setColor(colours.get(r));
g2.fill(gp);
// if (activeLayerBool && layer.getNumSelectedFeatures() > 0
// && layer.isFeatureSelected(record.getRecordNumber())) {
// g2.setColor(selectedFeatureColour);
// g2.draw(gp);
// }
}
}
}
if (isClipped) {
g2.setClip(oldClip);
}
}
}
break;
}
default:
break;
}
}
}
}
if (mapArea.isBorderVisible()) {
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(mapArea.getLineWidth()));
g2.setColor(mapArea.getBorderColour());
g2.drawRect(viewAreaULX,
viewAreaULY,
viewAreaWidth,
viewAreaHeight);
g2.setStroke(oldStroke);
}
if (mapArea.isReferenceMarksVisible()) {
oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(mapArea.getLineWidth()));
g2.setColor(mapArea.getBorderColour());
g2.drawLine(viewAreaULX,
viewAreaULY,
viewAreaULX,
viewAreaULY - referenceMarkSize);
g2.drawLine(viewAreaULX,
viewAreaULY,
viewAreaULX - referenceMarkSize,
viewAreaULY);
g2.drawLine(viewAreaLRX,
viewAreaULY,
viewAreaLRX,
viewAreaULY - referenceMarkSize);
g2.drawLine(viewAreaLRX,
viewAreaULY,
viewAreaLRX + referenceMarkSize,
viewAreaULY);
g2.drawLine(viewAreaULX,
viewAreaLRY,
viewAreaULX,
viewAreaLRY + referenceMarkSize);
g2.drawLine(viewAreaULX,
viewAreaLRY,
viewAreaULX - referenceMarkSize,
viewAreaLRY);
g2.drawLine(viewAreaLRX,
viewAreaLRY,
viewAreaLRX,
viewAreaLRY + referenceMarkSize);
g2.drawLine(viewAreaLRX,
viewAreaLRY,
viewAreaLRX + referenceMarkSize,
viewAreaLRY);
if (Double.isFinite(xRange) && !Double.isNaN(xRange)) {
// find the largest possible tick interval resulting in 5 or fewer ticks
double topCoord = mapExtent.getMaxY();
double bottomCoord = mapExtent.getMinY();
double leftCoord = mapExtent.getMinX();
double rightCoord = mapExtent.getMaxX();
double EWRange = rightCoord - leftCoord;
double NSRange = topCoord - bottomCoord;
double tickInterval = 0.0001;
double testRange = EWRange < NSRange ? EWRange : NSRange;
int numTickMarks = (int) Math.floor(testRange / tickInterval);
if (numTickMarks > 12) {
while (numTickMarks > 20) {
tickInterval = tickInterval * 10;
numTickMarks = (int) Math.floor(testRange / tickInterval);
}
}
if (numTickMarks < 3) {
tickInterval = tickInterval * 10;
//numTickMarks = (int)Math.floor(testRange / tickInterval);
}
double startingTickVal = Math.ceil(leftCoord / tickInterval) * tickInterval;
int x1, y1;
int halfReferenceMarkSize = referenceMarkSize / 3;
numTickMarks = (int) Math.floor(EWRange / tickInterval);
for (int k = 0; k <= numTickMarks; k++) {
x1 = (int) (viewAreaULX + (startingTickVal + (k * tickInterval) - leftCoord) / EWRange * viewAreaWidth);
if (startingTickVal + (k * tickInterval) > rightCoord) {
break;
}
g2.drawLine(x1,
viewAreaULY,
x1,
viewAreaULY - halfReferenceMarkSize);
g2.drawLine(x1,
viewAreaLRY,
x1,
viewAreaLRY + halfReferenceMarkSize);
}
numTickMarks = (int) Math.floor(NSRange / tickInterval);
startingTickVal = Math.floor(topCoord / tickInterval) * tickInterval;
for (int k = 0; k <= numTickMarks; k++) {
y1 = (int) (viewAreaULY + (topCoord - startingTickVal + (k * tickInterval)) / NSRange * viewAreaHeight);
if (y1 > viewAreaLRY) {
break;
} //topCoord - startingTickVal + (k * tickInterval) < bottomCoord) { break; }
g2.drawLine(viewAreaULX,
y1,
viewAreaULX - halfReferenceMarkSize,
y1);
g2.drawLine(viewAreaLRX,
y1,
viewAreaLRX + halfReferenceMarkSize,
y1);
}
}
g2.setStroke(oldStroke);
if (numLayers > 0) {
Font labelFont = mapArea.getLabelFont(); //new Font("SanSerif", Font.PLAIN, 10);
XYUnits = mapArea.getXYUnits().trim();
if (!XYUnits.isEmpty() && !XYUnits.equals("\u00B0")) {
String tmpStr = " " + XYUnits;
XYUnits = tmpStr;
}
// labels
Rectangle2D rect;
float ht, wd;
df = new DecimalFormat("###,###,###.#");
if ((currentExtent.getMaxY() - currentExtent.getMinY()) < 10
|| (currentExtent.getMaxX() - currentExtent.getMinX()) < 10) {
df = new DecimalFormat("###,###,###.##");
}
g2.setFont(labelFont);
metrics = g2.getFontMetrics(labelFont);
// float hgt = metrics.getAscent(); // + metrics.getDescent();
// float refMarkOffset = (referenceMarkSize - hgt) / 2.0f;
int offset = 6;
if (!XYUnits.equals("\u00B0")) {
label = df.format(currentExtent.getMinX() - (viewAreaWidth / mapScale - xRange) / 2) + XYUnits;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
g2.drawString(label, viewAreaULX + 4, viewAreaULY - offset); //3);
g2.drawString(label, viewAreaULX + 4, viewAreaLRY + ht + offset - 3);
label = df.format(currentExtent.getMaxX() + (viewAreaWidth / mapScale - xRange) / 2) + XYUnits;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
wd = (float) rect.getWidth() + 2;
g2.drawString(label, viewAreaLRX - wd, viewAreaULY - offset); //3);
g2.drawString(label, viewAreaLRX - wd, viewAreaLRY + ht + offset - 3);
} else {
double coordValue = currentExtent.getMinX() - (viewAreaWidth / mapScale - xRange) / 2;
String hemi = "E";
if (coordValue < 0) {
coordValue = -1 * coordValue;
hemi = "W";
}
label = df.format(coordValue) + XYUnits + hemi;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
g2.drawString(label, viewAreaULX + 4, viewAreaULY - offset); //3);
g2.drawString(label, viewAreaULX + 4, viewAreaLRY + ht + offset - 3);
coordValue = currentExtent.getMaxX() + (viewAreaWidth / mapScale - xRange) / 2;
hemi = "E";
if (coordValue < 0) {
coordValue = -1 * coordValue;
hemi = "W";
}
label = df.format(coordValue) + XYUnits + hemi;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
wd = (float) rect.getWidth() + 2;
g2.drawString(label, viewAreaLRX - wd, viewAreaULY - offset); //3);
g2.drawString(label, viewAreaLRX - wd, viewAreaLRY + ht + offset - 3);
}
metrics = g2.getFontMetrics(labelFont);
if (!XYUnits.equals("\u00B0")) {
label = df.format(currentExtent.getMaxY() + (viewAreaHeight / mapScale - yRange) / 2) + XYUnits;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
wd = (float) rect.getWidth() + 3;
//adv = metrics.stringWidth(label) + 3;
// g2.drawString(label, viewAreaLRX + ht, viewAreaULY + wd);
double xr = viewAreaULX - offset; //3;
double yr = viewAreaULY + wd;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
xr = viewAreaLRX + ht + offset - 4;
yr = viewAreaULY + wd;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
label = df.format(currentExtent.getMinY() - (viewAreaHeight / mapScale - yRange) / 2) + XYUnits;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
// wd = (float)rect.getWidth();
xr = viewAreaULX - offset;
yr = viewAreaLRY - 4;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
xr = viewAreaLRX + ht + offset - 4;
yr = viewAreaLRY - 4;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
} else {
double coordValue = currentExtent.getMaxY() + (viewAreaHeight / mapScale - yRange) / 2;
String hemi = "N";
if (coordValue < 0) {
coordValue = -1 * coordValue;
hemi = "S";
}
label = df.format(coordValue) + XYUnits + hemi;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
wd = (float) rect.getWidth() + 3;
//adv = metrics.stringWidth(label) + 3;
// g2.drawString(label, viewAreaLRX + ht, viewAreaULY + wd);
double xr = viewAreaULX - offset; //3;
double yr = viewAreaULY + wd;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
xr = viewAreaLRX + ht + offset - 4;
yr = viewAreaULY + wd;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
coordValue = currentExtent.getMinY() - (viewAreaHeight / mapScale - yRange) / 2;
hemi = "N";
if (coordValue < 0) {
coordValue = -1 * coordValue;
hemi = "S";
}
label = df.format(coordValue) + XYUnits + hemi;
rect = metrics.getStringBounds(label, g2);
ht = (float) rect.getHeight();
// wd = (float)rect.getWidth();
xr = viewAreaULX - offset;
yr = viewAreaLRY - 4;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
xr = viewAreaLRX + ht + offset - 4;
yr = viewAreaLRY - 4;
g2.translate(xr, yr);
g2.rotate(-Math.PI / 2.0, 0, 0);
g2.drawString(label, 0, 0);
g2.rotate(Math.PI / 2);
g2.translate(-xr, -yr);
}
}
}
if (mapArea.isNeatlineVisible() || mapArea.isSelected()) {
if (!mapArea.isSizeMaximizedToScreenSize()) {
oldStroke = g2.getStroke();
if (mapArea.isSelected() && !printingMap) {
g2.setColor(selectedColour);
g2.setStroke(dashed);
} else {
g2.setColor(mapArea.getBorderColour());
g2.setStroke(new BasicStroke(mapArea.getLineWidth()));
}
g2.drawRect(mapAreaULX,
mapAreaULY,
mapArea.getWidth(),
mapArea.getHeight());
g2.setStroke(oldStroke);
}
}
// replace the rotated font.
g2.setFont(oldFont);
// if (mapArea.getRotation() > 0) {
// g2.rotate(-mapArea.getRotation());
// }
if (usingDistanceTool || (digitizingNewFeature
&& (map.getActiveMapAreaElementNumber() == mapArea.getElementNumber()))) {
double topCoord = mapExtent.getMaxY();
double bottomCoord = mapExtent.getMinY();
double leftCoord = mapExtent.getMinX();
double rightCoord = mapExtent.getMaxX();
double EWRange = rightCoord - leftCoord;
double NSRange = topCoord - bottomCoord;
oldStroke = g2.getStroke();
g2.setColor(Color.yellow);
double x1, y1;
if (distPoints.size() > 1) {
GeneralPath polyline = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 5);
x1 = (viewAreaULX + (distPoints.get(0).x - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - distPoints.get(0).y) / NSRange * viewAreaHeight);
polyline.moveTo(x1, y1);
for (int i = 1; i < distPoints.size(); i++) {
x1 = (viewAreaULX + (distPoints.get(i).x - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - distPoints.get(i).y) / NSRange * viewAreaHeight);
polyline.lineTo(x1, y1);
}
g2.draw(polyline);
}
for (int i = 0; i < distPoints.size(); i++) {
if (i == distPoints.size() - 1) {
g2.setColor(Color.blue);
}
x1 = (viewAreaULX + (distPoints.get(i).x - leftCoord) / EWRange * viewAreaWidth);
y1 = (viewAreaULY + (topCoord - distPoints.get(i).y) / NSRange * viewAreaHeight);
g2.fillRect((int) x1 - 3, (int) y1 - 3, 6, 6);
}
g2.setStroke(oldStroke);
} else if (modifyingPixels && modifyPixelsX > 0 && modifyPixelsY > 0) {
double topCoord = mapExtent.getMaxY();
double bottomCoord = mapExtent.getMinY();
double leftCoord = mapExtent.getMinX();
double rightCoord = mapExtent.getMaxX();
double EWRange = rightCoord - leftCoord;
double NSRange = topCoord - bottomCoord;
int crosshairlength = 13;
int radius = 9;
int x1 = (int) (viewAreaULX + (modifyPixelsX - leftCoord) / EWRange * viewAreaWidth);
int y1 = (int) (viewAreaULY + (topCoord - modifyPixelsY) / NSRange * viewAreaHeight);
g2.setColor(Color.white);
g2.drawOval(x1 - radius - 1, y1 - radius - 1, 2 * radius + 2, 2 * radius + 2);
g2.setColor(Color.black);
g2.drawOval(x1 - radius, y1 - radius, 2 * radius, 2 * radius);
g2.setColor(Color.white);
g2.drawRect(x1 - 1, y1 - crosshairlength - 1, 2, crosshairlength * 2 + 2);
g2.drawRect(x1 - crosshairlength - 1, y1 - 1, crosshairlength * 2 + 2, 2);
g2.setColor(Color.black);
g2.drawLine(x1, y1 - crosshairlength, x1, y1 + crosshairlength);
g2.drawLine(x1 - crosshairlength, y1, x1 + crosshairlength, y1);
}
}
}
private double calculateArea() {
int numPoints;
double x1, y1, x2, y2;
int n1 = 0, n2 = 0;
double area = 0;
numPoints = distPoints.size();
if (numPoints < 3) {
return -1;
} // something's wrong!
double area2 = 0;
for (int j = 0; j < numPoints; j++) {
n1 = j;
if (j < numPoints - 1) {
n2 = j + 1;
} else {
n2 = 0;
}
x1 = distPoints.get(n1).x;
y1 = distPoints.get(n1).y;
x2 = distPoints.get(n2).x;
y2 = distPoints.get(n2).y;
area2 += (x1 * y2) - (x2 * y1);
}
area2 = area2 / 2.0;
if (area2 < 0) { // a positive area indicates counter-clockwise order
area += -area2;
} else {
area += area2;
}
return area;
}
@Override
public void mouseDragged(MouseEvent e) {
mouseDragged = true;
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
endCol = x;
endRow = y;
if (myMode == MOUSE_MODE_CARTO_ELEMENT
|| myMode == MOUSE_MODE_MAPAREA) {
for (CartographicElement ce : map.getCartographicElementList()) {
if (ce.isSelected()) {
ce.setUpperLeftX(x - ce.getSelectedOffsetX());
ce.setUpperLeftY(y - ce.getSelectedOffsetY());
}
}
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea.isVisible() && mapExtent.getMinY() != mapExtent.getMaxY()
&& backgroundMouseMode == MOUSE_MODE_PAN && !mapArea.isSelected()) {
int x2 = (int) ((e.getX() - pageLeft) / scale);
int y2 = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
double xRange = Math.abs(mapExtent.getMaxX() - mapExtent.getMinX());
double yRange = Math.abs(mapExtent.getMaxY() - mapExtent.getMinY());
double mapYEnd = mapExtent.getMinY() + (viewAreaLRY - y2) / viewAreaHeight * yRange;
double mapXEnd = mapExtent.getMinX() + (x2 - viewAreaULX) / viewAreaWidth * xRange;
double deltaX = mapX - mapXEnd;
double deltaY = mapY - mapYEnd;
if (Math.abs(deltaX / xRange) >= 0.05 || Math.abs(deltaY / yRange) >= 0.05) {
BoundingBox bb = new BoundingBox(mapExtent.getMinX() + deltaX,
mapExtent.getMinY() + deltaY,
mapExtent.getMaxX() + deltaX,
mapExtent.getMaxY() + deltaY);
mapArea.setCurrentExtent(bb);
}
}
}
} else if (myMode == MOUSE_MODE_RESIZE) {
CartographicElement ce = map.getCartographicElement(whichCartoElement);
if (ce.isSelected()) {
ce.resize(x, y, myResizeMode);
}
}
this.repaint();
}
boolean panning = false;
@Override
public void mouseMoved(MouseEvent e) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
boolean withinElement = false;
int nearDist = 8;
for (CartographicElement ce : map.getCartographicElementList()) {
int ulX = ce.getUpperLeftX();
int ulY = ce.getUpperLeftY();
int lrX = ce.getLowerRightX();
int lrY = ce.getLowerRightY();
// is the mouse within the element?
if (isBetween(x, ulX, lrX) && isBetween(y, ulY, lrY)) {
if (!(ce instanceof MapArea)) {
if (ce.isSelected() && myMode != MOUSE_MODE_CARTO_ELEMENT) {
this.setCursor(panCursor);
panning = true;
} else if (!ce.isSelected() && myMode != MOUSE_MODE_CARTO_ELEMENT
&& backgroundMouseMode != MOUSE_MODE_ZOOM
&& backgroundMouseMode != MOUSE_MODE_ZOOMOUT) {
this.setCursor(selectCursor);
}
myMode = MOUSE_MODE_CARTO_ELEMENT;
} else {
if (ce.isSelected() && myMode != MOUSE_MODE_MAPAREA
&& !digitizing) {
this.setCursor(panCursor);
panning = true;
} else if (myMode == MOUSE_MODE_FEATURE_SELECT) {
this.setCursor(selectFeatureCursor);
panning = false;
} else if (digitizing) {
this.setCursor(digitizeCursor);
panning = false;
}
myMode = MOUSE_MODE_MAPAREA;
updateStatus(e, (MapArea) ce);
}
whichCartoElement = ce.getElementNumber();
ce.setSelectedOffsetX(x - ce.getUpperLeftX());
ce.setSelectedOffsetY(y - ce.getUpperLeftY());
withinElement = true;
// are you near the edge of a selected element?
} else if (ce.isSelected() && isBetween(x, ulX - nearDist, lrX + nearDist)
&& isBetween(y, ulY - nearDist, lrY + nearDist)) {
if (myMode != MOUSE_MODE_RESIZE) {
/* public static final int RESIZE_MODE_N = 0;
public static final int RESIZE_MODE_S = 1;
public static final int RESIZE_MODE_E = 2;
public static final int RESIZE_MODE_W = 3;
public static final int RESIZE_MODE_NE = 4;
public static final int RESIZE_MODE_NW = 5;
public static final int RESIZE_MODE_SE = 6;
public static final int RESIZE_MODE_SW = 7;
*/
if (isBetween(x, ulX, lrX) && (y < ulY)) {
this.setCursor(new Cursor(java.awt.Cursor.N_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_N;
} else if (isBetween(x, ulX, lrX) && (y > lrY)) {
this.setCursor(new Cursor(java.awt.Cursor.S_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_S;
} else if (isBetween(y, ulY, lrY) && (x > ulX)) {
this.setCursor(new Cursor(java.awt.Cursor.E_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_E;
} else if (isBetween(y, ulY, lrY) && (x < lrX)) {
this.setCursor(new Cursor(java.awt.Cursor.W_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_W;
} else if ((y < ulY) && (x < ulX)) {
this.setCursor(new Cursor(java.awt.Cursor.NW_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_NW;
} else if ((y < ulY) && (x > lrX)) {
this.setCursor(new Cursor(java.awt.Cursor.NE_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_NE;
} else if ((y > lrY) && (x < ulX)) {
this.setCursor(new Cursor(java.awt.Cursor.SW_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_SW;
} else if ((y > lrY) && (x > lrX)) {
this.setCursor(new Cursor(java.awt.Cursor.SE_RESIZE_CURSOR));
myResizeMode = RESIZE_MODE_SE;
}
panning = false;
}
myMode = MOUSE_MODE_RESIZE;
whichCartoElement = ce.getElementNumber();
ce.setSelectedOffsetX(x - ce.getUpperLeftX());
ce.setSelectedOffsetY(y - ce.getUpperLeftY());
withinElement = true;
}
if (ce.isSelected()) {
ce.setSelectedOffsetX(x - ce.getUpperLeftX());
ce.setSelectedOffsetY(y - ce.getUpperLeftY());
}
if (myMode == MOUSE_MODE_MAPAREA && ce instanceof MapArea) {
calculateMapXY(e, (MapArea) ce);
}
}
if (!withinElement) {
if (myMode == MOUSE_MODE_CARTO_ELEMENT
|| myMode == MOUSE_MODE_MAPAREA
|| myMode == MOUSE_MODE_RESIZE) {
panning = false;
if (backgroundMouseMode == MOUSE_MODE_ZOOM) {
myMode = MOUSE_MODE_ZOOM;
this.setCursor(zoomCursor);
} else if (backgroundMouseMode == MOUSE_MODE_ZOOMOUT) {
myMode = MOUSE_MODE_ZOOMOUT;
this.setCursor(zoomOutCursor);
} else if (backgroundMouseMode == MOUSE_MODE_PAN) {
myMode = MOUSE_MODE_PAN;
this.setCursor(panCursor);
panning = true;
} else if (backgroundMouseMode == MOUSE_MODE_SELECT) {
myMode = MOUSE_MODE_SELECT;
this.setCursor(selectCursor);
} else if (backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT) {
myMode = MOUSE_MODE_FEATURE_SELECT;
this.setCursor(selectFeatureCursor);
}
whichCartoElement = -1;
this.repaint();
}
}
if (myMode == MOUSE_MODE_MAPAREA && backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT) {
this.repaint();
}
}
// Return true if val is between theshold1 and theshold2.
private static boolean isBetween(double val, double threshold1, double threshold2) {
if (val == threshold1 || val == threshold2) {
return true;
}
return threshold2 > threshold1 ? val > threshold1 && val < threshold2 : val > threshold2 && val < threshold1;
}
ArrayList<XYPoint> distPoints = new ArrayList<>();
double calculatedDistance;
JPopupMenu popupMenu = new JPopupMenu();
private XYPoint getMapXYCoordinates(int x, int y, MapArea mapArea) {
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
int x2 = (int) ((x - pageLeft) / scale);
int y2 = (int) ((y - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x2, viewAreaULX, viewAreaLRX) || !isBetween(y2, viewAreaULY, viewAreaLRY)) {
return null;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapY = currentExtent.getMinY() + (viewAreaLRY - y2) / viewAreaHeight * yRange;
mapX = currentExtent.getMinX() + (x2 - viewAreaULX) / viewAreaWidth * xRange;
return new XYPoint(mapX, mapY);
}
@Override
public void mouseClicked(MouseEvent e) {
int clickCount = e.getClickCount();
int button = e.getButton();
boolean isPopupTrigger = e.isPopupTrigger();
if (digitizing && digitizingNewFeature) {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (map.getActiveMapAreaElementNumber() != mapArea.getElementNumber()) {
return;
}
if (mapArea.getActiveLayer().getLayerType() != MapLayer.MapLayerType.VECTOR) {
return;
}
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x, viewAreaULX, viewAreaLRX) || !isBetween(y, viewAreaULY, viewAreaLRY)) {
return;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapY = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
mapX = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
distPoints.add(new XYPoint(mapX, mapY));
updateStatus(e, (MapArea) map.getCartographicElement(whichCartoElement));
VectorLayerInfo vli = (VectorLayerInfo) mapArea.getActiveLayer();
if (clickCount == 2) {
try {
vli.closeNewFeature(mapX, mapY);
distPoints.clear();
if (host instanceof WhiteboxGui) {
WhiteboxGui wb = (WhiteboxGui) host;
wb.digitizeNewFeature();
}
} catch (Exception ex) {
host.logException("Error adding new digitized point", ex);
host.showFeedback("An error has been enountered while digitizing.");
}
} else {
try {
vli.addNodeToNewFeature(mapX, mapY);
// host.showFeedback("An error has been enountered while digitizing.");
// }
} catch (Exception ex) {
host.logException("Error adding new digitized point", ex);
host.showFeedback("An error has been enountered while digitizing.");
}
}
if (vli.getShapeType().getBaseType() == ShapeType.POINT) {
distPoints.clear();
if (host instanceof WhiteboxGui) {
WhiteboxGui wb = (WhiteboxGui) host;
wb.digitizeNewFeature();
}
}
host.refreshMap(false);
}
}
} else if (clickCount == 2 && (myMode == MOUSE_MODE_CARTO_ELEMENT
|| myMode == MOUSE_MODE_MAPAREA) && !usingDistanceTool
&& backgroundMouseMode != MOUSE_MODE_ZOOM
&& backgroundMouseMode != MOUSE_MODE_ZOOMOUT
&& !modifyingPixels) {
if (host instanceof WhiteboxGui) { //SwingUtilities.getRoot(this) instanceof WhiteboxGui) {
WhiteboxGui wb = (WhiteboxGui) host;
wb.showMapProperties(whichCartoElement);
}
} else if (backgroundMouseMode == MOUSE_MODE_ZOOMOUT
&& button != 3 && !isPopupTrigger
&& !usingDistanceTool && !modifyingPixels) {
if (myMode != MOUSE_MODE_MAPAREA) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
map.zoom(x, y, (1 + clickCount * 0.15));
} else {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea.isVisible() && mapArea.getNumLayers() > 0) {
XYPoint point = getMapXYCoordinates(e.getX(), e.getY(), mapArea);
mapArea.naturalZoom(point.x, point.y, (1 + clickCount * 0.15));
} else {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
map.zoom(x, y, (1 + clickCount * 0.15));
}
}
}
} else if (backgroundMouseMode == MOUSE_MODE_ZOOM
&& button != 3 && !isPopupTrigger
&& !usingDistanceTool && !modifyingPixels) {
if (myMode != MOUSE_MODE_MAPAREA) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
map.zoom(x, y, (1 - clickCount * 0.15));
} else {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea.isVisible() && mapArea.getNumLayers() > 0) {
XYPoint point = getMapXYCoordinates(e.getX(), e.getY(), mapArea);
mapArea.naturalZoom(point.x, point.y, (1 - clickCount * 0.15));
} else {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
map.zoom(x, y, (1 - clickCount * 0.15));
}
}
}
} else if (clickCount == 1 && modifyingPixels && myMode != MOUSE_MODE_CARTO_ELEMENT
&& button != 3 && !isPopupTrigger) {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x, viewAreaULX, viewAreaLRX) || !isBetween(y, viewAreaULY, viewAreaLRY)) {
return;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
modifyPixelsY = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
modifyPixelsX = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
GridCell point = mapArea.getRowAndColumn(modifyPixelsX, modifyPixelsY);
modifyPixelsY = mapArea.getYCoordinateFromRow(point.row);
modifyPixelsX = mapArea.getXCoordinateFromColumn(point.col);
//mapArea.get
if (point.row >= 0) {
host.refreshMap(false);
RasterLayerInfo rli = (RasterLayerInfo) mapArea.getActiveLayer();
String fileName = new File(rli.getHeaderFile()).getName();
ModifyPixel mp = new ModifyPixel((Frame) findWindow(this), true, point, fileName);
if (mp.wasSuccessful()) {
point = mp.getValue();
rli.setDataValue(point.row, point.col, point.z);
rli.update();
host.refreshMap(false);
//mapinfo.setRowAndColumn(mp.getValue());
}
} else {
modifyPixelsX = -1;
modifyPixelsY = -1;
host.refreshMap(false);
}
}
}
} else if (clickCount == 1 && usingDistanceTool && button != 3 && !isPopupTrigger) {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (map.getActiveMapAreaElementNumber() != mapArea.getElementNumber()) {
return;
}
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x, viewAreaULX, viewAreaLRX) || !isBetween(y, viewAreaULY, viewAreaLRY)) {
return;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapY = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
mapX = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
distPoints.add(new XYPoint(mapX, mapY));
updateStatus(e, (MapArea) map.getCartographicElement(whichCartoElement));
host.refreshMap(true);
}
}
} else if (clickCount == 1 && (myMode == MOUSE_MODE_CARTO_ELEMENT
|| (myMode == MOUSE_MODE_MAPAREA && backgroundMouseMode != MOUSE_MODE_FEATURE_SELECT))
&& button != 3 && !isPopupTrigger) {
boolean isSelected = map.getCartographicElement(whichCartoElement).isSelected();
if (!isSelected) {
if (!e.isShiftDown()) {
map.deslectAllCartographicElements();
}
WhiteboxGui wb = (WhiteboxGui) host;
wb.setCartoElementToolbarVisibility(true);
map.getCartographicElement(whichCartoElement).setSelected(true);
this.setCursor(panCursor);
panning = true;
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
map.setActiveMapAreaByElementNum(map.getCartographicElement(whichCartoElement).getElementNumber());
host.refreshMap(true);
}
} else if (myMode == MOUSE_MODE_CARTO_ELEMENT) {
map.deslectAllCartographicElements();
//map.getCartographicElement(whichCartoElement).setSelected(false);
this.setCursor(selectCursor);
panning = false;
} else {
map.deslectAllCartographicElements();
panning = false;
switch (backgroundMouseMode) {
case MOUSE_MODE_ZOOM:
this.setCursor(zoomCursor);
break;
case MOUSE_MODE_PAN:
this.setCursor(panCursor);
panning = true;
break;
case MOUSE_MODE_SELECT:
this.setCursor(selectCursor);
break;
case MOUSE_MODE_FEATURE_SELECT:
this.setCursor(selectFeatureCursor);
break;
}
}
if (map.howManyElementsAreSelected() == 0) {
WhiteboxGui wb = (WhiteboxGui) host;
if (wb.isHideAlignToolbar()) {
wb.setCartoElementToolbarVisibility(false);
}
}
this.repaint();
} else if (clickCount == 1 && (myMode == MOUSE_MODE_MAPAREA
&& backgroundMouseMode != MOUSE_MODE_FEATURE_SELECT)
&& button != 3 && !isPopupTrigger) {
map.deslectAllCartographicElements();
this.repaint();
} else if (clickCount == 1 && backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT
&& button != 3 && !isPopupTrigger && !digitizingNewFeature) {
if (myMode == MOUSE_MODE_MAPAREA) { //map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea != null) {
mapArea.selectVectorFeatures(mapX, mapY);
updateStatus(e, mapArea);
}
}
} else if (clickCount == 2 && usingDistanceTool) {
if (usingDistanceTool) {
distPoints.clear();
}
} else if ((button == 3 || isPopupTrigger)
&& (myMode == MOUSE_MODE_CARTO_ELEMENT
|| myMode == MOUSE_MODE_MAPAREA) && clickCount == 1) {
CartographicElement ce = map.getCartographicElement(whichCartoElement);
popupMenu = new JPopupMenu();
popupMenu.setOpaque(true);
popupMenu.setLightWeightPopupEnabled(true);
if (ce instanceof MapTitle) {
popupMenu.add(new whitebox.ui.carto_properties.MapTitlePropertyGrid((MapTitle) ce, host));
} else if (ce instanceof MapArea) {
popupMenu.add(new whitebox.ui.carto_properties.MapAreaPropertyGrid((MapArea) ce, host));
} else if (ce instanceof MapTextArea) {
popupMenu.add(new whitebox.ui.carto_properties.MapTextAreaPropertyGrid((MapTextArea) ce, host));
} else if (ce instanceof NorthArrow) {
popupMenu.add(new whitebox.ui.carto_properties.NorthArrowPropertyGrid((NorthArrow) ce, host));
} else if (ce instanceof MapScale) {
popupMenu.add(new whitebox.ui.carto_properties.ScalePropertyGrid((MapScale) ce, host));
} else if (ce instanceof Neatline) {
popupMenu.add(new whitebox.ui.carto_properties.NeatlinePropertyGrid((Neatline) ce, host));
} else if (ce instanceof Legend) {
popupMenu.add(new whitebox.ui.carto_properties.LegendPropertyGrid((Legend) ce, host));
} else if (ce instanceof MapImage) {
popupMenu.add(new whitebox.ui.carto_properties.MapImagePropertyGrid((MapImage) ce, host));
}
popupMenu.setPreferredSize(new Dimension(300, popupMenu.getPreferredSize().height));
popupMenu.show(e.getComponent(),
e.getX(), e.getY());
} else {
map.deslectAllCartographicElements();
WhiteboxGui wb = (WhiteboxGui) host;
if (wb.isHideAlignToolbar()) {
wb.setCartoElementToolbarVisibility(false);
}
}
this.requestFocus();
}
double startX;
double startY;
double endX;
double endY;
int startCol;
int startRow;
int endCol;
int endRow;
boolean mouseDragged = false;
double mapX, mapY;
@Override
public void mousePressed(MouseEvent me) {
try {
// see if the middle button is pressed
if (SwingUtilities.isMiddleMouseButton(me)) {
System.out.println("I'm here!");
}
startCol = (int) ((me.getX() - pageLeft) / scale);
startRow = (int) ((me.getY() - pageTop) / scale);
if (myMode == MOUSE_MODE_MAPAREA) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((me.getX() - pageLeft) / scale);
int y = (int) ((me.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x, viewAreaULX, viewAreaLRX) || !isBetween(y, viewAreaULY, viewAreaLRY)) {
return;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapY = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
mapX = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
if (backgroundMouseMode == MOUSE_MODE_PAN) {
this.setCursor(panClosedHandCursor);
panning = true;
}
}
}
this.requestFocus();
} catch (Exception e) {
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (mouseDragged && backgroundMouseMode == MOUSE_MODE_SELECT
&& !panning && myMode != MOUSE_MODE_RESIZE) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
BoundingBox boxExtent = map.getPageExtent();
// it hasn't yet been initialized
boxExtent.setMinX(Math.min(x, startCol));
boxExtent.setMinY(Math.min(y, startRow));
boxExtent.setMaxX(Math.max(x, startCol));
boxExtent.setMaxY(Math.max(y, startRow));
for (CartographicElement ce : map.getCartographicElementList()) {
ce.setSelected(false);
int ulX = ce.getUpperLeftX();
int ulY = ce.getUpperLeftY();
int lrX = ce.getLowerRightX();
int lrY = ce.getLowerRightY();
BoundingBox elementExtent = new BoundingBox((double) ulX,
(double) ulY, (double) lrX, (double) lrY);
if (boxExtent.entirelyContains(elementExtent)) {
ce.setSelected(true);
}
}
} else if (mouseDragged && (myMode == MOUSE_MODE_ZOOM
|| myMode == MOUSE_MODE_CARTO_ELEMENT)
&& !usingDistanceTool
&& (myMode != MOUSE_MODE_RESIZE)) {
// if (mouseDragged && backgroundMouseMode == MOUSE_MODE_ZOOM
// && !usingDistanceTool
// && (myMode != MOUSE_MODE_RESIZE)) {
boolean zoomToBox = true;
if (myMode == MOUSE_MODE_CARTO_ELEMENT) {
CartographicElement ce = map.getCartographicElement(whichCartoElement);
if (ce.isSelected()) {
zoomToBox = false;
}
}
if (zoomToBox) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
BoundingBox pageExtent = map.getPageExtent();
pageExtent.setMinX(Math.min(x, startCol));
pageExtent.setMinY(Math.min(y, startRow));
pageExtent.setMaxX(Math.max(x, startCol));
pageExtent.setMaxY(Math.max(y, startRow));
map.setPageExtent(pageExtent);
}
} else if (mouseDragged && (myMode == MOUSE_MODE_RESIZE)) {
CartographicElement ce = map.getCartographicElement(whichCartoElement);
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
ce.resize(x, y, myResizeMode);
} else if (mouseDragged && myMode == MOUSE_MODE_MAPAREA) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()
&& !mapArea.isSelected()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double mapYEnd = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
double mapXEnd = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
if (backgroundMouseMode == MOUSE_MODE_FEATURE_SELECT) {
BoundingBox bb = new BoundingBox(Math.min(mapX, mapXEnd),
Math.min(mapY, mapYEnd),
Math.max(mapX, mapXEnd),
Math.max(mapY, mapYEnd));
mapArea.selectVectorFeaturesByBox(bb);
} else if (backgroundMouseMode == MOUSE_MODE_ZOOM) {
BoundingBox bb = new BoundingBox(Math.min(mapX, mapXEnd),
Math.min(mapY, mapYEnd),
Math.max(mapX, mapXEnd),
Math.max(mapY, mapYEnd));
mapArea.setCurrentExtent(bb);
} else if (backgroundMouseMode == MOUSE_MODE_PAN) {
double deltaX = mapX - mapXEnd;
double deltaY = mapY - mapYEnd;
BoundingBox bb = new BoundingBox(currentExtent.getMinX() + deltaX,
currentExtent.getMinY() + deltaY,
currentExtent.getMaxX() + deltaX,
currentExtent.getMaxY() + deltaY);
mapArea.setCurrentExtent(bb);
this.setCursor(panCursor);
panning = true;
}
}
}
mouseDragged = false;
this.repaint();
}
@Override
public void mouseEntered(MouseEvent me) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void mouseExited(MouseEvent me) {
//throw new UnsupportedOperationException("Not supported yet.");
}
private void calculateMapXY(MouseEvent e, MapArea mapArea) {
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
mapY = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
mapX = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
}
}
//private String xyUnits = null;
private void updateStatus(MouseEvent e, MapArea mapArea) {
if (status == null) {
return;
}
BoundingBox currentExtent = mapArea.getCurrentMapExtent();
if (mapArea.isVisible() && currentExtent.getMinY() != currentExtent.getMaxY()) {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
int referenceMarkSize = mapArea.getReferenceMarksSize();
int viewAreaULX = mapArea.getUpperLeftX() + referenceMarkSize;
int viewAreaULY = mapArea.getUpperLeftY() + referenceMarkSize;
int viewAreaLRX = mapArea.getLowerRightX() - referenceMarkSize;
int viewAreaLRY = mapArea.getLowerRightY() - referenceMarkSize;
double viewAreaWidth = viewAreaLRX - viewAreaULX;
double viewAreaHeight = viewAreaLRY - viewAreaULY;
if (mapArea.isSizeMaximizedToScreenSize() && !printingMap) {
viewAreaULX = (int) ((-pageLeft / scale) + referenceMarkSize);
viewAreaULY = (int) ((-pageTop / scale) + referenceMarkSize);
viewAreaLRX = viewAreaULX + (int) (w / scale - 2 * referenceMarkSize);
viewAreaLRY = viewAreaULY + (int) (h / scale - 2 * referenceMarkSize);
viewAreaWidth = viewAreaLRX - viewAreaULX;
viewAreaHeight = viewAreaLRY - viewAreaULY;
}
if (!isBetween(x, viewAreaULX, viewAreaLRX) || !isBetween(y, viewAreaULY, viewAreaLRY)) {
status.setMessage("");
return;
}
double xRange = Math.abs(currentExtent.getMaxX() - currentExtent.getMinX());
double yRange = Math.abs(currentExtent.getMaxY() - currentExtent.getMinY());
double mapY2 = currentExtent.getMinY() + (viewAreaLRY - y) / viewAreaHeight * yRange;
double mapX2 = currentExtent.getMinX() + (x - viewAreaULX) / viewAreaWidth * xRange;
DecimalFormat df = new DecimalFormat("###,###,###.0");
String xStr = df.format(mapX2);
String yStr = df.format(mapY2);
if (usingDistanceTool && distPoints.size() > 1) {
calculatedDistance = 0;
double mapX3, mapY3;
for (int i = 1; i < distPoints.size(); i++) {
mapX2 = distPoints.get(i).x;
mapY2 = distPoints.get(i).y;
mapX3 = distPoints.get(i - 1).x;
mapY3 = distPoints.get(i - 1).y;
calculatedDistance += Math.sqrt((mapX3 - mapX2) * (mapX3 - mapX2)
+ (mapY3 - mapY2) * (mapY3 - mapY2));
}
//calculatedDistance = Math.sqrt(calculatedDistance);
xStr = "Distance: " + df.format(calculatedDistance);
if (!mapArea.getXYUnits().toLowerCase().equals("not specified")) {
xStr += mapArea.getXYUnits();
}
if (distPoints.size() > 2) {
xStr += " Enclosed Area: " + df.format(calculateArea()) + " sqr. units";
}
status.setMessage(xStr);
} else if (!mapArea.isActiveLayerAVector()) {
GridCell point = mapArea.getRowAndColumn(mapX2, mapY2);
if (point.row >= 0) {
//double noDataValue = point.noDataValue;
DecimalFormat dfZ = new DecimalFormat("###,###,###.####");
String zStr;
if (!point.isValueNoData() && !Double.isNaN(point.z)) {
zStr = dfZ.format(point.z);
} else if (Double.isNaN(point.z)) {
zStr = "Not Available";
} else {
zStr = "NoData";
}
if (!point.isRGB || point.isValueNoData()) {
status.setMessage("E: " + xStr + " N: " + yStr
+ " Row: " + (int) (point.row) + " Col: "
+ (int) (point.col) + " Z: " + zStr);
} else {
String r = String.valueOf((int) point.z & 0xFF);
String g = String.valueOf(((int) point.z >> 8) & 0xFF);
String b = String.valueOf(((int) point.z >> 16) & 0xFF);
String a = String.valueOf(((int) point.z >> 24) & 0xFF);
if (a.equals("255")) {
status.setMessage("E: " + xStr + " N: " + yStr
+ " Row: " + (int) (point.row) + " Col: "
+ (int) (point.col) + " R: " + r + " G: " + g
+ " B: " + b);
} else {
status.setMessage("E: " + xStr + " N: " + yStr
+ " Row: " + (int) (point.row) + " Col: "
+ (int) (point.col) + " R: " + r + " G: " + g
+ " B: " + b + " A: " + a);
}
}
} else if (!Double.isNaN(x) && !Double.isNaN(y)) {
status.setMessage("E: " + xStr + " N: " + yStr);
}
} else {
// int selectedFeature = mapArea.getSelectedFeatureFromActiveVector();
// if (selectedFeature >= 0) {
// status.setMessage("E: " + xStr + " N: " + yStr + " Selected Feature: " + selectedFeature);
// } else {
status.setMessage("E: " + xStr + " N: " + yStr);
// }
}
}
}
public void removeLastNodeInFeature() {
if (distPoints.size() > 0) {
distPoints.remove(distPoints.size() - 1);
} else {
host.showFeedback("This tool removes the last digitized node in a feature that is being actively digitized.\n"
+ "It does not appear that there is a feature that is being digitized currently.");
}
}
private static Window findWindow(Component c) {
if (c instanceof Window) {
return (Window) c;
} else {
return findWindow(c.getParent());
}
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
double notches = e.getWheelRotation() * scrollZoomMultiplier;
if (myMode == MOUSE_MODE_MAPAREA) {
if (map.getCartographicElement(whichCartoElement) instanceof MapArea) {
MapArea mapArea = (MapArea) map.getCartographicElement(whichCartoElement);
if (mapArea.isVisible() && mapArea.getNumLayers() > 0) {
XYPoint point = getMapXYCoordinates(e.getX(), e.getY(), mapArea);
mapArea.naturalZoom(point.x, point.y, (1 + notches * 0.15));
host.refreshMap(false);
} else {
int x = (int) ((e.getX() - pageLeft) / scale);
int y = (int) ((e.getY() - pageTop) / scale);
map.zoom(x, y, (1 + notches * 0.1));
}
}
}
}
double scrollZoomMultiplier = 1.0d;
public void setScrollZoomDirection(ScrollZoomDirection direction) {
if (direction == ScrollZoomDirection.REVERSE) {
scrollZoomMultiplier = -1.0d;
} else {
scrollZoomMultiplier = 1.0d;
}
}
public enum ScrollZoomDirection {
NORMAL, REVERSE
}
}