package com.ztmap.common.utils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ztmap.common.constant.SupportDataType;
import com.ztmap.common.utils.domain.ExcelCellData;
import com.ztmap.common.utils.domain.ExcelDefinition;
import com.ztmap.common.utils.domain.ExcelRowData;
import com.ztmap.common.utils.domain.SpatialDataInfo;
import org.gdal.gdal.Band;
import org.gdal.gdal.ColorTable;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import org.gdal.ogr.*;
import org.gdal.osr.SpatialReference;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ShapeReader {

    private static ShapeReader instance;

    private ShapeReader(String code) {
        //System.out.println(System.getProperty("java.library.path"));
        //注册所有的驱动
        ogr.RegisterAll();
        //为了支持中文路径，请添加下面这句代码
        gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
        //为了使属性表字段支持中文，请添加下面这句
        gdal.SetConfigOption("SHAPE_ENCODING", code);
        //TODO: 设定data目录，待调整
        //F:\release-1800-x64-gdal-2-2-1-mapserver-7-0-6\bin
        gdal.SetConfigOption("GDAL_DATA","F:\\release-1928-x64-dev\\release-1928-x64\\bin\\gdal-data" );
    }

//	private static class ShapeReaderHolder {
//		private static ShapeReader reader = new ShapeReader();
//	}

    public static ShapeReader getIntance(String code) {

        if (instance == null) {
            instance = new ShapeReader(code);
        }

        return instance;
    }

    // D:\\shapes\\云南区县shp\\YN_V_G_QX_Project.shp
    public Layer readLayerFromShp(String strVectorFile) {
        // 打开文件
        DataSource ds = ogr.Open(strVectorFile, 0);

        // 读取图层字段信息
        Layer extentLayer = ds.GetLayer(0);

        return extentLayer;
    }

    public List<ExcelRowData> buildExcelRowsFromLayer(Layer extentLayer, int first, int lastrow, boolean ignoreGeom) {
        FeatureDefn def = extentLayer.GetLayerDefn();
        int fields_count = def.GetFieldCount();
        FieldDefn field_def = null;
        ArrayList<FieldDefn> fields = new ArrayList<FieldDefn>();
        for (int i = 0; i < fields_count; i++) {
            field_def = def.GetFieldDefn(i);
            String field_name = field_def.GetName();
            int field_type = field_def.GetFieldType();
            System.out.println("字段名称：" + field_name + ",字段类型：" + field_def.GetFieldTypeName(field_type));
            fields.add(field_def);
        }

        ExcelRowData row = null;
        List<ExcelCellData> cells = null;
        ExcelCellData cell = null;
        ExcelDefinition defi = null;
        List<ExcelRowData> rows = new ArrayList<ExcelRowData>();
        // 读取每个要素的属性信息
        for (int i = first; i < lastrow; i++) {
            Feature iFeature = extentLayer.GetFeature(i);
            if (null == iFeature) {
                continue;
            }
            row = new ExcelRowData();
            cells = new ArrayList<ExcelCellData>();
            if (!ignoreGeom) {
                Geometry geom = iFeature.GetGeometryRef();
                String str_json = geom.ExportToJson();
                System.out.println(str_json);

                cell = CreateShapeCell();
                cell.setData(str_json);
                cells.add(cell);
            }
            for (int j = 0; j < fields.size(); j++) {
                field_def = (FieldDefn) fields.get(j);
                int fType = field_def.GetFieldType();
                String fieldName = field_def.GetName();
                String fieldType = field_def.GetFieldTypeName(fType);

                cell = new ExcelCellData();
                defi = new ExcelDefinition();
                defi.setColumn(fieldName);
                defi.setTitle(fieldName);
                defi.setDataType(DataTypeTransfer(fieldType));
                cell.setDefinition(defi);

                if (fieldType.equalsIgnoreCase("Integer")) {
                    cell.setData(iFeature.GetFieldAsInteger(fieldName));
                } else if (fieldType.equalsIgnoreCase("Real")) {
                    cell.setData(iFeature.GetFieldAsDouble(fieldName));
                } else if (fieldType.equalsIgnoreCase("String")) {
                    cell.setData(iFeature.GetFieldAsString(fieldName));
                } else if (fieldType.equalsIgnoreCase("Date")) {
                    cell.setData(iFeature.GetFieldAsString(fieldName));
                } else {
                    cell.setData(iFeature.GetFieldAsString(fieldName));
                }

                cells.add(cell);
            }
            row.setCells(cells);
            rows.add(row);
        }
        return rows;
    }

    public static ExcelDefinition CreateShapeDefinition() {
        ExcelDefinition defi = new ExcelDefinition();
        defi.setColumn("Shape");
        defi.setTitle("Shape");
        defi.setShpFlag(true);
        defi.setDataType(SupportDataType.ShapeType);

        return defi;
    }

    public static ExcelCellData CreateShapeCell() {
        ExcelCellData cell = new ExcelCellData();
        ExcelDefinition defi = CreateShapeDefinition();

        cell.setDefinition(defi);

        return cell;
    }

    public static SupportDataType DataTypeTransfer(String fieldType) {
        if (fieldType.equalsIgnoreCase("Integer")) {
            return SupportDataType.NumberType;
        } else if (fieldType.equalsIgnoreCase("Real")) {
            return SupportDataType.NumberType;
        } else if (fieldType.equalsIgnoreCase("String")) {
            return SupportDataType.StringType;
        } else if (fieldType.equalsIgnoreCase("Date")) {
            return SupportDataType.StringType;
        } else {
            return SupportDataType.StringType;
        }
    }

    public List<ExcelDefinition> readShapeDefinitions(String file) {
        List<ExcelDefinition> fields = new ArrayList<>();
        ExcelDefinition defi = null;
        Layer extentLayer = readLayerFromShp(file);
        FeatureDefn def = extentLayer.GetLayerDefn();
        int fields_count = def.GetFieldCount();
        FieldDefn field_def = null;
        // ArrayList<FieldDefn> fields = new ArrayList<FieldDefn>();
        for (int i = 0; i < fields_count; i++) {
            field_def = def.GetFieldDefn(i);
            String fieldName = field_def.GetName();
            int field_type = field_def.GetFieldType();
            // System.out.println("字段名称：" + field_name + ",字段类型：" +
            // field_def.GetFieldTypeName(field_type));
            defi = new ExcelDefinition();
            defi.setColumn(fieldName);
            defi.setTitle(fieldName);
            defi.setDataType(DataTypeTransfer(field_def.GetFieldTypeName(field_type)));

            fields.add(defi);
        }
        fields.add(CreateShapeDefinition());

        return fields;
    }



    public void readRD(String rasterFilePath) {
        List<Map<String,Object>> dataList = new ArrayList<>();
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null){
                System.out.println("Open Failed...");
                return;
            }
            Band raster_band = poSrcDS.GetRasterBand(1);
            //ColorTable colorTable = raster_band.GetRasterColorTable();
            List<Color> colorTable = readRasterColorTable(rasterFilePath);
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            /*int[] buffer = new int[m_Width * m_Height]; // 存储数据的缓冲区
            int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                    gdalconstConstants.GDT_UInt32, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                System.out.println("no...");
                return;
            }
            System.out.println(JSONObject.toJSON(buffer));*/

            double min_value = 0;
            double max_value = 0;
            double no_data_value = 0;

            Double[] vals = new Double[1];
            raster_band.GetMaximum(vals);
            max_value = vals[0];
            raster_band.GetMinimum(vals);
            min_value = vals[0];
            raster_band.GetNoDataValue(vals);
            no_data_value = vals[0];

            System.out.println("OverviewCount="+raster_band.GetOverviewCount());
            if(m_Width > 3000 && raster_band.GetOverviewCount() > 0){

                for(int i=0;i<raster_band.GetOverviewCount();i++) {
                    System.out.println(JSONObject.toJSONString(raster_band.GetOverview(i)));
                }

                raster_band = raster_band.GetOverview(raster_band.GetOverviewCount()/2);
                m_Width = raster_band.GetXSize();
                m_Height = raster_band.GetYSize();
            }

            int[] buffer = new int[m_Width * m_Height]; // 存储数据的缓冲区
            int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,gdalconstConstants.GDT_UInt32, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                System.out.println("no...");
                return;
            }
            //System.out.println(JSONObject.toJSON(buffer));

            int index = 0;
            /*int type = BufferedImage.TYPE_INT_ARGB;
            BufferedImage image = new BufferedImage(m_Width,m_Height, type);
            for(int m=0;m<m_Height;m++){
                for(int n=0;n<m_Width;n++){
                    int value = buffer[index];
                    index++;
                    if(value == 0) continue;

                    Color color = colorTable.get(value);
                    image.setRGB(n,m,color.getRGB());
                }
                //System.out.println("row="+m);
            }

            ImageIO.write(image, "PNG", new File("f:/test.png"));


            if(true) return;*/


            int[] buffer2 = new int[m_Width * m_Height]; // 存储数据的缓冲区
            int index_ = 0;
            int perheight = 1000;
            int pos = 0;
            int[] buffer_ = null;
            for(int m=0;m<m_Height;m++){
                if(m % perheight == 0) {
                    buffer_ = new int[m_Width*perheight];
                    int sjheight = (m+perheight>m_Height?m_Height-m:perheight);
                    raster_band.ReadRaster(0, m, m_Width, sjheight, m_Width, sjheight, gdalconstConstants.GDT_UInt32, buffer_, 0, 0);
                    pos = 0;
                }
                for(int n=0;n<m_Width;n++){
                    if(max_value < buffer_[pos]){
                        buffer2[index_] = 0;
                    }else {
                        buffer2[index_] = buffer_[pos];
                    }
                    pos++;

                    index_++;

                }
            }
            //System.out.println(JSONObject.toJSON(buffer2));
            System.out.println(JSONObject.toJSON(buffer2.length));




            double[] adfGeoTransform = poSrcDS.GetGeoTransform();
            //System.out.println(JSONObject.toJSON(adfGeoTransform));

            index = 0;
            //计算每个像素点的经纬度
            for(int m=0;m<m_Height;m++){
                List<double[]> rows = new ArrayList<>();
                for(int n=0;n<m_Width;n++){
                    double px = adfGeoTransform[0] + n * adfGeoTransform[1] + m * adfGeoTransform[2];
                    double py = adfGeoTransform[3] + n * adfGeoTransform[4] + m * adfGeoTransform[5];
                    Map<String,Object> data = new HashMap<>();
                    //获取value值
                    int value = 0;//buffer[index];

                    index++;

                    data.put("row",m+1);
                    data.put("col",n+1);
                    data.put("value",value);

                    if(value != 0) {
                        //获取Color
                        Color color = colorTable.get(value);
                        data.put("color",JSONObject.toJSON(color)+"");
                    }else{
                        data.put("color","");
                    }
                    /*
                    Map geom = new HashMap();
                    geom.put("type","Point");
                    geom.put("coordinates",new double[]{px,py});
                     */
                    //data.put("Shape","POINT("+px+" "+py+")");
                    data.put("lng",px);
                    data.put("lat",py);
                    dataList.add(data);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws Exception {

        ShapeReader reader = ShapeReader.getIntance("UTF-8");
        String file = "C:\\Users\\小小张丫\\Downloads\\ne_10m_admin_0_countries\\ne_10m_admin_0_countries.shp";
        /*
        String targetFile = "F:\\binguan\\宾馆.json";*/
        Layer layer = reader.readLayerFromShp(file);
        List<Map<String,Object>> ftlist = new ArrayList<>();
        for(int i=0;i<layer.GetFeatureCount();i++){
            Map<String,Object> feature = new HashMap<>();
            ftlist.add(feature);
            Feature iFeature = layer.GetFeature(i);
            for(int j=0;j<iFeature.GetFieldCount();j++){
                feature.put(iFeature.GetFieldDefnRef(j).GetName(),iFeature.GetFieldAsString(j));
            }
            feature.put("Shape:",iFeature.GetGeometryRef().ExportToJson());
        }
        System.out.println(ftlist);
        //System.out.println(System.getenv("PATH"));
        //reader.writeShpJson(file, targetFile);

        //gdal栅格转矢量

        //SpatialDataInfo sdi = reader.readSpatialDataInfo("F:\\LandUse\\landuse.tif");
        //System.out.println(JSONObject.toJSON(sdi));

        //List<Color> colorList = reader.readRasterColorTable("F:\\全球数据-开发\\Forests2000\\Forests2000.tif");
        //System.out.println(JSONObject.toJSON(colorList));

        reader.readRD("F:\\全球数据-开发\\DEM-Gtopo30\\gtopo30onekm.tif");

        //List<Map<String,Object>> list = reader.readRasterDatas("F:\\全球数据-开发\\DEM-Gtopo30\\gtopo30onekm.tif",true);
        //System.out.println(JSONObject.toJSON(list));
        //System.out.println(list.size());

        //reader.createRasterImage("F:\\全球数据-开发\\Forests2000\\Forests2000.tif","f:/Forests2000.png");


        //int[] buffer = new int[43200*21600]; // 存储数据的缓冲区
        //System.out.println(buffer.length);

        //String data = reader.readRasterPixData("F:\\landuse\\landuse.tif");
        //System.out.println(JSONObject.toJSON(data));

        //reader.convertRasterToPicture("F:\\全球数据-开发\\Forests2000\\Forests2000.tif","F:\\dem\\dem.png");

        //reader.convertRasterToPicture("F:\\LandUse\\landuse.tif","F:\\LandUse\\landuse.png");

        //reader.getTransparencyImage();

        //reader.createRasterImage(43200,21600,list,"f:/temp.png");


        /*
        BufferedImage image = new BufferedImage(43200,21600, BufferedImage.TYPE_INT_ARGB);
        for(int i=0;i<43200;i++){
            for(int j=0;j<21600;j++){
                Color color = Color.red;
                if(i % 2 == 0) color = Color.blue;
                image.setRGB(i,j,color.getRGB());
            }
        }
        ImageIO.write(image, "PNG", new File("f:/temp.png"));

         */


        System.out.println("Finish...");

    }

    /**
     * 创建图像
     * @param width
     * @param height
     * @param pngPath
     */
    public boolean createRasterImage(int width,int height,List<Map<String,Object>> list,String pngPath){
        try{
            File file = new File(pngPath);
            //创建目录
            if(!file.getParentFile().exists()) file.getParentFile().mkdirs();

            int type = BufferedImage.TYPE_INT_ARGB;

            BufferedImage image = new BufferedImage(width, height, type);

            for(Map<String,Object> map:list){
                int value = Integer.parseInt(map.get("value").toString());
                if(value ==0) continue;
                int row = Integer.parseInt(map.get("row").toString());
                int col = Integer.parseInt(map.get("col").toString());
                Color myWhite = JSONObject.parseObject(map.get("color").toString(),Color.class);
                int color = myWhite.getRGB();
                //System.out.println("row="+row+",col="+col+",color="+color);
                image.setRGB(col-1,row-1,color);
            }
            ImageIO.write(image, "PNG", file);

            return true;

        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 读取栅格生成图片
     * @param rasterFilePath
     * @param pngPath
     * @return
     */
    public boolean createRasterImage(String rasterFilePath,String pngPath){
        try{
            File file = new File(pngPath);
            //创建目录
            if(!file.getParentFile().exists()) file.getParentFile().mkdirs();
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null){
                System.out.println("Open Failed...");
                return false;
            }
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            /*System.out.println("m_Width="+m_Width+",m_Height="+m_Height);

            double[] gepTransform = poSrcDS.GetGeoTransform();
            System.out.println(JSONObject.toJSON(gepTransform));
            double[] extent = new double[4];
            extent[0] = gepTransform[0];
            extent[1] = gepTransform[3] + m_Height * gepTransform[5] + gepTransform[4];
            extent[2] = gepTransform[0] + m_Width * gepTransform[1] + gepTransform[2];
            extent[3] = gepTransform[3];
            System.out.println(JSONObject.toJSON(extent));
            String sr_info = "";
            sr_info = poSrcDS.GetProjectionRef();
            System.out.println(sr_info);*/


            Band raster_band = poSrcDS.GetRasterBand(1);
            List<Color> colorTable = readRasterColorTable(rasterFilePath);

            int type = BufferedImage.TYPE_INT_ARGB;
            BufferedImage image = new BufferedImage(m_Width, m_Height, type);

            int perheight = 1000;
            int pos = 0;
            int[] buffer_ = null;
            for(int m=0;m<m_Height;m++){
                if(m % perheight == 0) {
                    buffer_ = new int[m_Width*perheight];
                    int sjheight = (m+perheight>m_Height?m_Height-m:perheight);
                    raster_band.ReadRaster(0, m, m_Width, sjheight, m_Width, sjheight, gdalconstConstants.GDT_UInt32, buffer_, 0, 0);
                    pos = 0;
                }
                for(int n=0;n<m_Width;n++){
                    int value = buffer_[pos];
                    pos++;
                    if(value == 0) continue;

                    Color color = colorTable.get(value);
                    image.setRGB(n,m,color.getRGB());
                }
                //System.out.println("row="+m);
            }

            ImageIO.write(image, "PNG", file);

            return true;

        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 栅格根据颜色表生成图片
     * @param rasterFilePath
     * @param file
     * @param colorTable
     * @return
     */
    public boolean createRasterImage(String rasterFilePath,File file,List<Integer> colorTable){
        try{
            //创建目录
            if(!file.getParentFile().exists()) file.getParentFile().mkdirs();
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null){
                System.out.println("Open Failed...");
                return false;
            }
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();


            Band raster_band = poSrcDS.GetRasterBand(1);
            int type = BufferedImage.TYPE_INT_ARGB;
            BufferedImage image = new BufferedImage(m_Width, m_Height, type);

            int perheight = 1000;
            int pos = 0;
            int[] buffer_ = null;
            for(int m=0;m<m_Height;m++){
                if(m % perheight == 0) {
                    buffer_ = new int[m_Width*perheight];
                    int sjheight = (m+perheight>m_Height?m_Height-m:perheight);
                    raster_band.ReadRaster(0, m, m_Width, sjheight, m_Width, sjheight, gdalconstConstants.GDT_UInt32, buffer_, 0, 0);
                    pos = 0;
                }
                for(int n=0;n<m_Width;n++){
                    int value = buffer_[pos];
                    pos++;
                    if(value == 0) continue;

                    image.setRGB(n,m,colorTable.get(value));
                }
                //System.out.println("row="+m);
            }

            ImageIO.write(image, "PNG", file);

            return true;

        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 创建透明的图片
     *
     * @param
     * @throws IOException
     */
    public void getTransparencyImage() throws IOException {
        //初始化基本数据
        int width = 255, height = 255, ascent = 1, line = 1;

        // 创建BufferedImage对象
        BufferedImage image = new BufferedImage(width, (height+ascent)*line, BufferedImage.TYPE_INT_ARGB);
        // 获取Graphics2D
        Graphics2D g2d = image.createGraphics();

        // ---------- 增加下面的代码使得背景透明 -----------------
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, (height+ascent)*line);
        g2d.dispose();
        g2d = image.createGraphics();
        // ---------- 背景透明代码结束 -----------------

        //抗锯齿 让图片看起来更清晰
        RenderingHints rh = g2d.getRenderingHints();
        rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHints(rh);

        // 画图 Start
        //获得字体颜色
        int r = 255,
                g = 0,
                b = 0;
        // 设置字体颜色
        g2d.setColor(new Color(r, g, b));

        g2d.drawLine(0, 100, 100, 100);

        // 画图 End
        // 释放对象
        g2d.dispose();
        // 保存文件
        ImageIO.write(image, "PNG", new File("F:/temp.png"));
    }

    /** 通过指定参数写一个图片  */
    public static boolean writeImage(BufferedImage bi, String picType, File file) {

        Graphics g = bi.getGraphics();

        g.setColor(new Color(12, 123, 88));
        g.drawLine(0, 100, 100, 100);
        g.dispose();
        boolean val = false;
        try {
            val = ImageIO.write(bi, picType, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }

    public int readTotalCnts(String file) {
        int result = 0;
        try {
            Layer extentLayer = readLayerFromShp(file);
            result = (int) extentLayer.GetFeatureCount();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 读取Shapefile图层范围，顺序：xmin xmax ymin ymax
     *
     * @param file
     * @return
     */
    public double[] readLayerExtent(String file) {
        double[] result = null;
        try {
            Layer extentLayer = readLayerFromShp(file);
            result = extentLayer.GetExtent();
            double temp = result[1];
            result[1] = result[2];
            result[2] = temp;

        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 读空间数据
     * @param file
     * @return
     */
    public SpatialDataInfo readSpatialDataInfo(String file) {

        SpatialDataInfo result = null;
        try {
            result = new SpatialDataInfo();
            String suffix = file.substring(file.lastIndexOf(".") + 1);
            if (suffix.equalsIgnoreCase("shp")) {
                Layer extentLayer = readLayerFromShp(file);
                double[] extent = extentLayer.GetExtent();

                double temp = extent[1];
                extent[1] = extent[2];
                extent[2] = temp;

                result.setExtent(extent);
                result.setSpatialReference(extentLayer.GetSpatialRef());
            } else if (suffix.equalsIgnoreCase("img") || suffix.equalsIgnoreCase("tif")) {
                Dataset poSrcDS = (Dataset) gdal.Open(file, gdalconstConstants.GA_ReadOnly);
                if (poSrcDS == null)
                    return null;

                int band_count = poSrcDS.GetRasterCount();
                result.setRasterBandCount(band_count);

                int m_Width = poSrcDS.GetRasterXSize();
                int m_Height = poSrcDS.GetRasterYSize();

                byte[] buffer = new byte[m_Width * m_Height]; // 存储数据的缓冲区
                Band raster_band = poSrcDS.GetRasterBand(1);
                /**int xoff, int yoff, int xsize, int ysize, int buf_xsize, int buf_ysize,
                 * int buf_type, byte[] regularArrayOut, int nPixelSpace, int nLineSpace*/
                int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                        gdalconstConstants.GDT_Byte, buffer, 0, 0);
                if (flag != gdalconstConstants.CE_None) {
                    System.out.println("no...");
                }

                /*
                double[] adfGeoTransform = poSrcDS.GetGeoTransform();
                System.out.println(JSONObject.toJSON(adfGeoTransform));
                //计算每个像素点的经纬度
                List<List<double[]>> allpix = new ArrayList<>();
                for(int m=0;m<m_Height;m++){
                    List<double[]> rows = new ArrayList<>();
                    for(int n=0;n<m_Width;n++){
                        double px = adfGeoTransform[0] + m * adfGeoTransform[1] + n * adfGeoTransform[2];
                        double py = adfGeoTransform[3] + m * adfGeoTransform[4] + n * adfGeoTransform[5];
                        rows.add(new double[]{px,py});
                    }
                    allpix.add(rows);
                }
                //System.out.println(JSONObject.toJSON(allpix));

                ColorTable colorTable = raster_band.GetRasterColorTable();
                for(int i=0;i<raster_band.GetDefaultRAT().GetColumnCount();i++) {
                    System.out.print(raster_band.GetDefaultRAT().GetNameOfCol(i)+"\t");
                }
                System.out.println();
                for(int j=0;j<raster_band.GetDefaultRAT().GetRowCount();j++){
                    for(int i=0;i<raster_band.GetDefaultRAT().GetColumnCount();i++) {
                        System.out.print(raster_band.GetDefaultRAT().GetValueAsString(j,i)+"\t");
                        //获取颜色
                        if(raster_band.GetDefaultRAT().GetNameOfCol(i).toLowerCase().equals("value")) {
                            Color color = colorTable.GetColorEntry(raster_band.GetDefaultRAT().GetValueAsInt(j,i));
                            System.out.println(JSONObject.toJSON(color));
                        }
                    }
                    System.out.println();
                }

                double min_value = 0;
                double max_value = 0;
                double no_data_value = 0;

                Double[] vals = new Double[10];
                raster_band.GetMaximum(vals);
                System.out.println(JSONObject.toJSON(vals));
                max_value = vals[0];
                raster_band.GetMinimum(vals);
                System.out.println(JSONObject.toJSON(vals));
                min_value = vals[0];
                raster_band.GetNoDataValue(vals);
                System.out.println(JSONObject.toJSON(vals));
                no_data_value = vals[0];
                System.out.println(JSONObject.toJSON(buffer));
                 */


                result.setRasterXSize(m_Width);
                result.setRasterYSize(m_Height);


                double nX = m_Width;
                double nY = m_Height;
                double[] gepTransform = poSrcDS.GetGeoTransform();
                result.setGeotransform(gepTransform);
				/*
				 * m_pDataset->GetGeoTransform( m_AdfGeoTransform );
				   m_AdfGeoTransform是一个含6个元素的数组，执行了这行代码后，我们就可以获取m_AdfGeoTransform数组的信息，
				   m_AdfGeoTransform[0]，m_AdfGeoTransform[3]是整个影像的坐下角坐标，
				   m_AdfGeoTransform[1]是影像宽度上的分辨率，m_AdfGeoTransform[5]是影像高度上的分辨率，
				   而对于m_AdfGeoTransform[2]和m_AdfGeoTransform[4]来说，如果影像是指北的，这两个参数的值为0。
				   有了这几个参数，我们就能通过以下两行代码求出影像左下角和右上角的信息：
				   XMin = m_AdfGeoTransform[0];
				   YMin = m_AdfGeoTransform[3];
					
				   XMax = m_AdfGeoTransform[0] + nX * m_AdfGeoTransform[1] + m_AdfGeoTransform[2]; 
				   YMax = m_AdfGeoTransform[3] + m_AdfGeoTransform[4] + nY * m_AdfGeoTransform[5];
				 *
				 * */
                /*顺序：xmin ymin xmax ymax*/
                double[] extent = new double[4];
                extent[0] = gepTransform[0];
                extent[1] = gepTransform[3] + nY * gepTransform[5] + gepTransform[4];
                extent[2] = gepTransform[0] + nX * gepTransform[1] + gepTransform[2];
                extent[3] = gepTransform[3];
                result.setExtent(extent);
                String sr_info = "";
                sr_info = poSrcDS.GetProjectionRef();
                //sr_info = poSrcDS.GetProjection();
                //sr_info = poSrcDS.GetGCPProjection();
                SpatialReference spatialReference = new SpatialReference(sr_info);
//				System.out.println(spatialReference.ExportToWkt());
//				System.out.println(spatialReference.GetAttrValue("PROJECTION"));
//				System.out.println(spatialReference.GetAttrValue("PROJCS"));
//				System.out.println(spatialReference.GetAttrValue("GEOGCS"));
//				System.out.println(spatialReference.GetAttrValue("GEOGCS", 2));
//				System.out.println(spatialReference.GetAttrValue("DATUM"));
//				System.out.println(spatialReference.GetAttrValue("PARAMETER"));
                result.setSpatialReference(spatialReference);
            }
        } catch (Exception e) {
            result = null;
        }

        return result;
    }

    /**
     * 读取栅格像素数据
     * @param file
     * @return
     */
    public String readRasterPixData(String file) {
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(file, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return null;

            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();
            Band raster_band = poSrcDS.GetRasterBand(1);
            int[] buffer = new int[m_Width * m_Height]; // 存储数据的缓冲区

            double min_value = 0;
            double max_value = 0;
            double no_data_value = 0;

            Double[] vals = new Double[1];
            raster_band.GetMaximum(vals);
            max_value = vals[0];
            raster_band.GetMinimum(vals);
            min_value = vals[0];
            raster_band.GetNoDataValue(vals);
            no_data_value = vals[0];


            int perheight = 1000;
            int index = 0;
            int pos = 0;
            int[] buffer_ = null;
            //计算每个像素点的经纬度
            for(int m=0;m<m_Height;m++){
                //读取指定行数据
                if(m % perheight == 0) {
                    buffer_ = new int[m_Width*perheight];
                    int sjheight = (m+perheight>m_Height?m_Height-m:perheight);
                    raster_band.ReadRaster(0, m, m_Width, sjheight, m_Width, sjheight, gdalconstConstants.GDT_UInt32, buffer_, 0, 0);
                    pos = 0;
                }
                for(int n=0;n<m_Width;n++){
                    int value = buffer_[pos]>max_value?0:buffer_[pos];
                    buffer[index] = value;
                    pos++;
                    index++;
                }
            }
            return JSONObject.toJSON(buffer).toString();

        } catch (Exception e) {
            return "";
        }
    }

    public int[] readRasterPixData2(String file) {
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(file, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return null;

            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            int[] buffer = new int[m_Width * m_Height]; // 存储数据的缓冲区
            Band raster_band = poSrcDS.GetRasterBand(1);
            int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                    gdalconstConstants.GDT_UInt32, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                System.out.println("no...");
                return null;
            }

            return buffer;

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 读取栅格颜色表
     * @param file
     * @return
     */
    public List<Color> readRasterColorTable(String file) {
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(file, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return null;
            Band raster_band = poSrcDS.GetRasterBand(1);
            System.out.println(JSONObject.toJSON(raster_band));
            ColorTable colorTable = raster_band.GetRasterColorTable();
            List<Color> colorList = new ArrayList<>();
            if(colorTable != null){
                for(int i=0;i<colorTable.GetCount();i++){
                    Color color = colorTable.GetColorEntry(i);
                    System.out.println(JSONObject.toJSON(color));
                    colorList.add(color);
                }
            }else{
                //生成颜色表
                //最小值
                double min_value = 0;
                //最大值
                double max_value = 0;
                Double[] vals = new Double[10];
                raster_band.GetMaximum(vals);
                max_value = vals[0];
                raster_band.GetMinimum(vals);
                min_value = vals[0];
                createColorTable(min_value,max_value,colorList);
            }
            return colorList;

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 生成颜色表
     * @param min_value
     * @param max_value
     * @param colorList
     */
    public void createColorTable(double min_value,double max_value,List<Color> colorList){
        String[] breakArray = new String[8];
        double dx_value = (max_value - min_value) / 8;
        for(int i=0;i<8;i++){
            breakArray[i] = (min_value+ i * dx_value)+"";
        }
        String colorStr = "[[0,0,0,255],[74,145,148,255],[77,141,124,255],[76,164,76,255],[161,135,63,255],[161,108,91,255],[151,75,144,255],[95,99,159,255]]";
        JSONArray colorArr = JSONArray.parseArray(colorStr);
        for(int i=0;i<min_value;i++){
            colorList.add(new Color(0,0,0,255));
        }
        for(double j=min_value;j<=max_value;j++){
            int[] clr = getlinearColor(j,colorArr,breakArray);
            colorList.add(new Color(clr[0],clr[1],clr[2],clr[3]));
        }
    }

    /**
     * 根据颜色列表生成颜色值
     * @param colorStr
     * @param min_value
     * @param max_value
     * @return
     */
    public void createColorTable(String colorStr,double min_value,double max_value,List<Integer> colorList){
        JSONArray colorArr = JSONArray.parseArray(colorStr);
        String[] breakArray = new String[colorArr.size()];
        double dx_value = (max_value - min_value) / colorArr.size();
        for(int i=0;i<colorArr.size();i++){
            breakArray[i] = (min_value+ i * dx_value)+"";
        }
        //String colorStr = "[[0,0,0,255],[74,145,148,255],[77,141,124,255],[76,164,76,255],[161,135,63,255],[161,108,91,255],[151,75,144,255],[95,99,159,255]]";

        for(int i=0;i<min_value;i++){
            colorList.add(new Color(0,0,0,0).getRGB());
        }
        for(double j=min_value;j<=max_value;j++){
            int[] clr = getlinearColor(j,colorArr,breakArray);
            colorList.add(new Color(clr[0],clr[1],clr[2],clr[3]).getRGB());
        }
    }

    /**
     * 读取栅格范围
     * @param rasterFilePath
     * @return
     */
    public double[] readRasterExtent(String rasterFilePath) {
        double[] result = new double[4];
        try {

            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return null;

            double nX = poSrcDS.GetRasterXSize();
            double nY = poSrcDS.GetRasterYSize();
            double[] gepTransform = poSrcDS.GetGeoTransform();
            result[0] = gepTransform[0];
            result[1] = gepTransform[3] + nY * gepTransform[5] + gepTransform[4];
            result[2] = gepTransform[0] + nX * gepTransform[1] + gepTransform[2];
            result[3] = gepTransform[3];
        } catch (Exception e) {
            result = null;
        }

        return result;
    }
    /**
     * 读取栅格数据总数
     * @param rasterFilePath
     * @return
     */
    public int readRasterTotalCnts(String rasterFilePath) {
        return readRasterTotalCnts(rasterFilePath,false);
    }
    public int readRasterTotalCnts(String rasterFilePath,boolean filter) {
        int result = 0;
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return 0;
            Band raster_band = poSrcDS.GetRasterBand(1);
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            int[] buffer = new int[m_Width * m_Height]; // 存储数据的缓冲区
            int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                    gdalconstConstants.GDT_UInt32, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                System.out.println("no...");
                return 0;
            }
            for(int i=0;i<buffer.length;i++){
                if(filter)
                    if(buffer[i] == 0) continue;
                result++;
            }

            //result = raster_band.GetDefaultRAT().GetRowCount();

        } catch (Exception e) {
        }
        return result;
    }
    /**
     * 读取栅格属性
     * @param rasterFilePath
     * @return
     */
    public List<ExcelDefinition> readRasterDefinitions(String rasterFilePath) {
        List<ExcelDefinition> fields = new ArrayList<>();
        try {
            //Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            //if (poSrcDS == null)
             //   return null;
            ExcelDefinition rowdefi = new ExcelDefinition();
            rowdefi.setColumn("row");
            rowdefi.setTitle("row");
            rowdefi.setDataType(SupportDataType.NumberType);
            fields.add(rowdefi);

            ExcelDefinition coldefi = new ExcelDefinition();
            coldefi.setColumn("col");
            coldefi.setTitle("col");
            coldefi.setDataType(SupportDataType.NumberType);
            fields.add(coldefi);

            ExcelDefinition valuedefi = new ExcelDefinition();
            valuedefi.setColumn("value");
            valuedefi.setTitle("value");
            valuedefi.setDataType(SupportDataType.NumberType);
            fields.add(valuedefi);

            ExcelDefinition colordefi = new ExcelDefinition();
            colordefi.setColumn("color");
            colordefi.setTitle("color");
            colordefi.setDataType(SupportDataType.StringType);
            fields.add(colordefi);

            ExcelDefinition lngdefi = new ExcelDefinition();
            lngdefi.setColumn("lng");
            lngdefi.setTitle("lng");
            lngdefi.setDataType(SupportDataType.NumberType);
            fields.add(lngdefi);

            ExcelDefinition latdefi = new ExcelDefinition();
            latdefi.setColumn("lat");
            latdefi.setTitle("lat");
            latdefi.setDataType(SupportDataType.NumberType);
            fields.add(latdefi);
            //fields.add(CreateShapeDefinition());

        } catch (Exception e) {

        }
        return fields;
    }
    public List<ExcelDefinition> readRasterDefinitions1(String rasterFilePath) {
        List<ExcelDefinition> fields = new ArrayList<>();
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return null;

            //只处理第1段
            Band raster_band = poSrcDS.GetRasterBand(1);
            ColorTable colorTable = raster_band.GetRasterColorTable();
            for(int i=0;i<raster_band.GetDefaultRAT().GetColumnCount();i++) {
                raster_band.GetDefaultRAT().GetUsageOfCol(i);
                int coltype = raster_band.GetDefaultRAT().GetTypeOfCol(i);
                //列是否引用
                int colUsage = raster_band.GetDefaultRAT().GetUsageOfCol(i);
                //判断是否是引用值,是代表是有颜色表引用
                if(colUsage>0) continue;


                String fieldName = raster_band.GetDefaultRAT().GetNameOfCol(i);
                ExcelDefinition defi = new ExcelDefinition();
                defi.setColumn(fieldName);
                defi.setTitle(fieldName);
                defi.setDataType(coltype==0?SupportDataType.NumberType:SupportDataType.StringType);
                if(colorTable!=null) {
                    if (raster_band.GetDefaultRAT().GetNameOfCol(i).toLowerCase().equals("value")) {
                        ExcelDefinition colordefi = new ExcelDefinition();
                        colordefi.setColumn("COLOR");
                        colordefi.setTitle("COLOR");
                        colordefi.setDataType(SupportDataType.StringType);
                        fields.add(colordefi);
                    }

                }
                fields.add(defi);
            }

        } catch (Exception e) {

        }
        return fields;
    }
    /**
     * 计算线性渐变色
     *
     * @param value      value
     * @param colorArr   颜色数组
     * @param breakArray 颜色分级
     * @return int[]
     */
    public static int[] getlinearColor(double value, JSONArray colorArr, String[] breakArray) {
        for (int i = 0; i < breakArray.length; i++) {
            double breakValue = Double.parseDouble(breakArray[i]);
            JSONArray rgba = colorArr.getJSONArray(i);
            if (value <= breakValue) {
                if (i == 0) {
                    return arrayToPixel(rgba);
                } else {
                    double lastBreak = Double.parseDouble(breakArray[i - 1]);
                    JSONArray lastrgba = colorArr.getJSONArray(i - 1);
                    int[] pixel = new int[4];
                    //计算RGB的线性值
                    pixel[0] = (int) linearInterpolation(value, lastBreak, breakValue, lastrgba.getFloat(0), rgba.getFloat(0));
                    pixel[1] = (int) linearInterpolation(value, lastBreak, breakValue, lastrgba.getFloat(1), rgba.getFloat(1));
                    pixel[2] = (int) linearInterpolation(value, lastBreak, breakValue, lastrgba.getFloat(2), rgba.getFloat(2));
                    pixel[3] = (int) linearInterpolation(value, lastBreak, breakValue, lastrgba.getFloat(3), rgba.getFloat(3));
                    return pixel;
                }
            }
        }
        return arrayToPixel(colorArr.getJSONArray(colorArr.size() - 1));
    }

    /**
     * 线性插值
     *
     * @param x       插值点坐标
     * @param x1      顶点坐标
     * @param x2      顶点坐标
     * @param x1value 顶点数值
     * @param x2value 顶点数值
     * @return 插值后的数值
     */
    static float linearInterpolation(double x, double x1, double x2, float x1value, float x2value) {
        return (float) (((x2 - x) / (x2 - x1) * x1value) + ((x - x1) / (x2 - x1) * x2value));
    }

    /**
     * array转int[] 获取像素点颜色
     *
     * @param rgba rgbaArray
     * @return int[]
     */
    static int[] arrayToPixel(JSONArray rgba) {
        int[] pixel = new int[4];
        pixel[0] = rgba.getInteger(0);
        pixel[1] = rgba.getInteger(1);
        pixel[2] = rgba.getInteger(2);
        pixel[3] = rgba.getInteger(3);
        return pixel;
    }

    /**
     * 读取栅格数据
     * @param rasterFilePath
     */
    public List<Map<String,Object>> readRasterDatas(String rasterFilePath) {
        return readRasterDatas(rasterFilePath,false);
    }
    public List<Map<String,Object>> readRasterDatas(String rasterFilePath,boolean filter) {
        List<Map<String,Object>> dataList = new ArrayList<>();
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return dataList;
            Band raster_band = poSrcDS.GetRasterBand(1);
            List<Color> colorTable = readRasterColorTable(rasterFilePath);
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            double min_value = 0;
            double max_value = 0;
            double no_data_value = 0;

            Double[] vals = new Double[1];
            raster_band.GetMaximum(vals);
            max_value = vals[0];
            raster_band.GetMinimum(vals);
            min_value = vals[0];
            raster_band.GetNoDataValue(vals);
            no_data_value = vals[0];


            double[] adfGeoTransform = poSrcDS.GetGeoTransform();
            int index = 0;
            int perheight = 1000;
            int pos = 0;
            int[] buffer_ = null;
            //计算每个像素点的经纬度
            for(int m=0;m<m_Height;m++){
                //读取指定行数据
                if(m % perheight == 0) {
                    buffer_ = new int[m_Width*perheight];
                    int sjheight = (m+perheight>m_Height?m_Height-m:perheight);
                    raster_band.ReadRaster(0, m, m_Width, sjheight, m_Width, sjheight, gdalconstConstants.GDT_UInt32, buffer_, 0, 0);
                    pos = 0;
                }

                for(int n=0;n<m_Width;n++){
                    double px = adfGeoTransform[0] + n * adfGeoTransform[1] + m * adfGeoTransform[2];
                    double py = adfGeoTransform[3] + n * adfGeoTransform[4] + m * adfGeoTransform[5];
                    Map<String,Object> data = new HashMap<>();

                    int value = buffer_[pos]>max_value?0:buffer_[pos];//buffer[index];
                    pos++;

                    index++;

                    /*if(index % 10000 == 0){
                        System.out.println("row="+m+",col="+n+",value="+value);
                    }*/

                    if(filter)
                        if(value == 0) continue;

                    data.put("row",m+1);
                    data.put("col",n+1);
                    data.put("value",value);

                    if(value != 0) {
                        //获取Color
                        Color color = colorTable.get(value == colorTable.size()?value-1:value);
                        data.put("color",JSONObject.toJSON(color)+"");
                    }else{
                        data.put("color","");
                    }
                    /*
                    Map geom = new HashMap();
                    geom.put("type","Point");
                    geom.put("coordinates",new double[]{px,py});
                     */
                    //data.put("Shape","POINT("+px+" "+py+")");
                    data.put("lng",px);
                    data.put("lat",py);

                    dataList.add(data);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return dataList;

    }
    public List<Map<String,Object>> readRasterDatas1(String rasterFilePath) {
        List<Map<String,Object>> dataList = new ArrayList<>();
        try {
            Dataset poSrcDS = (Dataset) gdal.Open(rasterFilePath, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null)
                return dataList;
            Band raster_band = poSrcDS.GetRasterBand(1);
            ColorTable colorTable = raster_band.GetRasterColorTable();
            for(int j=0;j<raster_band.GetDefaultRAT().GetRowCount();j++){
                Map<String,Object> map = new HashMap<>();
                for(int i=0;i<raster_band.GetDefaultRAT().GetColumnCount();i++) {
                    //类型
                    int colType = raster_band.GetDefaultRAT().GetTypeOfCol(i);
                    //列是否引用
                    int colUsage = raster_band.GetDefaultRAT().GetUsageOfCol(i);
                    //判断是否是引用值,是代表是有颜色表引用
                    if(colUsage>0) continue;

                    String colName = raster_band.GetDefaultRAT().GetNameOfCol(i);
                    //值
                    String colValue = raster_band.GetDefaultRAT().GetValueAsString(j,i);

                    map.put(colName,colValue);

                    if(colorTable!=null) {
                        //获取实际颜色值
                        if (raster_band.GetDefaultRAT().GetNameOfCol(i).toLowerCase().equals("value")) {
                            Color color = colorTable.GetColorEntry(raster_band.GetDefaultRAT().GetValueAsInt(j,i));
                            map.put("COLOR",JSONObject.toJSON(color).toString()+"");
                        }
                    }
                }
                dataList.add(map);
            }

        } catch (Exception e) {

        }

        return dataList;

    }

    public List<ExcelRowData> buildExcelRowsFromRaster(String rasterFilePath, int first, int lastrow) {
        List<ExcelDefinition> fields = readRasterDefinitions(rasterFilePath);
        List<Map<String,Object>> datas = readRasterDatas(rasterFilePath);

        ExcelRowData row = null;
        List<ExcelCellData> cells = null;
        ExcelCellData cell = null;
        ExcelDefinition defi = null;
        List<ExcelRowData> rows = new ArrayList<ExcelRowData>();
        // 读取每个要素的属性信息
        for (int i = first; i < lastrow; i++) {
            Map<String,Object> iFeature = datas.get(i);
            if (null == iFeature) {
                continue;
            }
            row = new ExcelRowData();
            cells = new ArrayList<ExcelCellData>();
            for (int j = 0; j < fields.size(); j++) {
                ExcelDefinition field_def = (ExcelDefinition) fields.get(j);
                String fieldName = field_def.getColumn();
                String fieldType = field_def.getDataType().toString();

                cell = new ExcelCellData();
                defi = new ExcelDefinition();
                defi.setColumn(fieldName);
                defi.setTitle(fieldName);
                defi.setDataType(DataTypeTransfer(fieldType));
                cell.setDefinition(defi);

                cell.setData(iFeature.get(fieldName));

                cells.add(cell);
            }
            row.setCells(cells);
            rows.add(row);
        }
        return rows;
    }
    public List<ExcelRowData> readRasterData(String filePath, Integer page, Integer limit) {
        int lastRowNum = readRasterTotalCnts(filePath);
        int startRow = 0;
        int endRow = 0;

        if (page == 0 && limit == 0) {
            //读取所有数据
            startRow = 0;
            endRow = lastRowNum;
        } else {
            //按范围读取数据
            if (page == 1) {
                startRow = 0;
                endRow = startRow + limit;
                endRow = endRow > lastRowNum ? (lastRowNum + 1) : endRow;
            } else {
                startRow = (page - 1) * limit;
                int tmp = startRow + limit;
                endRow = tmp < lastRowNum ? tmp : lastRowNum;
            }
        }
        return buildExcelRowsFromRaster(filePath, startRow, endRow);
    }

    public List<ExcelRowData> readShapeData(String filePath, Integer page, Integer limit, boolean ignoreGeom) {
        int lastRowNum = readTotalCnts(filePath);
        int startRow = 0;
        int endRow = 0;

        if (page == 0 && limit == 0) {
            //读取所有数据
            startRow = 0;
            endRow = lastRowNum;
        } else {
            //按范围读取数据
            if (page == 1) {
                startRow = 0;
                endRow = startRow + limit;
                endRow = endRow > lastRowNum ? (lastRowNum + 1) : endRow;
            } else {
                startRow = (page - 1) * limit;
                int tmp = startRow + limit;
                endRow = tmp < lastRowNum ? tmp : lastRowNum;
            }
        }
        Layer extentLayer = readLayerFromShp(filePath);
        return buildExcelRowsFromLayer(extentLayer, startRow, endRow, ignoreGeom);
    }


    /**
     * Shapefile生成JSON文件
     *
     * @param file
     * @param targetJsonFile 待生成的目标JSON文件
     * @return
     * @throws Exception
     */
    public Boolean writeShpJson(String file, String targetJsonFile) throws Exception {
        Boolean result = false;
        try {
            DataSource ds = ogr.Open(file, 0);
            // 将要素转换为GeoJson格式
            Driver dv = ogr.GetDriverByName("GeoJSON");
            DataSource dataSource = dv.CopyDataSource(ds, targetJsonFile);
            //String command = "ogr2ogr -f \"GeoJSON\" " + targetJsonFile + " " + file;
            //Runtime.getRuntime().exec(command);
            //result = execCommand(command);
            //dataSource.CommitTransaction();
            String data = readFileContent(targetJsonFile);
            try {
                JSONObject.parseObject(data);
                return true;
            } catch (Exception e) {
                FileWriter fileWriter = new FileWriter(targetJsonFile, true);
                BufferedWriter bw = new BufferedWriter(fileWriter);
                bw.write("]");
                bw.write("}");
                bw.close();
                fileWriter.close();
                return true;
            }
        } catch (Exception e) {
            return false;
        }
    }

    public boolean execCommand(String commnad) {
        try {
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec(commnad);
            OutputProcessor error = new OutputProcessor(proc.getErrorStream());
            OutputProcessor input = new OutputProcessor(proc.getInputStream());
            error.start();
            input.start();
            int exitCode = proc.waitFor();
            if (exitCode == 0) {
                return true;
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }

    public String getShpJson(String jsonFile) {
        File file = new File(jsonFile);
        StringBuilder result = new StringBuilder();
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String s = null;
            while ((s = br.readLine()) != null) {
                result.append(System.lineSeparator() + s);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    /**
     * 将栅格数据转换成图片
     * @param raster_path
     * @param picture_path
     * @return
     */
    public Boolean convertRasterToPicture(String raster_path, String picture_path) {
        Boolean result = false;
        try {

            Dataset poSrcDS = (Dataset) gdal.Open(raster_path, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null) {
                return null;
            }

            // 以创建复制的方式，生成图片文件
            org.gdal.gdal.Driver hDriver= null;
            String suffix = picture_path.substring(picture_path.lastIndexOf(".") + 1);
            if (suffix.equalsIgnoreCase("jpg")) {
                hDriver = gdal.GetDriverByName("JPEG");
            } else if (suffix.equalsIgnoreCase("bmp")) {
                hDriver = gdal.GetDriverByName("BMP");
            } else if (suffix.equalsIgnoreCase("png")) {
                hDriver = gdal.GetDriverByName("PNG");
            } else {
                hDriver = gdal.GetDriverByName("JPEG");// JPEG PNG BMP
            }

            Dataset picture = hDriver.CreateCopy(picture_path, poSrcDS);

            if (picture != null) {
                result = true;
            } else {
                System.out.println("********图片生成失败！********");
            }
            hDriver.delete();
        } catch (Exception e) {
            result = false;
        }

        return result;
    }

    public Boolean convertRasterToPicture2(String raster_path, String picture_path) {

        Boolean result = false;
        try {

            Dataset poSrcDS = (Dataset) gdal.Open(raster_path, gdalconstConstants.GA_ReadOnly);
            if (poSrcDS == null) {
                return null;
            }

            // 获取图像的基本信息,并把数据读入缓冲区间
            String result_path = picture_path;
            int m_Width = poSrcDS.GetRasterXSize();
            int m_Height = poSrcDS.GetRasterYSize();

            /* 以下程序是生成JPG的过程，上面的程序只为获得创建过程中的一些参数，如：图像的高、宽及图像数据 */
            // 把数据保存到临时文件MEM
            org.gdal.gdal.Driver pDriverMEM = gdal.GetDriverByName("MEM");
            Dataset pOutMEMDataset = pDriverMEM.Create("", m_Width, m_Height, 3);// ,gdalconstConstants.GDT_Byte

            int band_count = poSrcDS.GetRasterCount();
            Boolean flag = false;
            for (int i = 1; i <= band_count; i++) {
                flag = WriteRasterBand(poSrcDS, i, pOutMEMDataset);
                if (!flag) {
                    break;
                }
            }

            String suffix = picture_path.substring(picture_path.lastIndexOf(".") + 1);
            // 以创建复制的方式，生成jpg文件
            org.gdal.gdal.Driver pDriverJPG = null;
            if (suffix.equalsIgnoreCase("jpg")) {
                pDriverJPG = gdal.GetDriverByName("JPEG");
            } else if (suffix.equalsIgnoreCase("bmp")) {
                pDriverJPG = gdal.GetDriverByName("BMP");
            } else if (suffix.equalsIgnoreCase("png")) {
                pDriverJPG = gdal.GetDriverByName("PNG");
            } else {
                gdal.GetDriverByName("JPEG");// JPEG PNG BMP
            }
            Dataset picture = pDriverJPG.CreateCopy(result_path, pOutMEMDataset); // 创建jpg文件
            if (picture != null) {
                result = true;
            } else {
                System.out.println("********图片生成失败！********");
            }

        } catch (Exception e) {
            result = false;
        }

        return result;
    }

    private Boolean WriteRasterBand(Dataset tif_ds, int idx_band, Dataset mem_ds) {

        Boolean result = true;
        try {
            int m_Width = tif_ds.GetRasterXSize();
            int m_Height = tif_ds.GetRasterYSize();

            byte[] buffer = new byte[m_Width * m_Height]; // 存储数据的缓冲区

            org.gdal.gdal.Band raster_band = tif_ds.GetRasterBand(idx_band);
            /**int xoff, int yoff, int xsize, int ysize, int buf_xsize, int buf_ysize,
             * int buf_type, byte[] regularArrayOut, int nPixelSpace, int nLineSpace*/
            int flag = raster_band.ReadRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                    gdalconstConstants.GDT_Byte, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                return false;
            }

            double min_value = 0;
            double max_value = 0;
            double no_data_value = 0;

            Double[] vals = new Double[10];
            raster_band.GetMaximum(vals);
            max_value = vals[0];
            raster_band.GetMinimum(vals);
            min_value = vals[0];
            raster_band.GetNoDataValue(vals);
            no_data_value = vals[0];

            int posSrc = 0, posScan = 0;

            for (int i = 0; i < m_Height; i++) //row
            {
                for (int j = 0; j < m_Width; j++) //col
                {
                    double item = buffer[posSrc++];
                    if (item == no_data_value) {
                        buffer[posScan++] = 0; //黑色
                    } else {
                        buffer[posScan++] = (byte) ((item - min_value) * 256 / (max_value - min_value));
                    }
                }
            }

            Band pOutMEMRasterBand = mem_ds.GetRasterBand(idx_band);
            flag = pOutMEMRasterBand.WriteRaster(0, 0, m_Width, m_Height, m_Width, m_Height,
                    gdalconstConstants.GDT_Byte, buffer, 0, 0);
            if (flag != gdalconstConstants.CE_None) {
                return false;
            }
        } catch (Exception e) {
            result = false;
        }

        return result;
    }


    public String readFileContent(String filePath) {
        String str_result = "";
        try {
            String encoding = "UTF-8";
            File file = new File(filePath);
            if (file.isFile() && file.exists()) {
                // 判断文件是否存在
                InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt = null;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    str_result += lineTxt;
                }
                System.out.println("文本内容长度：" + str_result.length());
                read.close();
                bufferedReader.close();
            } else {
                System.out.println("找不到指定的文件");
                return "";
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }

        return str_result;
    }
}
