package com.revolsys.swing.map.old; import com.revolsys.geometry.cs.CoordinateSystem; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.swing.map.ComponentViewport2D; public class FactorZoomMode implements ZoomMode { /** The multiplication Factor to zoom by. */ private final double factor; public FactorZoomMode(final double factor) { this.factor = factor; } /** * Get the best bounding box matching the zoom mode policy * * @param viewport The viewport. * @param boundingBox The bounding box. * @return The bounding box. */ @Override public BoundingBox getBoundingBox(final ComponentViewport2D viewport, final BoundingBox boundingBox) { final GeometryFactory geometryFactory = viewport.getGeometryFactory(); final CoordinateSystem coordinateSystem = geometryFactory.getCoordinateSystem(); final GeometryFactory bboxGeometryFactory = boundingBox.getGeometryFactory(); BoundingBox newBoundingBox = boundingBox; if (bboxGeometryFactory == null) { newBoundingBox = boundingBox.convert(geometryFactory); } else { if (bboxGeometryFactory.equals(geometryFactory)) { newBoundingBox = boundingBox; } else { newBoundingBox = boundingBox.convert(geometryFactory); } final BoundingBox areaBoundingBox = coordinateSystem.getAreaBoundingBox(); newBoundingBox = boundingBox.intersection(areaBoundingBox); } final double viewAspectRatio = viewport.getViewAspectRatio(); final double modelAspectRatio = newBoundingBox.getAspectRatio(); if (viewAspectRatio != modelAspectRatio) { final double width = newBoundingBox.getWidth(); final double height = newBoundingBox.getHeight(); if (viewAspectRatio > modelAspectRatio) { final double newWidth = height * viewAspectRatio; final double deltaX = (newWidth - width) / 2; newBoundingBox = newBoundingBox.expand(deltaX, 0); } else if (viewAspectRatio < modelAspectRatio) { final double newHeight = width / viewAspectRatio; final double deltaY = (newHeight - height) / 2; newBoundingBox = newBoundingBox.expand(0, deltaY); } } return newBoundingBox; } /** * Zoom the map so that the specified bounding box is visible. * * @param viewport The viewport. * @param boundingBox The bounding box. */ @Override public void zoom(final ComponentViewport2D viewport, final BoundingBox boundingBox) { final BoundingBox newBoundingBox = getBoundingBox(viewport, boundingBox); viewport.setBoundingBox(newBoundingBox); } /** * Zoom the map to include the bounding box specified by the model coordinate * pair. * * @param viewport The viewport. * @param x1 The first x coordinate. * @param y1 The first y coordinate. * @param x2 The second x coordinate. * @param y2 The second y coordinate. */ @Override public void zoom(final ComponentViewport2D viewport, final double x1, final double y1, final double x2, final double y2) { final double viewWidth = viewport.getViewWidthPixels(); final double viewHeight = viewport.getViewHeightPixels(); final double xc1 = Math.max(Math.min(x1, viewWidth - 1), 0); final double yc1 = Math.max(Math.min(y1, viewHeight - 1), 0); final double xc2 = Math.max(Math.min(x2, viewWidth - 1), 0); final double yc2 = Math.max(Math.min(y2, viewHeight - 1), 0); final BoundingBox boundingBox = viewport.getBoundingBox(xc1, yc1, xc2, yc2); viewport.setBoundingBox(boundingBox); } /** * Zoom the map in by the multiplication at the view coordinate, re-centring * the map at the model coordinate represented by the view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. * @param factor The multiplication factor to zoom by. */ private void zoomAndRecentre(final ComponentViewport2D viewport, final double x, final double y, final double factor) { final double[] ordinates = viewport.toModelCoordinates(x, y); final double mapX = ordinates[0]; final double mapY = ordinates[1]; final double scale = Math.min(viewport.getScale() * factor, viewport.getMaxScale()); final double width = viewport.getModelWidth(scale); final double height = viewport.getModelHeight(scale); final GeometryFactory geometryFactory = viewport.getGeometryFactory(); final double x1 = mapX - width / 2; final double y1 = mapY - height / 2; final double x2 = x1 + width; final double y2 = y1 + height; final BoundingBox boundingBox = geometryFactory.newBoundingBox(x1, y1, x2, y2); viewport.setBoundingBox(boundingBox); } /** * Zoom the map in one level at the view coordinate, with the model coordinate * being maintained at the same view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. */ @Override public void zoomIn(final ComponentViewport2D viewport, final double x, final double y) { zoomProportional(viewport, x, y, 1 / this.factor); } /** * Zoom the map in one level at the view coordinate, re-centring the map at * the model coordinate represented by the view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. */ @Override public void zoomInAndRecentre(final ComponentViewport2D viewport, final double x, final double y) { zoomAndRecentre(viewport, x, y, 1 / this.factor); } /** * Zoom the map out one level at the view coordinate, with the model * coordinate being maintained at the same view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. */ @Override public void zoomOut(final ComponentViewport2D viewport, final double x, final double y) { zoomProportional(viewport, x, y, this.factor); } /** * Zoom the map in one level at the view coordinate, re-centring the map at * the model coordinate represented by the view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. */ @Override public void zoomOutAndRecentre(final ComponentViewport2D viewport, final double x, final double y) { zoomAndRecentre(viewport, x, y, this.factor); } /** * Zoom the map in by the multiplication factor at the view coordinate, with * the model coordinate being maintained at the same view coordinate. * * @param viewport The viewport to zoom. * @param x The x coordinate. * @param y The y coordinate. * @param factor The multiplication factor to zoom by. */ private void zoomProportional(final ComponentViewport2D viewport, final double x, final double y, final double factor) { final double[] ordinates = viewport.toModelCoordinates(x, y); final double mapX = ordinates[0]; final double mapY = ordinates[1]; final double scale = Math.min(viewport.getScale() * factor, viewport.getMaxScale()); final double width = viewport.getModelWidth(scale); final double height = viewport.getModelHeight(scale); final double viewWidth = viewport.getViewWidthPixels(); final double xProportion = x / viewWidth; final double viewHeight = viewport.getViewHeightPixels(); final double yProportion = (viewHeight - y) / viewHeight; final GeometryFactory geometryFactory = viewport.getGeometryFactory(); final double x1 = mapX - width * xProportion; final double y1 = mapY - height * yProportion; final double x2 = x1 + width; final double y2 = y1 + height; final BoundingBox boundingBox = geometryFactory.newBoundingBox(x1, y1, x2, y2); viewport.setBoundingBox(boundingBox); } }