/* * Copyright (c) 2016 Metron, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Metron, Inc. nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL METRON, INC. BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.metsci.glimpse.charts.shoreline.gshhs; import java.io.DataInput; import java.io.IOException; import java.util.LinkedHashSet; import java.util.Set; /** * @author hogye */ public class GshhsPolygonHeader { private static final Set<Integer> supportedVersions = new LinkedHashSet<Integer>( ); static { supportedVersions.add( 7 ); supportedVersions.add( 6 ); supportedVersions.add( 4 ); } /** * In GSHHS version 7 (perhaps aka 1.10, version 2) * the polygon type "river-lake" was added and consigned to level 2 */ public static enum PolygonType { land(1), lake(2), islandInLake(3), pondInIslandInLake(4), riverLake(2); public final int level; private PolygonType( int level ) { this.level = level; } } public static enum PolygonDataSource { wdb2, wvs } public static class UnrecognizedValueException extends Exception { private static final long serialVersionUID = 2928195545196276594L; public UnrecognizedValueException( String fieldName, int value ) { super( String.format( "Unrecognized value for %s: %d", fieldName, value ) ); } } public final int id; public final int numVertices; public final PolygonType type; public final boolean crossesGreenwich; public final PolygonDataSource dataSource; public final double westLon_DEG; public final double eastLon_DEG; public final double southLat_DEG; public final double northLat_DEG; /** * Area of polygon in km^2 */ public final double area_KM2; /** * Area of original full-resolution polygon in km^2 (Double.NaN if not supported in GSHHS version) */ public final double area_full; /** * Id of container polygon that encloses this polygon (-1 if none, -2 if not supported in GSHHS version) */ public final int container; /** * Id of ancestor polygon in the full resolution set that was the source of this polygon (-1 if none, -2 if not supported in GSHHS version) */ public final int ancestor; public GshhsPolygonHeader( DataInput in ) throws IOException, UnrecognizedValueException { id = in.readInt( ); numVertices = in.readInt( ); int flag = in.readInt( ); int typeByte = ( flag & 0xff ); int versionByte = ( ( flag >> 8 ) & 0xff ); if ( !supportedVersions.contains( versionByte ) ) throw new UnrecognizedValueException( "version", versionByte ); crossesGreenwich = ( ( ( flag >> 16 ) & 0xff ) == 1 ); int dataSourceByte = ( ( flag >> 24 ) & 0x01 ); switch ( dataSourceByte ) { case 0: dataSource = PolygonDataSource.wdb2; break; case 1: dataSource = PolygonDataSource.wvs; break; default: throw new UnrecognizedValueException( "data source", dataSourceByte ); } boolean riverLake = ( ( flag >> 25 ) & 0x01 ) == 1; if ( versionByte == 7 && riverLake ) { type = PolygonType.riverLake; } else { switch ( typeByte ) { case 1: type = PolygonType.land; break; case 2: type = PolygonType.lake; break; case 3: type = PolygonType.islandInLake; break; case 4: type = PolygonType.pondInIslandInLake; break; default: type = PolygonType.lake; } } westLon_DEG = 1e-6 * in.readInt( ); eastLon_DEG = 1e-6 * in.readInt( ); southLat_DEG = 1e-6 * in.readInt( ); northLat_DEG = 1e-6 * in.readInt( ); area_KM2 = 0.1 * in.readInt( ); if ( versionByte == 7 ) { area_full = 0.1 * in.readInt( ); container = in.readInt( ); ancestor = in.readInt( ); } else { area_full = Double.NaN; container = -2; ancestor = -2; } } }