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

nl.cloudfarming.client.geoviewer.render.GeometricalWidget Maven / Gradle / Ivy

Go to download

AgroSense geoviewer render - contains classes for rendering of various geo objects

The newest version!
/**
 * 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 nl.cloudfarming.client.geoviewer.render;

import com.vividsolutions.jts.geom.Geometry;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.logging.Level;
import java.util.logging.Logger;
import nl.cloudfarming.client.geoviewer.Geometrical;
import nl.cloudfarming.client.geoviewer.Palette;
import nl.cloudfarming.client.lib.geotools.GeometryTools;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.netbeans.api.visual.model.ObjectScene;
import org.netbeans.api.visual.model.ObjectState;

/**
 * An GeometricalWidget is a object on the map which is used for interaction
 * from the user with a dynamic object on the map . Someone can see a toolTip
 * for a dynamic object and can use a context menu (right mouse click on an
 * object).
 *
 * @author Timon Veenstra
 */
public class GeometricalWidget extends GeographicalWidget {

    private static final int ICON_SIZE = 20;
    private final Geometrical geometrical;
    static final double DISTANCE = 0.00001;
    private final Geometry envelope;
    private final GeoTranslator geoTranslator;
    private static final Logger LOGGER = Logger.getLogger(GeometricalWidget.class.getName());

    /**
     * Initialize the widget for a dynamic object on the specified location with
     * a toolTip and a context menu.
     *
     * @param scene A class that keeps associations between widgets and the
     * objects that model them
     * @param geoTranslator the translator to translate geo to pixel and visa
     * versa
     * @param geometrical geometrical object to display on the map
     * @param palette palette with colors
     * @param envelope Optional paramater with a boundingbox, if null the
     * boundingbox of the geometrical will be used. When painting multiple
     * GeometricalWidget on one canvas, always use the envelope of the combined
     * geometries!
     */
    public GeometricalWidget(final ObjectScene scene, GeoTranslator geoTranslator, final Geometrical geometrical, Palette palette, Geometry envelope) {
        super(geometrical, palette, scene);
        if (geometrical == null || geometrical.getGeometry() == null) {
            throw new IllegalArgumentException("argument geometrical or its geometry cannot be null");
        }
        this.geometrical = geometrical;
        this.envelope = (envelope != null) ? envelope : geometrical.getGeometry().getEnvelope();
        this.geoTranslator = geoTranslator;
        setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE));
        setToolTipText(geometrical.getTooltipText());
    }

    /**
     * Initialize the widget for a dynamic object on the specified location with
     * a toolTip and a context menu.
     *
     * @param scene A class that keeps associations between widgets and the
     * objects that model them
     * @param geoTranslator the translator to translate geo to pixel and visa
     * versa
     * @param geometrical geometrical object to display on the map
     * @param palette palette with colors
     */
    public GeometricalWidget(final ObjectScene scene, GeoTranslator geoTranslator, final Geometrical geometrical, Palette palette) {
        this(scene, geoTranslator, geometrical, palette, geometrical.getGeometry().getEnvelope());
    }

    @Override
    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
        LOGGER.log(Level.FINEST, "notifyStateChanged, previous state {0}, new state {1}", new Object[]{previousState, state});
        setForeground(this.palette.getColorForState(getState()));
        repaint();
    }

    @Override
    protected void paintWidget() {
        //
        // set the preferred widget bounds based on the geometry and current state of the mapviewer
        //
        Rectangle clientArea = GeometryRenderer.getViewport(geometrical.getGeometry(), this.envelope, getScene().getClientArea(), geoTranslator);
        
        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());
        g.setColor(getForeground());
        //
        // dispatch painting of the geometry to the geometry renderer
        //
        GeometryRenderer renderer = GeometryRendererFactory.getRenderer(geometrical.getGeometry());
        renderer.render(geometrical.getGeometry(), this.envelope, getSceneViewport(), geoTranslator, getState(), g);
        //
        // dispose of the graphics copy
        //
        g.dispose();
    }

    /**
     * Determines if a widget isHit. A widget is hit when a point lays between
     * the bounds of the widget and: - The localLocation intersects the widgets
     * GeoPostition - the localLocation is within a distance of DISTANCE of
     * GeoPosition
     *
     * @param localLocation the Point which possibly hits the widget
     * @return if the widget is hit
     */
    @Override
    public boolean isHitAt(Point localLocation) {
        if (isVisible() && getBounds().contains(localLocation)) {
            Geometry geometry = geometrical.getGeometry();

            GeoPosition geoPosition = geoTranslator.pixelToGeo(getScene().getClientArea(), envelope, localLocation);
            com.vividsolutions.jts.geom.Point pnt = GeometryTools.getPoint(geoPosition.getLongitude(), geoPosition.getLatitude());

            return geometry.intersects(pnt) || geometry.isWithinDistance(pnt, DISTANCE);

        } else {
            return false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy