Пример #1
0
        public int?UpdateModel(Person currentPerson, out string stormwaterJurisdictionName)

        {
            var delineationStagings = currentPerson.DelineationStagingsWhereYouAreTheUploadedByPerson.ToList();

            // Will  break if there are multiple batches of staged uploads, which is precisely what we want to happen.
            var stormwaterJurisdiction = delineationStagings.Select(x => x.StormwaterJurisdiction).Distinct().Single();

            stormwaterJurisdictionName = stormwaterJurisdiction.GetOrganizationDisplayName();

            // Starting from the treatment BMP is kind of backwards, conceptually, but it's easier to read and write
            var treatmentBMPNames     = delineationStagings.Select(x => x.TreatmentBMPName).ToList();
            var treatmentBMPsToUpdate = stormwaterJurisdiction.TreatmentBMPs.Where(x => treatmentBMPNames.Contains(x.TreatmentBMPName)).ToList();

            foreach (var treatmentBMP in treatmentBMPsToUpdate)
            {
                var delineationStaging = delineationStagings.Single(z => treatmentBMP.TreatmentBMPName == z.TreatmentBMPName);

                treatmentBMP.Delineation?.Delete(HttpRequestStorage.DatabaseEntities);

                treatmentBMP.Delineation = new Models.Delineation(
                    delineationStaging.DelineationStagingGeometry,
                    DelineationType.Distributed.DelineationTypeID, false, treatmentBMP.TreatmentBMPID, DateTime.Now, false)
                {
                    VerifiedByPersonID      = currentPerson.PersonID,
                    DateLastVerified        = DateTime.Now,
                    DelineationGeometry4326 =
                        CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(delineationStaging
                                                                                          .DelineationStagingGeometry)
                };
            }

            return(treatmentBMPsToUpdate.Count);
        }
        private static void MergeAndReproject(DatabaseEntities dbContext, Person person)
        {
            // MergeListHelper doesn't handle same-table foreign keys well, so we use a stored proc to run the merge
            dbContext.Database.CommandTimeout = 30000;
            dbContext.Database.ExecuteSqlCommand("EXEC dbo.pUpdateRegionalSubbasinLiveFromStaging");

            // unfortunately, now we have to create the catchment geometries in 4326, since SQL isn't capable of doing this.
            dbContext.RegionalSubbasins.Load();
            dbContext.Watersheds.Load();
            foreach (var regionalSubbasin in dbContext.RegionalSubbasins)
            {
                regionalSubbasin.CatchmentGeometry4326 = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(regionalSubbasin.CatchmentGeometry);
            }

            // Watershed table is made up from the dissolves/ aggregation of the Regional Subbasins feature layer, so we need to update it when Regional Subbasins are updated
            foreach (var watershed in dbContext.Watersheds)
            {
                watershed.WatershedGeometry4326 = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(watershed.WatershedGeometry);
            }
            dbContext.SaveChanges(person);

            dbContext.Database.ExecuteSqlCommand("EXEC dbo.pTreatmentBMPUpdateWatershed");
            dbContext.Database.CommandTimeout = 30000;
            dbContext.Database.ExecuteSqlCommand("EXEC dbo.pUpdateRegionalSubbasinIntersectionCache");
        }
        /// <summary>
        /// Creates a Grid statistics result object.
        /// </summary>
        /// <param name="calculationCoordinateSystemId">The calculation coordinate system id.</param>
        /// <param name="displayCoordinateSystemId">The display coordinate system id.</param>
        /// <param name="gridCellSize">Size of the grid cell.</param>
        /// <param name="cells">Grid statistics cell list returned from web service.</param>
        /// <returns></returns>
        public static CombinedGridStatisticsResult Create(
            CoordinateSystemId calculationCoordinateSystemId,
            CoordinateSystemId displayCoordinateSystemId,
            int gridCellSize,
            IList <IGridCellCombinedStatistics> cells)
        {
            var model = new CombinedGridStatisticsResult();

            model.Cells = new List <CombinedGridStatisticsCellResult>();
            model.CalculationCoordinateSystemId   = (int)displayCoordinateSystemId;
            model.CalculationCoordinateSystemName = CoordinateSystemHelper.GetCoordinateSystemName(calculationCoordinateSystemId);
            model.DisplayCoordinateSystemId       = (int)calculationCoordinateSystemId;
            model.DisplayCoordinateSystemName     = CoordinateSystemHelper.GetCoordinateSystemName(displayCoordinateSystemId);
            model.GridCellSize = gridCellSize;

            if (cells == null || cells.Count == 0)
            {
                return(model);
            }
            //model.GridCellSize = cells[0].GridCellSize;
            //model.GridCellCoordinateSystemId = (int)cells[0].GridCoordinateSystem;
            //model.GridCellCoordinateSystem = cells[0].GridCoordinateSystem.ToString();
            foreach (IGridCellCombinedStatistics gridCell in cells)
            {
                model.Cells.Add(CombinedGridStatisticsCellResult.Create(gridCell));
            }
            return(model);
        }
Пример #4
0
        public void UpdateModel(Models.OnlandVisualTrashAssessmentArea onlandVisualTrashAssessmentArea)
        {
            if (IsParcelPicker.GetValueOrDefault())
            {
                // since this is parcel picks, we don't need to reproject; the parcels are already in the correct system (State Plane)
                var unionListGeometries = HttpRequestStorage.DatabaseEntities.Parcels.Where(x => ParcelIDs.Contains(x.ParcelID)).Select(x => x.ParcelGeometry).ToList().UnionListGeometries();
                var onlandVisualTrashAssessmentAreaGeometry2771 = unionListGeometries.FixSrid(CoordinateSystemHelper.NAD_83_HARN_CA_ZONE_VI_SRID);
                onlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentAreaGeometry     = onlandVisualTrashAssessmentAreaGeometry2771;
                onlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentAreaGeometry4326 = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(onlandVisualTrashAssessmentAreaGeometry2771);
            }
            else
            {
                var dbGeometrys = WktAndAnnotations.Select(x =>
                                                           DbGeometry.FromText(x.Wkt, CoordinateSystemHelper.NAD_83_HARN_CA_ZONE_VI_SRID).ToSqlGeometry().MakeValid()
                                                           .ToDbGeometry());
                var newGeometry4326 = dbGeometrys.ToList().UnionListGeometries();

                // since this is coming from the browser, we have to transform to State Plane
                onlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentAreaGeometry =
                    CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(newGeometry4326);

                onlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentAreaGeometry4326 =
                    newGeometry4326.FixSrid(CoordinateSystemHelper.WGS_1984_SRID);

                HttpRequestStorage.DatabaseEntities.SaveChanges();
            }
        }
Пример #5
0
        private static List <Point> GetPointsFromDbGeometry(DbGeometry geometry)
        {
            // since the bounding box is being sent TO the browser, we better reproject to Web Mercator if necessary
            if (geometry.CoordinateSystemId != CoordinateSystemHelper.WGS_1984_SRID)
            {
                geometry = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(geometry);
            }


            var pointList = new List <Point>();

            if (!DbGeometryToGeoJsonHelper.CanParseGeometry(geometry))
            {
                return(pointList);
            }

            var pointCount = geometry.Envelope.ElementAt(1).PointCount.Value;
            var envelope   = geometry.Envelope.ElementAt(1);


            for (var i = 1; i <= pointCount; i++)
            {
                var dbGeometryPoint = envelope.PointAt(i);

                if (!dbGeometryPoint.XCoordinate.HasValue || !dbGeometryPoint.YCoordinate.HasValue)
                {
                    continue;
                }

                pointList.Add(new Point(envelope.PointAt(i).YCoordinate.Value, envelope.PointAt(i).XCoordinate.Value));
            }
            return(pointList);
        }
Пример #6
0
        /// <summary>
        /// Calculates the combined grid result.
        /// </summary>
        /// <param name="calculationCoordinateSystemId">The calculation coordinate system id.</param>
        /// <param name="gridCellSize">Size of the grid cell.</param>
        /// <param name="wfsLayerId">The WFS layer id.</param>
        /// <returns>Combined grid cell statistics.</returns>
        public CombinedGridStatisticsResult CalculateCombinedGridResult(int calculationCoordinateSystemId, int gridCellSize, int wfsLayerId)
        {
            GridSpecification gridSpecification       = new GridSpecification();
            CoordinateSystem  displayCoordinateSystem = MySettings.Presentation.Map.DisplayCoordinateSystem;

            gridSpecification.GridCoordinateSystem    = (GridCoordinateSystem)calculationCoordinateSystemId;
            gridSpecification.GridCellSize            = gridCellSize;
            gridSpecification.IsGridCellSizeSpecified = true;
            gridSpecification.GridCellGeometryType    = GridCellGeometryType.Polygon;
            if (MySettings.Filter.Spatial.IsActive)
            {
                // Create bounding box from spatial filter
                ObservableCollection <DataPolygon> polygons = MySettings.Filter.Spatial.Polygons;
                if (polygons.Count > 0)
                {
                    BoundingBox      boundingBox                 = polygons.GetBoundingBox();
                    CoordinateSystem toCoordinateSystem          = CoordinateSystemHelper.GetCoordinateSystemFromGridCoordinateSystem(gridSpecification.GridCoordinateSystem);
                    IPolygon         convertedBoundingBoxPolygon = GisTools.CoordinateConversionManager.GetConvertedBoundingBox(boundingBox, MySettings.Filter.Spatial.PolygonsCoordinateSystem, toCoordinateSystem);
                    BoundingBox      convertedBoundingBox        = convertedBoundingBoxPolygon.GetBoundingBox();
                    gridSpecification.BoundingBox = convertedBoundingBox;
                }
            }

            WfsLayerSetting wfsLayer              = SessionHandler.MySettings.DataProvider.MapLayers.WfsLayers.FirstOrDefault(l => l.Id == wfsLayerId);
            string          featuresUrl           = "";
            string          featureCollectionJson = null;

            if (wfsLayer.IsFile)
            {
                featureCollectionJson = JObject.FromObject(MySettingsManager.GetMapDataFeatureCollection(UserContext, wfsLayer.GeometryName, gridSpecification.GridCoordinateSystem.GetCoordinateSystemId())).ToString();
            }
            else
            {
                if (string.IsNullOrEmpty(wfsLayer.Filter))
                {
                    featuresUrl = string.Format("{0}?service=wfs&version=1.1.0&request=GetFeature&typeName={1}",
                                                wfsLayer.ServerUrl, wfsLayer.TypeName);
                }
                else
                {
                    featuresUrl =
                        string.Format("{0}?service=wfs&version=1.1.0&request=GetFeature&typeName={1}&filter={2}",
                                      wfsLayer.ServerUrl, wfsLayer.TypeName, wfsLayer.Filter);
                }
            }
            var speciesObservationSearchCriteriaManager        = new SpeciesObservationSearchCriteriaManager(UserContext);
            SpeciesObservationSearchCriteria    searchCriteria = speciesObservationSearchCriteriaManager.CreateSearchCriteria(MySettings);
            IList <IGridCellCombinedStatistics> gridCells      = CoreData.AnalysisManager.GetGridCellFeatureStatisticsCombinedWithSpeciesObservationCounts(UserContext, gridSpecification, searchCriteria, null, featuresUrl, featureCollectionJson, displayCoordinateSystem);

            if (MySettings.Calculation.GridStatistics.GenerateAllGridCells)
            {
                gridCells = AddEmptyGridCells(gridCells, gridSpecification, displayCoordinateSystem);
                gridCells = RemoveGridCellsOutsideBounds(gridCells, gridSpecification);
            }

            gridCells = gridCells.OrderBy(x => x.Identifier).ToList();
            return(CombinedGridStatisticsResult.Create(
                       (CoordinateSystemId)calculationCoordinateSystemId, displayCoordinateSystem.Id, gridCellSize, gridCells));
        }
Пример #7
0
        public LocationViewModel(Models.FieldVisit fieldVisit)
        {
            // this is going TO The browser, so it has to be reprojected to web mercator
            var reprojected = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(fieldVisit.TreatmentBMP.LocationPoint);

            TreatmentBMPPointY = reprojected.YCoordinate;
            TreatmentBMPPointX = reprojected.XCoordinate;
        }
Пример #8
0
        /// <summary>
        /// Converts to GeoJSON after reprojecting to 4326 if necessary.
        /// </summary>
        /// <param name="inp"></param>
        /// <returns></returns>
        public static Feature FromDbGeometryWithReprojectionCheck(DbGeometry inp)
        {
            // this is going TO the browser, so it needs to be transformed from 2771 to 4326 if it's not already
            if (inp.CoordinateSystemId != CoordinateSystemHelper.WGS_1984_SRID)
            {
                inp = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(inp);
            }

            return(FromDbGeometryWithNoReproject(inp));
        }
Пример #9
0
        /// <summary>
        /// Creates the presentation map view model.
        /// </summary>
        /// <returns>A view model.</returns>
        public PresentationMapViewModel CreatePresentationMapViewModel()
        {
            PresentationMapViewModel model = new PresentationMapViewModel();

            model.PresentationCoordinateSystems = CoordinateSystemHelper.GetPresentationMapCoordinateSystems();
            model.DownloadCoordinateSystems     = CoordinateSystemHelper.GetDownloadMapCoordinateSystems();
            model.GridMapsCoordinateSystems     = CoordinateSystemHelper.GetGridMapsCoordinateSystems();
            model.IsSettingsDefault             = MapSettings.IsSettingsDefault() && SessionHandler.MySettings.Calculation.GridStatistics.IsCoordinateSystemSettingsDefault();
            return(model);
        }
Пример #10
0
        public OnlandVisualTrashAssessmentObservation ToOnlandVisualTrashAssessmentObservation()
        {
            DbGeometry locationPoint4326 = DbSpatialHelper.MakeDbGeometryFromCoordinates(LocationX.GetValueOrDefault(),
                                                                                         LocationY.GetValueOrDefault(), CoordinateSystemHelper.NAD_83_HARN_CA_ZONE_VI_SRID);

            var locationPoint2771 =
                CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(locationPoint4326);

            return(new OnlandVisualTrashAssessmentObservation(OnlandVisualTrashAssessmentObservationID,
                                                              OnlandVisualTrashAssessmentID, locationPoint2771, Note, ObservationDateTime, locationPoint4326));
        }
Пример #11
0
        public WfsStatisticsGridResult CalculateGridResult(IUserContext userContext, int coordinateSystemId, int gridSize, int wfsLayerId)
        {
            var requestedGridCoordinateSystem = (GridCoordinateSystem)coordinateSystemId;
            var gridSpecification             = new GridSpecification
            {
                GridCoordinateSystem    = requestedGridCoordinateSystem,
                GridCellSize            = gridSize,
                IsGridCellSizeSpecified = true,
                GridCellGeometryType    = GridCellGeometryType.Polygon
            };

            if (MySettings.Filter.Spatial.IsActive)
            {
                // Create bounding box from spatial filter
                var polygons = MySettings.Filter.Spatial.Polygons;
                if (polygons.Count > 0)
                {
                    var boundingBox                 = polygons.GetBoundingBox();
                    var toCoordinateSystem          = CoordinateSystemHelper.GetCoordinateSystemFromGridCoordinateSystem(gridSpecification.GridCoordinateSystem);
                    var convertedBoundingBoxPolygon = GisTools.CoordinateConversionManager.GetConvertedBoundingBox(boundingBox, MySettings.Filter.Spatial.PolygonsCoordinateSystem, toCoordinateSystem);
                    gridSpecification.BoundingBox = convertedBoundingBoxPolygon.GetBoundingBox();
                }
            }

            var    displayCoordinateSystem = MySettings.Presentation.Map.DisplayCoordinateSystem;
            var    wfsLayer              = SessionHandler.MySettings.DataProvider.MapLayers.WfsLayers.FirstOrDefault(l => l.Id == wfsLayerId);
            string featuresUrl           = null;
            string featureCollectionJson = null;

            if (wfsLayer.IsFile)
            {
                featureCollectionJson = JObject.FromObject(MySettingsManager.GetMapDataFeatureCollection(userContext, wfsLayer.GeometryName, requestedGridCoordinateSystem.GetCoordinateSystemId())).ToString();
            }
            else
            {
                if (string.IsNullOrEmpty(wfsLayer.Filter))
                {
                    featuresUrl = string.Format("{0}?service=wfs&version=1.1.0&request=GetFeature&typeName={1}", wfsLayer.ServerUrl, wfsLayer.TypeName);
                }
                else
                {
                    featuresUrl = string.Format("{0}?service=wfs&version=1.1.0&request=GetFeature&typeName={1}&filter={2}", wfsLayer.ServerUrl, wfsLayer.TypeName, wfsLayer.Filter);
                }
            }

            var list = CoreData.AnalysisManager.GetGridFeatureStatistics(UserContext, null, featuresUrl, featureCollectionJson, gridSpecification, displayCoordinateSystem);

            return(WfsStatisticsGridResult.Create(list));
        }
Пример #12
0
        public virtual void UpdateModel(Models.TreatmentBMP treatmentBMP, Person currentPerson)
        {
            // note that these nullables will never be null due to the Required attribute
            // this is coming FROM the browser, so it has to be reprojected to CA State Plane
            var locationPoint4326 = DbSpatialHelper.MakeDbGeometryFromCoordinates(TreatmentBMPPointX.GetValueOrDefault(),
                                                                                  TreatmentBMPPointY.GetValueOrDefault(), CoordinateSystemHelper.WGS_1984_SRID);
            var locationPoint = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(locationPoint4326);

            treatmentBMP.LocationPoint     = locationPoint;
            treatmentBMP.LocationPoint4326 = locationPoint4326;

            treatmentBMP.UpdateUpstreamBMPReferencesIfNecessary();

            // associate watershed, lspc basin, precipitation zone
            treatmentBMP.SetTreatmentBMPPointInPolygonDataByLocationPoint(locationPoint);

            treatmentBMP.UpdatedCentralizedBMPDelineationIfPresent();
        }
Пример #13
0
        // ReSharper disable once UnusedMember.Global
        public static IEnumerable <HRURequestFeature> GetHRURequestFeatures(this IHaveHRUCharacteristics iHaveHRUCharacteristics)
        {
            var baseAttributes = new HRURequestFeatureAttributes
            {
                ObjectID = iHaveHRUCharacteristics.PrimaryKey,
                Area     = iHaveHRUCharacteristics.GetCatchmentGeometry().Area.GetValueOrDefault(),
                Length   = iHaveHRUCharacteristics.GetCatchmentGeometry().Length.GetValueOrDefault(),
            };

            var catchmentGeometry =
                CoordinateSystemHelper.Project2771To2230(iHaveHRUCharacteristics.GetCatchmentGeometry());

            for (var i = 1; i <= catchmentGeometry.ElementCount; i++)
            {
                if (catchmentGeometry.ElementAt(i).SpatialTypeName.ToUpper() == "POLYGON")
                {
                    yield return(new HRURequestFeature(catchmentGeometry.ElementAt(i), baseAttributes, i));
                }
            }
        }
        public ActionResult RefineAssessmentArea(OnlandVisualTrashAssessmentPrimaryKey onlandVisualTrashAssessmentPrimaryKey, RefineAssessmentAreaViewModel viewModel)
        {
            var onlandVisualTrashAssessment = onlandVisualTrashAssessmentPrimaryKey.EntityObject;

            if (!ModelState.IsValid)
            {
                return(ViewRefineAssessmentArea(onlandVisualTrashAssessment, viewModel));
            }

            // these come in in web mercator...
            var dbGeometrys         = viewModel.WktAndAnnotations.Select(x => DbGeometry.FromText(x.Wkt, CoordinateSystemHelper.WGS_1984_SRID).ToSqlGeometry().MakeValid().ToDbGeometry());
            var unionListGeometries = dbGeometrys.ToList().UnionListGeometries();

            // ...and then get fixed here
            onlandVisualTrashAssessment.DraftGeometry = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(unionListGeometries);
            onlandVisualTrashAssessment.IsDraftGeometryManuallyRefined = true;
            HttpRequestStorage.DatabaseEntities.SaveChanges();

            return(RedirectToAppropriateStep(viewModel, OVTASection.RefineAssessmentArea, onlandVisualTrashAssessment));
        }
        public FileResult Download(RegionalSubbasinRevisionRequestPrimaryKey regionalSubbasinRevisionRequestPrimaryKey)
        {
            var geometry = regionalSubbasinRevisionRequestPrimaryKey.EntityObject
                           .RegionalSubbasinRevisionRequestGeometry;

            var reprojectedGeometry = CoordinateSystemHelper.ProjectWebMercatorTo2230(geometry);

            var geoJson = DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(reprojectedGeometry);

            var serializedGeoJson = JsonConvert.SerializeObject(geoJson);

            var outputLayerName = $"BMP_{regionalSubbasinRevisionRequestPrimaryKey.EntityObject.TreatmentBMP.TreatmentBMPID}_RevisionRequest";

            using (var workingDirectory = new DisposableTempDirectory())
            {
                var outputPathForLayer =
                    Path.Combine(workingDirectory.DirectoryInfo.FullName, outputLayerName);


                var ogr2OgrCommandLineRunner = new Ogr2OgrCommandLineRunner(NeptuneWebConfiguration.Ogr2OgrExecutable,
                                                                            CoordinateSystemHelper.NAD_83_CA_ZONE_VI_SRID,
                                                                            NeptuneWebConfiguration.HttpRuntimeExecutionTimeout.TotalMilliseconds);

                ogr2OgrCommandLineRunner.ImportGeoJsonToFileGdb(serializedGeoJson, outputPathForLayer,
                                                                outputLayerName, false, true);

                using (var zipFile = DisposableTempFile.MakeDisposableTempFileEndingIn(".zip"))
                {
                    ZipFile.CreateFromDirectory(workingDirectory.DirectoryInfo.FullName, zipFile.FileInfo.FullName);
                    var fileStream = zipFile.FileInfo.OpenRead();
                    var bytes      = fileStream.ReadFully();
                    fileStream.Close();
                    fileStream.Dispose();
                    return(File(bytes, "application/zip", $"{outputLayerName}.zip"));
                }
            }
        }
Пример #16
0
        public static IEnumerable <HRURequestFeature> GetHRURequestFeatures(this IEnumerable <LoadGeneratingUnit> loadGeneratingUnits)
        {
            foreach (var loadGeneratingUnit in loadGeneratingUnits)
            {
                var baseAttributes = new HRURequestFeatureAttributes
                {
                    ObjectID       = loadGeneratingUnit.PrimaryKey,
                    Area           = loadGeneratingUnit.LoadGeneratingUnitGeometry.Area.GetValueOrDefault(),
                    Length         = loadGeneratingUnit.LoadGeneratingUnitGeometry.Length.GetValueOrDefault(),
                    QueryFeatureID = loadGeneratingUnit.LoadGeneratingUnitID
                };
                var catchmentGeometry =
                    CoordinateSystemHelper.Project2771To2230(loadGeneratingUnit.LoadGeneratingUnitGeometry);

                for (var i = 1; i <= catchmentGeometry.ElementCount; i++)
                {
                    if (catchmentGeometry.ElementAt(i).SpatialTypeName.ToUpper() == "POLYGON")
                    {
                        yield return(new HRURequestFeature(catchmentGeometry.ElementAt(i), baseAttributes,
                                                           loadGeneratingUnit.LoadGeneratingUnitID));
                    }
                }
            }
        }
        private static TreatmentBMP ParseRequiredAndOptionalFieldAndCreateBMP(string[] row,
                                                                              Dictionary <string, int> fieldsDict, int rowNumber, out List <string> errorList,
                                                                              TreatmentBMPType treatmentBMPType, List <Organization> organizations,
                                                                              List <StormwaterJurisdiction> stormwaterJurisdictions, List <string> treatmentBMPNamesInCsv)
        {
            errorList = new List <string>();

            var treatmentBMPName         = SetStringValue(row, fieldsDict, rowNumber, errorList, "BMP Name", TreatmentBMP.FieldLengths.TreatmentBMPName, true);
            var stormwaterJurisdictionID = FindLookupValue(row, fieldsDict, "Jurisdiction", rowNumber, errorList, stormwaterJurisdictions, x => x.Organization.OrganizationName, x => x.StormwaterJurisdictionID, false, true);

            if (!stormwaterJurisdictionID.HasValue || string.IsNullOrWhiteSpace(treatmentBMPName))
            {
                // no point in going further if we don't have a name and jurisdiction
                return(null);
            }

            if (!string.IsNullOrWhiteSpace(treatmentBMPName))
            {
                if (treatmentBMPNamesInCsv.Contains(treatmentBMPName))
                {
                    errorList.Add(
                        $"The BMP with Name '{treatmentBMPName}' was already added in this upload, duplicate name is found at row: {rowNumber}");
                }
                treatmentBMPNamesInCsv.Add(treatmentBMPName);
            }

            var treatmentBMP = HttpRequestStorage.DatabaseEntities.TreatmentBMPs.SingleOrDefault(x =>
                                                                                                 x.TreatmentBMPName == treatmentBMPName &&
                                                                                                 x.StormwaterJurisdictionID == stormwaterJurisdictionID.Value);

            if (treatmentBMP != null)
            {
                // one last check; make sure the treatment bmp type of the existing treatment bmp matches the passed type
                if (treatmentBMPType.TreatmentBMPTypeID != treatmentBMP.TreatmentBMPTypeID)
                {
                    errorList.Add(
                        $"BMP with name '{treatmentBMPName}' has a Type '{treatmentBMP.TreatmentBMPType.TreatmentBMPTypeName}', which does not match the uploaded Type '{treatmentBMPType.TreatmentBMPTypeName}' for row: {rowNumber}");
                }
            }
            else
            {
                treatmentBMP = new TreatmentBMP(treatmentBMPName, treatmentBMPType.TreatmentBMPTypeID,
                                                stormwaterJurisdictionID.Value, default(int), false,
                                                default(int), default(int));
            }

            var isNew = !ModelObjectHelpers.IsRealPrimaryKeyValue(treatmentBMP.TreatmentBMPID);
            var treatmentBMPLatitude  = row[fieldsDict["Latitude"]];
            var treatmentBMPLongitude = row[fieldsDict["Longitude"]];
            var locationPoint4326     = ParseLocation(treatmentBMPLatitude, treatmentBMPLongitude, rowNumber, errorList,
                                                      isNew);

            if (locationPoint4326 != null)
            {
                treatmentBMP.LocationPoint4326 = locationPoint4326;
                var locationPoint = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(locationPoint4326);
                treatmentBMP.LocationPoint = locationPoint;

                treatmentBMP.SetTreatmentBMPPointInPolygonDataByLocationPoint(locationPoint);
            }

            var ownerOrganizationID = FindLookupValue(row, fieldsDict, "Owner", rowNumber, errorList, organizations,
                                                      x => x.OrganizationName, x => x.OrganizationID, false, isNew);

            if (ownerOrganizationID.HasValue)
            {
                treatmentBMP.OwnerOrganizationID = ownerOrganizationID.Value;
            }

            //start of Optional Fields
            var yearBuilt =
                GetOptionalIntFieldValue(row, fieldsDict, rowNumber, errorList, "Year Built or Installed");

            if (yearBuilt.HasValue)
            {
                treatmentBMP.YearBuilt = yearBuilt;
            }

            var assetIDInSystemOfRecord = SetStringValue(row, fieldsDict, rowNumber, errorList,
                                                         "Asset ID in System of Record", TreatmentBMP.FieldLengths.SystemOfRecordID, false);

            if (!string.IsNullOrWhiteSpace(assetIDInSystemOfRecord))
            {
                treatmentBMP.SystemOfRecordID = assetIDInSystemOfRecord;
            }

            var notes = SetStringValue(row, fieldsDict, rowNumber, errorList, "Notes",
                                       TreatmentBMP.FieldLengths.Notes, false);

            if (!string.IsNullOrWhiteSpace(notes))
            {
                treatmentBMP.Notes = notes;
            }

            var fieldNameRequiredLifespanOfInstallation = "Required Lifespan of Installation";

            if (fieldsDict.ContainsKey(fieldNameRequiredLifespanOfInstallation))
            {
                var treatmentBMPLifespanTypeID = FindLookupValue(row, fieldsDict,
                                                                 fieldNameRequiredLifespanOfInstallation, rowNumber, errorList, TreatmentBMPLifespanType.All,
                                                                 x => x.TreatmentBMPLifespanTypeDisplayName, x => x.TreatmentBMPLifespanTypeID, true, false);
                if (treatmentBMPLifespanTypeID.HasValue)
                {
                    treatmentBMP.TreatmentBMPLifespanTypeID = treatmentBMPLifespanTypeID;
                }

                var fieldNameAllowableEndDateOfInstallationIfApplicable =
                    "Allowable End Date of Installation (if applicable)";
                if (fieldsDict.ContainsKey(fieldNameAllowableEndDateOfInstallationIfApplicable))
                {
                    var requiredLifespanOfInstallation = row[fieldsDict[fieldNameRequiredLifespanOfInstallation]];
                    var allowableEndDateOfInstallation =
                        row[fieldsDict[fieldNameAllowableEndDateOfInstallationIfApplicable]];
                    var isAllowableEndDateOfInstallationEmpty =
                        string.IsNullOrWhiteSpace(allowableEndDateOfInstallation);
                    if (isAllowableEndDateOfInstallationEmpty && treatmentBMPLifespanTypeID ==
                        TreatmentBMPLifespanType.FixedEndDate.TreatmentBMPLifespanTypeID)
                    {
                        errorList.Add(
                            $"An end date must be provided if the '{fieldNameRequiredLifespanOfInstallation}' field is set to fixed end date for row: {rowNumber}");
                    }

                    if (!isAllowableEndDateOfInstallationEmpty && treatmentBMPLifespanTypeID !=
                        TreatmentBMPLifespanType.FixedEndDate.TreatmentBMPLifespanTypeID)
                    {
                        errorList.Add(
                            $"An end date was provided when '{fieldNameRequiredLifespanOfInstallation}' field was set to {requiredLifespanOfInstallation} for row: {rowNumber}");
                    }

                    if (!treatmentBMPLifespanTypeID.HasValue && !isAllowableEndDateOfInstallationEmpty)
                    {
                        errorList.Add(
                            $"An end date was provided when '{fieldNameRequiredLifespanOfInstallation}' field was set to null for row: {rowNumber}");
                    }

                    if (!isAllowableEndDateOfInstallationEmpty)
                    {
                        if (!DateTime.TryParse(allowableEndDateOfInstallation,
                                               out var allowableEndDateOfInstallationDateTime))
                        {
                            errorList.Add(
                                $"{fieldNameAllowableEndDateOfInstallationIfApplicable} can not be converted to Date Time format at row: {rowNumber}");
                        }
                        else
                        {
                            treatmentBMP.TreatmentBMPLifespanEndDate = allowableEndDateOfInstallationDateTime;
                        }
                    }
                }
            }

            var requiredFieldVisitsPerYear = GetOptionalIntFieldValue(row, fieldsDict, rowNumber, errorList,
                                                                      "Required Field Visits Per Year");

            if (requiredFieldVisitsPerYear.HasValue)
            {
                treatmentBMP.RequiredFieldVisitsPerYear = requiredFieldVisitsPerYear;
            }

            var requiredPostStormFieldVisitsPerYear = GetOptionalIntFieldValue(row, fieldsDict, rowNumber,
                                                                               errorList, "Required Post-Storm Field Visits Per Year");

            if (requiredPostStormFieldVisitsPerYear.HasValue)
            {
                treatmentBMP.RequiredPostStormFieldVisitsPerYear = requiredPostStormFieldVisitsPerYear;
            }

            //End of Optional Fields
            var trashCaptureStatusTypeID = FindLookupValue(row, fieldsDict, "Trash Capture Status", rowNumber,
                                                           errorList, TrashCaptureStatusType.All, x => x.TrashCaptureStatusTypeDisplayName,
                                                           x => x.TrashCaptureStatusTypeID, true, isNew);

            if (trashCaptureStatusTypeID.HasValue)
            {
                treatmentBMP.TrashCaptureStatusTypeID = trashCaptureStatusTypeID.Value;
            }

            var treatmentBMPSizingBasisTypeID = FindLookupValue(row, fieldsDict, "Sizing Basis", rowNumber,
                                                                errorList, SizingBasisType.All, x => x.SizingBasisTypeDisplayName, x => x.SizingBasisTypeID, true,
                                                                isNew);

            if (treatmentBMPSizingBasisTypeID.HasValue)
            {
                treatmentBMP.SizingBasisTypeID = treatmentBMPSizingBasisTypeID.Value;
            }

            return(treatmentBMP);
        }
        protected override void RunJobImplementation()
        {
            var person = DbContext.People.Find(PersonID);

            if (person == null)
            {
                throw new InvalidOperationException("PersonID must be valid!");
            }
            try
            {
                var landUseBlockStagings    = person.LandUseBlockStagingsWhereYouAreTheUploadedByPerson;
                var stormwaterJurisdictions = DbContext.StormwaterJurisdictions.ToList();
                var stormwaterJurisdictionsPersonCanEdit =
                    person.GetStormwaterJurisdictionsPersonCanViewWithContext(DbContext).ToList();

                var allowedStormwaterJurisdictionNames = string.Join(", ",
                                                                     stormwaterJurisdictions.Select(x => x.Organization.OrganizationName).ToList());
                var allowedPermitTypeNames =
                    string.Join(", ", PermitType.All.Select(x => x.PermitTypeDisplayName).ToList());
                var allowedPriorityLandUseTypeNames = string.Join(", ",
                                                                  PriorityLandUseType.All.Select(x => x.PriorityLandUseTypeDisplayName).ToList());

                var count                 = 0;
                var errorList             = new List <string>();
                var landUseBlocksToUpload = new List <LandUseBlock>();

                foreach (var landUseBlockStaging in landUseBlockStagings)
                {
                    var landUseBlock = new LandUseBlock(default(int), default(int), string.Empty, default(DbGeometry),
                                                        default(decimal), string.Empty, default(decimal), default(decimal), default(int), default(int), default(DbGeometry));


                    var landUseBlockPLUType = landUseBlockStaging.PriorityLandUseType;
                    if (!PriorityLandUseType.All.Select(x => x.PriorityLandUseTypeDisplayName)
                        .Contains(landUseBlockPLUType))
                    {
                        errorList.Add(
                            $"The Priority Land Use Type '{landUseBlockPLUType}' at row {count} was not found. Acceptable values are {allowedPriorityLandUseTypeNames}");
                    }
                    else
                    {
                        landUseBlock.PriorityLandUseTypeID = PriorityLandUseType.All
                                                             .Single(x => x.PriorityLandUseTypeDisplayName == landUseBlockPLUType).PriorityLandUseTypeID;
                    }

                    landUseBlock.LandUseDescription = landUseBlockStaging.LandUseDescription;


                    landUseBlock.TrashGenerationRate = landUseBlockStaging.TrashGenerationRate;
                    landUseBlock.LandUseForTGR       = landUseBlockStaging.LandUseForTGR;

                    if (landUseBlockStaging.LandUseForTGR == "Residential")
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = landUseBlockStaging.MedianHouseholdIncome;
                        landUseBlock.MedianHouseholdIncomeRetail      = 0;
                    }
                    else if (landUseBlockStaging.LandUseForTGR == "Retail")
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = 0;
                        landUseBlock.MedianHouseholdIncomeRetail      = landUseBlockStaging.MedianHouseholdIncome;
                    }
                    else
                    {
                        landUseBlock.MedianHouseholdIncomeResidential = 0;
                        landUseBlock.MedianHouseholdIncomeRetail      = 0;
                    }

                    var stormwaterJurisdictionName = landUseBlockStaging.StormwaterJurisdiction;
                    if (string.IsNullOrEmpty(stormwaterJurisdictionName))
                    {
                        errorList.Add(
                            $"The Stormwater Jurisdiction at row {count} is null, empty or whitespace. A value must be provided");
                    }

                    if (!stormwaterJurisdictions.Select(x => x.Organization.OrganizationName)
                        .Contains(stormwaterJurisdictionName))
                    {
                        errorList.Add(
                            $"The Stormwater Jurisdiction '{stormwaterJurisdictionName}' at row {count} was not found. Acceptable values are {allowedStormwaterJurisdictionNames}");
                    }
                    else
                    {
                        var stormwaterJurisdictionToAssign = stormwaterJurisdictions
                                                             .Single(x => x.Organization.OrganizationName == landUseBlockStaging.StormwaterJurisdiction);
                        if (stormwaterJurisdictionsPersonCanEdit.Select(x => x.StormwaterJurisdictionID)
                            .Contains(stormwaterJurisdictionToAssign.StormwaterJurisdictionID))
                        {
                            landUseBlock.StormwaterJurisdictionID =
                                stormwaterJurisdictionToAssign.StormwaterJurisdictionID;
                            if (landUseBlockStaging.LandUseBlockStagingGeometry == null)
                            {
                                errorList.Add(
                                    $"The Land Use Block Geometry at row {count} is null. A value must be provided");
                            }
                            else
                            {
                                var clippedGeometry = landUseBlockStaging.LandUseBlockStagingGeometry.Intersection(
                                    stormwaterJurisdictionToAssign.StormwaterJurisdictionGeometry.GeometryNative);

                                landUseBlock.LandUseBlockGeometry     = clippedGeometry;
                                landUseBlock.LandUseBlockGeometry4326 =
                                    CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(clippedGeometry);

                                if (clippedGeometry.IsEmpty)
                                {
                                    errorList.Add(
                                        $"The Land Use Block Geometry at row {count} is not in the assigned Stormwater Jurisdiction. Please make sure Land Use Block is in {stormwaterJurisdictionToAssign.Organization.OrganizationName}.");
                                }
                            }
                        }
                        else
                        {
                            errorList.Add(
                                $"You do not have permission to edit Stormwater Jurisdiction {stormwaterJurisdictionToAssign.Organization.OrganizationName}. Please remove all features with this Stormwater Jurisdiction from the upload and try again.");
                        }
                    }



                    var permitType = landUseBlockStaging.PermitType;
                    if (string.IsNullOrEmpty(permitType))
                    {
                        errorList.Add(
                            $"The Permit Type at row {count} is null, empty or whitespace. A value must be provided");
                    }

                    if (!PermitType.All.Select(x => x.PermitTypeDisplayName).Contains(landUseBlockStaging.PermitType))
                    {
                        errorList.Add(
                            $"The Permit Type '{permitType}' at row {count} was not found. Acceptable values are {allowedPermitTypeNames}");
                    }
                    else
                    {
                        landUseBlock.PermitTypeID =
                            PermitType.All.Single(x => x.PermitTypeDisplayName == permitType).PermitTypeID;
                    }

                    landUseBlocksToUpload.Add(landUseBlock);
                    count++;
                }

                if (!errorList.Any())
                {
                    var stormwaterJurisdictionIDsToClear =
                        landUseBlocksToUpload.Select(x => x.StormwaterJurisdictionID).Distinct();
                    var stormwaterJurisdictionToClears = stormwaterJurisdictions
                                                         .Where(x => stormwaterJurisdictionIDsToClear.Contains(x.StormwaterJurisdictionID)).ToList();

                    //foreach (var stormwaterJurisdictionToClear in stormwaterJurisdictionToClears)
                    //{
                    //    var landUseBlocksToClear = stormwaterJurisdictionToClear.LandUseBlocks;
                    //    var trashGeneratingUnitsToUpdateLandUseBlockID = landUseBlocksToClear.SelectMany(x=>x.TrashGeneratingUnits);

                    //    foreach (var trashGeneratingUnit in trashGeneratingUnitsToUpdateLandUseBlockID)
                    //    {
                    //        trashGeneratingUnit.LandUseBlockID = null;
                    //    }
                    //    DbContext.SaveChanges(person);

                    //    DbContext.LandUseBlocks.DeleteLandUseBlock(landUseBlocksToClear);
                    //    DbContext.SaveChanges(person);

                    //}

                    // NP 6/25 SUPER gross to fire plain sql at the db, but trying to use the ORM as above results in exceeding any reasonable timeout
                    var landUseBlockIDsToClear = stormwaterJurisdictionToClears.SelectMany(x => x.LandUseBlocks)
                                                 .Select(x => x.LandUseBlockID).ToList();

                    if (landUseBlockIDsToClear.Any())
                    {
                        var landUseBlockIDsToClearCommaSeparatedString = string.Join(",", landUseBlockIDsToClear);

                        var nullOutTGULandUseBlockIDs =
                            $"UPDATE dbo.TrashGeneratingUnit SET LandUseBlockID = null WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";

                        var nullOutTGU4326LandUseBlockIDs =
                            $"UPDATE dbo.TrashGeneratingUnit4326 SET LandUseBlockID = null WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";
                        var deleteLandUseBlocks =
                            $"DELETE FROM dbo.LandUseBlock WHERE LandUseBlockID in ({landUseBlockIDsToClearCommaSeparatedString})";

                        DbContext.Database.CommandTimeout = 960;
                        DbContext.Database.ExecuteSqlCommand(nullOutTGULandUseBlockIDs);
                        DbContext.Database.ExecuteSqlCommand(nullOutTGU4326LandUseBlockIDs);
                        DbContext.Database.ExecuteSqlCommand(deleteLandUseBlocks);
                    }

                    DbContext.LandUseBlocks.AddRange(landUseBlocksToUpload);
                    DbContext.SaveChanges(person);

                    var body =
                        "Your Land Use Block Upload has been processed. The updated Land Use Blocks are now in the Orange County Stormwater Tools system. It may take up to 24 hours for updated Trash Results to appear in the system.";

                    var mailMessage = new MailMessage
                    {
                        Subject = "Land Use Block Upload Results",
                        Body    = body,
                        From    = DoNotReplyMailAddress()
                    };

                    mailMessage.To.Add(person.Email);
                    SitkaSmtpClient.Send(mailMessage);
                }
                else
                {
                    var body =
                        "Your Land Use Block upload had errors. Please review the following report, correct the errors, and try again: \n" +
                        string.Join("\n", errorList);

                    var mailMessage = new MailMessage
                    {
                        Subject = "Land Use Block Upload Error",
                        Body    = body,
                        From    = DoNotReplyMailAddress()
                    };

                    mailMessage.To.Add(person.Email);
                    SitkaSmtpClient.Send(mailMessage);
                }

                DbContext.pLandUseBlockStagingDeleteByPersonID(PersonID);
            }
            catch (Exception)
            {
                var body =
                    "There was an unexpected system error during processing of your Land Use Block Upload. The Orange County Stormwater Tools development team will investigate and be in touch when this issue is resolved.";

                var mailMessage = new MailMessage
                {
                    Subject = "Land Use Block Upload Error",
                    Body    = body,
                    From    = DoNotReplyMailAddress()
                };

                mailMessage.To.Add(person.Email);
                SitkaSmtpClient.Send(mailMessage);

                throw;
            }
        }
Пример #19
0
        public ActionResult ForTreatmentBMP(TreatmentBMPPrimaryKey treatmentBMPPrimaryKey,
                                            ForTreatmentBMPViewModel viewModel)
        {
            if (!Enum.TryParse(viewModel.DelineationType, out DelineationTypeEnum delineationTypeEnum))
            {
                // todo: really should return a 400 bad request
                return(Json(new { error = "Invalid Delineation Type" }));
            }

            DbGeometry geom4326;

            if (viewModel.WellKnownText.Count == 1)
            {
                geom4326 = viewModel.WellKnownText[0] == DbGeometryToGeoJsonHelper.POLYGON_EMPTY
                    ? null
                    : DbGeometry.FromText(viewModel.WellKnownText[0], CoordinateSystemHelper.WGS_1984_SRID).ToSqlGeometry()
                           .MakeValid().ToDbGeometry().FixSrid(CoordinateSystemHelper.WGS_1984_SRID);
            }
            else
            {
                geom4326 = viewModel.WellKnownText
                           .Select(x =>
                                   DbGeometry.FromText(x, CoordinateSystemHelper.WGS_1984_SRID).ToSqlGeometry().MakeValid()
                                   .ToDbGeometry().FixSrid(CoordinateSystemHelper.WGS_1984_SRID)).ToList()
                           .UnionListGeometries();
            }

            DbGeometry geom2771 = null;

            // like all POSTs from the browser, transform to State Plane
            if (geom4326 != null)
            {
                geom2771 = CoordinateSystemHelper.ProjectWebMercatorToCaliforniaStatePlaneVI(geom4326);
            }

            var treatmentBMP            = treatmentBMPPrimaryKey.EntityObject;
            var treatmentBMPDelineation = treatmentBMP.Delineation;

            // for queueing the LGU job
            var newShape = geom2771;
            var oldShape = treatmentBMPDelineation?.DelineationGeometry;

            var delineationType = DelineationType.ToType(delineationTypeEnum);

            if (treatmentBMPDelineation != null)
            {
                if (geom4326 != null)
                {
                    treatmentBMPDelineation.DelineationGeometry     = geom2771;
                    treatmentBMPDelineation.DelineationGeometry4326 = geom4326;
                    treatmentBMPDelineation.DelineationTypeID       =
                        delineationType.DelineationTypeID;
                    treatmentBMPDelineation.IsVerified       = false;
                    treatmentBMPDelineation.DateLastModified = DateTime.Now;
                }
                else
                {
                    treatmentBMPDelineation.DeleteDelineation(HttpRequestStorage.DatabaseEntities);
                }
            }
            else
            {
                if (geom4326 == null)
                {
                    return(Json(new { success = true }));
                }

                var delineation =
                    new Delineation(geom2771, delineationType.DelineationTypeID, false, treatmentBMP.TreatmentBMPID,
                                    DateTime.Now, false)
                {
                    DelineationGeometry4326 = geom4326
                };
                HttpRequestStorage.DatabaseEntities.Delineations.Add(delineation);
            }

            HttpRequestStorage.DatabaseEntities.SaveChanges();

            if (!(newShape == null & oldShape == null) && treatmentBMP.TreatmentBMPType.TreatmentBMPModelingType != null)
            {
                ModelingEngineUtilities.QueueLGURefreshForArea(oldShape, newShape);
            }

            return(Json(new { success = true, delineationID = treatmentBMP.Delineation.DelineationID }));
        }
Пример #20
0
        public void UpdateModel(Models.OnlandVisualTrashAssessment onlandVisualTrashAssessment,
                                ICollection <OnlandVisualTrashAssessmentPreliminarySourceIdentificationType> allOnlandVisualTrashAssessmentPreliminarySourceIdentificationTypes)
        {
            if (Finalize.GetValueOrDefault())
            {
                onlandVisualTrashAssessment.OnlandVisualTrashAssessmentScoreID = ScoreID;
                onlandVisualTrashAssessment.Notes                = Notes;
                onlandVisualTrashAssessment.CompletedDate        = AssessmentDate;
                onlandVisualTrashAssessment.IsProgressAssessment = IsProgressAssessment;

                // create the assessment area
                if (onlandVisualTrashAssessment.AssessingNewArea.GetValueOrDefault())
                {
                    var onlandVisualTrashAssessmentAreaGeometry2771 =
                        onlandVisualTrashAssessment
                        .DraftGeometry;

                    var onlandVisualTrashAssessmentArea = new Models.OnlandVisualTrashAssessmentArea(AssessmentAreaName,
                                                                                                     onlandVisualTrashAssessment.StormwaterJurisdiction,
                                                                                                     onlandVisualTrashAssessmentAreaGeometry2771)
                    {
                        OnlandVisualTrashAssessmentAreaGeometry4326 = CoordinateSystemHelper.ProjectCaliforniaStatePlaneVIToWebMercator(onlandVisualTrashAssessment.DraftGeometry)
                    };

                    HttpRequestStorage.DatabaseEntities.SaveChanges();

                    onlandVisualTrashAssessment.OnlandVisualTrashAssessmentAreaID =
                        onlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentAreaID;
                    onlandVisualTrashAssessment.DraftGeometry        = null;
                    onlandVisualTrashAssessment.DraftAreaDescription = null;
                }

                onlandVisualTrashAssessment.OnlandVisualTrashAssessmentStatusID =
                    OnlandVisualTrashAssessmentStatus.Complete.OnlandVisualTrashAssessmentStatusID;

                HttpRequestStorage.DatabaseEntities.SaveChanges();

                onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.AssessmentAreaDescription =
                    AssessmentAreaDescription;

                onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.OnlandVisualTrashAssessmentBaselineScoreID =
                    onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.CalculateScoreFromBackingData(false)?
                    .OnlandVisualTrashAssessmentScoreID;

                if (IsProgressAssessment)
                {
                    onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea
                    .OnlandVisualTrashAssessmentProgressScoreID =
                        onlandVisualTrashAssessment.OnlandVisualTrashAssessmentScoreID;
                }

                if (onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.TransectLine == null && onlandVisualTrashAssessment.OnlandVisualTrashAssessmentObservations.Count >= 2)
                {
                    var transect = onlandVisualTrashAssessment.GetTransect();
                    onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.TransectLine = transect;
                    onlandVisualTrashAssessment.IsTransectBackingAssessment = true;

                    var transectBackingAssessment = onlandVisualTrashAssessment.OnlandVisualTrashAssessmentArea.GetTransectBackingAssessment();
                    if (transectBackingAssessment != null)
                    {
                        transectBackingAssessment.IsTransectBackingAssessment = false;
                    }
                }
            }
            else
            {
                onlandVisualTrashAssessment.OnlandVisualTrashAssessmentScoreID = ScoreID;
                onlandVisualTrashAssessment.Notes                = Notes;
                onlandVisualTrashAssessment.DraftAreaName        = AssessmentAreaName;
                onlandVisualTrashAssessment.DraftAreaDescription = AssessmentAreaDescription;
            }

            var onlandVisualTrashAssessmentPreliminarySourceIdentificationTypesToUpdate = PreliminarySourceIdentifications.Where(x => x.Has).Select(x =>
                                                                                                                                                    new OnlandVisualTrashAssessmentPreliminarySourceIdentificationType(
                                                                                                                                                        OnlandVisualTrashAssessmentID.GetValueOrDefault(),
                                                                                                                                                        x.PreliminarySourceIdentificationTypeID.GetValueOrDefault())
            {
                ExplanationIfTypeIsOther = x.ExplanationIfTypeIsOther
            }).ToList();

            onlandVisualTrashAssessment.OnlandVisualTrashAssessmentPreliminarySourceIdentificationTypes.Merge(onlandVisualTrashAssessmentPreliminarySourceIdentificationTypesToUpdate,
                                                                                                              allOnlandVisualTrashAssessmentPreliminarySourceIdentificationTypes,
                                                                                                              (z, w) => z.OnlandVisualTrashAssessmentID == w.OnlandVisualTrashAssessmentID && z.PreliminarySourceIdentificationTypeID == w.PreliminarySourceIdentificationTypeID,
                                                                                                              (z, w) => z.ExplanationIfTypeIsOther = w.ExplanationIfTypeIsOther
                                                                                                              );

            // bug?: why are we nulling these unconditionally?
            onlandVisualTrashAssessment.DraftAreaDescription = null;
            onlandVisualTrashAssessment.DraftAreaName        = null;
            onlandVisualTrashAssessment.DraftGeometry        = null;
        }