Package org.geotools.swing.tool

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

/*
*    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.util.Collection;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;

import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.jts.Geometries;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;

import org.opengis.feature.Feature;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

/**
* Helper class used by {@linkplain InfoTool} to query vector features in a
* {@linkplain org.geotools.map.FeatureLayer}.
*
* @author Michael Bedward
* @since 2.6
*
* @source $URL$
* @version $URL$
*/
public class FeatureLayerHelper extends InfoToolHelper {

    /**
     * Default distance fraction used with line and point features.
     * When the user clicks on the map, this tool searches for features within
     * a rectangle of width w centred on the mouse location, where w is the
     * average map side length multiplied by the value of this constant.
     */
    public static final double DEFAULT_DISTANCE_FRACTION = 0.01d;

    private static final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
    private static final FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2(null);

    private String attrName;
    private Geometries geomType;

    /**
     * No argument constructor required by the helper lookup system.
     */
    public FeatureLayerHelper() {
    }

    /**
     * {@inheritDoc}
     * The {@code layer} argument must be an instance of {@linkplain FeatureLayer}.
     */
    @Override
    public void setLayer(Layer layer) {
        if (!(layer instanceof FeatureLayer)) {
            throw new IllegalArgumentException("layer must be an instance of FeatureLayer");
        }

        super.setLayer(layer);

        GeometryDescriptor geomDesc = layer.getFeatureSource().getSchema().getGeometryDescriptor();
        attrName = geomDesc.getLocalName();

        Class<? extends Geometry> geomClass = (Class<? extends Geometry>) geomDesc.getType().getBinding();
        geomType = Geometries.getForBinding(geomClass);
    }

    @Override
    public boolean isSupportedLayer(Layer layer) {
        return layer instanceof FeatureLayer;
    }

    @Override
    public InfoToolResult getInfo(DirectPosition2D pos) throws Exception {
        InfoToolResult result = new InfoToolResult();

        if (isValid()) {
            Filter filter = null;
            if (geomType == Geometries.POLYGON || geomType == Geometries.MULTIPOLYGON) {
                Geometry posGeom = createSearchPoint(pos);
                filter = filterFactory.intersects(
                        filterFactory.property(attrName),
                        filterFactory.literal(posGeom));

            } else {
                ReferencedEnvelope env = createSearchEnv(pos);
                filter = filterFactory.bbox(filterFactory.property(attrName), env);
            }

            Query query = new Query(null, filter);
            query.setCoordinateSystemReproject(getMapContent().getCoordinateReferenceSystem());
            FeatureSource featureSource = getLayer().getFeatureSource();
            Collection<PropertyDescriptor> descriptors = featureSource.getSchema().getDescriptors();

            FeatureCollection queryResult = featureSource.getFeatures(query);
            FeatureIterator iter = queryResult.features();

            try {
                while (iter.hasNext()) {
                    Feature f = iter.next();
                    result.newFeature(f.getIdentifier().getID());
                    for (PropertyDescriptor desc : descriptors) {
                        Name name = desc.getName();
                        Object value = f.getProperty(name).getValue();

                        if (value != null) {
                            if (value instanceof Geometry) {
                                result.setFeatureValue(name, value.getClass().getSimpleName());
                            } else {
                                result.setFeatureValue(name, value);
                            }
                        } else {
                            result.setFeatureValue(name, "null");
                        }
                    }
                }

            } finally {
                iter.close();
            }
        }

        return result;
    }

    /**
     * Converts the query position, in map content coordinates, to a position
     * in layer coordinates and returns it as a JTS {@code Point}.
     *
     * @param pos query position in map content coordaintes
     * @return point in layer coordinates
     */
    private Geometry createSearchPoint(DirectPosition2D pos) {
        try {
            DirectPosition2D trPos = new DirectPosition2D();
            getContentToLayerTransform().transform(pos, trPos);
            Geometry point = geometryFactory.createPoint(new Coordinate(trPos.x, trPos.y));
            return point;

        } catch (Exception ex) {
            throw new IllegalStateException(ex);
        }
    }

    private ReferencedEnvelope createSearchEnv(DirectPosition2D pos) {
        ReferencedEnvelope mapBounds = getMapContent().getViewport().getBounds();
        if (mapBounds == null || mapBounds.isEmpty()) {
            // fall back to layer bounds
            Layer layer = getLayer();
            if (layer == null) {
                // this should never happen
                throw new IllegalStateException("Target layer has been lost");
            }
            mapBounds = getLayer().getBounds();
        }

        double halfWidth = 0.5 * DEFAULT_DISTANCE_FRACTION
                * (mapBounds.getWidth() + mapBounds.getHeight());

        CoordinateReferenceSystem contentCRS = getMapContent().getCoordinateReferenceSystem();
        ReferencedEnvelope env = new ReferencedEnvelope(
                pos.x - halfWidth, pos.x + halfWidth,
                pos.y - halfWidth, pos.y + halfWidth,
                contentCRS);

        if (isTransformRequired()) {
            CoordinateReferenceSystem layerCRS =
                    getLayer().getFeatureSource().getSchema().getCoordinateReferenceSystem();

            try {
                env = env.transform(layerCRS, true);
            } catch (Exception ex) {
                throw new IllegalStateException(ex);
            }
        }

        return env;
    }
}
TOP

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

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.