public int countImagesInSector(Sector sector, int levelNumber) { if (sector == null) { String msg = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } Level targetLevel = this.levels.getLastLevel(); if (levelNumber >= 0) { for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) { if (this.levels.isLevelEmpty(i)) continue; targetLevel = this.levels.getLevel(i); break; } } // Collect all the tiles intersecting the input sector. LatLon delta = targetLevel.getTileDelta(); Angle latOrigin = this.levels.getTileOrigin().getLatitude(); Angle lonOrigin = this.levels.getTileOrigin().getLongitude(); final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin); final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin); final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin); final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin); int numRows = nwRow - seRow + 1; int numCols = seCol - nwCol + 1; return numRows * numCols; }
/** * Causes the View attached to the specified WorldWindow to animate to the specified sector. The * View starts animating at its current location and stops when the sector fills the window. * * @param wwd the WorldWindow who's View animates. * @param sector the sector to go to. * @throws IllegalArgumentException if either the <code>wwd</code> or the <code>sector</code> are * <code>null</code>. */ public static void goTo(WorldWindow wwd, Sector sector) { if (wwd == null) { String message = Logging.getMessage("nullValue.WorldWindow"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } // Create a bounding box for the specified sector in order to estimate its size in model // coordinates. Box extent = Sector.computeBoundingBox( wwd.getModel().getGlobe(), wwd.getSceneController().getVerticalExaggeration(), sector); // Estimate the distance between the center position and the eye position that is necessary to // cause the sector to // fill a viewport with the specified field of view. Note that we change the distance between // the center and eye // position here, and leave the field of view constant. Angle fov = wwd.getView().getFieldOfView(); double zoom = extent.getRadius() / fov.cosHalfAngle() / fov.tanHalfAngle(); // Configure OrbitView to look at the center of the sector from our estimated distance. This // causes OrbitView to // animate to the specified position over several seconds. To affect this change immediately use // the following: // ((OrbitView) wwd.getView()).setCenterPosition(new Position(sector.getCentroid(), 0d)); // ((OrbitView) wwd.getView()).setZoom(zoom); wwd.getView().goTo(new Position(sector.getCentroid(), 0d), zoom); }
public void flush() throws IOException { if (!dirty) return; FileOutputStream fos = null; OutputStreamWriter osw = null; try { fos = new FileOutputStream(filePath); osw = new OutputStreamWriter(fos, charset); // 全局数据 for (Line l : globalLines) { osw.write(l.toString()); osw.write('\n'); } // 各个块 for (Sector s : sectors) { osw.write(s.toString()); } dirty = false; } finally { // XXX 因为stream之间有一定的依赖顺序,必须按照一定的顺序关闭流 if (osw != null) osw.close(); if (fos != null) fos.close(); } }
public static void main(String[] args) { String testDataLocation = "testData/HighResolutionTerrain/"; HashMap<String, Sector> sectors = new HashMap<String, Sector>(); sectors.put( testDataLocation + "HRTOutputTest01.txt", Sector.fromDegrees(37.8, 38.3, -120, -119.3)); sectors.put( testDataLocation + "HRTOutputTest02.txt", Sector.fromDegrees(32.34767, 32.77991, 70.88239, 71.47658)); sectors.put( testDataLocation + "HRTOutputTest03.txt", Sector.fromDegrees(32.37825, 71.21130, 32.50050, 71.37926)); try { if (args.length > 0 && args[0].equals("-generateTestData")) { for (Map.Entry<String, Sector> sector : sectors.entrySet()) { String filePath = sector.getKey(); generateReferenceValues(filePath, sector.getValue()); } } for (Map.Entry<String, Sector> sector : sectors.entrySet()) { String filePath = sector.getKey(); ArrayList<Position> referencePositions = readReferencePositions(filePath); ArrayList<Position> computedPositions = computeElevations(referencePositions); testPositions(filePath, referencePositions, computedPositions); } } catch (FileNotFoundException e) { e.printStackTrace(); } }
protected static boolean isSectorVisible( DrawContext dc, Sector sector, double minDistanceSquared, double maxDistanceSquared) { View view = dc.getView(); Position eyePos = view.getEyePosition(); if (eyePos == null) return false; Angle lat = clampAngle(eyePos.getLatitude(), sector.getMinLatitude(), sector.getMaxLatitude()); Angle lon = clampAngle(eyePos.getLongitude(), sector.getMinLongitude(), sector.getMaxLongitude()); Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d); double distSquared = dc.getView().getEyePoint().distanceToSquared3(p); //noinspection RedundantIfStatement if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared) return false; return true; }
private MercatorTextureTile[][] getTilesInSector(Sector sector, int levelNumber) { if (sector == null) { String msg = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } Level targetLevel = this.levels.getLastLevel(); if (levelNumber >= 0) { for (int i = levelNumber; i < this.getLevels().getLastLevel().getLevelNumber(); i++) { if (this.levels.isLevelEmpty(i)) continue; targetLevel = this.levels.getLevel(i); break; } } // Collect all the tiles intersecting the input sector. LatLon delta = targetLevel.getTileDelta(); Angle latOrigin = this.levels.getTileOrigin().getLatitude(); Angle lonOrigin = this.levels.getTileOrigin().getLongitude(); final int nwRow = Tile.computeRow(delta.getLatitude(), sector.getMaxLatitude(), latOrigin); final int nwCol = Tile.computeColumn(delta.getLongitude(), sector.getMinLongitude(), lonOrigin); final int seRow = Tile.computeRow(delta.getLatitude(), sector.getMinLatitude(), latOrigin); final int seCol = Tile.computeColumn(delta.getLongitude(), sector.getMaxLongitude(), lonOrigin); int numRows = nwRow - seRow + 1; int numCols = seCol - nwCol + 1; MercatorTextureTile[][] sectorTiles = new MercatorTextureTile[numRows][numCols]; for (int row = nwRow; row >= seRow; row--) { for (int col = nwCol; col <= seCol; col++) { TileKey key = new TileKey(targetLevel.getLevelNumber(), row, col, targetLevel.getCacheName()); Sector tileSector = this.levels.computeSectorForKey(key); MercatorSector mSector = MercatorSector.fromSector(tileSector); // TODO: check sectorTiles[nwRow - row][col - nwCol] = new MercatorTextureTile(mSector, targetLevel, row, col); } } return sectorTiles; }
protected static ArrayList<Position> computeElevations(ArrayList<Position> locations) { Sector sector = Sector.boundingSector(locations); HighResolutionTerrain hrt = new HighResolutionTerrain(new Earth(), sector, null, 1.0); ArrayList<Position> computedPositions = new ArrayList<Position>(); for (LatLon latLon : locations) { Double elevation = hrt.getElevation(latLon); computedPositions.add(new Position(latLon, Math.round(elevation * 10000.0) / 10000.0)); } return computedPositions; }
private boolean needToSplit(DrawContext dc, Sector sector) { Vec4[] corners = sector.computeCornerPoints(dc.getGlobe(), dc.getVerticalExaggeration()); Vec4 centerPoint = sector.computeCenterPoint(dc.getGlobe(), dc.getVerticalExaggeration()); View view = dc.getView(); double d1 = view.getEyePoint().distanceTo3(corners[0]); double d2 = view.getEyePoint().distanceTo3(corners[1]); double d3 = view.getEyePoint().distanceTo3(corners[2]); double d4 = view.getEyePoint().distanceTo3(corners[3]); double d5 = view.getEyePoint().distanceTo3(centerPoint); double minDistance = d1; if (d2 < minDistance) minDistance = d2; if (d3 < minDistance) minDistance = d3; if (d4 < minDistance) minDistance = d4; if (d5 < minDistance) minDistance = d5; double cellSize = (Math.PI * sector.getDeltaLatRadians() * dc.getGlobe().getRadius()) / 20; // TODO return !(Math.log10(cellSize) <= (Math.log10(minDistance) - this.splitScale)); }
public URL getURL(Tile tile, String altImageFormat) throws MalformedURLException { StringBuffer sb; if (this.URLTemplate == null) { sb = new StringBuffer(WWXML.fixGetMapString(tile.getLevel().getService())); if (!sb.toString().toLowerCase().contains("service=wms")) sb.append("service=WMS"); sb.append("&request=GetMap"); sb.append("&version=").append(this.wmsVersion); sb.append(this.crs); sb.append("&layers=").append(this.layerNames); sb.append("&styles=").append(this.styleNames != null ? this.styleNames : ""); sb.append("&transparent=TRUE"); if (this.backgroundColor != null) sb.append("&bgcolor=").append(this.backgroundColor); this.URLTemplate = sb.toString(); } else { sb = new StringBuffer(this.URLTemplate); } String format = (altImageFormat != null) ? altImageFormat : this.imageFormat; if (null != format) sb.append("&format=").append(format); sb.append("&width=").append(tile.getWidth()); sb.append("&height=").append(tile.getHeight()); Sector s = tile.getSector(); sb.append("&bbox="); sb.append(s.getMinLongitude().getDegrees()); sb.append(","); sb.append(s.getMinLatitude().getDegrees()); sb.append(","); sb.append(s.getMaxLongitude().getDegrees()); sb.append(","); sb.append(s.getMaxLatitude().getDegrees()); // sb.append("&"); // terminate the query string return new java.net.URL(sb.toString().replace(" ", "%20")); }
public void setString(String sector, String key, String value) { dirty = true; Collection<Line> lines = getSectorLines(sector); if (lines == null) { Sector s = new Sector(); s.name = sector; sectors.add(s); lines = s.lines; } for (Line l : lines) { if (l.key.equals(key)) { l.value = value; return; } } Line l = new Line(); l.key = key; l.equalSign = true; l.value = value; lines.add(l); }
protected boolean isNavSectorVisible( DrawContext dc, double minDistanceSquared, double maxDistanceSquared) { if (!navSector.intersects(dc.getVisibleSector())) return false; View view = dc.getView(); Position eyePos = view.getEyePosition(); if (eyePos == null) return false; // check for eyePos over globe if (Double.isNaN(eyePos.getLatitude().getDegrees()) || Double.isNaN(eyePos.getLongitude().getDegrees())) return false; Angle lat = clampAngle(eyePos.getLatitude(), navSector.getMinLatitude(), navSector.getMaxLatitude()); Angle lon = clampAngle( eyePos.getLongitude(), navSector.getMinLongitude(), navSector.getMaxLongitude()); Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d); double distSquared = dc.getView().getEyePoint().distanceToSquared3(p); //noinspection RedundantIfStatement if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared) return false; return true; }
protected static void legacyWmsRestoreStateToParams( RestorableSupport rs, RestorableSupport.StateObject context, AVList params) { // WMSTiledImageLayer has historically used a different format for storing LatLon and Sector // properties // in the restorable state XML documents. Although WMSTiledImageLayer no longer writes these // properties, // we must provide support for reading them here. Double lat = rs.getStateValueAsDouble(context, AVKey.LEVEL_ZERO_TILE_DELTA + ".Latitude"); Double lon = rs.getStateValueAsDouble(context, AVKey.LEVEL_ZERO_TILE_DELTA + ".Longitude"); if (lat != null && lon != null) params.setValue(AVKey.LEVEL_ZERO_TILE_DELTA, LatLon.fromDegrees(lat, lon)); Double minLat = rs.getStateValueAsDouble(context, AVKey.SECTOR + ".MinLatitude"); Double minLon = rs.getStateValueAsDouble(context, AVKey.SECTOR + ".MinLongitude"); Double maxLat = rs.getStateValueAsDouble(context, AVKey.SECTOR + ".MaxLatitude"); Double maxLon = rs.getStateValueAsDouble(context, AVKey.SECTOR + ".MaxLongitude"); if (minLat != null && minLon != null && maxLat != null && maxLon != null) params.setValue(AVKey.SECTOR, Sector.fromDegrees(minLat, maxLat, minLon, maxLon)); }
protected static ArrayList<Position> generateReferenceLocations( Sector sector, int numLats, int numLons) { ArrayList<Position> locations = new ArrayList<Position>(); double dLat = (sector.getMaxLatitude().degrees - sector.getMinLatitude().degrees) / (numLats - 1); double dLon = (sector.getMaxLongitude().degrees - sector.getMinLongitude().degrees) / (numLons - 1); for (int j = 0; j < numLats; j++) { double lat = sector.getMinLatitude().degrees + j * dLat; for (int i = 0; i < numLons; i++) { double lon = sector.getMinLongitude().degrees + i * dLon; // Specify angles to five decimal places. locations.add( Position.fromDegrees( Math.round(lat * 100000.0) / 100000.0, Math.round(lon * 100000.0) / 100000.0, 0)); } } return locations; }
private static Sector parseSectorName(String line) { int index1 = line.indexOf('['); int index2 = line.indexOf(']'); if (index1 < 0 || index2 < 0 || index1 > index2) return null; int index3 = StringUtil.find_first_of(line, COMMENT_STARTERS, index2); // 检查 space0 int index = StringUtil.find_first_not_of(line, SPACES); if (index < 0 || index < index1) return null; // 检查 space3 index = StringUtil.find_first_not_of(line, SPACES, index2 + 1); if ((index3 < 0 && index >= 0) || (index < index3)) return null; Sector ret = new Sector(); ret.space0 = line.substring(0, index1); if (index3 >= 0) ret.space3 = line.substring(index2 + 1, index3); else ret.space3 = line.substring(index2 + 1); if (index3 >= 0) ret.comment = line.substring(index3); else ret.comment = null; ret.name = line.substring(index1 + 1, index2); index = StringUtil.find_first_not_of(ret.name, SPACES); if (index >= 0) { ret.space1 = ret.name.substring(0, index); ret.name = ret.name.substring(index); index = StringUtil.find_last_not_of(ret.name, SPACES); if (index >= 0) { ret.space2 = ret.name.substring(index + 1); ret.name = ret.name.substring(0, index + 1); } else { ret.space2 = null; } } else { ret.space1 = ret.name; ret.name = null; ret.space2 = null; } return ret; }
public BufferedImage composeImageForSector( Sector sector, int imageWidth, int imageHeight, int levelNumber, String mimeType, boolean abortOnError, BufferedImage image) { if (sector == null) { String message = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (levelNumber < 0) { levelNumber = this.levels.getLastLevel().getLevelNumber(); } else if (levelNumber > this.levels.getLastLevel().getLevelNumber()) { Logging.logger() .warning( Logging.getMessage( "generic.LevelRequestedGreaterThanMaxLevel", levelNumber, this.levels.getLastLevel().getLevelNumber())); levelNumber = this.levels.getLastLevel().getLevelNumber(); } MercatorTextureTile[][] tiles = this.getTilesInSector(sector, levelNumber); if (tiles.length == 0 || tiles[0].length == 0) { Logging.logger().severe(Logging.getMessage("layers.TiledImageLayer.NoImagesAvailable")); return null; } if (image == null) image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); for (MercatorTextureTile[] row : tiles) { for (MercatorTextureTile tile : row) { if (tile == null) continue; BufferedImage tileImage; try { tileImage = this.getImage(tile, mimeType); double sh = ((double) imageHeight / (double) tileImage.getHeight()) * (tile.getSector().getDeltaLat().divide(sector.getDeltaLat())); double sw = ((double) imageWidth / (double) tileImage.getWidth()) * (tile.getSector().getDeltaLon().divide(sector.getDeltaLon())); double dh = imageHeight * (-tile.getSector().getMaxLatitude().subtract(sector.getMaxLatitude()).degrees / sector.getDeltaLat().degrees); double dw = imageWidth * (tile.getSector().getMinLongitude().subtract(sector.getMinLongitude()).degrees / sector.getDeltaLon().degrees); AffineTransform txf = g.getTransform(); g.translate(dw, dh); g.scale(sw, sh); g.drawImage(tileImage, 0, 0, null); g.setTransform(txf); } catch (Exception e) { if (abortOnError) throw new RuntimeException(e); String message = Logging.getMessage("generic.ExceptionWhileRequestingImage", tile.getPath()); Logging.logger().log(java.util.logging.Level.WARNING, message, e); } } } return image; }
private void appendGeoTiff(ArrayList<TiffIFDEntry> ifds, AVList params) throws IOException, IllegalArgumentException { if (null == params || 0 == params.getEntries().size()) { String reason = Logging.getMessage("nullValue.AVListIsNull"); Logging.logger().finest(Logging.getMessage("GeotiffWriter.GeoKeysMissing", reason)); return; } long offset = this.theChannel.position(); if (params.hasKey(AVKey.DISPLAY_NAME)) { String value = params.getStringValue(AVKey.DISPLAY_NAME); if (null != value && 0 < value.trim().length()) { offset = this.theChannel.position(); byte[] bytes = value.trim().getBytes(); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add(new TiffIFDEntry(Tiff.Tag.DOCUMENT_NAME, Tiff.Type.ASCII, bytes.length, offset)); } } if (params.hasKey(AVKey.DESCRIPTION)) { String value = params.getStringValue(AVKey.DESCRIPTION); if (null != value && 0 < value.trim().length()) { offset = this.theChannel.position(); byte[] bytes = value.trim().getBytes(); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add( new TiffIFDEntry(Tiff.Tag.IMAGE_DESCRIPTION, Tiff.Type.ASCII, bytes.length, offset)); } } if (params.hasKey(AVKey.VERSION)) { String value = params.getStringValue(AVKey.VERSION); if (null != value && 0 < value.trim().length()) { offset = this.theChannel.position(); byte[] bytes = value.trim().getBytes(); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add( new TiffIFDEntry(Tiff.Tag.SOFTWARE_VERSION, Tiff.Type.ASCII, bytes.length, offset)); } } if (params.hasKey(AVKey.DATE_TIME)) { String value = params.getStringValue(AVKey.DATE_TIME); if (null != value && 0 < value.trim().length()) { offset = this.theChannel.position(); byte[] bytes = value.getBytes(); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add(new TiffIFDEntry(Tiff.Tag.DATE_TIME, Tiff.Type.ASCII, bytes.length, offset)); } } if (params.hasKey(AVKey.SECTOR)) { if (params.hasKey(AVKey.PIXEL_WIDTH) && params.hasKey(AVKey.PIXEL_HEIGHT)) { offset = this.theChannel.position(); double[] values = new double[] { (Double) params.getValue(AVKey.PIXEL_WIDTH), (Double) params.getValue(AVKey.PIXEL_HEIGHT), isElevation(params) ? 1d : 0d }; byte[] bytes = this.getBytes(values); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add( new TiffIFDEntry( GeoTiff.Tag.MODEL_PIXELSCALE, Tiff.Type.DOUBLE, values.length, offset)); } if (params.hasKey(AVKey.WIDTH) && params.hasKey(AVKey.HEIGHT)) { offset = this.theChannel.position(); double w = (Integer) params.getValue(AVKey.WIDTH); double h = (Integer) params.getValue(AVKey.HEIGHT); Sector sec = (Sector) params.getValue(AVKey.SECTOR); double[] values = new double[] { // i , j, k=0, x, y, z=0 0d, 0d, 0d, sec.getMinLongitude().degrees, sec.getMaxLatitude().degrees, 0d, w - 1, 0d, 0d, sec.getMaxLongitude().degrees, sec.getMaxLatitude().degrees, 0d, w - 1, h - 1, 0d, sec.getMaxLongitude().degrees, sec.getMinLatitude().degrees, 0d, 0d, h - 1, 0d, sec.getMinLongitude().degrees, sec.getMinLatitude().degrees, 0d, }; byte[] bytes = this.getBytes(values); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add( new TiffIFDEntry(GeoTiff.Tag.MODEL_TIEPOINT, Tiff.Type.DOUBLE, values.length, offset)); } // Tiff.Tag.MODEL_TRANSFORMATION excludes Tiff.Tag.MODEL_TIEPOINT & Tiff.Tag.MODEL_PIXELSCALE if (params.hasKey(AVKey.MISSING_DATA_SIGNAL) || params.hasKey(AVKey.MISSING_DATA_REPLACEMENT)) { offset = this.theChannel.position(); Object nodata = params.hasKey(AVKey.MISSING_DATA_SIGNAL) ? params.getValue(AVKey.MISSING_DATA_SIGNAL) : params.getValue(AVKey.MISSING_DATA_REPLACEMENT); String value = "" + nodata + "\0"; byte[] bytes = value.getBytes(); this.theChannel.write(ByteBuffer.wrap(bytes)); ifds.add(new TiffIFDEntry(GeoTiff.Tag.GDAL_NODATA, Tiff.Type.ASCII, bytes.length, offset)); } if (params.hasKey(AVKey.COORDINATE_SYSTEM)) { String cs = params.getStringValue(AVKey.COORDINATE_SYSTEM); if (AVKey.COORDINATE_SYSTEM_GEOGRAPHIC.equals(cs)) { if (isElevation(params)) this.writeGeographicElevationGeoKeys(ifds, params); else this.writeGeographicImageGeoKeys(ifds, params); } else if (AVKey.COORDINATE_SYSTEM_PROJECTED.equals(cs)) { String msg = Logging.getMessage("GeotiffWriter.FeatureNotImplementedd", cs); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); // TODO extract PCS (Projection Coordinate System) } else { String msg = Logging.getMessage("GeotiffWriter.UnknownCoordinateSystem", cs); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } } }
protected void validateParameters(AVList list, int srcWidth, int srcHeight) throws IllegalArgumentException { if (null == list || 0 == list.getValues().size()) { String reason = Logging.getMessage("nullValue.AVListIsNull"); String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", reason); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } if (!(srcWidth > 0 && srcHeight > 0)) { String msg = Logging.getMessage("generic.InvalidImageSize", srcWidth, srcHeight); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } if (list.hasKey(AVKey.WIDTH)) { int width = (Integer) list.getValue(AVKey.WIDTH); if (width != srcWidth) { String msg = Logging.getMessage("GeotiffWriter.ImageWidthMismatch", width, srcWidth); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } else list.setValue(AVKey.WIDTH, srcWidth); if (list.hasKey(AVKey.HEIGHT)) { int height = (Integer) list.getValue(AVKey.HEIGHT); if (height != srcHeight) { String msg = Logging.getMessage("GeotiffWriter.ImageHeightMismatch", height, srcHeight); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } else list.setValue(AVKey.HEIGHT, srcHeight); Sector sector = null; if (list.hasKey(AVKey.SECTOR)) sector = (Sector) list.getValue(AVKey.SECTOR); if (null == sector) { String msg = Logging.getMessage("GeotiffWriter.NoSectorSpecified"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (!list.hasKey(AVKey.COORDINATE_SYSTEM)) { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.COORDINATE_SYSTEM); Logging.logger().finest(msg); // throw new IllegalArgumentException(msg); // assume Geodetic Coordinate System list.setValue(AVKey.COORDINATE_SYSTEM, AVKey.COORDINATE_SYSTEM_GEOGRAPHIC); } if (!list.hasKey(AVKey.PROJECTION_EPSG_CODE)) { if (isGeographic(list)) { // assume WGS84 list.setValue(AVKey.PROJECTION_EPSG_CODE, GeoTiff.GCS.WGS_84); } else { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.PROJECTION_EPSG_CODE); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } } // if PIXEL_WIDTH is specified, we are not overriding it because UTM images // will have different pixel size if (!list.hasKey(AVKey.PIXEL_WIDTH)) { if (isGeographic(list)) { double pixelWidth = sector.getDeltaLonDegrees() / (double) srcWidth; list.setValue(AVKey.PIXEL_WIDTH, pixelWidth); } else { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.PIXEL_WIDTH); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } } // if PIXEL_HEIGHT is specified, we are not overriding it // because UTM images will have different pixel size if (!list.hasKey(AVKey.PIXEL_HEIGHT)) { if (isGeographic(list)) { double pixelHeight = sector.getDeltaLatDegrees() / (double) srcHeight; list.setValue(AVKey.PIXEL_HEIGHT, pixelHeight); } else { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.PIXEL_HEIGHT); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } } if (!list.hasKey(AVKey.PIXEL_FORMAT)) { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.PIXEL_FORMAT); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } else { String pixelFormat = list.getStringValue(AVKey.PIXEL_FORMAT); if (!AVKey.ELEVATION.equals(pixelFormat) && !AVKey.IMAGE.equals(pixelFormat)) { String msg = Logging.getMessage("Geotiff.UnknownGeoKeyValue", pixelFormat, AVKey.PIXEL_FORMAT); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } // validate elevation parameters if (AVKey.ELEVATION.equals(list.getValue(AVKey.PIXEL_FORMAT))) { if (!list.hasKey(AVKey.DATA_TYPE)) { String msg = Logging.getMessage("GeotiffWriter.GeoKeysMissing", AVKey.DATA_TYPE); Logging.logger().finest(msg); throw new IllegalArgumentException(msg); } String type = list.getStringValue(AVKey.DATA_TYPE); if (!AVKey.FLOAT32.equals(type) && !AVKey.INT16.equals(type)) { String msg = Logging.getMessage("Geotiff.UnknownGeoKeyValue", type, AVKey.DATA_TYPE); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } } if (!list.hasKey(AVKey.ORIGIN)) { // set UpperLeft corner as the origin, if not specified LatLon origin = new LatLon(sector.getMaxLatitude(), sector.getMinLongitude()); list.setValue(AVKey.ORIGIN, origin); } if (list.hasKey(AVKey.BYTE_ORDER) && !AVKey.BIG_ENDIAN.equals(list.getStringValue(AVKey.BYTE_ORDER))) { String msg = Logging.getMessage( "generic.UnrecognizedByteOrder", list.getStringValue(AVKey.BYTE_ORDER)); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } if (!list.hasKey(AVKey.DATE_TIME)) { // add NUL (\0) termination as required by TIFF v6 spec (20 bytes length) String timestamp = String.format("%1$tY:%1$tm:%1$td %tT\0", Calendar.getInstance()); list.setValue(AVKey.DATE_TIME, timestamp); } if (!list.hasKey(AVKey.VERSION)) { list.setValue(AVKey.VERSION, Version.getVersion()); } }