Package org.locationtech.udig.tools.internal.ui.util

Source Code of org.locationtech.udig.tools.internal.ui.util.LayerUtil

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2012, Refractions Research Inc.
* (C) 2006, Axios Engineering S.L. (Axios)
* (C) 2006, County Council of Gipuzkoa, Department of Environment and Planning
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Axios BSD
* License v1.0 (http://udig.refractions.net/files/asd3-v10.html).
*/
package org.locationtech.udig.tools.internal.ui.util;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.locationtech.udig.catalog.IGeoResource;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.command.MapCommand;
import org.locationtech.udig.project.command.factory.SelectionCommandFactory;
import org.locationtech.udig.project.render.IViewportModel;
import org.locationtech.udig.ui.ProgressManager;

import org.eclipse.core.runtime.NullProgressMonitor;
import org.geotools.data.DataStore;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

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

import org.locationtech.udig.tools.feature.util.FeatureUtil;

/**
* Layer Utilities
* <p>
* Commons operations to get and set layer components.
* </p>
*
* @author Mauricio Pazos (www.axios.es)
* @author Aritz Davila (www.axios.es)
* @since 1.1.0
*/
public final class LayerUtil {

  private LayerUtil() {
    // util class
  }

  /**
   * Creates a Query for the selected features of <code>layer</code> or all
   * the features if it has no selection set and
   * <code>fallbackToWholeLayer</code> is <code>true</code>.
   *
   * @param layer
   * @return a Query for the selection
   */
  private static Query getSelectionQuery(final ILayer layer) {

    final boolean queryForSelectedFeatures = true;
    final Query selectionQuery = layer.getQuery(queryForSelectedFeatures);
    final Query layerQuery = new Query(selectionQuery);
    CoordinateReferenceSystem layerCrs = layer.getCRS();
    if (ILayer.UNKNOWN_CRS == layerCrs) {
      CoordinateReferenceSystem mapCRS = MapUtil.getCRS(layer.getMap());
      layerQuery.setCoordinateSystem(mapCRS);
    }

    Filter filter = selectionQuery.getFilter();
    // no selection? perform over the whole layer
    if (Filter.EXCLUDE.equals(filter)) {
      layerQuery.setFilter(Filter.INCLUDE);
    }
    return layerQuery;
  }

  /**
   * Computes the number of features selected. It will return all if any
   * feature is selected
   *
   * @param layer
   *            an <code>ILayer</code> that can resolve to
   *            <code>FeatureSource</code> for which to compute the number of
   *            selected features.
   * @return the number of features selected, if any, or the total number of
   *         features in the layer if no features are selected,
   * @throws IOException
   */
  public static int getCountOfSelectedFeatures(final ILayer layer) throws IOException {

    return getCountOfSelectedFeatures(layer, Filter.INCLUDE);
  }

  /**
   * Computes the number of features selected. It will return all if any
   * feature is selected.
   *
   * @param layer
   * @param filter
   * @return the count of features in layer or Integer.MAX_VALUE if the
   *         feature collection has more than Integer.MAX_VALUE features
   * @throws IOException
   */
  public static int getCountOfSelectedFeatures(final ILayer layer, final Filter filter) throws IOException {

    FeatureSource<SimpleFeatureType, SimpleFeature> source = layer.getResource(FeatureSource.class, null);
    assert source != null;

    final Query query = getSelectionQuery(layer);
    FeatureCollection<SimpleFeatureType, SimpleFeature> features = source.getFeatures(query);
    // if empty select all layer is computed (filter none)
    if (features.isEmpty()) {
      features = source.getFeatures(filter);
    }
    int count = FeatureUtil.computeCollectionSize(features);

    return count;
  }

  /**
   * Returns the features selected in layer.
   *
   * @param layer
   *            the layer to obtain the selected features from
   * @param fallbackToWholeLayer
   *            wether to return the whole layer's features if no selection is
   *            set for the layer
   * @return FeatureCollection holding the selection
   * @throws IOException
   *             if occurs getting the selection
   */
  public static FeatureCollection<SimpleFeatureType, SimpleFeature> getSelectedFeatures(final ILayer layer)
    throws IOException {
    return getSelectedFeatures(layer, Filter.INCLUDE);
  }

  /**
   * Retruns all layer's features
   *
   * @param layer
   * @return all features
   * @throws IOException
   */
  public static FeatureCollection<SimpleFeatureType, SimpleFeature> findAllFeatures(final ILayer layer)
    throws IOException {

    return getSelectedFeatures(layer, Filter.INCLUDE);
  }

  /**
   * Returns the features selected in layer or all feature if there is not any
   * selected feature
   *
   * @param layer
   *            the layer to obtain the selected features from
   * @param fallbackToWholeLayer
   *            Whether to return the whole layer's features if no selection
   *            is set for the layer
   * @param extraFilter
   *            non null Filter to append to the layer's selection filter. Use
   *            {@link Filter#NONE} instead of <code>null</code> to indicate
   *            no additional filter.
   * @return FeatureCollection holding the selection
   * @throws IOException
   *             if occurs getting the selection
   */
  public static FeatureCollection<SimpleFeatureType, SimpleFeature> getSelectedFeaturesfinal ILayer layer,
                                              final Filter extraFilter)
    throws IOException {

    assert layer != null;
    assert extraFilter != null;

    FeatureSource<SimpleFeatureType, SimpleFeature> source = layer.getResource(FeatureSource.class, ProgressManager
          .instance().get());

    if (source == null) {
      return FeatureCollections.newCollection();
    }

    FeatureCollection<SimpleFeatureType, SimpleFeature> features;

    Query selectionQuery = getSelectionQuery(layer);

    if (!Filter.INCLUDE.equals(extraFilter)) {

      Filter selectionFilter = selectionQuery.getFilter();
      FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
      Filter filter = ff.and(selectionFilter, extraFilter);
      selectionQuery.setFilter(filter);

      features = source.getFeatures(selectionQuery);
    } else {
      features = source.getFeatures();
    }

    return features;
  }

  /**
   * Traverses the <code>map</code>'s layers ensuring it does not already
   * contains a layer named <code>name</code> and returns a non existent layer
   * name, either by returning <code>name</code> itself, or by adding a number
   * postfix to it.
   *
   * @param map
   * @param name
   * @return a non already existent layer name in the map
   */
  public static String findNewLayerName(final IMap map, final String name) {
    String newLayerName = name;
    Set<String> layerNames = new HashSet<String>();
    for (ILayer layer : map.getMapLayers()) {
      layerNames.add(layer.getName());
    }
    int matches = 1;
    while (layerNames.contains(newLayerName)) {
      matches++;
      newLayerName = name + matches;
    }
    return newLayerName;
  }

  /**
   * Returns a non existing type name in <code>ds</code> based on the proposed
   * <code>name</code>.
   *
   * @param existingLayer
   *            the layer from which to inspect its enclosing map and referred
   *            DataStore to avoid duplicated type names
   * @param name
   *            a proposed type name to base the returned name on
   * @return <code>name</code> if it don't already exists in the layer's map
   *         nor in its DataStore. A non existent type name in the data store
   *         with <code>name</code> as prefix otherwise.
   * @throws IOException
   */
  public static String findNewLayerName(final ILayer existingLayer, final String name) throws IOException {
    String newLayerName = findNewLayerName(existingLayer.getMap(), name);

    IGeoResource resource = existingLayer.findGeoResource(FeatureSource.class);
    if (resource != null) {
      FeatureSource<SimpleFeatureType, SimpleFeature> source = resource.resolve(FeatureSource.class,
            new NullProgressMonitor());
      DataStore ds = (DataStore) source.getDataStore();
      String[] dsTypes = ds.getTypeNames();
      Set<String> typeNames = new HashSet<String>(Arrays.asList(dsTypes));
      int matches = 1;
      while (typeNames.contains(newLayerName)) {
        matches++;
        newLayerName = name + matches;
      }
    }
    return newLayerName;
  }

  /**
   * Returns the layer's CRS ensuring it is not {@link ILayer#UNKNOWN_CRS}
   * <p>
   * If <code>sourceLayer.getCRS()</code> is {@link ILayer#UNKNOWN_CRS}, it
   * means the underlying FeatureSource has no CRS defined, thus, for the sake
   * of performing spatial operations, the Map's CRS is returned instead.
   * </p>
   *
   * @param sourceLayer
   * @return the layer's CRS of the Map's one of the layer's CRS is
   *         {@link ILayer#UNKNOWN_CRS}
   */
  public static CoordinateReferenceSystem getCrs(ILayer sourceLayer) {
    assert sourceLayer != null;
    CoordinateReferenceSystem crs = sourceLayer.getCRS();
    if (ILayer.UNKNOWN_CRS == crs) {
      IMap map = sourceLayer.getMap();
      IViewportModel viewportModel = map.getViewportModel();
      crs = viewportModel.getCRS();
    }
    return crs;
  }

  public static Coordinate mapToLayer(IMap map, ILayer layer, Coordinate coordInMapCrs) {
    try {
      MathTransform toLayer = layer.mapToLayerTransform();
      double[] src = { coordInMapCrs.x, coordInMapCrs.y };
      double[] dst = new double[2];
      toLayer.transform(src, 0, dst, 0, 1);
      return new Coordinate(dst[0], dst[1]);
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    } catch (TransformException ex) {
      throw new RuntimeException(ex);
    }
  }

  /**
   * @param layer
   * @return the class of layer's default geometry
   */
  public static Class<? extends Geometry> getGeometryClass(final ILayer layer) {

    assert layer != null;

    GeometryDescriptor type = layer.getSchema().getGeometryDescriptor();

    Class<? extends Geometry> geomClass = (Class<? extends Geometry>) type.getType().getBinding();

    return geomClass;
  }

  /**
   * Presents the features selected into the source layer
   *
   * @param sourceLayer
   * @param filter
   */
  public static void presentSelection(ILayer sourceLayer, Filter filter) {

    assert sourceLayer != null;
    assert filter != null;

    MapCommand createSelectCommand = SelectionCommandFactory.getInstance().createSelectCommand(sourceLayer, filter);
    sourceLayer.getMap().sendCommandSync(createSelectCommand);
  }

  /**
   * Check if the given layer is compatible with the any of the geometries
   * from the geometry list.
   *
   * @param layer Layer to check its compatibility.
   * @param geometries List of geometries.
   * @return True if the layer is compatible.
   */
  public static boolean isCompatible(ILayer layer, List<?> geometries) {

    if (layer==null){
      return false;
    }
    Class<?> type = layer.getSchema().getGeometryDescriptor().getType().getBinding();
    return geometries.contains(type);
  }

}
TOP

Related Classes of org.locationtech.udig.tools.internal.ui.util.LayerUtil

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.