/*
* GPLv2 or 3, Copyright (c) 2010 Andrzej Zaborowski
*
* Implements a fake MapView that we can pass to WMSLayer's .paint,
* this will give us two things:
* # We'll be able to tell WMSLayer.paint() what area we want it
* to download (it ignores the "bounds" parameter) and override
* isVisible and friends as needed, and
* # We'll receive notifications from Grabber when we need to
* repaint (and call WMSLayer's .paint again) because the
* Grabber downloaded some or all of the tiles that we asked
* WMSLayer for and WMSLayer created the Grabber passing it
* our MapView. Otherwise we wouldn't be able to tell when
* this happened and could only guess.
*/
package wmsturbochallenge;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import org.openstreetmap.josm.data.ProjectionBounds;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.gui.MapView;
class FakeMapView extends MapView {
public ProjectionBounds view_bounds;
public MapView parent;
public Graphics2D graphics;
public BufferedImage ground_image;
public int ground_width = -1;
public int ground_height = -1;
public double scale;
public double max_east_west;
public FakeMapView(MapView parent, double scale) {
super(null, null, null); //TODO MapView constructor contains registering listeners and other code, that probably shouldn't be called in fake map view
this.parent = parent;
this.scale = scale;
ProjectionBounds parent_bounds = parent.getProjectionBounds();
max_east_west =
parent_bounds.maxEast - parent_bounds.minEast;
}
public void setProjectionBounds(ProjectionBounds bounds) {
view_bounds = bounds;
if (bounds.maxEast - bounds.minEast > max_east_west) {
max_east_west = bounds.maxEast - bounds.minEast;
/* We need to set the parent MapView's bounds (i.e.
* zoom level) to the same as ours max possible
* bounds to avoid WMSLayer thinking we're zoomed
* out more than we are or it'll pop up an annoying
* "requested area is too large" popup.
*/
EastNorth parent_center = parent.getCenter();
parent.zoomTo(new ProjectionBounds(
new EastNorth(
parent_center.east() -
max_east_west / 2,
parent_center.north()),
new EastNorth(
parent_center.east() +
max_east_west / 2,
parent_center.north())));
/* Request again because NavigatableContent adds
* a border just to be sure.
*/
ProjectionBounds new_bounds =
parent.getProjectionBounds();
max_east_west =
new_bounds.maxEast - new_bounds.minEast;
}
Point vmin = getPoint(bounds.getMin());
Point vmax = getPoint(bounds.getMax());
int w = vmax.x + 1;
int h = vmin.y + 1;
if (w <= ground_width && h <= ground_height) {
graphics.setClip(0, 0, w, h);
return;
}
if (w > ground_width)
ground_width = w;
if (h > ground_height)
ground_height = h;
ground_image = new BufferedImage(ground_width,
ground_height,
BufferedImage.TYPE_INT_RGB);
graphics = ground_image.createGraphics();
graphics.setClip(0, 0, w, h);
}
@Override
public ProjectionBounds getProjectionBounds() {
return view_bounds;
}
@Override
public Point getPoint(EastNorth p) {
double x = p.east() - view_bounds.minEast;
double y = view_bounds.maxNorth - p.north();
x /= this.scale;
y /= this.scale;
return new Point((int) x, (int) y);
}
@Override
public EastNorth getEastNorth(int x, int y) {
return new EastNorth(
view_bounds.minEast + x * this.scale,
view_bounds.minNorth - y * this.scale);
}
public boolean isVisible(int x, int y) {
return true;
}
@Override
public Graphics getGraphics() {
return graphics;
}
@Override
public void repaint() {
}
}