imageutil.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,510 行 · 第 1/5 页
JAVA
1,510 行
private static long computeSizeOfBufferDataType(int bufferDataType) { switch (bufferDataType) { case java.awt.image.DataBuffer.TYPE_BYTE: return (Byte.SIZE / 8); case java.awt.image.DataBuffer.TYPE_DOUBLE: return (Double.SIZE / 8); case java.awt.image.DataBuffer.TYPE_FLOAT: return (Float.SIZE / 8); case java.awt.image.DataBuffer.TYPE_INT: return (Integer.SIZE / 8); case java.awt.image.DataBuffer.TYPE_SHORT: case java.awt.image.DataBuffer.TYPE_USHORT: return (Short.SIZE / 8); case java.awt.image.DataBuffer.TYPE_UNDEFINED: break; } return 0L; } /** * Opens a spatial image. Reprojects the image if it is in UTM projection. * * @param imageFile source image * @param interpolation_mode the interpolation mode if the image is reprojected. * * @return AVList * * @throws IOException if there is a problem opening the file. * @throws WWRuntimeException if the image type is unsupported. */ public static AVList openSpatialImage(File imageFile, int interpolation_mode) throws IOException // TODO: rename { AVList values = new AVListImpl(); BufferedImage image; Sector sector; //Check for Geotiff if ((imageFile.getName().toLowerCase().endsWith(".tiff") || (imageFile.getName().toLowerCase().endsWith( ".tif")))) { GeotiffReader reader = new GeotiffReader(imageFile); image = reader.read(); if (reader.isGeotiff()) { return handleGeotiff(image, reader, interpolation_mode); } } //if not geotiff, contine through for other formats image = ImageIO.read(imageFile); if (image == null) { String message = Logging.getMessage("generic.ImageReadFailed", imageFile); Logging.logger().severe(message); throw new WWRuntimeException(message); } File[] worldFiles = WorldFile.getWorldFiles(imageFile.getAbsoluteFile()); if (worldFiles == null || worldFiles.length == 0) { String message = Logging.getMessage("WorldFile.WorldFileNotFound", imageFile.getAbsolutePath()); Logging.logger().severe(message); throw new FileNotFoundException(message); } values.setValue(AVKey.IMAGE, image); WorldFile.decodeWorldFiles(worldFiles, values); sector = (Sector) values.getValue(AVKey.SECTOR); if (sector == null) ImageUtil.reprojectUtmToGeographic(values, interpolation_mode); sector = (Sector) values.getValue(AVKey.SECTOR); if (sector == null) { String message = "Problem generating bounding sector for the image"; throw new WWRuntimeException(message); } values.setValue(AVKey.SECTOR, sector); return values; } /** * Opens a spatial image. Reprojects the image if it is in UTM projection. * * @param imageFile source image * * @return AVList * * @throws IOException if there is a problem opening the file. */ public static AVList openSpatialImage(File imageFile) throws IOException { return openSpatialImage(imageFile, ImageUtil.NEAREST_NEIGHBOR_INTERPOLATION); } /** * Opens a Geotiff image image. Reprojects the image if it is in UTM projection. * * @param image BufferedImage * @param reader GeotiffReader * @param interpolation_mode the interpolation mode if the image is reprojected. * * @return AVList * * @throws IOException if there is a problem opening the file. */ private static AVList handleGeotiff(BufferedImage image, GeotiffReader reader, int interpolation_mode) throws IOException { AVList values = new AVListImpl(); values.setValue(AVKey.IMAGE, image); Sector sector; if ((reader.getGeoCodec().hasGeoKey(GeoCodec.ProjectionGeoKey) || (reader.getGeoCodec().hasGeoKey( GeoCodec.ProjectedCSTypeGeoKey)))) { char hemi; int zone; int[] vals; if (reader.getGeoCodec().hasGeoKey(GeoCodec.ProjectionGeoKey)) vals = reader.getGeoCodec().getGeoKeyAsInts(GeoCodec.ProjectionGeoKey); else vals = reader.getGeoCodec().getGeoKeyAsInts(GeoCodec.ProjectedCSTypeGeoKey); int projection = vals[0]; /* from http://www.remotesensing.org/geotiff/spec/geotiff6.html#6.3.3.2 UTM (North) Format: 160zz UTM (South) Format: 161zz */ if ((projection >= 16100) && (projection <= 16199)) //UTM Zone South { hemi = 'S'; zone = projection - 16100; } else if ((projection >= 16000) && (projection <= 16099)) //UTM Zone North { hemi = 'N'; zone = projection - 16000; } else if ((projection >= 26900) && (projection <= 26999)) //UTM : NAD83 { hemi = 'N'; zone = projection - 26900; } else if ((projection >= 32600) && (projection <= 32699)) //UTM : WGS84 { hemi = 'N'; zone = projection - 32600; } else if ((projection >= 32700) && (projection <= 32799)) //UTM : WGS84 { hemi = 'S'; zone = projection - 32700; } else { String message = Logging.getMessage("generic.ProjectionUnsupported"); Logging.logger().severe(message); throw new IOException(message); } //dump "world file" values into values values.setValue(WorldFile.WORLD_FILE_HEMISPHERE, String.valueOf(hemi)); values.setValue(WorldFile.WORLD_FILE_ZONE, Integer.toString(zone)); values.setValue(WorldFile.WORLD_FILE_X_PIXEL_SIZE, reader.getGeoCodec().getModelPixelScaleX()); values.setValue(WorldFile.WORLD_FILE_Y_PIXEL_SIZE, (-1 * reader.getGeoCodec().getModelPixelScaleY())); //shift to center double xD = reader.getGeoCodec().getTiePoints()[0].getX() + (reader.getGeoCodec().getModelPixelScaleX() * .5); double yD = reader.getGeoCodec().getTiePoints()[0].getY() - (reader.getGeoCodec().getModelPixelScaleY() * .5); values.setValue(WorldFile.WORLD_FILE_X_LOCATION, xD); values.setValue(WorldFile.WORLD_FILE_Y_LOCATION, yD); ImageUtil.reprojectUtmToGeographic(values, interpolation_mode); sector = (Sector) values.getValue(AVKey.SECTOR); } else if (reader.getGeoCodec().hasGeoKey(GeoCodec.GeographicTypeGeoKey) && !reader.getGeoCodec() .hasGeoKey(GeoCodec.ProjectedCSTypeGeoKey)) { //assumes GEO todo check for geo code 4326 double[] bbox = reader.getGeoCodec().getBoundingBox(image.getWidth(), image.getHeight()); sector = new Sector(Angle.fromDegreesLatitude(bbox[3]), Angle.fromDegreesLatitude(bbox[1]), Angle.fromDegreesLongitude(bbox[0]), Angle.fromDegreesLongitude(bbox[2])); } else { String message = Logging.getMessage("generic.ProjectionUnsupported"); Logging.logger().severe(message); throw new IOException(message); } values.setValue(AVKey.SECTOR, sector); return values; } /** * Reprojects an imge in UTM projection to Geo/WGS84. * * @param values AVList: contains the bufferedimage and the values from the world file. Stores resulting image in * values * @param mode the interpolation mode if the image is reprojected. */ public static void reprojectUtmToGeographic(AVList values, int mode) { //TODO pull these const from TMCoord? double False_Easting = 500000; double False_Northing = 0; double Scale = 0.9996; Earth earth = new Earth(); //need globe for TM if (values == null) { String message = Logging.getMessage("nullValue.ImageSource"); // TODO: correct log message Logging.logger().severe(message); throw new IllegalStateException(message); } BufferedImage image = (BufferedImage) values.getValue(AVKey.IMAGE); int width = image.getWidth(); int height = image.getHeight(); BufferedImage biOut; //Note: image type always BufferedImage.TYPE_INT_ARGB to handle transparent no-data areas after reprojection if ((image.getColorModel() != null) && (image.getColorModel() instanceof IndexColorModel)) { biOut = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB, (IndexColorModel) image.getColorModel()); } else { biOut = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); } double xPixelSize = 0; double yPixelSize = 0; Object o = values.getValue(WorldFile.WORLD_FILE_X_PIXEL_SIZE); if (o != null && o instanceof Double) xPixelSize = (Double) o; o = values.getValue(WorldFile.WORLD_FILE_Y_PIXEL_SIZE); if (o != null && o instanceof Double) yPixelSize = (Double) o; // TODO: validate that all these values exist and are valid double xLocation = (Double) values.getValue(WorldFile.WORLD_FILE_X_LOCATION); double yLocation = (Double) values.getValue(WorldFile.WORLD_FILE_Y_LOCATION); int zone = Integer.parseInt((String) values.getValue(WorldFile.WORLD_FILE_ZONE)); char hemisphere = ((String) values.getValue(WorldFile.WORLD_FILE_HEMISPHERE)).charAt(0); UTMCoord upperLeft = UTMCoord.fromUTM(zone, hemisphere, xLocation, yLocation); UTMCoord utmUpperLeft = UTMCoord.fromUTM(zone, hemisphere, upperLeft.getEasting() - xPixelSize * .5, upperLeft.getNorthing() - yPixelSize * .5); UTMCoord utmLowerRight = UTMCoord.fromUTM(zone, hemisphere, utmUpperLeft.getEasting() + (width * xPixelSize), utmUpperLeft.getNorthing() + (height * yPixelSize)); //Get rect Geo bbox UTMCoord utmLowerLeft = UTMCoord.fromUTM(zone, upperLeft.getHemisphere(), utmUpperLeft.getEasting(), utmLowerRight.getNorthing()); UTMCoord utmUpperRight = UTMCoord.fromUTM(zone, upperLeft.getHemisphere(), utmLowerRight.getEasting(), utmUpperLeft.getNorthing()); Angle rightExtent = Angle.max(utmUpperRight.getLongitude(), utmLowerRight.getLongitude()); Angle leftExtent = Angle.min(utmLowerLeft.getLongitude(), utmUpperLeft.getLongitude()); Angle topExtent = Angle.max(utmUpperRight.getLatitude(), utmUpperLeft.getLatitude()); Angle bottomExtent = Angle.min(utmLowerRight.getLatitude(), utmLowerLeft.getLatitude()); Sector sector = new Sector(bottomExtent, topExtent, leftExtent, rightExtent); values.setValue(AVKey.SECTOR, sector); //moving to center of pixel double yPixel = (bottomExtent.getDegrees() - topExtent.getDegrees()) / height; double xPixel = (rightExtent.getDegrees() - leftExtent.getDegrees()) / width; double topExtent2 = sector.getMaxLatitude().getDegrees() + (yPixel * .5); double leftExtent2 = sector.getMinLongitude().getDegrees() + (xPixel * .5); TMCoord tmUpperLeft = TMCoord.fromLatLon(utmUpperLeft.getLatitude(), utmUpperLeft.getLongitude(), earth, Angle.fromDegrees(0.0), utmUpperLeft.getCentralMeridian(), False_Easting, False_Northing, Scale); double srcTop = tmUpperLeft.getNorthing() + (yPixelSize * .5); double srcLeft = tmUpperLeft.getEasting() + (xPixelSize * .5); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { double yTarget = topExtent2 + y * yPixel; double xTarget = leftExtent2 + x * xPixel; TMCoord TM = TMCoord.fromLatLon(Angle.fromDegreesLatitude(yTarget), Angle.fromDegreesLongitude(xTarget), earth, Angle.fromDegrees(0.0), utmUpperLeft.getCentralMeridian(), False_Easting, False_Northing, Scale); double distFromCornerX = TM.getEasting() - srcLeft;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?