Package org.geotools.map

Source Code of org.geotools.map.DefaultMapContext

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2003-2008, 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.map;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.data.FeatureSource;
import org.geotools.data.memory.CollectionSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.event.MapLayerListEvent;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.feature.type.FeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

/**
* A kinder gentler implementation of {@linkplain org.geotools.map.MapContext} that produces defaults
* as needed.
* <p>
* This implementation produces defaults as needed for:
* <ul>
* <li>Map Bounds are generated from the first layer if needed</li>
* <li>Default Styles are generated if needed for display</li>
* </ul>
*
* @author Andrea Aime
*
*
* @source $URL$
*         http://svn.osgeo.org/geotools/trunk/modules/library/render/src/main/java/org/geotools
*         /map/DefaultMapContext.java $
*        
* @deprecated Use {@link MapContent} instead
*/
public class DefaultMapContext extends MapContext {

    /**
     * Creates a default empty map context. The coordinate reference system for the map context
     * should be set explicitly, or implicitly via {@code addLayer} prior to using the context.
     */
    public DefaultMapContext() {
        super((CoordinateReferenceSystem) null);
    }

    /**
     * Creates a default empty map context
     *
     * @param crs
     *            the coordindate reference system to be used with this context (may be null and set
     *            later)
     */
    public DefaultMapContext(final CoordinateReferenceSystem crs) {
        super(null, null, null, null, null, crs);
    }

    /**
     * Creates a map context with the provided layers.
     * <p>
     * Note, the coordinate reference system for the context will be set from that of the first
     * layer with an available CRS.
     *
     * @param layers
     *            an array of MapLayer objects (may be empty or null) to be added to this context
     */
    public DefaultMapContext(MapLayer[] layers) {
        super(layers, DefaultGeographicCRS.WGS84);
    }

    /**
     * Creates a map context with the provided layers and coordinate reference system
     *
     * @param layers
     *            an array of MapLayer objects (may be empty or null) to be added to this context
     *
     * @param crs
     *            the coordindate reference system to be used with this context (may be null and set
     *            later)
     */
    public DefaultMapContext(MapLayer[] layers, final CoordinateReferenceSystem crs) {
        super(layers, null, null, null, null, crs);
    }

    /**
     * Creates a map context
     * <p>
     * Note, the coordinate reference system for the context will be set from that of the first
     * layer with an available CRS.
     *
     * @param layers
     *            an array of MapLayer objects (may be empty or null) to be added to this context
     *
     * @param title
     *            a title for this context (e.g. might be used by client-code that is displaying the
     *            context's layers); may be null or an empty string
     *
     * @param contextAbstract
     *            a short description of the context and its contents; may be null or an empty
     *            string
     *
     * @param contactInformation
     *            can be used, for example, to record the creators or custodians of the data that
     *            are, or will be, held by this context; may be null or an empty string
     *
     * @param keywords
     *            an optional array of key words pertaining to the data that are, or will be, held
     *            by this context; may be null or a zero-length String array
     *
     */
    public DefaultMapContext(MapLayer[] layers, String title, String contextAbstract,
            String contactInformation, String[] keywords) {
        super(layers, title, contextAbstract, contactInformation, keywords, null);
    }

    /**
     * Creates a new map context
     *
     * @param layers
     *            an array of MapLayer objects (may be empty or null) to be added to this context
     *
     * @param title
     *            a title for this context (e.g. might be used by client-code that is displaying the
     *            context's layers); may be null or an empty string
     *
     * @param contextAbstract
     *            a short description of the context and its contents; may be null or an empty
     *            string
     *
     * @param contactInformation
     *            can be used, for example, to record the creators or custodians of the data that
     *            are, or will be, held by this context; may be null or an empty string
     *
     * @param keywords
     *            an optional array of key words pertaining to the data that are, or will be, held
     *            by this context; may be null or a zero-length String array
     *
     * @param crs
     *            the coordindate reference system to be used with this context (may be null and set
     *            later)
     */
    public DefaultMapContext(MapLayer[] layers, String title, String contextAbstract,
            String contactInformation, String[] keywords, final CoordinateReferenceSystem crs) {
        super(layers, title, contextAbstract, contactInformation, keywords, crs);
    }

    /**
     * Add a new layer if not already present and trigger a {@linkplain MapLayerListEvent}. If a
     * coordinate reference system has not been set for the context an attempt is made to retrieve
     * one from the new layer and use that as the context's CRS.
     *
     * @param index
     *            the position at which to insert the layer in the list of layers held by this
     *            context
     *
     * @param layer
     *            the map layer to add
     *
     * @return true if the layer was added; false otherwise (layer was already present)
     */
    @SuppressWarnings("deprecation")
    public boolean addLayer(int index, MapLayer mapLayer) {
        // checkCRS(mapLayer);
        Layer layer = mapLayer.toLayer();
        layers().add(index, layer);
        return true;
    }

    /**
     * Add a new layer, if not already present, to the end of the list of layers held by this
     * context and trigger a {@linkplain MapLayerListEvent} If a coordinate reference system has not
     * been set for the context an attempt is made to retrieve one from the new layer and use that
     * as the context's CRS.
     *
     * @param layer
     *            the map layer to add
     *
     * @return true if the layer was added; false otherwise (layer was already present)
     */
    @SuppressWarnings("deprecation")
    public boolean addLayer(MapLayer mapLayer) {
        //checkCRS(mapLayer);
        layers().add(mapLayer.toLayer());
        return true;
    }

    /**
     * Add the given feature source as a new layer to the end of the list of layers held by this
     * context and trigger a {@linkplain MapLayerListEvent}. This is a convenience method equivalent
     * to {@linkplain #addLayer}(new DefaultMapLayer(featureSource, style).
     * <p>
     * If a coordinate reference system has not been set for the context an attempt is made to
     * retrieve one from the new layer and use that as the context's CRS.
     * <p>
     * If {@code style} is null, a default style is created using
     * {@linkplain SLD#createSimpleStyle(org.opengis.feature.simple.SimpleFeatureType)}.
     *
     * @param featureSource
     *            the source of the features for the new layer
     *
     * @param style
     *            a Style object to be used in rendering this layer.
     */
    public void addLayer(FeatureSource featureSource, Style style) {
        //checkCRS(featureSource);
        Style layerStyle = checkStyle(style, featureSource.getSchema());
        addLayer(new DefaultMapLayer(featureSource, layerStyle, ""));
    }

    /**
     * Add the given collection source as a new layer to the end of the list of layers held by this
     * context and trigger a {@linkplain MapLayerListEvent}. This is a convenience method equivalent
     * to {@linkplain #addLayer}(new DefaultMapLayer(source, style).
     * <p>
     * If a coordinate reference system has not been set for the context an attempt is made to
     * retrieve one from the new layer and use that as the context's CRS.
     *
     * @param source
     *            the source of the features for the new layer
     * @param style
     *            a Style object to be used in rendering this layer
     */
    public void addLayer(CollectionSource source, Style style) {
        throw new UnsupportedOperationException("FeatureSource required");
    }

    /**
     * Add a grid coverage as a new layer to the end of the list of layers held by this context.
     * <p>
     * If a coordinate reference system has not been set for the context an attempt is made to
     * retrieve one from the grid coverage and use that as the context's CRS.
     *
     * @param gc
     *            the grid coverage
     * @param style
     *            a Style to be used when rendering the new layer
     */
    public void addLayer(GridCoverage gc, Style style) {
        if (style == null) {
            throw new IllegalArgumentException("style cannot be null");
        }
        // checkCRS(gc.getCoordinateReferenceSystem());
        if (gc instanceof GridCoverage2D) {
            Layer layer = new GridCoverageLayer((GridCoverage2D) gc, style);
            layers().add(layer);
        } else {
            throw new UnsupportedOperationException("GridCoverage2D required");
        }
    }

    /**
     * Add a grid coverage data to be supplied by the given reader as a new layer to the end of the
     * list of layers held by this context.
     * <p>
     * If a coordinate reference system has not been set for the context an attempt is made to
     * retrieve one from the reader and use that as the context's CRS.
     *
     * @param reader
     *            the grid coverage reader
     * @param style
     *            a Style to be used when rendering the new layer
     */
    public void addLayer(GridCoverage2DReader reader, Style style) {
        if (style == null) {
            throw new IllegalArgumentException("Style cannot be null");
        }
        // checkCRS(reader.getCrs());
        Layer layer = new GridReaderLayer(reader, style);
        layers().add(layer);
    }

    /**
     * Add the given feature collection as a new layer to the end of the list of layers held by this
     * context and trigger a {@linkplain MapLayerListEvent}. This is a convenience method equivalent
     * to {@linkplain #addLayer}(new DefaultMapLayer(collection, style).
     *
     * @param collection
     *            the collection of features for the new layer
     * @param style
     *            a Style object to be used in rendering this layer
     */
    public void addLayer(FeatureCollection featureCollection, Style style) {
        FeatureType schema = featureCollection.getSchema();
        Style layerStyle = checkStyle(style, schema);
        // checkCRS(schema.getCoordinateReferenceSystem()); // Jody: added for consistency
        Layer layer = new FeatureLayer(featureCollection, layerStyle);
        this.layers().add(layer);
    }

    /**
     * Add the given collection as a new layer to the end of the list of layers held by this context
     * and trigger a {@linkplain MapLayerListEvent}. This is a convenience method equivalent to
     * {@linkplain #addLayer}(new DefaultMapLayer(collection, style).
     *
     * @param collection
     *            the collection of features for the new layer
     * @param style
     *            a Style object to be used in rendering this layer
     */
    @SuppressWarnings("unchecked")
    public void addLayer(Collection collection, Style style) {
        if (collection instanceof FeatureCollection) {
            FeatureCollection featureCollection = (FeatureCollection) collection;
            addLayer( featureCollection, style);
        } else {
            throw new IllegalArgumentException("FeatureCollection required");
        }
    }

    /**
     * If a CRS has not been defined for this context, attempt to get one from this map layer and
     * set it as the context's CRS. Invoked by addLayer methods.
     *
     * @param layer
     *            a map layer being added to the context
     */
//    @SuppressWarnings("deprecation")
//    private void checkCRS(MapLayer layer) {
//        FeatureSource<? extends FeatureType, ? extends Feature> featureSource = layer
//                .getFeatureSource();
//        if (featureSource != null) {
//            checkCRS(featureSource);
//        } else {
//            CollectionSource source = layer.getSource();
//            if (source != null) {
//                checkCRS(source.getCRS());
//            }
//        }
//    }

    /**
     * If a CRS has not been defined for this context, attempt to get one from this featureSource
     * and set it as the context's CRS. Invoked by addLayer.
     *
     * @param featureSource
     *            a feature source being added in a new layer
     */
//    private void checkCRS(FeatureSource<? extends FeatureType, ? extends Feature> featureSource) {
//        if (featureSource != null) {
//            checkCRS(featureSource.getSchema().getCoordinateReferenceSystem());
//        }
//    }

    /**
     * Sets the viewport CRS if needed.
     * <p>
     * This amounts to the viewport taking its default CRS from the first provided layer.
     */
//    private void checkCRS(CoordinateReferenceSystem crs) {
//        if( viewport != null && viewport.getCoordinateReferenceSystem() != null ){
//            if (crs != null) {
//                getViewport().setCoordinateReferenceSystem(crs);
//            }
//        }
//    }

    /**
     * Helper for some addLayer methods that take a Style argument. Checks if the style is null and,
     * if so, attepts to create a default Style.
     *
     * @param style
     *            style argument that was passed to addLayer
     * @param featureType
     *            feature type for which a default style be will made if required
     *
     * @return the input Style object if not {@code null}, or a Style instance for a default style
     */
    private Style checkStyle(Style style, FeatureType featureType) {
        if (style != null) {
            return style;
        }

        Style defaultStyle = SLD.createSimpleStyle(featureType);
        if (defaultStyle == null) {
            throw new IllegalStateException("Failed to creaate a default style for the layer");
        }

        return defaultStyle;
    }

    /**
     * Remove the given layer from this context, if present, and trigger a
     * {@linkplain MapLayerListEvent}
     *
     * @param layer
     *            the layer to be removed
     *
     * @return true if the layer was present; false otherwise
     */
    public boolean removeLayer(MapLayer layer) {
        int index = indexOf(layer);
        // getLayerBounds();
        if (index == -1) {
            return false;
        } else {
            removeLayer(index);

            return true;
        }
    }

    /**
     * Remove the layer at the given position in the list of layers held by this context. The
     * position must be valid or an IndexOutOfBoundsException will result. CAlling this method
     * triggers a {@linkplain MapLayerListEvent}.
     *
     * @param index
     *            the position of the layer in this context's list of layers
     *
     * @return the layer that was removed
     */
    public MapLayer removeLayer(int index) {
        Layer removed = layers().remove(index);
        return new DefaultMapLayer(removed);
    }

    /**
     * Add an array of new layers to this context and trigger a {@link MapLayerListEvent}.
     *
     * @param layers
     *            the new layers that are to be added.
     *
     * @return the number of new layers actually added (will be less than the length of the layers
     *         array if some layers were already present)
     */
    @SuppressWarnings("deprecation")
    public int addLayers(MapLayer[] array) {
        if ((array == null) || (array.length == 0)) {
            return 0;
        }
        return super.addLayers(toLayerList(array));
    }

    /**
     * Remove an array of layers, if present, and trigger a {@link MapLayerListEvent}.
     *
     * @param layers
     *            The layers that are to be removed.
     */
    public void removeLayers(MapLayer[] array) {
        if ((array == null) || (array.length == 0) || layers().isEmpty()) {
            return;
        }
        List<Layer> layersToRemove = toLayerList(array);
        layers().removeAll(layersToRemove);
    }

    /**
     * Return this model's list of layers. If no layers are present, then an empty array is
     * returned.
     *
     * @return This model's list of layers.
     */
    @SuppressWarnings("deprecation")
    public MapLayer[] getLayers() {
        MapLayer[] array = new MapLayer[layers().size()];
        int index = 0;
        for (Iterator<Layer> iter = layers().iterator(); iter.hasNext(); index++) {
            Layer layer = iter.next();
            array[index] = new DefaultMapLayer(layer);
        }
        return array;
    }
   
    /**
     * Return the requested layer.
     *
     * @param index
     *            index of layer to return.
     *
     * @return the layer at the specified position
     *
     * @throws IndexOutOfBoundsException
     *             if the index is out of range
     */
    @SuppressWarnings("deprecation")
    public MapLayer getLayer(int index) throws IndexOutOfBoundsException {
        Layer layer = layers().get(index);
        return new DefaultMapLayer(layer);
    }

    /**
     * Remove all of the map layers from this context. This triggers a MapLayerListEvent.
     *
     */
    public void clearLayerList() {
        layers().clear();
    }
   
    @Override
    public synchronized MapViewport getViewport() {
        if(viewport == null) {
            viewport = new MapViewport();
            try {
                ReferencedEnvelope layerBounds = getLayerBounds();
                if(layerBounds != null) {
                    viewport.setBounds( layerBounds );
                    viewport.setCoordinateReferenceSystem(layerBounds.getCoordinateReferenceSystem());
                }
            } catch (IOException e) {
            }
        }
        return viewport;
    }
   
}
TOP

Related Classes of org.geotools.map.DefaultMapContext

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.