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

eu.limetri.client.mapviewer.swing.render.IconWidget 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 .
 */
package eu.limetri.client.mapviewer.swing.render;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Point2D;


import org.netbeans.api.visual.model.ObjectScene;

import com.vividsolutions.jts.geom.Coordinate;

import eu.limetri.api.geo.Geometrical;
import eu.limetri.client.mapviewer.api.Palette;
import eu.limetri.client.mapviewer.data.GeoPosition;

/**
 * This widget can draw an icon with corresponding label on the centroid of the
 * given geographical.
 *
 * @author Wytse Visser
 */
public class IconWidget extends GeometricalWidget {

//    private static final Logger LOGGER = Logger.getLogger("nl.cloudfarming.client.geoviewer.render.IconWidget");
    private static final int ICON_SIZE = 32;
    private static final int MINIMUM_ICON_SIZE = 2;
    /**
     * The distance in pixels between the icon and its label in the default zoom
     */
    private static final int ICON_LABEL_MARGIN = 15;
    private final GeoTranslator geoTranslator;

    private static final double DEFAULT_DIFFERENCE = 0.0002; //what does this number mean?
    
    public IconWidget(final Geometrical geometrical, Palette palette, GeoTranslator geoTranslator, ObjectScene scene) {
        super(scene, geoTranslator, geometrical, palette);
        this.geoTranslator = geoTranslator;

        setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE));
        setToolTipText(geometrical.getTooltipText());
    }

    @Override
    protected void paintWidget() {
        Image img = getGeographical().getIcon();
        final double iconResizeFactor = 1.0 / Math.max(getZoomLevel() - 2, 1);
        final int iconHeight = getResizedIconSize(img.getHeight(null), iconResizeFactor);
        final int iconWidth = getResizedIconSize(img.getWidth(null), iconResizeFactor);

        com.vividsolutions.jts.geom.Point centroid = getGeographical().getCentroid();
        if (centroid != null) {
            Coordinate coordinate = new Coordinate(centroid.getX(), centroid.getY());
            Point2D point = geoTranslator.geoToPixel(null, null, coordinate);
            int x = (int) Math.round(point.getX() - iconWidth / 2);
            int y = (int) Math.round(point.getY() - iconHeight / 2);

            Graphics2D g = (Graphics2D) getGraphics().create();
            setPreferredBounds(new Rectangle(x, y, iconWidth, iconHeight));
            g.clip(getPreferredBounds());

            g.drawImage(img, x, y, iconWidth, iconHeight, null);
            g.dispose();

            // Draw the icon label in a new instance of Graphics2D, because it's outside the clip of the previous one
            g = (Graphics2D) getGraphics().create();
            drawIconLabel(g, getGeographical().getIconLabel(), x, y, iconResizeFactor, iconHeight);
            g.dispose();
        }
    }

    private double getZoomLevel() {
        Point2D left = new java.awt.Point(0, 0);
        GeoPosition leftPosition = geoTranslator.pixelToGeo(null, null, left);

        Point2D slightlyMoreToTheRight = new java.awt.Point(10, 0);
        GeoPosition rightPosition = geoTranslator.pixelToGeo(null, null, slightlyMoreToTheRight);

        final double difference = rightPosition.getLongitude() - leftPosition.getLongitude();
        return difference / DEFAULT_DIFFERENCE;
    }

    /**
     * Computes the size the icon should have on the map.
     *
     * @param originalSize The size of the icon before resizing
     * @param resizeFactor The factor to resize the icon with
     * @return The new size of the icon. This is at least MINIMUM_ICON_SIZE
     */
    private int getResizedIconSize(int originalSize, double resizeFactor) {
        return Math.max(MINIMUM_ICON_SIZE, (int) Math.round(originalSize * resizeFactor));
    }

    /**
     * Draws the label of the geographical's icon underneath the icon itself
     *
     * @param g
     * @param iconLabel The label to draw
     * @param x The x position of the geographical on the map
     * @param y The y position of the geographical on the map
     * @param iconResizeFactor The factor the icon is resized with
     * @param iconHeight The height of the icon on the map
     */
    private void drawIconLabel(Graphics2D g, String iconLabel, int x, int y, double iconResizeFactor, int iconHeight) {
        Font font = g.getFont();
        final int fontSize = (int) Math.round(font.getSize() * iconResizeFactor);
        g.setFont(new Font(font.getName(), font.getStyle(), fontSize));

        y += iconHeight + ICON_LABEL_MARGIN * iconResizeFactor;
        g.drawString(iconLabel, x, y);
    }

    @Override
    public boolean isHitAt(Point localLocation) {
        return isVisible() && getBounds().contains(localLocation);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy