Package org.locationtech.udig.catalog.jgrass.core

Source Code of org.locationtech.udig.catalog.jgrass.core.JGrassMapsetGeoResource

/*
* JGrass - Free Open Source Java GIS http://www.jgrass.org
* (C) HydroloGIS - www.hydrologis.com
*
* 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 HydroloGIS BSD
* License v1.0 (http://udig.refractions.net/files/hsd3-v10.html).
*/
package org.locationtech.udig.catalog.jgrass.core;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.locationtech.udig.catalog.CatalogPlugin;
import org.locationtech.udig.catalog.ICatalog;
import org.locationtech.udig.catalog.ID;
import org.locationtech.udig.catalog.IGeoResourceInfo;
import org.locationtech.udig.catalog.IResolve;
import org.locationtech.udig.catalog.IResolveChangeEvent;
import org.locationtech.udig.catalog.IResolveChangeEvent.Type;
import org.locationtech.udig.catalog.IResolveDelta;
import org.locationtech.udig.catalog.IResolveDelta.Kind;
import org.locationtech.udig.catalog.IResolveFolder;
import org.locationtech.udig.catalog.IResolveManager;
import org.locationtech.udig.catalog.IService;
import org.locationtech.udig.catalog.URLUtils;
import org.locationtech.udig.catalog.internal.CatalogImpl;
import org.locationtech.udig.catalog.internal.ResolveChangeEvent;
import org.locationtech.udig.catalog.internal.ResolveDelta;
import org.locationtech.udig.catalog.ui.CatalogUIPlugin;
import org.locationtech.udig.catalog.ui.ISharedImages;
import org.locationtech.udig.ui.ExceptionDetailsDialog;
import org.locationtech.udig.ui.ProgressManager;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.resource.ImageDescriptor;
import org.geotools.gce.grassraster.JGrassConstants;
import org.geotools.gce.grassraster.JGrassRegion;
import org.geotools.gce.grassraster.JGrassUtilities;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import org.locationtech.udig.catalog.jgrass.JGrassPlugin;

/**
* Represents the GRASS Mapset in the JGrass Location service for uDig.
*
* <p>
* The JGrass georesource is part of the JGrass service and takes care of
* representing the Mapset, which is located inside the Location and holds the
* information of the Active Region.
* </p>
*
* @author Andrea Antonello (www.hydrologis.com)
* @since 2.0
*/
public class JGrassMapsetGeoResource implements IResolveFolder {

    /** the parent service field */
    private JGrassService parent = null;

    /** name field */
    private String name = null;

    /** error message field */
    private Throwable msg = null;

    /** the resources members field */
    private List<IResolve> jgrassMapMembers = null;

    private ImageDescriptor icon;

    private Map<String, String> mapNamesAndTypes;

    private CoordinateReferenceSystem locationCrs;

    private File mapsetFile;

    private File cellFolderFile;

    public JGrassMapsetGeoResource( JGrassService parent, String name, String mapsetPath ) {
        this.parent = parent;
        this.name = name;

        mapsetFile = new File(mapsetPath);
        if (!mapsetFile.exists() || !mapsetFile.isDirectory()) {
            throw new IllegalArgumentException("The GRASS mapset has to be a folder: " + mapsetPath);
        }
        cellFolderFile = new File(mapsetFile, JGrassConstants.CELL);

        locationCrs = parent.getLocationCrs();
    }

    public <T> boolean canResolve( Class<T> adaptee ) {
        // garbage in, garbage out
        if (adaptee == null)
            return false;

        /*
         * in this case our resource is a folder, therefore of type File
         */
        if (adaptee.isAssignableFrom(IService.class) || adaptee.isAssignableFrom(IGeoResourceInfo.class)
                || adaptee.isAssignableFrom(File.class))
            return true;

        return CatalogPlugin.getDefault().getResolveManager().canResolve(this, adaptee);

    }

    public <T> T resolve( Class<T> adaptee, IProgressMonitor monitor ) throws IOException {
        if (adaptee == null)
            return null;

        if (adaptee.isAssignableFrom(IService.class)) {
            return adaptee.cast(parent);
        }
        if (adaptee.isAssignableFrom(File.class)) {
            return adaptee.cast(mapsetFile);
        }
        // bad call to resolve
        IResolveManager rm = CatalogPlugin.getDefault().getResolveManager();
        if (rm.canResolve(this, adaptee)) {
            return rm.resolve(this, adaptee, monitor);
        }
        return null;
    }

    /**
     * scan for the maps in every mapset and define of which type they are,
     * create the map resource, which will be the final leaf of the database
     */

    public List<IResolve> members( IProgressMonitor monitor ) {
        // concurrent access
        synchronized (this) {
            if (jgrassMapMembers == null) {
                // load the properties
                Map<String, String> mapNamesAndTypes = loadMaps(monitor);
                if (mapNamesAndTypes == null) {
                    // error occurred
                    return null;
                }

                /*
                 * get rasters first, then vectors, then sites (filter out
                 * .svn)
                 */
                jgrassMapMembers = new ArrayList<IResolve>();

                for( Map.Entry<String, String> item : mapNamesAndTypes.entrySet() ) {

                    String name = item.getKey();
                    String type = item.getValue();

                    IResolve jgrassMapGeoResource = new JGrassMapGeoResource(parent, this, name, type);
                    jgrassMapMembers.add(jgrassMapGeoResource);
                }

                return jgrassMapMembers;
            }

        }

        return jgrassMapMembers;
    }

    /**
     * <p>
     * scan for all available maps in the mapset and check for their type
     * </p>
     * <p>
     * <b>Note:</b> the value of the hashmap is of the format TYPE|PATH
     * </p>
     *
     * @param monitor
     * @return the hashmap with all the maps by name and type
     */
    private Map<String, String> loadMaps( IProgressMonitor monitor ) {
        try {
            mapNamesAndTypes = new HashMap<String, String>();
            /*
             * binary grass raster maps
             */
            // check the raster maps folder

            File[] rasterFiles = cellFolderFile.listFiles();
            if (rasterFiles == null) {
                msg = new Throwable("Either dir does not exist or is not a directory");
            } else {
                // check raster file bundle consistency and add map if ok
                for( File rasterFile : rasterFiles ) {
                    if (JGrassUtilities.checkRasterMapConsistence(mapsetFile.getAbsolutePath(), rasterFile.getName())) {
                        StringBuilder sb = new StringBuilder();
                        sb.append(JGrassConstants.GRASSBINARYRASTERMAP);
                        sb.append("|");
                        sb.append(rasterFile.getAbsolutePath());
                        mapNamesAndTypes.put(rasterFile.getName(), sb.toString());
                    }
                }
            }
            // clear message, everything is ok
            msg = null;

            return mapNamesAndTypes;

        } catch (Throwable e) {
            msg = e;
        }

        return null;
    }

    public URL getIdentifier() {
        String parentFile = URLUtils.urlToFile(parent.getIdentifier()).getAbsolutePath();

        URL mapsetId = createId(parentFile, name);
        return mapsetId;
    }

    public Throwable getMessage() {
        return msg;
    }

    public Status getStatus() {
        // error occured
        if (msg != null) {
            return Status.BROKEN;
        }

        // if the folder hasn't been scanned yet
        if (jgrassMapMembers == null) {
            return Status.NOTCONNECTED;
        }

        return Status.CONNECTED;
    }

    /**
     * <p>
     * get some information about the mapset resource
     * </p>
     *
     * @author Andrea Antonello - www.hydrologis.com
     * @since 1.1.0
     */
    class JGrassMapsetGeoResourceInfo extends IGeoResourceInfo {
        public JGrassMapsetGeoResourceInfo( IProgressMonitor monitor ) throws IOException {
            this.name = JGrassMapsetGeoResource.this.name;
            this.title = this.name;
            this.description = "JGrass Mapset (" + getIdentifier() + ")"; //$NON-NLS-1$ //$NON-NLS-2$

            // calculate bounds
            JGrassRegion activeRegionWindow = getActiveRegionWindow();
            this.bounds = new ReferencedEnvelope(activeRegionWindow.getEnvelope(), getCRS());
            super.icon = CatalogUIPlugin.getDefault().getImageDescriptor(ISharedImages.CATALOG_OBJ);
        }

        public CoordinateReferenceSystem getCRS() {
            return locationCrs;
        }
    }

    public JGrassRegion getActiveRegionWindow() {
        try {
            return new JGrassRegion(getActiveRegionWindowPath());
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public String getActiveRegionWindowPath() {
        File windFile = new File(mapsetFile, JGrassConstants.WIND);
        if (!windFile.exists()) {
            windFile = new File(mapsetFile, JGrassConstants.WIND.toLowerCase());
            if (!windFile.exists()) {
                msg = new Throwable("Couldn't find a suitable region file in the mapset. Check your Location.");
                return null;
            }
        }
        return windFile.getAbsolutePath();
    }

    public ImageDescriptor getIcon( IProgressMonitor monitor ) {
        if (icon == null) {
            icon = CatalogUIPlugin.getDefault().getImageDescriptor(ISharedImages.GRID_OBJ);
        }
        return icon;
    }

    public String getTitle() {
        return name;
    }

    public void dispose( IProgressMonitor monitor ) {
        jgrassMapMembers = null;
    }

    public IResolve parent( IProgressMonitor monitor ) throws IOException {
        return parent;
    }

    public IService getService( IProgressMonitor monitor ) {
        return parent;
    }

    public ID getID() {
        ID id = new ID(getIdentifier());
        return id;
    }

    public static URL createId( String locationPath, String mapsetName ) {
        try {
            URL locationUrl = new File(locationPath).toURI().toURL();
            String locationUrlString = URLUtils.urlToString(locationUrl, false);
            if (!locationUrlString.endsWith("/")) {
                locationUrlString = locationUrlString + "/";
            }
            return new URL(locationUrlString + "#/" + mapsetName);
        } catch (MalformedURLException e) {
            throw (Error) new AssertionError("Url should always work this is a bug").initCause(e);
        }
    }

    public Set<String> getMapnamesList() {
        Set<String> mapnamesSet = mapNamesAndTypes.keySet();
        return mapnamesSet;
    }

    /**
     * Adds the supplied raster map to the Mapset in the catalog.
     *
     * <p>
     * The map is added to the catalog into the {@link JGrassService JGrass
     * service} without the need of resetting the service.
     * </p>
     *
     * @param mapName
     *            the name of the map to be added.
     * @param mapType
     *            the type defining the format of the map to add.
     * @return the {@link JGrassMapGeoResource georesource} that was added.
     */
    public JGrassMapGeoResource addMap( String mapName, String mapType ) {
        String mapPath = new File(cellFolderFile, mapName).getAbsolutePath();
        String mapTypeAndPath = mapType + "|" + mapPath;
        JGrassMapGeoResource resource = new JGrassMapGeoResource(parent, this, mapName, mapTypeAndPath);
        if (jgrassMapMembers == null) {
            jgrassMapMembers = members(ProgressManager.instance().get(null));
        }

        if (!jgrassMapMembers.contains(resource)) {
            jgrassMapMembers.add(resource);

            ICatalog catalog = getService(null).parent(null);
            if (catalog instanceof CatalogImpl) {
                IResolveDelta delta = new ResolveDelta(resource, Kind.ADDED);
                IResolveChangeEvent event = new ResolveChangeEvent(this, Type.POST_CHANGE, delta);
                ((CatalogImpl) catalog).fire(event);
            }
        } else {
            try {
                int index = jgrassMapMembers.indexOf(resource);
                IResolve iResolve = jgrassMapMembers.get(index);
                // ((JGrassMapGeoResource) iResolve).resetBoundInfo();
                resource = ((JGrassMapGeoResource) iResolve);
                resource.resetBoundInfo();
            } catch (IOException e) {
                String message = "An error occurred while reloading the file bounds info.";
                ExceptionDetailsDialog.openError(null, message, IStatus.ERROR, JGrassPlugin.PLUGIN_ID, e);
            }
        }
        return resource;
    }

    public JGrassMapGeoResource removeMap( String mapName, String mapType ) {
        String mapPath = new File(cellFolderFile, mapName).getAbsolutePath();
        String mapTypeAndPath = mapType + "|" + mapPath;
        JGrassMapGeoResource resource = new JGrassMapGeoResource(parent, this, mapName, mapTypeAndPath);
        if (jgrassMapMembers == null) {
            jgrassMapMembers = members(ProgressManager.instance().get(null));
        }
        if (jgrassMapMembers.contains(resource)) {
            jgrassMapMembers.remove(resource);

            ICatalog catalog = getService(null).parent(null);
            if (catalog instanceof CatalogImpl) {
                IResolveDelta delta = new ResolveDelta(resource, Kind.REMOVED);
                IResolveChangeEvent event = new ResolveChangeEvent(this, Type.POST_CHANGE, delta);
                ((CatalogImpl) catalog).fire(event);
            }
        }
        return resource;
    }

    /**
     * Getter for the mapset file.
     *
     * @return the mapset file.
     */
    public File getFile() {
        return mapsetFile;
    }

    /**
     * Getter for the location {@link CoordinateReferenceSystem}.
     *
     * @return the location's crs.
     */
    public CoordinateReferenceSystem getLocationCrs() {
        return locationCrs;
    }
}
TOP

Related Classes of org.locationtech.udig.catalog.jgrass.core.JGrassMapsetGeoResource

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.