Java GDAL简单工具类

package cn.piesat.pielib.common.utils;

import org.gdal.gdal.Band;
import org.gdal.gdal.ColorTable;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.ogr.*;
import org.gdal.osr.SpatialReference;

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class GdalUtil {
    // GBK的编码格式
    private static final String CODE_GBK="0x4D";
    // CGCS2000坐标系
    private static String proWkt = "GEOGCS['GCS_China_Geodetic_Coordinate_System_2000',DATUM['China_2000',SPHEROID['CGCS2000',6378137.0,298.257222101]],PRIMEM['Greenwich',0.0],UNIT['Degree',0.0174532925199433]]";
    private static Driver shpDriver;
    private static Driver tiffDriver;
    static {
        ogr.RegisterAll();
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        gdal.SetConfigOption("SHAPE_ENCODING", "");
        shpDriver = ogr.GetDriverByName("ESRI Shapefile");
    }

    /**
     * 获取DataSource
     */
    public static DataSource getShpDataSource(String shpFilePath){
        if(isShpFileGBK(shpFilePath)){
            gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
        }else{
            gdal.SetConfigOption("SHAPE_ENCODING", "");
        }
        shpDriver = ogr.GetDriverByName("ESRI Shapefile");
        DataSource dataSource = shpDriver.Open(shpFilePath);
        return dataSource;
    }

    /**
     * 判断shp编码格式是否为GBK
     */
    public static boolean isShpFileGBK(String shpFilePath){
        InputStream in  =null;
        File dbfFile = null;
        boolean isGBK = false;
        try {
            String dbfFilePath = shpFilePath.substring(0,shpFilePath.lastIndexOf("."));
            dbfFile = new File(dbfFilePath+".dbf");
            if(dbfFile.exists()){
                in = new FileInputStream(dbfFile);
                byte[] bytes = new byte[30];
                in.read(bytes);
                byte b = bytes[29];
                if(CODE_GBK.equalsIgnoreCase("0x"+Integer.toHexString(Byte.toUnsignedInt(b)))){
                    isGBK = true;
                }
            }
            in.close();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (in!=null){
                try {
                    in.close();
                }catch (Exception ex){
                    ex.printStackTrace();
                }
            }
        }
        return isGBK;
    }

    /**
     * 获取Shp文件的投影信息
     */
    public static SpatialReference getShpSpatialReference(String shpFilePath){
        DataSource ds = getShpDataSource(shpFilePath);
        if(null != ds){
            return ds.GetLayer(0).GetSpatialRef();
        }
        ds.delete();
        ds = null;
        return null;
    }

    /**
     * 获取Shp的中心点
     */
    public double[] getShpCenter(String shpFilePath){
        double[] center = {0,0};
        double[] envelope = getShpEnvelope(shpFilePath);
        if(null != envelope && envelope.length ==4){
            double xMin = envelope[0];
            double yMin = envelope[1];
            double xMax = envelope[2];
            double yMax = envelope[3];
            double xCenter = (xMin + xMax)/2;
            double yCenter = (yMin + yMax)/2;
            center[0] = xCenter;
            center[1] = yCenter;
        }
        return center;
    }

    /**
     * 获取Shp的最小外接矩形
     */
    public double[] getShpEnvelope(String shpFilePath){
        DataSource ds = getShpDataSource(shpFilePath);
        if(ds == null){
            return null;
        }
        Layer lyr = ds.GetLayer(0);
        long size = lyr.GetFeatureCount();
        System.out.println(size);
        Feature feature = lyr.GetNextFeature();
        double [] envelope  = new double[]{1,2,3,4};
        feature.GetGeometryRef().GetEnvelope(envelope);
        feature.delete();
        feature = null;
        lyr.delete();
        lyr = null;
        ds.delete();
        ds = null;
        return envelope;
    }

    /**
     * 获取Geometry的中心点
     */
    public double[] getGeometryCenter(Geometry geometry){
        double [] envelope  = new double[]{1,2,3,4};
        geometry.GetEnvelope(envelope);
        double[] center = {0,0};
        if(null != envelope && envelope.length ==4){
            double xMin = envelope[0];
            double yMin = envelope[1];
            double xMax = envelope[2];
            double yMax = envelope[3];
            double xCenter = (xMin + xMax)/2;
            double yCenter = (yMin + yMax)/2;
            center[0] = xCenter;
            center[1] = yCenter;
        }
        return center;
    }

    /**
     * 获取Geometry的最小外接矩形
     */
    public double[] getGeometryEnvelope(Geometry geometry){
        double [] envelope  = new double[]{1,2,3,4};
        geometry.GetEnvelope(envelope);
        return envelope;
    }

    /**
     * GeoJSON转WKT
     */
    public static String geoJson2WKT(String geoJson){
        Geometry geometry = Geometry.CreateFromJson(geoJson);
        String wkt = geometry.ExportToWkt();
        geometry.delete();
        geometry = null;
        return wkt;
    }

    /**
     * WKT转GeoJSON
     */
    public static String wkt2GeoJson(String wkt){
        Geometry geometry = Geometry.CreateFromJson(wkt);
        String geoJson = geometry.ExportToJson();
        geometry.delete();
        geometry = null;
        return geoJson;
    }

    /**
     * Geometry投影转换
     */
    public static void geometryTransform(Geometry geometry, int destEpsg){
        SpatialReference destSr = new SpatialReference();
        destSr.ImportFromEPSG(destEpsg);
        if(null != geometry){
            geometry.TransformTo(destSr);
        }
        destSr.delete();
        destSr = null;
    }

    /**
     * Geometry投影转换
     */
    public static void geometryTransform(Geometry geometry,int oldEpsg, int destEpsg){
        SpatialReference oldSr = new SpatialReference();
        oldSr.ImportFromEPSG(oldEpsg);
        SpatialReference destSr = new SpatialReference();
        destSr.ImportFromEPSG(destEpsg);
        if(null != geometry){
            geometry.AssignSpatialReference(oldSr);
            geometry.TransformTo(destSr);
        }
        oldSr.delete();
        oldSr = null;
        destSr.delete();
        destSr = null;
    }

    /**
     * Shp文件投影转换
     *
     * @param shpFilePath
     * @param destShpFilePath
     */
    public static void shpTransform(String shpFilePath, String destShpFilePath, int epsg) {
        try {
            if(isShpFileGBK(shpFilePath)){
                gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
            }else{
                gdal.SetConfigOption("SHAPE_ENCODING", "");
            }
            shpDriver = ogr.GetDriverByName("ESRI Shapefile");
            DataSource resultDS = shpDriver.CreateDataSource(destShpFilePath,null);
            DataSource oDS = getShpDataSource(shpFilePath);
            SpatialReference dst = new SpatialReference();
            dst.ImportFromEPSG(epsg);
            Layer shpLayer = oDS.GetLayer(0);
            String shpLayerName = shpLayer.GetName();
            Layer resultLayer = resultDS.CreateLayer(shpLayerName, dst, shpLayer.GetGeomType());
            FeatureDefn featureDefn = shpLayer.GetLayerDefn();
            for (int fieldIndex = 0; fieldIndex < featureDefn.GetFieldCount(); fieldIndex++) {
                FieldDefn fde = featureDefn.GetFieldDefn(fieldIndex);
                if (fde.GetFieldType() == ogr.OFTReal) {
                    fde.SetPrecision(4);
                }
                resultLayer.CreateField(fde);
            }
            Feature feature = null;
            while ((feature = shpLayer.GetNextFeature()) != null) {
                Geometry geometry = feature.GetGeometryRef();
                geometry.TransformTo(dst);
                resultLayer.CreateFeature(feature.Clone());
                geometry.delete();
                feature.delete();
                feature = null;
            }
            // 存储到硬盘
            resultLayer.SyncToDisk();
            featureDefn.delete();
            dst.delete();
            resultLayer.delete();
            shpLayer.delete();
            oDS.delete();
            resultDS.delete();
            featureDefn = null;
            dst = null;
            resultLayer = null;
            shpLayer = null;
            oDS = null;
            resultDS = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取proj.4
     */
    public static String getSpatialReferenceProj4(SpatialReference sr){
        return sr.ExportToProj4();
    }

    /**
     * Tiff转Png
     */
    public static void getPngFromTiff(String tiffFilePath, String pngFilePath){
        Dataset tiffDataset = gdal.Open(tiffFilePath);
        org.gdal.gdal.Driver pngDriver = gdal.GetDriverByName("PNG");
        Dataset pngDataset = pngDriver.CreateCopy(pngFilePath, tiffDataset);
        tiffDataset.delete();
        tiffDataset = null;
        pngDataset.delete();
        pngDataset = null;
    }

    /**
     * Tiff转png
     */
    public static void getPngFromTiff(String tiffFilePath, String pngFilePath, int nWidth, int nHeight, boolean isSeries) throws IOException {
        Dataset tiffDataset = gdal.Open(tiffFilePath);
        int oWidth = tiffDataset.getRasterXSize();
        int oHeight = tiffDataset.getRasterYSize();
        if(!isSeries){
            nHeight = nWidth*oHeight/oWidth;
        }
        int rasterCount = tiffDataset.GetRasterCount();
        if(rasterCount == 1){
            Band band = tiffDataset.GetRasterBand(1);
            ColorTable colorTable = band.GetColorTable();
            byte[] bytes = new byte[nWidth * nHeight];
            band.ReadRaster(0, 0, oWidth, oHeight, nWidth, nHeight, band.getDataType(), bytes);
            BufferedImage image = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_INT_RGB);
            for(int i=0; i< nWidth; i++){
                for(int j=0; j< nHeight; j++){
                    int entry = bytes[nWidth*j + i] & 0xff;
                    Color color = colorTable.GetColorEntry(entry);
                    image.setRGB(i, j, color.getRGB());
                }
            }

            File imgFile = new File(pngFilePath);
            ImageIO.write(image, "JPEG", imgFile);
        }else if(rasterCount >= 3){
            byte[] bytes = new byte[nWidth*nHeight*3];
            tiffDataset.ReadRaster(0, 0, oWidth, oHeight, nWidth, nHeight, tiffDataset.GetRasterBand(1).getDataType(),
                    bytes, new int[]{1,2,3});
            BufferedImage image = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_INT_RGB);
            for(int i=0; i< nWidth; i++){
                for(int j=0; j< nHeight; j++){
                    int r = bytes[nWidth*j + i] & 0xff;
                    int g = bytes[nWidth*nHeight +  nWidth*j + i] & 0xff;
                    int b = bytes[nWidth*nHeight*2 + nWidth*j + i] & 0xff;
                    Color color = new Color(r, g, b);
                    image.setRGB(i, j, color.getRGB());
                }
            }
            File imgFile = new File(pngFilePath);
            ImageIO.write(image, "JPEG", imgFile);
        }

        tiffDataset.delete();
        tiffDataset = null;
    }

    /**
     * Tiff缩放
     */
    public static void tiffScaleTranslate(String oldTiffFilePath, String newTiffFilePath, float scale){
        Dataset oTiffDataset = gdal.Open(oldTiffFilePath);
        int oWidth = oTiffDataset.GetRasterXSize();
        int oHeight = oTiffDataset.GetRasterYSize();
        int nWidth = Math.round(oWidth*scale);
        int nHeight = Math.round(oHeight*scale);
        int bandCount = oTiffDataset.getRasterCount();
        Dataset nTiffDataset = gdal.GetDriverByName("GTiff").Create(newTiffFilePath, nWidth, nHeight, bandCount);
        byte[] bytes = new byte[nWidth * nHeight*bandCount];
        int[] bandArray = new int[bandCount];
        for(int i=0; i<bandCount; i++){
            bandArray[i] = i + 1;
        }

        oTiffDataset.ReadRaster(0, 0, oWidth, oHeight, nWidth, nHeight,
                oTiffDataset.GetRasterBand(1).getDataType(), bytes, bandArray);
        nTiffDataset.WriteRaster(0, 0, nWidth, nHeight, nWidth, nHeight,
                oTiffDataset.GetRasterBand(1).getDataType(), bytes, bandArray);
        nTiffDataset.delete();
        nTiffDataset = null;
        oTiffDataset.delete();
        oTiffDataset = null;
    }
}
 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值