Package org.geotools.swing.tool

Source Code of org.geotools.swing.tool.InfoToolHelper

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2008-2011, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library 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
*    Lesser General Public License for more details.
*/

package org.geotools.swing.tool;

import java.awt.geom.AffineTransform;
import java.lang.ref.WeakReference;
import java.util.logging.Logger;

import org.geotools.geometry.DirectPosition2D;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.map.event.MapBoundsEvent;
import org.geotools.map.event.MapBoundsListener;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.geotools.util.logging.Logging;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

/**
* Abstract base class for helper classes used by {@linkplain InfoTool} to query
* features in map layers.
*
* @author Michael Bedward
* @since 2.6
*
* @source $URL$
* @version $URL$
*/
public abstract class InfoToolHelper implements MapBoundsListener {
    private static final Logger LOGGER = Logging.getLogger("org.geotools.swing");

    /**
     * String key used for the position element in the {@code Map} passed to
     * {@linkplain #getInfo( org.geotools.util.KVP )}.
     */
    public static final String KEY_POSITION = "pos";

    protected WeakReference<MapContent> contentRef;
    protected WeakReference<Layer> layerRef;

    private boolean transformFailed;
    private MathTransform transform;


    /**
     * CAlled by the helper lookup system when selecting a helper
     * for a given layer.
     *
     * @param layer the layer
     *
     * @return {@code true} is this helper can handle the layer
     *
     * @throws IllegalArgumentException if {@code layer} is {@code null}
     */
    public abstract boolean isSupportedLayer(Layer layer);

    /**
     * Gets layer data at the specified position. If there are no feature
     * data at the position, an empty {@code InfoToolResult} object is
     * returned.
     *
     * @param pos query position
     * @return layer data
     *
     * @throws Exception on error querying the layer
     */
    public abstract InfoToolResult getInfo(DirectPosition2D pos) throws Exception;

    /**
     * Checks if this helper is holding a reference to a {@code MapContent} and
     * a {@code Layer}.Helpers only hold a {@code WeakReference} to both the
     * map content and layer to avoid blocking garbage collection when layers
     * are discarded.
     *
     * @return {@code true} if both map content and layer references are valid
     */
    public boolean isValid() {
        return contentRef != null && contentRef.get() != null
                && layerRef != null && layerRef.get() != null;
    }

    /**
     * Sets the map content for this helper.
     *
     * @param layer the map content
     *
     * @throws IllegalArgumentException if {@code content} is {@code null}
     */
    public void setMapContent(MapContent content) {
        if (content == null) {
            throw new IllegalArgumentException("content must not be null");
        }
       
        contentRef = new WeakReference<MapContent>(content);
        clearTransform();
    }

    /**
     * Gets the map content associated with this helper.
     *
     * @return the map content
     */
    public MapContent getMapContent() {
        return contentRef != null ? contentRef.get() : null;
    }

    /**
     * Sets the map layer for this helper.
     *
     * @param layer the map layer
     *
     * @throws IllegalArgumentException if {@code layer} is {@code null}
     */
    public void setLayer(Layer layer) {
        if (layer == null) {
            throw new IllegalArgumentException("layer must not be null");
        }

        layerRef = new WeakReference<Layer>(layer);
        clearTransform();
    }



    /**
     * Gets the map layer associated with this helper.
     * @return
     */
    public Layer getLayer() {
        return layerRef != null ? layerRef.get() : null;
    }

    /**
     * A method from the {@code MapBoundsListener} interface used to listen
     * for a change to the map content's coordinate reference system.
     */
    @Override
    public void mapBoundsChanged(MapBoundsEvent event) {
        clearTransform();
    }

    /**
     * Gets the {@code MathTransform} used to convert coordinates from the
     * projection being used by the {@code MapContent} to that of the
     * {@code Layer}.
     *
     * @return the transform or {@code null} if the layer's CRS is the same
     *     as that of the map content, or if either has no CRS defined
     */
    protected MathTransform getContentToLayerTransform() {
        if (transform == null && !transformFailed) {
            MapContent content = getMapContent();
            Layer layer = getLayer();

            if (content != null && layer != null) {
                CoordinateReferenceSystem contentCRS = content.getCoordinateReferenceSystem();
                CoordinateReferenceSystem layerCRS =
                        layer.getFeatureSource().getSchema().getCoordinateReferenceSystem();

                if (contentCRS != null && layerCRS != null) {
                    if (CRS.equalsIgnoreMetadata(contentCRS, layerCRS)) {
                        transform = new AffineTransform2D(new AffineTransform());
                       
                    } else {
                        try {
                            transform = CRS.findMathTransform(contentCRS, layerCRS, true);
                        } catch (Exception ex) {
                            LOGGER.warning("Can't transform map content CRS to layer CRS");
                            transformFailed = true;
                        }
                    }
                }

            } else {
                // one or both of content and layer CRS is null
                transform = new AffineTransform2D(new AffineTransform());
            }
        }

        return transform;
    }

    protected boolean isTransformRequired() {
        return !getContentToLayerTransform().isIdentity();
    }

    protected void clearTransform() {
        transform = null;
        transformFailed = false;
    }

}
TOP

Related Classes of org.geotools.swing.tool.InfoToolHelper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.