//method为省时候调用,只切割指定的省份
        public static bool CreateTileByWATAByCSharpFromProvince(string keyString, string curDatFullname, ref string start, ref string end, ref string datnums, ref string yearmmddForID)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            string[] gridlist = HookHelper.gridsize.Split(',');

            int   gridrow    = 1001;
            int   gridcol    = 1001;
            float rainSRCFBL = 0.01f;

            if (gridlist.Count() == 2)
            {
                gridrow = int.Parse(gridlist[0]);
                gridcol = int.Parse(gridlist[1]);
            }

            if (gridlist.Count() == 3)
            {
                gridrow    = int.Parse(gridlist[0]);
                gridcol    = int.Parse(gridlist[1]);
                rainSRCFBL = float.Parse(gridlist[2]);
            }

            string datPureName = System.IO.Path.GetFileNameWithoutExtension(curDatFullname);

            //!解析当前dat文件
            //!创建数据存储结构
            DatFileStruct datStruct = new DatFileStruct();

            datStruct.col = gridcol;
            datStruct.row = gridrow;
            datStruct.fbl = rainSRCFBL;


            // 读取文件
            BinaryReader br;

            try
            {
                br = new BinaryReader(new FileStream(curDatFullname,
                                                     FileMode.Open, FileAccess.Read, FileShare.Read));
            }
            catch (IOException e)
            {
                Console.WriteLine(string.Format("{0}台风场文件解析场次信息失败,继续下一个", curDatFullname) + DateTime.Now);
                return(false);
            }
            try
            {
                //! 第一部分数据 年(year)、月日时(mdh)、该台风总时次(times) 均为整型  3 * 4 个字节
                //inFile.read((char*)&datStruct.headerone[0], 3 * sizeof(int));
                int year  = br.ReadInt32();
                int mdh   = br.ReadInt32();
                int times = br.ReadInt32();
                //////
                string yearStr = year.ToString();


                year = int.Parse(yearStr);
                ///////
                datStruct.headerone[0] = year;
                datStruct.headerone[1] = mdh;
                datStruct.headerone[2] = times;

                string mdhSt = mdh.ToString();
                if (mdhSt.Length == 5)
                {
                    mdhSt = String.Format("0{0}", mdhSt);
                }
                //System.String.Substring(Int32 startIndex, Int32 length)
                string ymdhstr = String.Format("{0}{1}", yearStr, mdhSt);

                //1,2,3位的year前边必须补0,不然会识别错误, 5位的不识别.传入程序的时间以4位为准,统一从2000年开始,追加,模型输出时候纠正时间
                string yearStrForCalc = "2020";
                //DateTime dt = Convert.ToDateTime(yearStrForCalc + "-" + mdhSt.Substring(0, 2) + "-" + mdhSt.Substring(2, 2) + " " + mdhSt.Substring(4, 2) + ":00:00");
                DateTime dt = Convert.ToDateTime(yearStrForCalc + "-" + "01" + "-" + "01" + " " + "00" + ":00:00");
                //! 传入到模型中的时间值,用来计算该时间段的水文结果
                start   = dt.ToString("yyyy-MM-ddTHH:mm");
                end     = (dt.AddHours(times - 1)).ToString("yyyy-MM-ddTHH:mm");
                datnums = times.ToString();

                //该变量是根据时间值组合是数字串,后续作为降雨及计算结果的输出文件名称前缀,year前自动补0,与模型计算中更新rainfile中规则一致
                yearmmddForID = yearStr + mdhSt.Substring(0, 2) + mdhSt.Substring(2, 2) + mdhSt.Substring(4, 2);

                //!2、第二部分,是各个场次经纬度列表
                datStruct.Lats = new double[times];
                datStruct.Lons = new double[times];
                for (int tindex = 0; tindex < datStruct.headerone[2]; ++tindex)
                {
                    double lat = br.ReadDouble();
                    double lon = br.ReadDouble();
                    datStruct.Lats[tindex] = lat;
                    datStruct.Lons[tindex] = lon;
                }

                //!3、第三部分,是所有场次的网格数据存储,三维数组存放每个时间的网格数据
                datStruct.rain = new float[times, datStruct.row, datStruct.col];
                for (int tindex = 0; tindex < datStruct.headerone[2]; ++tindex)
                {
                    datStruct.curRainIndex = tindex;

                    byte[] datbytes = br.ReadBytes(datStruct.row * datStruct.col * 4);

                    for (int r = 0; r < datStruct.row; ++r)
                    {
                        for (int c = 0; c < datStruct.col; ++c)
                        {
                            //float val = br.ReadSingle();
                            //datStruct.rain[tindex, r, c] = val;
                            datStruct.rain[tindex, r, c] = BitConverter.ToSingle(datbytes, (r * datStruct.col + c) * 4);
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Console.WriteLine(string.Format("{0}台风场文件解析场次信息失败,继续下一个", curDatFullname) + DateTime.Now);
                br.Close();
                return(false);
            }
            br.Close();
            stopwatch.Stop();
            Console.WriteLine(string.Format("读取{0}台风场文件耗时{1}", curDatFullname, stopwatch.ElapsedMilliseconds));
            stopwatch.Restart();

            //!22 数据读取完成,则需要插值到各个计算单元,然后写出
            //! 遍历所有的计算单元信息表,写出数据
            //! 遍历每个计算单元,然后在其中遍历每个场次的数据
            int unitNUM = dbTableConfigs[keyString]["GRID_HSFX_UNIT"].Rows.Count;
            //unit 表
            DataTable grid_unit_tables = dbTableConfigs[keyString]["GRID_HSFX_UNIT"];

            int countOfHaveRain = 0;

            for (int i = 0; i < unitNUM; ++i)
            {
                //!单元的信息
                string provinceName = keyString;
                string groovyName   = grid_unit_tables.Rows[i]["GroovyName"].ToString();

                //!当前场次下某个单元的所有时间文件写出
                bool status = WriteAscFileByParams(datPureName, provinceName, groovyName, yearmmddForID, datStruct, grid_unit_tables.Rows[i]);
                if (status)
                {
                    countOfHaveRain++;
                    //Console.WriteLine(string.Format("{0}台风场文件在{1}省下{2}单元目录切片成功", curDatFullname, provinceName, groovyName) + DateTime.Now);
                }
                else
                {
                    //Console.WriteLine(string.Format("{0}台风场文件在{1}省下{2}单元目录切片失败", curDatFullname, provinceName, groovyName) + DateTime.Now);
                }
                //stopwatch.Stop();
                //Console.WriteLine(string.Format("写入{0}台风场第{1}个计算单元耗时{2}", curDatFullname, i, stopwatch.ElapsedMilliseconds));
                //stopwatch.Restart();
            }
            stopwatch.Stop();
            Console.WriteLine(string.Format("写入{0}台风场文件耗时{1}", curDatFullname, stopwatch.ElapsedMilliseconds));

            Console.WriteLine(string.Format("{0}台风场文件在{1}节点下共有{2}个计算单元,其中{3}个计算单元中有有效降雨", curDatFullname, HookHelper.computerNode, unitNUM, countOfHaveRain) + DateTime.Now);

            //CSVLog
            if (HookHelper.useCSVLOG.Equals("true"))
            {
                CSVData.addData(CSVData.GetRowNumber(), "HostName", System.Net.Dns.GetHostName());
                var serverIP = Program.GetLocalIP(HookHelper.serachIP);
                CSVData.addData(CSVData.GetRowNumber(), "服务器IP", serverIP);
                CSVData.addData(CSVData.GetRowNumber(), "计算节点", HookHelper.computerNode);
                CSVData.addData(CSVData.GetRowNumber(), "eventId", Path.GetFileNameWithoutExtension(curDatFullname));
                CSVData.addData(CSVData.GetRowNumber(), "计算单元个数", unitNUM);
                CSVData.addData(CSVData.GetRowNumber(), "有效降雨单元个数", countOfHaveRain);
            }



            datStruct.headerone = null;
            datStruct.rain      = null;
            datStruct.Lons      = null;
            datStruct.Lats      = null;
            return(true);
        }
        public static bool WriteAscFileByParamsOneTime(string datPureName, string provinceName, string groovyName, string startTimeCurDat, DatFileStruct dStruct, DataRow paramsUnitDT, int tIndex)
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            //当前单元输出路径
            if (!dbValues.ContainsKey(provinceName))
            {
                return(false);
            }
            string outrainTilepath   = dbValues[provinceName]["rainTileFolder"];
            string unitOutdir        = outrainTilepath + "\\" + datPureName + "\\" + groovyName;
            bool   isHaveRainCurUnit = false;

            float destDegFbl = 0.01f;

            //for (int t = 0; t < dStruct.headerone[2]; ++t)
            {
                dStruct.curRainIndex = tIndex;
                //!当前文件名
                string curWriteFileName = String.Format("{0}\\{1}-{2}.asc", unitOutdir, datPureName, tIndex);

                if (curWriteFileName.Contains("WHF66_3_4"))
                {
                    int a = 0;
                }

                //! 使用c#写出
                //@ 判断当前时段的降雨数据是否 对 当前传入的计算单元有降雨,有则写出,无则跳过;
                // 模型在执行计算的时候会搜索对应的降雨,找不到则自动跳过计算
                double xa1 = dStruct.Lons[dStruct.curRainIndex]; double ya1 = dStruct.Lats[dStruct.curRainIndex];
                double xa2 = xa1 + dStruct.fbl * (dStruct.col); double ya2 = ya1 + dStruct.fbl * (dStruct.row);

                int    NODATA_value = -9999;
                double xb1          = double.Parse(paramsUnitDT["left"].ToString());
                double yb1          = double.Parse(paramsUnitDT["bottom"].ToString());

                double xllcorner = double.Parse(paramsUnitDT["xllcorner"].ToString());
                double yllcorner = double.Parse(paramsUnitDT["yllcorner"].ToString());
                double cellsize  = double.Parse(paramsUnitDT["cellsize"].ToString());

                int unitCols = int.Parse(paramsUnitDT["ncols"].ToString());
                int unitRows = int.Parse(paramsUnitDT["nrows"].ToString());

                double xb2 = xb1 + destDegFbl * (unitCols - 1);
                double yb2 = yb1 + destDegFbl * (unitRows - 1);

                int ret = overlap(xa1, ya1, xa2, ya2, xb1, yb1, xb2, yb2);

                if (ret == 0)
                {
                    //Console.WriteLine(string.Format("{0}不存在有效的降雨数据!!!", curWriteFileName) + DateTime.Now);
                    return(false);
                }

                //! 有数据才创建目录
                if (!Directory.Exists(unitOutdir))
                {
                    Directory.CreateDirectory(unitOutdir);
                }

                //写出数据
                StringBuilder lines = new StringBuilder();
                //! 1、先写出文件头,起点投影坐标xy以及行列号
                //stream << "ncols" << " " << params.ncols.toInt() << "\n";
                //stream << "nrows" << " " << params.nrows.toInt() << "\n";
                //stream << "xllcorner" << " " << params.xllcorner << "\n";
                //stream << "yllcorner" << " " << params.yllcorner << "\n";
                //stream << "cellsize" << " " << params.cellsize << "\n";
                //stream << "NODATA_value" << " " << QString("%1").arg(-9999, 0, 10) << "\n";

                lines.Append(String.Format("ncols {0}\n", unitCols));
                lines.Append(String.Format("nrows {0}\n", unitRows));
                lines.Append(String.Format("xllcorner {0}\n", xllcorner));
                lines.Append(String.Format("yllcorner {0}\n", yllcorner));
                lines.Append(String.Format("cellsize {0}\n", cellsize));
                lines.Append(String.Format("NODATA_value {0}\n", NODATA_value));
                //1 根据每个单元的参数记录的起点经纬度,行列数,遍历计算当前点在台风场数据中的索引号,从中取出对应的值
                //! 如果计算出来的索引号行或者列为负值,则说明不在范围内,赋值为0
                int   outRow   = unitRows;
                int   outCol   = unitCols;
                float outStLon = (float)(xb1);
                float outStLat = (float)(yb1);

                float stLon = (float)dStruct.Lons[dStruct.curRainIndex];
                float stLat = (float)dStruct.Lats[dStruct.curRainIndex];

                //! 先写出一行,再写一行
                //! 由于asc中文件的参数信息是做下脚,但是数据是先存左上开始
                for (int r = outRow - 1; r >= 0; --r)
                {
                    for (int c = 0; c < outCol; ++c)
                    {
                        //! 坐标索引转换,根据起点坐标 分辨率,行列号,计算当前点位经纬度,根据台风场的经纬度值,计算在台风场中的行列号 ,赋值即可
                        //! 当前坐标
                        float curLon = outStLon + destDegFbl * c;
                        float curLat = outStLat + destDegFbl * r;

                        //! 在台风场中的索引号
                        int originRow = (int)Math.Ceiling((curLat - stLat) * (1 / dStruct.fbl));;
                        int originCol = (int)Math.Ceiling((curLon - stLon) * (1 / dStruct.fbl));

                        float curRain = 0.0f;
                        if (originRow >= 0 && originCol >= 0 && originRow <= dStruct.row - 1 && originCol <= dStruct.col - 1)
                        {
                            curRain = dStruct.rain[0, originRow, originCol];
                            if (curRain < 0 || curRain == NODATA_value || double.IsNaN(curRain))
                            {
                                curRain = 0.0f;
                            }
                        }

                        lines.Append(curRain);
                        if (c == outCol - 1)
                        {
                            lines.Append("\n"); //添加分隔符
                        }
                        else
                        {
                            lines.Append(" "); //添加分隔符
                        }
                    }
                }

                isHaveRainCurUnit = true;

                //stopwatch.Stop();
                //Console.WriteLine("--计算" + stopwatch.ElapsedMilliseconds);
                //stopwatch.Restart();

                FileStream   fs = new FileStream(curWriteFileName, FileMode.Create, FileAccess.Write); //定义写入方式
                StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding("GB2312"));    //写入文件格式

                sw.Write(lines.ToString());
                sw.Close();
                fs.Close();

                //stopwatch.Stop();
                //Console.WriteLine("--写入" + stopwatch.ElapsedMilliseconds);
                //stopwatch.Restart();
            }

            return(isHaveRainCurUnit);
        }