All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.limetri.client.mapviewer.swing.render.DataSetWidget Maven / Gradle / Ivy

/*
 * Copyright (C) 2008-2013 LimeTri. All rights reserved.
 *
 * 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 .
 * 
 * Contributors:
 *    Timon Veenstra  - initial API and implementation and/or initial documentation
 */
package eu.limetri.client.mapviewer.swing.render;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import eu.limetri.api.geo.Geographical;
import eu.limetri.api.geo.DataRecord;
import eu.limetri.api.geo.DataSet;
import eu.limetri.client.mapviewer.api.Palette;
import eu.limetri.client.mapviewer.data.GeoPosition;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Point2D;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.coverage.grid.GridCoverage2D;
import org.netbeans.api.visual.model.ObjectState;
import org.netbeans.api.visual.widget.Scene;

/**
 *
 * @author Timon Veenstra 
 */
public class DataSetWidget  extends GeographicalWidget {

    private static final int ICON_SIZE = 20;
    private String id;
    private final Geographical geographical;
    private final Geometry envelope;
    private final GeoTranslator geoTranslator;
    private static final Logger LOGGER = Logger.getLogger(DataSetWidget.class.getCanonicalName());

    public DataSetWidget(String id, Geographical geographical, Palette palette, Geometry envelope, GeoTranslator geoTranslator, Scene scene) {
        super(geographical, palette, scene);
        this.id = id;
        this.geographical = geographical;
        this.envelope = (envelope != null)?envelope:geographical.getBoundingBox();
        this.geoTranslator = geoTranslator;
        setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE));
        setToolTipText(geographical.getTooltipText());
    }
    
    @Override
    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
        repaint();
    }
    
    @Override
    protected void paintWidget() {
        LOGGER.finest("painting GridCoverage2DWidget");
        //
        // set the preferred widget bounds based on the geometry and current state of the mapviewer
        //
        Rectangle clientArea = GeometryRenderer.getViewport(geographical.getBoundingBox(), this.envelope, getScene().getClientArea(), geoTranslator);
        LOGGER.log(Level.FINEST, "calculated client area {0}", clientArea);
        clientArea = (clientArea != null) ? clientArea : super.calculateClientArea();
        setPreferredBounds(clientArea);
        //
        // prepare the graphics and clip to the widget bounds to minimize paint effort
        //
        Graphics2D g = (Graphics2D) getGraphics().create();
        g.clip(getPreferredBounds());
        //
        // dispatch painting of the geometry to the geometry renderer
        //
        //TODO pass in envelope of the map extend, ie getScene().getClientArea()
        DataSet objectToRender = geographical.getRenderObject(getSceneEnvelope(geoTranslator)); 

        if (objectToRender == null) {
            paintBusyIcon(g);
        } else {
            DataSetRenderer renderer = new DataSetRenderer();
            renderer.paint(objectToRender, geographical.getBoundingBox(), getScene().getClientArea(), g, getPalette(), getState(), geoTranslator);
            
            if (geographical instanceof Geographical.AsyncRenderObject){
                Geographical.AsyncRenderObject asyncRenderObject = (Geographical.AsyncRenderObject) geographical;
                if (asyncRenderObject.hasStaleRenderObject()) {
                    paintBusyIcon(g);
                }
            }
        }
        //
        // dispose of the graphics copy
        //
        g.dispose();        
    }
    
    protected void paintBusyIcon(Graphics2D g) {
        // TODO: see IconWidget.paintWidget
    }
    
    private Envelope getSceneEnvelope(GeoTranslator translator) {
        Rectangle r = getSceneViewport();
        LOGGER.log(Level.FINEST, "Scene rectangle: {0}", r);
        try {
            GeoPosition gp1 = translator.pixelToGeo(null, null, new Point2D.Double(r.getMinX(), r.getMinY()));
            GeoPosition gp2 = translator.pixelToGeo(null, null, new Point2D.Double(r.getMaxX(), r.getMaxY()));
            Envelope e = new Envelope(gp1.getLongitude(), gp2.getLongitude(), gp1.getLatitude(), gp2.getLatitude());
            LOGGER.log(Level.FINEST, "Scene envelope (WGS84): {0}", e);
            return e;
        } catch (NullPointerException npe) {
            // behavior depends on translator implementation:
            // this should be a JXMapGeoTranslator as it doesn't require an input bounding box
            // (because in the case of the scene that's what we're actually trying to determine...);
            // can't test for class explicitly as that would create a circular dependency.
            LOGGER.log(Level.FINEST, "Cannot compute scene envelope");
            return null;
        }
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy