eu.limetri.client.mapviewer.layer.weather.painter.WeatherOverlayPainter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapviewer-weather Show documentation
Show all versions of mapviewer-weather Show documentation
MapViewer Weather layer project
/**
* Copyright (C) 2008-2012 AgroSense Foundation.
*
* AgroSense 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.
*
* There are special exceptions to the terms and conditions of the GPLv3 as it
* is applied to this software, see the FLOSS License Exception
* .
*
* AgroSense 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
* AgroSense. If not, see .
*/
package eu.limetri.client.mapviewer.layer.weather.painter;
import eu.limetri.client.mapviewer.data.Tile;
import eu.limetri.client.mapviewer.data.TileFactoryInfo;
import eu.limetri.client.mapviewer.layer.weather.tilefactory.WeatherFactory;
import eu.limetri.client.mapviewer.layer.weather.tilefactory.WeatherTileFactoryInfo;
import eu.limetri.client.mapviewer.swing.JXMapViewer;
import eu.limetri.client.mapviewer.swing.impl.OfflineTileFactorySwing;
import eu.limetri.client.mapviewer.swing.overlay.AbstractOverlayPainter;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
/**
*
* @author Frantisek Post
*/
public class WeatherOverlayPainter extends AbstractOverlayPainter {
private Image loadingImage;
OfflineTileFactorySwing tileFactory;
private TileLoadListener tileLoadListener = new TileLoadListener();
JXMapViewer mapViewer;
Graphics2D graphics;
WeatherFactory weatherFactory;
public WeatherOverlayPainter(String mapType, String title) {
TileFactoryInfo factoryInfo = new WeatherTileFactoryInfo(mapType);
tileFactory = new OfflineTileFactorySwing(factoryInfo);
loadingImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB);
weatherFactory = new WeatherFactory();
init();
setName(title);
}
private void init() {
setVisible(false);
}
@Override
public void setVisible(boolean visible) {
boolean oldVisible = isVisible();
super.setVisible(visible);
if (oldVisible && !visible && mapViewer != null) {
mapViewer.repaint();
}
}
@Override
public void paint(Graphics2D g, JXMapViewer mapviewer, int width, int height) {
if (!visible) {
return;
}
Rectangle viewportBounds = mapviewer.getViewportBounds();
if (this.mapViewer == null) {
this.mapViewer = mapviewer;
this.graphics = g;
}
Graphics2D g2 = (Graphics2D) g.create();
int rule = AlphaComposite.SRC_OVER;
Composite comp = AlphaComposite.getInstance(rule , 0.3f );
g2.setComposite(comp );
int zoom = mapviewer.getZoom();
int size = tileFactory.getTileSize(zoom);
// calculate the "visible" viewport area in tiles
int numWide = viewportBounds.width / size + 2;
int numHigh = viewportBounds.height / size + 2;
TileFactoryInfo info = tileFactory.getInfo();
int tpx = (int) Math.floor(viewportBounds.getX() / info.getTileSize(0));
int tpy = (int) Math.floor(viewportBounds.getY() / info.getTileSize(0));
// fetch the tiles from the factory and store them in the tiles cache
// attach the tileLoadListener
for (int x = 0; x <= numWide; x++) {
for (int y = 0; y <= numHigh; y++) {
int itpx = x + tpx;// topLeftTile.getX();
int itpy = y + tpy;// topLeftTile.getY();
// only proceed if the specified tile point lies within the area
// being painted
if (g2.getClipBounds().intersects(new Rectangle(itpx * size - viewportBounds.x, itpy * size - viewportBounds.y, size, size))) {
Tile tile = tileFactory.getTile(itpx, itpy, zoom);
if (!tile.isLoaded()) {
tile.addUniquePropertyChangeListener("loaded", tileLoadListener); // this is a filthy hack
}
int ox = ((itpx * tileFactory.getTileSize(zoom)) - viewportBounds.x);
int oy = ((itpy * tileFactory.getTileSize(zoom)) - viewportBounds.y);
if (tile.isLoaded()) {
g2.drawImage(tile.getImage(), ox, oy, null);
} else {
//show resized image while loading
Tile superTile = tileFactory.getTile(itpx / 2, itpy / 2, zoom + 1);
if (superTile.isLoaded()) {
int offX = (itpx % 2) * size / 2;
int offY = (itpy % 2) * size / 2;
g2.drawImage(superTile.getImage(), ox, oy, ox + size, oy + size, offX, offY, offX + size / 2, offY + size / 2, null);
}
}
}
}
}
g2.dispose();
}
public Image getLoadingImage() {
return loadingImage;
}
@Override
protected void processMapEvent(MouseEvent event) {
//noop
}
private final class TileLoadListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (visible && Tile.LOADED.equals(evt.getPropertyName()) && Boolean.TRUE.equals(evt.getNewValue()) && mapViewer != null) {
mapViewer.repaint();
}
}
}
}