⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shpfiles.java

📁 shape file read and write
💻 JAVA
字号:
/**
 * 
 */
package org.geotools.data.shapefile;

import static org.geotools.data.shapefile.ShpFileType.SHP;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.data.DataUtilities;

/**
 * The collection of all the files that are the shapefile and its metadata and
 * indices.
 * 
 * <p>
 * This class has methods for performing actions on the files. Currently mainly
 * for obtaining read and write channels and streams. But in the future a move
 * method may be introduced.
 * </p>
 * 
 * <p>
 * Note: The method that require locks (such as getInputStream()) will
 * automatically acquire locks and the javadocs should document how to release
 * the lock. Therefore the methods {@link #acquireRead(ShpFileType, FileReader)}
 * and {@link #acquireWrite(ShpFileType, FileWriter)}svn
 * </p>
 * 
 * @author jesse
 */
public class ShpFiles {
    /**
     * The urls for each type of file that is associated with the shapefile. The
     * key is the type of file
     */
    private final Map<ShpFileType, URL> urls = new HashMap<ShpFileType, URL>();

    private final Lock readWriteLock = new ReentrantLock();

    private final Collection<ShpFilesLocker> lockers = new LinkedList<ShpFilesLocker>();

    /**
     * Searches for all the files and adds then to the map of files.
     * 
     * @param fileName
     *                the filename or url of any one of the shapefile files
     * @throws MalformedURLException
     *                 if it isn't possible to create a URL from string. It will
     *                 be used to create a file and create a URL from that if
     *                 both fail this exception is thrown
     */
    public ShpFiles(String fileName) throws MalformedURLException {
        try {
            URL url = new URL(fileName);
            init(url);
        } catch (MalformedURLException e) {
            init(new File(fileName).toURI().toURL());
        }
    }

    /**
     * Searches for all the files and adds then to the map of files.
     * 
     * @param file
     *                any one of the shapefile files
     * 
     * @throws FileNotFoundException
     *                 if the shapefile associated with file is not found
     */
    public ShpFiles(File file) throws MalformedURLException {
        init(file.toURI().toURL());
    }

    /**
     * Searches for all the files and adds then to the map of files.
     * 
     * @param file
     *                any one of the shapefile files
     * 
     */
    public ShpFiles(URL url) throws IllegalArgumentException {
        init(url);
    }

    private void init(URL url) {
        String base = baseName(url);
        if (base == null) {
            throw new IllegalArgumentException(
                    url.getPath()
                            + " is not one of the files types that is known to be associated with a shapefile");
        }

        String urlString = url.toExternalForm();
        char lastChar = urlString.charAt(urlString.length()-1);
        boolean upperCase = Character.isUpperCase(lastChar);

        for (ShpFileType type : ShpFileType.values()) {
            
            String extensionWithPeriod = type.extensionWithPeriod;
            if( upperCase ){
                extensionWithPeriod = extensionWithPeriod.toUpperCase();
            }else{
                extensionWithPeriod = extensionWithPeriod.toLowerCase();
            }
            
            URL newURL;
            String string = base + extensionWithPeriod;
            try {
                newURL = new URL(url, string);
            } catch (MalformedURLException e) {
                // shouldn't happen because the starting url was constructable
                throw new RuntimeException(e);
            }
            urls.put(type, newURL);
        }

        // if the files are local check each file to see if it exists
        // if not then search for a file of the same name but try all combinations of the 
        // different cases that the extension can be made up of.
        // IE Shp, SHP, Shp, ShP etc...
        if( isLocal() ){
            Set<Entry<ShpFileType, URL>> entries = urls.entrySet();
            Map<ShpFileType, URL> toUpdate = new HashMap<ShpFileType, URL>();
            for (Entry<ShpFileType, URL> entry : entries) {
                if( !exists(entry.getKey()) ){
                    url = findExistingFile(entry.getKey(), entry.getValue());
                    if( url!=null ){
                        toUpdate.put(entry.getKey(), url);
                    }
                }
            }
            
            urls.putAll(toUpdate);
            
        }
        
    }

    private URL findExistingFile(ShpFileType shpFileType, URL value) {
        final File file = DataUtilities.urlToFile(value);
        File directory = file.getParentFile();
        if( directory==null ){
            // doesn't exist
            return null;
        }
        File[] files = directory.listFiles(new FilenameFilter(){

            public boolean accept(File dir, String name) {
                return file.getName().equalsIgnoreCase(name);
            }
            
        });
        if( files.length>0 ){
            try {
                return files[0].toURI().toURL();
            } catch (MalformedURLException e) {
                ShapefileDataStoreFactory.LOGGER.log(Level.SEVERE, "", e);
            }
        }
        return null;
    }

    /**
     * This verifies that this class has been closed correctly (nothing locking)
     */
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        dispose();
    }

    void dispose() {
        if (numberOfLocks() != 0) {
            logCurrentLockers(Level.SEVERE);
            lockers.clear(); // so as not to get this log again.
        }
    }

    /**
     * Writes to the log all the lockers and when they were constructed.
     * 
     * @param logLevel
     *                the level at which to log.
     */
    public void logCurrentLockers(Level logLevel) {
        for (ShpFilesLocker locker : lockers) {
            ShapefileDataStoreFactory.LOGGER
                    .log(
                            logLevel,
                            "The following locker still has a lock

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -