public static void QueueLGURefreshForArea(DbGeometry oldShape, DbGeometry newShape)
        {
            DbGeometry loadGeneratingUnitRefreshAreaGeometry;

            if (oldShape == null && newShape == null)
            {
                throw new InvalidOperationException("At least one input to QueueLGURefreshForArea must not be null.");
            }

            if (oldShape == null)
            {
                loadGeneratingUnitRefreshAreaGeometry = newShape;
            }
            else if (newShape == null)
            {
                loadGeneratingUnitRefreshAreaGeometry = oldShape;
            }
            else
            {
                loadGeneratingUnitRefreshAreaGeometry = oldShape.Union(newShape);
            }

            var loadGeneratingUnitRefreshArea = new LoadGeneratingUnitRefreshArea(loadGeneratingUnitRefreshAreaGeometry);

            HttpRequestStorage.DatabaseEntities.LoadGeneratingUnitRefreshAreas.Add(loadGeneratingUnitRefreshArea);
            HttpRequestStorage.DatabaseEntities.SaveChanges();

            BackgroundJob.Enqueue(() => ScheduledBackgroundJobLaunchHelper.RunLoadGeneratingUnitRefreshJob(loadGeneratingUnitRefreshArea.LoadGeneratingUnitRefreshAreaID));
        }
        private FeatureCollection MakeClipFeatureCollectionFromRefreshArea(
            LoadGeneratingUnitRefreshArea loadGeneratingUnitRefreshArea)
        {
            if (loadGeneratingUnitRefreshArea == null)
            {
                return(null);
            }

            var lguInputClipFeatures = DbContext.LoadGeneratingUnits
                                       .Where(x => x.LoadGeneratingUnitGeometry.Intersects(loadGeneratingUnitRefreshArea
                                                                                           .LoadGeneratingUnitRefreshAreaGeometry)).ToList().Select(x =>
                                                                                                                                                    DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(x.LoadGeneratingUnitGeometry)).ToList();

            return(new FeatureCollection(lguInputClipFeatures)
            {
                CRS = new NamedCRS("EPSG:2771")
            });
        }
        private void LoadGeneratingUnitRefreshImpl(int?loadGeneratingUnitRefreshAreaID)
        {
            Logger.Info($"Processing '{JobName}'");

            var outputLayerName = Guid.NewGuid().ToString();
            var outputLayerPath = $"{Path.Combine(Path.GetTempPath(), outputLayerName)}.shp";

            var clipLayerPath = $"{Path.Combine(Path.GetTempPath(), outputLayerName)}_inputClip.json";

            var additionalCommandLineArguments = new List <string> {
                outputLayerPath
            };

            LoadGeneratingUnitRefreshArea loadGeneratingUnitRefreshArea = null;

            if (loadGeneratingUnitRefreshAreaID != null)
            {
                loadGeneratingUnitRefreshArea = DbContext.LoadGeneratingUnitRefreshAreas.Find(loadGeneratingUnitRefreshAreaID);
                var lguInputClipFeatures = DbContext.LoadGeneratingUnits
                                           .Where(x => x.LoadGeneratingUnitGeometry.Intersects(loadGeneratingUnitRefreshArea
                                                                                               .LoadGeneratingUnitRefreshAreaGeometry)).ToList().Select(x => DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(x.LoadGeneratingUnitGeometry)).ToList();

                var lguInputClipFeatureCollection = new FeatureCollection(lguInputClipFeatures)
                {
                    CRS = new NamedCRS("EPSG:2771")
                };

                // in case the load-generating units were deleted by an update, add the refresh area itself to the clip collection
                lguInputClipFeatureCollection.Features.Add(
                    DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(loadGeneratingUnitRefreshArea
                                                                            .LoadGeneratingUnitRefreshAreaGeometry));

                //var lguInputClipGeoJson = DbGeometryToGeoJsonHelper.FromDbGeometryWithNoReproject(dbGeometry);
                var lguInputClipGeoJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(lguInputClipFeatureCollection);

                File.WriteAllText(clipLayerPath, lguInputClipGeoJsonString);
                additionalCommandLineArguments.AddRange(new List <string> {
                    "--clip", clipLayerPath
                });
            }
            // a PyQGIS script computes the LGU layer and saves it as a shapefile
            var processUtilityResult = QgisRunner.ExecutePyqgisScript($"{NeptuneWebConfiguration.PyqgisWorkingDirectory}ModelingOverlayAnalysis.py", NeptuneWebConfiguration.PyqgisWorkingDirectory, additionalCommandLineArguments);

            if (processUtilityResult.ReturnCode != 0)
            {
                Logger.Error("LGU Geoprocessing failed. Output:");
                Logger.Error(processUtilityResult.StdOutAndStdErr);
                throw new GeoprocessingException(processUtilityResult.StdOutAndStdErr);
            }

            try
            {
                if (loadGeneratingUnitRefreshAreaID != null)
                {
                    DbContext.Database.ExecuteSqlCommand(
                        $"EXEC dbo.pDeleteLoadGeneratingUnitsPriorToDeltaRefresh @LoadGeneratingUnitRefreshAreaID = {loadGeneratingUnitRefreshAreaID}");
                }
                else
                {
                    DbContext.Database.ExecuteSqlCommand(
                        $"EXEC dbo.pDeleteLoadGeneratingUnitsPriorToTotalRefresh");
                }

                var ogr2OgrCommandLineRunner =
                    new Ogr2OgrCommandLineRunnerForLGU(NeptuneWebConfiguration.Ogr2OgrExecutable, CoordinateSystemHelper.NAD_83_HARN_CA_ZONE_VI_SRID, 3.6e+6);

                ogr2OgrCommandLineRunner.ImportLoadGeneratingUnitsFromShapefile(outputLayerName, outputLayerPath,
                                                                                NeptuneWebConfiguration.DatabaseConnectionString);

                if (loadGeneratingUnitRefreshArea != null)
                {
                    loadGeneratingUnitRefreshArea.ProcessDate = DateTime.Now;
                    DbContext.SaveChangesWithNoAuditing();
                }
            }
            catch (Ogr2OgrCommandLineException e)
            {
                Logger.Error("LGU loading (CRS: 2771) via GDAL reported the following errors. This usually means an invalid geometry was skipped. However, you may need to correct the error and re-run the TGU job.", e);
                throw;
            }

            // clean up temp files if not running in a local environment
            if (NeptuneWebConfiguration.NeptuneEnvironment.NeptuneEnvironmentType != NeptuneEnvironmentType.Local)
            {
                File.Delete(outputLayerPath);
                if (loadGeneratingUnitRefreshAreaID != null)
                {
                    File.Delete(clipLayerPath);
                }
            }
        }