com.vividsolutions.jtstest.testbuilder.ui.render.GridRenderer Maven / Gradle / Ivy
The newest version!
/*
* The JTS Topology Suite is a collection of Java classes that
* implement the fundamental operations required to validate a given
* geo-spatial data set to a known topological specification.
*
* Copyright (C) 2001 Vivid Solutions
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jtstest.testbuilder.ui.render;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.*;
import java.text.NumberFormat;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.math.MathUtil;
import com.vividsolutions.jtstest.testbuilder.AppConstants;
import com.vividsolutions.jtstest.testbuilder.Viewport;
import com.vividsolutions.jtstest.testbuilder.model.DrawingGrid;
import com.vividsolutions.jtstest.testbuilder.ui.ColorUtil;
public class GridRenderer {
private static final int MIN_VIEW_GRID_SIZE = 5;
private Viewport viewport;
private DrawingGrid grid;
private boolean isEnabled = true;
private NumberFormat gridSizeFormat;
public GridRenderer(Viewport viewport, DrawingGrid grid) {
this.viewport = viewport;
this.grid = grid;
gridSizeFormat = NumberFormat.getInstance();
gridSizeFormat.setGroupingUsed(false);
}
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
public void paint(Graphics2D g) {
if (! isEnabled)
return;
try {
drawAxes(g);
drawLinedGrid(g);
// drawDottedGrid(g);
drawGridSizeLabel(g, viewport.gridMagnitudeModel());
}
// guards against crazy data causing problems
catch (ArithmeticException ex) {
return;
}
}
private boolean isResolvable() {
Point2D p1 = viewport.toModel(new Point(0, 0));
Point2D p2 = viewport.toModel(new Point(MIN_VIEW_GRID_SIZE, 0));
return grid.isResolvable(p1, p2);
}
private static final Coordinate MODEL_ORIGIN = new Coordinate(0, 0);
private void drawAxes(Graphics2D g) {
// draw XY axes
g.setColor(AppConstants.AXIS_CLR);
g.setStroke(new BasicStroke(AppConstants.AXIS_WIDTH));
Point2D viewOrigin = viewport.toView(MODEL_ORIGIN);
double vOriginX = viewOrigin.getX();
double vOriginY = viewOrigin.getY();
if (vOriginX >= 0.0 && vOriginX <= viewport.getWidthInView()) {
g.draw(new Line2D.Double(vOriginX, 0, vOriginX, viewport
.getHeightInView()));
}
if (vOriginY >= 0.0 && vOriginY <= viewport.getHeightInView()) {
g.draw(new Line2D.Double(0, vOriginY, viewport.getWidthInView(), vOriginY));
}
}
private int maxVisibleMagnitude()
{
double visibleExtentModel = viewport.getModelEnv().maxExtent();
// if input is bogus then just return something reasonable
if (visibleExtentModel <= 0.0)
return 1;
double log10 = MathUtil.log10(visibleExtentModel);
return (int) log10;
}
/*
private static final int MIN_GRID_PIXELS = 2;
private int gridMagnitudeModel()
{
double pixelSizeModel = viewport.toModel(1);
double pixelSizeModelLog = Math.log10(pixelSizeModel);
int gridMag = (int) Math.ceil(pixelSizeModelLog);
// Check if grid size is too small and if so increase it one magnitude
double gridSizeModel = Math.pow(10, gridMag);
double gridSizeView = viewport.toView(gridSizeModel);
// System.out.println("\ncand gridSizeView= " + gridSizeView);
if (gridSizeView <= MIN_GRID_PIXELS )
gridMag += 1;
// System.out.println("pixelSize= " + pixelSize + " pixelLog10= " + pixelSizeLog);
return gridMag;
}
*/
private static final int GRID_MAJOR_LINE_CLR = 220;
private static final int GRID_MINOR_LINE_CLR = 240;
private void drawLinedGrid(Graphics2D g)
{
int gridMagModel = viewport.gridMagnitudeModel();
double gridSizeModel = Math.pow(10, gridMagModel);
double gridSizeView = viewport.toView(gridSizeModel);
Envelope modelEnv = viewport.getModelEnv();
//System.out.println("gridSizeView= " + gridSizeView);
/**
* Major Grid (10x)
*/
double gridSize10Model = 10 * gridSizeModel;
PrecisionModel pmGrid10 = new PrecisionModel(1.0/gridSize10Model);
double basex10Model = pmGrid10.makePrecise(modelEnv.getMinX());
double basey10Model = pmGrid10.makePrecise(modelEnv.getMinY());
Point2D basePt10View = viewport.toView(new Coordinate(basex10Model, basey10Model));
double gridSize10View = viewport.toView(gridSize10Model);
/**
* Major-Major Grid (100x)
*/
double gridSize100Model = 100 * gridSizeModel;
PrecisionModel pmGrid100 = new PrecisionModel(1.0/gridSize100Model);
double basex100Model = pmGrid100.makePrecise(modelEnv.getMinX());
double basey100Model = pmGrid100.makePrecise(modelEnv.getMinY());
Point2D basePt100View = viewport.toView(new Coordinate(basex100Model, basey100Model));
double gridSize100View = viewport.toView(gridSize100Model);
/**
* Minor Grid
* Only display if dots are sparse enough
*/
if (gridSizeView >= 4) {
PrecisionModel pmGrid = new PrecisionModel(1.0/gridSizeModel);
double basexModel = pmGrid.makePrecise(modelEnv.getMinX());
double baseyModel = pmGrid.makePrecise(modelEnv.getMinY());
Point2D basePtView = viewport.toView(new Coordinate(basexModel, baseyModel));
g.setStroke(new BasicStroke());
g.setColor(ColorUtil.gray(GRID_MINOR_LINE_CLR));
drawGridLines(g, basePtView.getX(), basePtView.getY(), gridSizeView);
}
g.setStroke(new BasicStroke());
g.setColor(ColorUtil.gray(GRID_MAJOR_LINE_CLR));
drawGridLines(g, basePt10View.getX(), basePt10View.getY(), gridSize10View);
/**
* Major-Major Grid (100x)
*/
Stroke strokeMajor2 = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {4, 6}, // Dash pattern
0); // Dash phase
g.setStroke(strokeMajor2);
g.setColor(ColorUtil.gray(100));
drawGridLines(g, basePt100View.getX(), basePt100View.getY(), gridSize100View);
/**
* Semi-Major dots (10x + 5)
*/
float dash10Offset = ((int) basePt10View.getY()) % (int) gridSize10View;
dash10Offset = (float) (gridSize10View - dash10Offset + gridSize10View/2);
g.setColor(Color.BLACK);
Stroke strokeMid = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {0, (float) gridSize10View/2}, // Dash pattern
dash10Offset); // Dash phase
g.setStroke(strokeMid);
drawGridLines(g,
basePt10View.getX() - gridSize10View/2,
0,
gridSize10View/2);
}
private void drawDottedGrid(Graphics2D g)
{
int gridMagModel = viewport.gridMagnitudeModel();
double gridSizeModel = Math.pow(10, gridMagModel);
double gridSizeView = viewport.toView(gridSizeModel);
//System.out.println("gridSizeView= " + gridSizeView);
/**
* Major Grid (10x)
*/
double gridSize10Model = 10 * gridSizeModel;
PrecisionModel pmGrid10 = new PrecisionModel(1.0/gridSize10Model);
Envelope modelEnv = viewport.getModelEnv();
double basex10Model = pmGrid10.makePrecise(modelEnv.getMinX());
double basey10Model = pmGrid10.makePrecise(modelEnv.getMinY());
Point2D basePt10View = viewport.toView(new Coordinate(basex10Model, basey10Model));
double gridSize10View = viewport.toView(gridSize10Model);
g.setStroke(new BasicStroke());
g.setColor(AppConstants.GRID_MAJOR_CLR);
drawGridLines(g, basePt10View.getX(), basePt10View.getY(), gridSize10View);
/**
* Major-Major Grid (100x)
*/
double gridSize100Model = 100 * gridSizeModel;
PrecisionModel pmGrid100 = new PrecisionModel(1.0/gridSize100Model);
double basex100Model = pmGrid100.makePrecise(modelEnv.getMinX());
double basey100Model = pmGrid100.makePrecise(modelEnv.getMinY());
Point2D basePt100View = viewport.toView(new Coordinate(basex100Model, basey100Model));
double gridSize100View = viewport.toView(gridSize100Model);
Stroke strokeMajor2 = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {4, 6}, // Dash pattern
0); // Dash phase
g.setStroke(strokeMajor2);
g.setColor(AppConstants.GRID_MINOR_CLR);
drawGridLines(g, basePt100View.getX(), basePt100View.getY(), gridSize100View);
/**
* Semi-Major grid (10x + 5)
*/
/*
// disabled for now - a bit too many lines
g.setColor(AppConstants.GRID_MAJOR_CLR);
Stroke strokeMid = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {4, 6}, // Dash pattern
0); // Dash phase
g.setStroke(strokeMid);
drawGridLines(g,
basePt10View.getX() - gridSize10View/2,
basePt10View.getY() + gridSize10View/2,
gridSize10View);
*/
float dash10Offset = ((int) basePt10View.getY()) % (int) gridSize10View;
dash10Offset = (float) (gridSize10View - dash10Offset + gridSize10View/2);
/**
* Minor Grid
* Only display if dots are sparse enough
*/
if (gridSizeView >= 4) {
PrecisionModel pmGrid = new PrecisionModel(1.0/gridSizeModel);
double basexModel = pmGrid.makePrecise(modelEnv.getMinX());
double baseyModel = pmGrid.makePrecise(modelEnv.getMinY());
Point2D basePtView = viewport.toView(new Coordinate(basexModel, baseyModel));
float dashOffset = ((int) basePtView.getY()) % (int) gridSizeView;
dashOffset = (float) gridSizeView - dashOffset;
//System.out.println("dashOffset= " + dashOffset);
Stroke strokeMinor = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {0, (float) gridSizeView }, // Dash pattern
dashOffset); // Dash phase
g.setStroke(strokeMinor);
g.setColor(AppConstants.GRID_MINOR_CLR);
drawGridLines(g, basePtView.getX(), 0, gridSizeView);
}
/**
* Semi-Major dots (10x + 5)
*/
g.setColor(Color.BLACK);
Stroke strokeMid = new BasicStroke(1, // Width of stroke
BasicStroke.CAP_SQUARE, // End cap style
BasicStroke.JOIN_MITER, // Join style
10, // Miter limit
new float[] {0, (float) gridSize10View/2}, // Dash pattern
dash10Offset); // Dash phase
g.setStroke(strokeMid);
drawGridLines(g,
basePt10View.getX() - gridSize10View/2,
0,
gridSize10View/2);
}
private void drawGridSizeLabel(Graphics2D g, int gridMagModel)
{
/**
* Draw grid size text
*/
g.setColor(Color.BLUE);
int viewHeight = (int) viewport.getHeightInView();
int viewWidth = (int) viewport.getWidthInView();
if (Math.abs(gridMagModel) <= 3) {
// display as number
double gridSize = Math.pow(10, gridMagModel);
g.drawString(gridSizeFormat.format(gridSize), 2, viewHeight - 1);
}
else {
// display as exponent
g.drawString("10", 2, viewHeight - 1);
g.drawString(gridMagModel + "", 20, viewHeight - 8);
}
}
private void drawFixedGrid(Graphics2D g) {
// draw grid major lines
double gridSize = grid.getGridSize();
double gridSizeInView = gridSize * viewport.getScale();
//System.out.println(gridSizeInView);
Point2D ptLL = viewport.getLowerLeftCornerInModel();
double minx = grid.snapToMajorGrid(ptLL).getX();
double miny = grid.snapToMajorGrid(ptLL).getY();
Point2D minPtView = viewport.toView(new Coordinate(minx, miny));
g.setColor(AppConstants.GRID_MAJOR_CLR);
drawGridLines(g, minPtView.getX(), minPtView.getY(), gridSizeInView);
}
private void drawGridLines(Graphics2D g, double minx, double maxy, double gridSizeInView)
{
double viewWidth = viewport.getWidthInView();
double viewHeight = viewport.getHeightInView();
//Point2D minPtView = viewport.toView(new Coordinate(minx, miny));
/**
* Can't draw right to edges of panel, because
* Swing inset border occupies that space.
*/
// draw vertical grid lines
for (double x = minx; x < viewWidth; x += gridSizeInView) {
// don't draw grid line right next to panel border
if (x < 2) continue;
g.draw(new Line2D.Double(x, 0, x, viewHeight - 0));
}
// skip drawing horizontal grid lines if maxy is invalid
if (maxy <= 0) return;
for (double y = maxy; y > 0; y -= gridSizeInView) {
// don't draw grid line right next to panel border
if (y < 2) continue;
g.draw(new Line2D.Double(0, y, viewWidth - 0, y));
}
}
private static final int TICK_LEN = 5;
private static final int SCALE_TEXT_OFFSET_X = 40;
private static final int SCALE_TEXT_OFFSET_Y = 2;
/**
* Not very pleasing
*
* @param g
*/
private void drawScaleMarks(Graphics2D g)
{
Envelope viewEnv = viewport.getViewEnv();
int viewMag = maxVisibleMagnitude();
double gridIncModel = Math.pow(10.0, viewMag);
double gridIncView = viewport.toView(gridIncModel);
// ensure at least 3 ticks are shown
if (3 * gridIncView > viewEnv.maxExtent()) {
gridIncView /= 10.0;
viewMag -= 1;
}
g.setColor(Color.BLACK);
// draw X axis ticks
double tickX = viewport.getWidthInView() - gridIncView;
int viewHeight = (int) viewport.getHeightInView();
while (tickX > 0) {
g.draw(new Line2D.Double(tickX, viewHeight + 1, tickX, viewHeight - TICK_LEN));
tickX -= gridIncView;
}
// draw Y axis ticks
double tickY = viewport.getHeightInView() - gridIncView;
int viewWidth = (int) viewport.getWidthInView();
while (tickY > 0) {
g.draw(new Line2D.Double(viewWidth + 1, tickY, viewWidth - TICK_LEN, tickY));
tickY -= gridIncView;
}
// draw Scale magnitude
g.drawString("10", viewWidth - 35, viewHeight - 1);
g.drawString(viewMag+"", viewWidth - 20, viewHeight - 8);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy