rpffileindex.java

来自「world wind java sdk 源码」· Java 代码 · 共 1,054 行 · 第 1/3 页

JAVA
1,054
字号
/* Copyright (C) 2001, 2007 United States Government as represented by
the Administrator of the National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.layers.rpf;

import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.util.Logging;

import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * @author dcollins
 * @version $Id: RPFFileIndex.java 4565 2008-02-28 17:53:41Z dcollins $
 */
public class RPFFileIndex
{
    private final Table rpfFileTable;
    private final Table waveletTable;
    private final Table directoryTable;
    private final IndexProperties properties;
    private static final String FILE_ID = "RPF_FILE_INDEX";
    private static final String VERSION = "VERSION_0_1";
    private static final int FILE_ID_LENGTH = 16;
    private static final int VERSION_LENGTH = 16;

    public RPFFileIndex()
    {
        this.rpfFileTable = new Table();
        this.waveletTable = new Table();
        this.directoryTable = new Table();
        this.rpfFileTable.setRecordFactory(new RecordFactory() {
            public Record newRecord(long key) {
                return new RPFFileRecord(key);
            }
        });
        this.waveletTable.setRecordFactory(new RecordFactory() {
            public Record newRecord(long key) {
                return new WaveletRecord(key);
            }
        });
        this.directoryTable.setRecordFactory(new RecordFactory() {
            public Record newRecord(long key) {
                return new DirectoryRecord(key);
            }
        });
        this.properties = new IndexProperties();
    }

    public Table getRPFFileTable()
    {
        return this.rpfFileTable;
    }

    public Table getWaveletTable()
    {
        return this.waveletTable;
    }

    public Table getDirectoryTable()
    {
        return this.directoryTable;
    }

    public IndexProperties getIndexProperties()
    {
        return properties;
    }

    public File getRPFFile(long key)
    {
        if (key == Table.INVALID_KEY)
        {
            String message = "key is invalid: " + key;
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        File file = null;
        RPFFileRecord rec = (RPFFileRecord) this.rpfFileTable.getRecord(key);
        if (rec != null)
        {
            file = getFile(rec.getFilename(), rec.getDirectorySecondaryKey());
        }
        return file;
    }

    public File getWaveletFile(long key)
    {
        if (key == Table.INVALID_KEY)
        {
            String message = "key is invalid: " + key;
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        File file = null;
        WaveletRecord rec = (WaveletRecord) this.waveletTable.getRecord(key);
        if (rec != null)
        {
            file = getFile(rec.getFilename(), rec.getDirectorySecondaryKey());
        }
        return file;
    }

    private File getFile(String filename, long directoryKey)
    {
        File file = null;
        if (directoryKey != Table.INVALID_KEY)
        {
            DirectoryRecord dirRec = (DirectoryRecord) this.directoryTable.getRecord(directoryKey);
            file = new File(dirRec != null ? dirRec.getPath() : null, filename);
        }
        return file;
    }

    public Record createRPFFileRecord(File file)
    {
        if (file == null)
        {
            String message = Logging.getMessage("nullValue.FileIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        // Attempt to create a directory record from the File's parent-file.
        String directory = file.getParent();
        Record dirRecord = createDirectoryRecord(directory);

        // Attempt to create a file record from the File's name.
        String filename = file.getName();
        Record record = this.rpfFileTable.createRecord();
        ((RPFFileRecord) record).filename = filename;
        ((RPFFileRecord) record).directorySecondaryKey = dirRecord != null ? dirRecord.getKey() : Table.INVALID_KEY;    

        return record;
    }

    public Record createWaveletRecord(File file, long rpfFileKey)
    {
        if (file == null)
        {
            String message = Logging.getMessage("nullValue.FileIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        // Attempt to create a directory record from the File's parent-file.
        String directory = file.getParent();
        Record dirRecord = createDirectoryRecord(directory);

        // Attempt to create a file record from the File's name.
        String filename = file.getName();
        Record record = this.waveletTable.createRecord();
        ((WaveletRecord) record).filename = filename;
        ((WaveletRecord) record).directorySecondaryKey = dirRecord != null ? dirRecord.getKey() : Table.INVALID_KEY;

        // Attempt to update the RPFFileRecord.
        Record rpfRecord = this.rpfFileTable.getRecord(rpfFileKey);
        if (rpfRecord != null)
        {
            ((RPFFileRecord) rpfRecord).waveletSecondaryKey = record.getKey();
            ((WaveletRecord) record).rpfFileSecondaryKey = rpfRecord.getKey();
        }

        return record;
    }

    private synchronized Record createDirectoryRecord(String path)
    {
        Record record = null;
        if (path != null)
        {
            for (Record rec : this.directoryTable.getRecords())
            {
                if (((DirectoryRecord) rec).path.equals(path))
                {
                    record = rec;
                    break;
                }
            }

            if (record == null)
            {
                record = this.directoryTable.createRecord();
                ((DirectoryRecord) record).path = path;
            }
        }
        return record;
    }

    public void updateBoundingSector()
    {
        Sector bs = null;
        for (Record rec : this.rpfFileTable.getRecords())
        {
            RPFFileRecord rpfRec = (RPFFileRecord) rec;
            Sector fs = rpfRec.getSector();
            // If the entry has no sector, then ignore it.
            if (fs != null)
                bs = (bs != null ? bs.union(fs) : fs);
        }

        if (bs != null)
        {
            bs = Sector.fromDegrees(
                clamp(bs.getMinLatitude().degrees, -90d, 90d),
                clamp(bs.getMaxLatitude().degrees, -90d, 90d),
                clamp(bs.getMinLongitude().degrees, -180d, 180d),
                clamp(bs.getMaxLongitude().degrees, -180d, 180d));
        }
        this.properties.setBoundingSector(bs);
    }

    private static double clamp(double x, double min, double max)
    {
        return x < min ? min : x > max ? max : x;
    }

    public void load(java.nio.ByteBuffer buffer) throws IOException
    {
        if (buffer == null)
        {
            String message = Logging.getMessage("nullValue.ByteBufferIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }

        String fileId = getString(buffer, FILE_ID_LENGTH);
        if (!FILE_ID.equals(fileId))
        {
            String message = "buffer does not contain an RPFFileIndex";
            Logging.logger().severe(message);
            throw new IOException(message);
        }
        //noinspection UnusedDeclaration
        String version = getString(buffer, VERSION_LENGTH);

        LocationSection locationSection = new LocationSection(buffer);
        this.properties.load(buffer, locationSection.getInformationSectionLocation());
        this.rpfFileTable.load(buffer, locationSection.getRPFFileTableSectionLocation());
        this.waveletTable.load(buffer, locationSection.getWaveletTableSectionLocation());
        this.directoryTable.load(buffer, locationSection.getDirectoryTableSectionLocation());
    }

    public java.nio.ByteBuffer save() throws IOException
    {
        java.nio.ByteBuffer informationSectionBuffer = this.properties.save();
        java.nio.ByteBuffer rpfFileTableBuffer = this.rpfFileTable.save();
        java.nio.ByteBuffer waveletTableBuffer = this.waveletTable.save();
        java.nio.ByteBuffer directoryTableBuffer = this.directoryTable.save();

        int location = FILE_ID_LENGTH + VERSION_LENGTH;
        LocationSection locationSection = new LocationSection();
        location += locationSection.locationSectionLength;
        locationSection.setInformationSection(informationSectionBuffer.limit(), location);
        location += informationSectionBuffer.limit();
        locationSection.setRPFFileTableSection(rpfFileTableBuffer.limit(), location);
        location += rpfFileTableBuffer.limit();
        locationSection.setWaveletTableSection(waveletTableBuffer.limit(), location);
        location += waveletTableBuffer.limit();
        locationSection.setDirectoryTableSection(directoryTableBuffer.limit(), location);
        location += directoryTableBuffer.limit();
        
        java.nio.ByteBuffer locationSectionBuffer = locationSection.save();

        int length =
            FILE_ID_LENGTH + VERSION_LENGTH
            + locationSectionBuffer.limit()
            + informationSectionBuffer.limit()
            + rpfFileTableBuffer.limit()
            + waveletTableBuffer.limit()
            + directoryTableBuffer.limit();
        java.nio.ByteBuffer buffer = java.nio.ByteBuffer.allocate(length);

        putString(buffer, FILE_ID, FILE_ID_LENGTH);
        putString(buffer, VERSION, VERSION_LENGTH);
        buffer.put(locationSectionBuffer);
        buffer.put(informationSectionBuffer);
        buffer.put(rpfFileTableBuffer);
        buffer.put(waveletTableBuffer);
        buffer.put(directoryTableBuffer);

        buffer.flip();
        return buffer;
    }

    public static class Table
    {
        private final List<Record> records;
        private final Map<Long, Record> keyIndex;
        private RecordFactory recordFactory;
        private volatile long uniqueKey = INVALID_KEY;
        static final long INVALID_KEY = -1L;

        public Table()
        {
            this.records = new ArrayList<Record>();
            this.keyIndex = new HashMap<Long, Record>();
            this.recordFactory = new DefaultRecordFactory();
        }

        public final List<Record> getRecords()
        {
            return this.records;
        }

        public final Record getRecord(long key)
        {
            Record found = null;
            if (key != INVALID_KEY)
            {
                found = this.keyIndex.get(key);
            }
            return found;
        }

        public RecordFactory getRecordFactory()
        {
            return this.recordFactory;
        }

        public void setRecordFactory(RecordFactory recordFactory)
        {
            if (recordFactory == null)
            {
                String message = "RecordFactory is null";
                Logging.logger().severe(message);
                throw new IllegalArgumentException(message);
            }
            
            this.recordFactory = recordFactory;
        }

        public Record createRecord()
        {
            long key = createUniqueKey();
            return newRecord(key);
        }

        Record newRecord(long key)
        {
            Record rec = this.recordFactory.newRecord(key);
            putRecord(key, rec);
            return rec;
        }

        private void putRecord(long key, Record record)
        {

⌨️ 快捷键说明

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