示例#1
0
    public override void Initialize(DateTime Start, DateTime End, IEnumerable<Catchment> Catchments)
    {
      base.Initialize(Start, End, Catchments);

      //Source, Catchment
      Dictionary<string, int> Sources = new Dictionary<string,int>();
      Dictionary<string, XYPoint> PointSources = new Dictionary<string,XYPoint>();

      List<XYPoint> points = new List<XYPoint>();

      //Read in the points
      using (ShapeReader sr = new ShapeReader(ShapeFile.FileName))
      {
        foreach (var gd in sr.GeoData)
        {
          XYPoint xp = gd.Geometry as XYPoint;
          if (!PointSources.ContainsKey(gd.Data[ShapeFile.ColumnNames[0]].ToString())) //Some sources are listed multiple times
            if(gd.Data[ShapeFile.ColumnNames[1]].ToString()=="land")
              PointSources.Add(gd.Data[ShapeFile.ColumnNames[0]].ToString(), gd.Geometry as XYPoint);
        }
      }
      NewMessage("Distributing sources in catchments");
      //Distribute points on catchments
      Parallel.ForEach(PointSources, (p) =>
      {
        foreach (var c in Catchments)
        {
          if (c.Geometry.Contains(p.Value.X, p.Value.Y))
          {
            //if (c.CoastalZones.Any(co=>co.Contains(p.Value.X, p.Value.Y)))
              lock (Lock)
                Sources.Add(p.Key, c.ID);
              break;
          }
        }
      });
      NewMessage(PointSources.Count +" point sources distributed on " + Sources.Values.Distinct().Count().ToString() + " catchments");
      
      Dictionary<string, int> entries = new Dictionary<string, int>();
      foreach (var source in Sources.Keys)
        entries.Add(source, 0);


      NewMessage("Reading outlet data");
      //Read source data and distrubute on catchments
      using (DBFReader dbf = new DBFReader(DBFFile.FileName))
      {
        int k = 0;
        for (int i = 0; i < dbf.NoOfEntries; i++)
        {
          string id = dbf.ReadString(i, DBFFile.ColumnNames[0]).Trim();
          int year = dbf.ReadInt(i, DBFFile.ColumnNames[1]);
          double value = dbf.ReadDouble(i, DBFFile.ColumnNames[2]);

          int catchid;

          if (Sources.TryGetValue(id, out catchid))
          {
            entries[id] += 1;
            Dictionary<int, double> timevalues;
            if (!YearlyData.TryGetValue(catchid, out timevalues))
            {
              timevalues = new Dictionary<int, double>();
              YearlyData.Add(catchid, timevalues);
            }
            if (timevalues.ContainsKey(year))
              timevalues[year] += value;
            else
            {
              if (year >= Start.Year) //This also removes some -99 years
                timevalues.Add(year, value);
            }
          }
          else
          {
            //if we have outlet data but no source placed
            k++;
          }
        }
        NewMessage(k + " time series entries have no points");
      }


      foreach (var c in YearlyData.Values)
        foreach (var val in c.ToList())
          c[val.Key] = val.Value/ ((DateTime.DaysInMonth(val.Key,2) + 337.0) * 86400.0);

      NewMessage(entries.Values.Count(v => v == 0) + " points have no time series data");

      NewMessage("Initialized");
    }
    /// <summary>
    /// Reads the particles and distributes them on the dictionaries
    /// </summary>
    /// <param name="shapefilename"></param>
    public IEnumerable<Particle> ReadParticleFile(string shapefilename, Func<DBFReader, int, SinkType,bool> ExcludeThis, bool DrainToBoundaryOption)
    {
      List<int> RedoxedParticles = new List<int>();
      Dictionary<int, Particle> NonRedoxedParticles = new Dictionary<int, Particle>();
      NewMessage("Reading particles from: " + shapefilename);
      int k = 0;


      using (DBFReader sr = new DBFReader(shapefilename))
      {
        try
        {
          for (int i = 0; i < sr.NoOfEntries; i++)
          {
            int id = sr.ReadInt(i, "ID");
            SinkType sinktype = (SinkType)Enum.Parse(typeof(SinkType), sr.ReadString(i, "SinkType"));
            if (sinktype == SinkType.Active_cell) //Do not create a new particle
              RedoxedParticles.Add(id);
            else if (ExcludeThis != null && ExcludeThis(sr, i, sinktype))
            {
              k++;
            }
            else
            {
              Particle p = new Particle();
              
              p.Registration = sr.ReadInt(i, "Registrati");
              p.XStart = sr.ReadDouble(i, "X-Birth");
              p.YStart = sr.ReadDouble(i, "Y-Birth");
              p.ZStart = sr.ReadDouble(i, "Z-Birth");
              p.X = sr.ReadDouble(i, "X-Reg");
              p.Y = sr.ReadDouble(i, "Y-Reg");
              p.Z = sr.ReadDouble(i, "Z-Reg");
              p.TravelTime = sr.ReadDouble(i, "TravelTime");
              p.SinkType = sinktype;
              NonRedoxedParticles.Add(id, p);

              if(DrainToBoundaryOption && p.SinkType == SinkType.Drain_to_Boundary)
              {
                p.X = p.XStart;
                p.Y = p.YStart;
                p.Z = p.ZStart;
                p.Registration = 0;
              }
            }
          }
        }
        catch (Exception e)
        {

          NewMessage("Error reading data");

        }
      }

      int nosink = 0;
      //Set the registration on all particles that have be redoxed
      foreach (var pid in RedoxedParticles)
        if (NonRedoxedParticles.ContainsKey(pid))
          NonRedoxedParticles[pid].Registration = 1;
        else
          nosink++;

      NewMessage("Excluded: " + k + " particles.");

      return NonRedoxedParticles.Values;

    }