/// <summary> extract soil data and write a site file /// </summary> /// <param name="outpath"></param> /// <param name="agMipJson"></param> public static void ExtractSoilData(string outpath, JObject agMipJson, ref string errorOut) { IList <JToken> results; try { results = agMipJson["soils"].First["soilLayer"].Children().ToList(); if (results.Count == 0) { Console.WriteLine(SiteData.MissingSoilErrorMsg); errorOut += SiteData.MissingSoilErrorMsg; return; } } catch (Exception) { Console.WriteLine(SiteData.MissingSoilErrorMsg); errorOut += SiteData.MissingSoilErrorMsg; return; } List <SoilLayer> soilLayers = new List <SoilLayer>(); List <string> soilParameter = new List <string>() { "depth", "sllt", "sllb", "sloc", "slic", "slwp", "slfc1", "slsat", "sabdm", "slsnd", "slcly", "slsil" }; foreach (JToken token in results) { if (!Util.HasMissingParameter(soilParameter, "soil", token, ref errorOut)) { double depth = (double)token["depth"].ToObject(typeof(double)); // not documented in standard = thickness double soilTopLayerDepth = (double)token["sllt"].ToObject(typeof(double)); double soilBaseLayerDepth = (double)token["sllb"].ToObject(typeof(double)); double soilOrganicCarbonLayer = (double)token["sloc"].ToObject(typeof(double)); double inertOrganicCarbonLayer = (double)token["slic"].ToObject(typeof(double)); // Inert organic carbon by layer double wiltingPoint = (double)token["slwp"].ToObject(typeof(double)); // Soil water content (wilting point) at 15 atmosphere pressure double fieldWaterCapacity = (double)token["slfc1"].ToObject(typeof(double)); // Soil water content at 1/3 atmosphere pressure double saturation = (double)token["slsat"].ToObject(typeof(double)); // Soil water, saturated double bulkDensity = (double)token["sabdm"].ToObject(typeof(double)); // Soil bulk density, moist, determined on field sample g/cm3 double sand = (double)token["slsnd"].ToObject(typeof(double)); double clay = (double)token["slcly"].ToObject(typeof(double)); double silt = (double)token["slsil"].ToObject(typeof(double)); //schluff SoilLayer soilLayer = SiteData.FromAgMIP(soilTopLayerDepth, soilBaseLayerDepth, depth, soilOrganicCarbonLayer, bulkDensity, sand, clay, saturation, wiltingPoint, fieldWaterCapacity); soilLayers.Add(soilLayer); } } SaveSoilData(outpath, soilLayers); }
public void Constructor_WithConstructionProperties_ExpectedValues() { // Setup const string materialName = "test"; var random = new Random(11); bool isAquifer = random.NextBoolean(); bool usePop = random.NextBoolean(); var shearStrengthModel = random.NextEnumValue <ShearStrengthModel>(); double abovePhreaticLevel = random.NextDouble(); double belowPhreaticLevel = random.NextDouble(); double cohesion = random.NextDouble(); double frictionAngle = random.NextDouble(); double shearStrengthRatio = random.NextDouble(); double strengthIncreaseExponent = random.NextDouble(); double pop = random.NextDouble(); double dilatancy = random.NextDouble(); var waterPressureInterpolationModel = random.NextEnumValue <WaterPressureInterpolationModel>(); // Call var layer = new SoilLayer(new Point2D[0], new SoilLayer.ConstructionProperties { MaterialName = materialName, IsAquifer = isAquifer, UsePop = usePop, ShearStrengthModel = shearStrengthModel, AbovePhreaticLevel = abovePhreaticLevel, BelowPhreaticLevel = belowPhreaticLevel, Cohesion = cohesion, FrictionAngle = frictionAngle, ShearStrengthRatio = shearStrengthRatio, StrengthIncreaseExponent = strengthIncreaseExponent, Pop = pop, Dilatancy = dilatancy, WaterPressureInterpolationModel = waterPressureInterpolationModel }, Enumerable.Empty <SoilLayer>()); // Assert Assert.AreEqual(materialName, layer.MaterialName); Assert.AreEqual(isAquifer, layer.IsAquifer); Assert.AreEqual(usePop, layer.UsePop); Assert.AreEqual(shearStrengthModel, layer.ShearStrengthModel); Assert.AreEqual(abovePhreaticLevel, layer.AbovePhreaticLevel); Assert.AreEqual(belowPhreaticLevel, layer.BelowPhreaticLevel); Assert.AreEqual(cohesion, layer.Cohesion); Assert.AreEqual(frictionAngle, layer.FrictionAngle); Assert.AreEqual(shearStrengthRatio, layer.ShearStrengthRatio); Assert.AreEqual(strengthIncreaseExponent, layer.StrengthIncreaseExponent); Assert.AreEqual(pop, layer.Pop); Assert.AreEqual(dilatancy, layer.Dilatancy); Assert.AreEqual(waterPressureInterpolationModel, layer.WaterPressureInterpolationModel); }
private static IEnumerable <IEnumerable <Point2D> > GetInnerLoopsRecursively(SoilLayer layer) { var innerLoops = new List <IEnumerable <Point2D> >(); foreach (SoilLayer nestedLayer in layer.NestedLayers) { innerLoops.Add(nestedLayer.OuterRing); innerLoops.AddRange(GetInnerLoopsRecursively(nestedLayer)); } return(innerLoops); }
public void Constructor_ExpectedValues() { // Setup var layers = new SoilLayer[0]; var preconsolidationStresses = new PreconsolidationStress[0]; // Call var profile = new SoilProfile(layers, preconsolidationStresses); // Assert Assert.AreSame(layers, profile.Layers); Assert.AreSame(preconsolidationStresses, profile.PreconsolidationStresses); }
public void Constructor_WithAllParameters_ExpectedValues() { // Setup var outerRing = new Point2D[0]; var nestedLayers = new SoilLayer[0]; // Call var layer = new SoilLayer(outerRing, new SoilLayer.ConstructionProperties(), nestedLayers); // Assert Assert.AreSame(outerRing, layer.OuterRing); Assert.AreSame(nestedLayers, layer.NestedLayers); }
/// <summary> get data from AgMIP an convert it to monica format /// </summary> /// <param name="soilTopLayerDepth">soil layer depth top in cm</param> /// <param name="soilBaseLayerDepth">soil layer depth base/bottom in cm</param> /// <param name="depth">soil layer depth in cm</param> /// <param name="soilOrganicCarbonLayer">soil carbon layer in g[C]/100g[soil]</param> /// <param name="bulkDensity"></param> /// <param name="sand">part sand in [0-100] %</param> /// <param name="clay">part clay in [0-100] % </param> /// <param name="saturation"> saturation (pore volume) in [0-100] %</param> /// <param name="wiltingPoint">wilting point [0-100] % (m3/m3) </param> /// <param name="fieldCapacity">field capacity [0-100]% (m3/m3)</param> /// <returns></returns> private static SoilLayer FromAgMIP(double soilTopLayerDepth, double soilBaseLayerDepth, double depth, double soilOrganicCarbonLayer, double bulkDensity, double sand, double clay, double saturation, double wiltingPoint, double fieldCapacity) { SoilLayer soilLayer = new SoilLayer(); if (((soilBaseLayerDepth - soilTopLayerDepth) - depth) > TINY) { throw new FormatException("soil_layer_base_depth - soil_layer_top_depth should equal depth"); } soilLayer.Thickness = depth * 0.01; // from cm in m soilLayer.SoilOrganicCarbon = soilOrganicCarbonLayer; //g[C]/100g[soil] soilLayer.SoilBulkDensity = bulkDensity * 1000; // g/cm3 -> kg/m3 soilLayer.Sand = sand * 0.01; // recheck soilLayer.Clay = clay * 0.01; soilLayer.PoreVolume = saturation * 0.01; soilLayer.PermanentWiltingPoint = wiltingPoint * 0.01; //vol% [0-1] (m3/m3) soilLayer.FieldCapacity = fieldCapacity * 0.01; // vol% [0-1] (m3/m3) return(soilLayer); }
private static void AssertSoilLayerProperties(SoilLayer soilLayer, LayerWithSoil layerWithSoil) { Assert.AreEqual(soilLayer.IsAquifer, layerWithSoil.IsAquifer); Assert.AreEqual(CSharpWrapperWaterPressureInterpolationModel.Hydrostatic, layerWithSoil.WaterPressureInterpolationModel); Assert.IsNotNull(layerWithSoil.Soil); Assert.AreEqual(ShearStrengthModelType.Shansep, layerWithSoil.Soil.ShearStrengthAbovePhreaticLevelModel); Assert.AreEqual(ShearStrengthModelType.Shansep, layerWithSoil.Soil.ShearStrengthBelowPhreaticLevelModel); Assert.AreEqual(soilLayer.MaterialName, layerWithSoil.Soil.Name); Assert.AreEqual(soilLayer.AbovePhreaticLevel, layerWithSoil.Soil.AbovePhreaticLevel); Assert.AreEqual(soilLayer.BelowPhreaticLevel, layerWithSoil.Soil.BelowPhreaticLevel); Assert.AreEqual(soilLayer.Cohesion, layerWithSoil.Soil.Cohesion); Assert.AreEqual(soilLayer.FrictionAngle, layerWithSoil.Soil.FrictionAngle); Assert.AreEqual(soilLayer.ShearStrengthRatio, layerWithSoil.Soil.RatioCuPc); Assert.AreEqual(soilLayer.StrengthIncreaseExponent, layerWithSoil.Soil.StrengthIncreaseExponent); Assert.AreEqual(soilLayer.Dilatancy, layerWithSoil.Soil.Dilatancy); AssertIrrelevantValues(layerWithSoil); }
public void Constructor_EmptyConstructionProperties_ExpectedValues() { // Call var layer = new SoilLayer(new Point2D[0], new SoilLayer.ConstructionProperties(), Enumerable.Empty <SoilLayer>()); // Assert Assert.IsFalse(layer.IsAquifer); Assert.IsFalse(layer.UsePop); Assert.IsEmpty(layer.MaterialName); Assert.AreEqual(ShearStrengthModel.CPhi, layer.ShearStrengthModel); Assert.IsNaN(layer.AbovePhreaticLevel); Assert.IsNaN(layer.BelowPhreaticLevel); Assert.IsNaN(layer.Cohesion); Assert.IsNaN(layer.FrictionAngle); Assert.IsNaN(layer.ShearStrengthRatio); Assert.IsNaN(layer.StrengthIncreaseExponent); Assert.IsNaN(layer.Pop); Assert.IsNaN(layer.Dilatancy); Assert.AreEqual(WaterPressureInterpolationModel.Automatic, layer.WaterPressureInterpolationModel); }
public void Create_SoilProfile_ExpectedLayersWithSoil() { // Setup var outerRing1 = new Point2D[0]; var outerRing2 = new Point2D[0]; var outerRing3 = new Point2D[0]; var outerRing4 = new Point2D[0]; var outerRing5 = new Point2D[0]; var outerRing6 = new Point2D[0]; var soilProfile = new SoilProfile ( new[] { new SoilLayer(outerRing1, CreateRandomConstructionProperties(21, "Material 1"), new[] { new SoilLayer(outerRing2, CreateRandomConstructionProperties(22, "Material 2"), new[] { new SoilLayer(outerRing3, CreateRandomConstructionProperties(22, "Material 3"), Enumerable.Empty <SoilLayer>()) }), new SoilLayer(outerRing4, CreateRandomConstructionProperties(23, "Material 4"), Enumerable.Empty <SoilLayer>()) }), new SoilLayer(outerRing5, CreateRandomConstructionProperties(24, "Material 5"), new[] { new SoilLayer(outerRing6, CreateRandomConstructionProperties(25, "Material 6"), Enumerable.Empty <SoilLayer>()) }) }, Enumerable.Empty <PreconsolidationStress>() ); // Call LayerWithSoil[] layersWithSoil = LayerWithSoilCreator.Create(soilProfile, out IDictionary <SoilLayer, LayerWithSoil> layerLookup); // Assert SoilLayer layer1 = soilProfile.Layers.ElementAt(0); SoilLayer layer2 = layer1.NestedLayers.ElementAt(0); SoilLayer layer3 = layer2.NestedLayers.ElementAt(0); SoilLayer layer4 = layer1.NestedLayers.ElementAt(1); SoilLayer layer5 = soilProfile.Layers.ElementAt(1); SoilLayer layer6 = layer5.NestedLayers.ElementAt(0); Assert.AreEqual(6, layersWithSoil.Length); Assert.AreEqual(outerRing1, layersWithSoil[0].OuterRing); CollectionAssert.AreEqual(new[] { outerRing2, outerRing3, outerRing4 }, layersWithSoil[0].InnerRings); AssertSoilLayerProperties(layer1, layersWithSoil[0]); Assert.AreEqual(outerRing2, layersWithSoil[1].OuterRing); CollectionAssert.AreEqual(new[] { outerRing3 }, layersWithSoil[1].InnerRings); AssertSoilLayerProperties(layer2, layersWithSoil[1]); Assert.AreEqual(outerRing3, layersWithSoil[2].OuterRing); CollectionAssert.IsEmpty(layersWithSoil[2].InnerRings); AssertSoilLayerProperties(layer3, layersWithSoil[2]); Assert.AreEqual(outerRing4, layersWithSoil[3].OuterRing); CollectionAssert.IsEmpty(layersWithSoil[3].InnerRings); AssertSoilLayerProperties(layer4, layersWithSoil[3]); Assert.AreEqual(outerRing5, layersWithSoil[4].OuterRing); CollectionAssert.AreEqual(new[] { outerRing6 }, layersWithSoil[4].InnerRings); AssertSoilLayerProperties(layer5, layersWithSoil[4]); Assert.AreEqual(outerRing6, layersWithSoil[5].OuterRing); CollectionAssert.IsEmpty(layersWithSoil[5].InnerRings); AssertSoilLayerProperties(layer6, layersWithSoil[5]); SoilLayer[] originalSoilLayers = { layer1, layer2, layer3, layer4, layer5, layer6 }; Assert.AreEqual(layersWithSoil.Length, layerLookup.Count); for (var i = 0; i < layersWithSoil.Length; i++) { Assert.AreSame(originalSoilLayers[i], layerLookup.ElementAt(i).Key); Assert.AreSame(layersWithSoil.ElementAt(i), layerLookup.ElementAt(i).Value); } }
private double getLayerCapacityByProrationOfHorizon(double pDepth, SoilLayer pSoilLayer) { double lDepthSum = 0; double lReturnLayerWaterSum = 0; IEnumerable <Horizon> query; double lRemainRoot = 0; double lLastHorizonLayerCapacity = 0; double lLastHorizonLayerDepth = 0; double lFieldCapacityDepthCM = 10; try { query = this.horizonList.OrderBy(lHorizon => lHorizon.Order); foreach (Horizon lHorizon in query) { //To the root substract the passed horizon depth lRemainRoot = pDepth - lDepthSum; lDepthSum += lHorizon.HorizonLayerDepth; switch (pSoilLayer) { case SoilLayer.AvailableWater: lLastHorizonLayerCapacity = lHorizon.GetAvailableWaterCapacity(); break; case SoilLayer.FieldCapacity: lLastHorizonLayerCapacity = lHorizon.GetFieldCapacity(); break; case SoilLayer.PermanentWiltingPoint: lLastHorizonLayerCapacity = lHorizon.GetPermanentWiltingPoint(); break; default: lLastHorizonLayerCapacity = 0; break; } lLastHorizonLayerDepth = lHorizon.HorizonLayerDepth; // La raiz es mas grande que hasta este horizonte, calculo y sigo if (lDepthSum <= pDepth) { lReturnLayerWaterSum += lLastHorizonLayerCapacity * lLastHorizonLayerDepth / lFieldCapacityDepthCM; } // La raiz llega/termina en este horizonte, calculo y termino else if (lHorizon.HorizonLayerDepth > lRemainRoot && lRemainRoot > 0) { lReturnLayerWaterSum += lLastHorizonLayerCapacity * lRemainRoot / lFieldCapacityDepthCM; break; } } //If the root is bigger than all the horizonList i have defined if (lDepthSum < pDepth) { lRemainRoot = pDepth - lDepthSum; lReturnLayerWaterSum += lLastHorizonLayerCapacity * lRemainRoot / lFieldCapacityDepthCM; } } catch (Exception ex) { logger.Error(ex, "Exception in Soil.getLayerCapacityByProrationOfHorizon " + "\n" + ex.Message + "\n" + ex.StackTrace); throw ex; } return(lReturnLayerWaterSum); }
//------------------------------------------------------------------------------------------------- static SortedList <string, SoilLayer> FindSoilLayerProperties(string aKey, string aArea) { const string CR = "\r"; if (aKey == null || aKey.Length == 0) { return(null); } SortedList <String, SoilLayer> SoilLayers = new SortedList <String, SoilLayer>(); // This is the SQL query to be submitted to the SSURGO web service string Query = "SELECT" + CR + "saversion, saverest," + CR + "l.areasymbol, l.areaname, l.lkey," + CR + "mu.musym, mu.muname, museq, mu.mukey," + CR + "hydgrpdcd" + CR + "compname, slope_r, comppct_r, c.cokey, " + CR + "hzdept_r, hzdepb_r, ksat_r, ch.chkey " + CR + "FROM sacatalog sac" + CR + "INNER JOIN legend l ON l.areasymbol = sac.areasymbol" + CR + "AND l.areasymbol = " + "'" + aArea + "'" + CR + "INNER JOIN mapunit mu ON mu.lkey = l.lkey" + CR + "AND mu.mukey = " + "'" + aKey + "'" + CR + "LEFT OUTER JOIN muaggatt m ON m.mukey = mu.mukey" + CR + "LEFT OUTER JOIN component c ON c.mukey = mu.mukey" + CR + "LEFT OUTER JOIN chorizon ch ON ch.cokey = c.cokey" + CR; // Here we use a Service Reference to run the SQL query against the SSURGO // database. See http://msdn.microsoft.com/en-us/library/bb628652.aspx for // instructions on how to create a Service Referenc. The URL of NRCS's // SSURGO web service required by the Service Reference is: //"https://sdmdataaccess.nrcs.usda.gov/Tabular/SDMTabularService.asmx". ServiceReference1.SDMTabularServiceSoapClient Soap = new ServiceReference1.SDMTabularServiceSoapClient(); System.Data.DataSet SystemDataSet = Soap.RunQuery(Query); Soap.Close(); // Now we extract the data for each soil layer in the mapping unit we queried. if (SystemDataSet.Tables.Count > 0) { string Name = ""; DataTable Table = SystemDataSet.Tables[0]; foreach (DataRow Row in Table.Rows) { Object[] RowItemArray = Row.ItemArray; Name = (string)RowItemArray[(int)FieldNumbers.musym]; string Key = (string)RowItemArray[(int)FieldNumbers.chkey]; string HSG = (string)RowItemArray[(int)FieldNumbers.hydgrpdcd]; if (HSG.Length > 0) { string Hzdept_r = (string)RowItemArray[(int)FieldNumbers.hzdept_r]; string Hzdepb_r = (string)RowItemArray[(int)FieldNumbers.hzdepb_r]; string Ksat_r = (string)RowItemArray[(int)FieldNumbers.ksat_r]; SoilLayer Layer = new SoilLayer(); if (!Double.TryParse(Hzdept_r, out Layer.DepthToTop)) { Layer.DepthToTop = -999; } if (!Double.TryParse(Hzdepb_r, out Layer.DepthToBottom)) { Layer.DepthToBottom = -999; } if (!Double.TryParse(Ksat_r, out Layer.KSAT)) { Layer.KSAT = -999; } Layer.HSG = HSG; if (!Int32.TryParse((string)RowItemArray[(int)FieldNumbers.comppct_r], out Layer.CompPct_R)) { Layer.CompPct_R = 0; } if (!Double.TryParse((string)RowItemArray[(int)FieldNumbers.slope_r], out Layer.Slope_R)) { Layer.Slope_R = 0; } if (!SoilLayers.ContainsKey(Key)) { SoilLayers.Add(Key, Layer); } } } } return(SoilLayers); }