/// <summary> /// Create an Erdas image file given specs /// </summary> public Image(string filename, Dimensions dimensions, int bandCount, System.TypeCode bandType, IMetadata metadata) { // if filename does not end in .gis or .lan throw exception string extension = Path.GetExtension(filename).ToLower(); if (!(extension.Equals(".gis")) && !(extension.Equals(".lan"))) throw new ApplicationException("Erdas image must have either GIS or LAN as extension"); // if dimensions are messed up throw exception if ((dimensions.Rows < 1) || (dimensions.Columns < 1)) throw new ApplicationException("Erdas image given invalid dimensions"); // if bandCount messed up throw exception if ((bandCount < 1) || (bandCount > 0xffff)) throw new ApplicationException("Erdas image given invalid band count"); // more bandCount checking if (extension.Equals(".gis")) { if (bandCount > 1) throw new ApplicationException("Erdas GIS files cannot support multiband images"); } this.imageHeader = new ImageHeader(dimensions, bandType, bandCount, metadata); this.imageHeader.Write(filename); }
private Metadata metadata; // the metadata assoc w/ raster /// <summary> /// No arg constructor /// </summary> /// <remark> /// Used before calling Read() /// </remark> public ImageHeader() { this.dimensions = new Dimensions(0,0); this.bandType = System.TypeCode.Byte; this.bandSize = 0; this.bandCount = 0; this.metadata = new Metadata(); }
/// <summary> /// Open a writer on a new file /// </summary> public WritableImage(string filename, Dimensions dimensions, int bandCount, System.TypeCode bandType, IMetadata metadata) : base(filename, dimensions, bandCount, bandType, metadata) { this.pixelsWritten = 0; // open file for writing this.file = new FileStream(filename,FileMode.Open); this.fileWriter = new BinaryWriter(this.file); }
/// <summary> /// Fully specified constructor - used before calling Write() /// </summary> /// <remark> /// Usually used before calling Write() but could call NoArg constructor, /// Read(), and then Write() if copying images /// </remark> public ImageHeader(Dimensions dimensions, System.TypeCode bandType, int bandCount, IMetadata metadata) { this.dimensions = dimensions; this.bandType = bandType; this.bandCount = bandCount; this.metadata = metadata as Metadata; if (bandType == System.TypeCode.Byte) this.bandSize = 1; else if (bandType == System.TypeCode.UInt16) this.bandSize = 2; else throw new ApplicationException("ImageHeader: bandType must either be Byte or UInt16"); }
private void TryCtor(string filename, Dimensions dimensions, int bandCount, System.TypeCode bandType, IMetadata metadata) { try { Image image = new Image(filename, dimensions, bandCount, bandType, metadata); } catch (System.Exception exc) { Data.Output.WriteLine(exc.Message); throw; } }
/// <summary> /// Read the Erdas Image Header from a file given filename /// </summary> /// <remark> /// Uses variable definitions straight from Erdas spec - ipack, nbands, /// irows, icols, xstart, ystart, maptyp, nclass, iautyp, acre, xmap, /// ymap, xcell, ycell /// </remark> public void Read(string filename) { // init members as needed this.metadata = new Metadata(); // prepare to read header FileStream file = null; BinaryReader fileReader = null; System.UInt16 ipack = 0; System.UInt16 nbands = 0; System.UInt32 irows = 0; System.UInt32 icols = 0; try { // open file file = new FileStream(filename,FileMode.Open); fileReader = new BinaryReader(file); // Read Header // if not start with "HEAD74" throw exception byte[] sentinel = fileReader.ReadBytes(6); if ((sentinel[0] != (byte)'H') || (sentinel[1] != (byte)'E') || (sentinel[2] != (byte)'A') || (sentinel[3] != (byte)'D') || (sentinel[4] != (byte)'7') || (sentinel[5] != (byte)'4')) throw new ApplicationException(filename+" is not an ERDAS 7.4 compatible image file"); // packing ipack = fileReader.ReadUInt16(); // nbands nbands = fileReader.ReadUInt16(); // unused byte[] unused = fileReader.ReadBytes(6); // icols icols = fileReader.ReadUInt32(); // irows irows = fileReader.ReadUInt32(); // xstart System.Int32 xstart = fileReader.ReadInt32(); this.metadata[MetadataIds.RASTER_ULX] = xstart; // ystart System.Int32 ystart = fileReader.ReadInt32(); this.metadata[MetadataIds.RASTER_ULY] = ystart; // unused unused = fileReader.ReadBytes(56); // maptyp System.UInt16 maptyp = fileReader.ReadUInt16(); string projection = Projections.find(maptyp); if (projection != null) this.metadata[MetadataIds.PROJECTION] = projection; if (maptyp == 0) this.metadata[MetadataIds.SCALE_UNITS] = "degrees"; else if (maptyp == 2) this.metadata[MetadataIds.SCALE_UNITS] = "feet"; else this.metadata[MetadataIds.SCALE_UNITS] = "meters"; // nclass : calc if needed but never has been in past System.UInt16 nclass = fileReader.ReadUInt16(); // unused unused = fileReader.ReadBytes(14); // iautyp System.UInt16 iautyp = fileReader.ReadUInt16(); // acre System.Single acre = fileReader.ReadSingle(); // xmap System.Single xmap = fileReader.ReadSingle(); this.metadata[MetadataIds.WORLD_ULX] = xmap; // ymap System.Single ymap = fileReader.ReadSingle(); this.metadata[MetadataIds.WORLD_ULY] = ymap; // xcell System.Single xcell = fileReader.ReadSingle(); this.metadata[MetadataIds.X_SCALE] = xcell; // ycell System.Single ycell = fileReader.ReadSingle(); this.metadata[MetadataIds.Y_SCALE] = ycell; } catch { throw; } finally { if (fileReader != null) fileReader.Close(); // the prev line automatically closes file also else if (file != null) file.Close(); } // now set instance vars // metadata already set by above code this.dimensions = new Dimensions((int)irows,(int)icols); this.bandCount = nbands; if (ipack == 0) { this.bandType = System.TypeCode.Byte; this.bandSize = 1; } else if (ipack == 2) { this.bandType = System.TypeCode.UInt16; this.bandSize = 2; } else throw new ApplicationException("ImageHeader: Only 8 and 16 bit bands are supported"); }
//--------------------------------------------------------------------- /// <summary> /// Runs a model scenario. /// </summary> public static void Run(string scenarioPath) { // Initialize plug-ins manager with the default plug-ins // database in the folder where application resides. PlugIns.Manager.Initialize(PlugIns.Database.DefaultPath); IScenario scenario = LoadScenario(scenarioPath); cellLength = 29.0f; // 29m hard-wired until metadata implemented in raster driver LoadSpecies(scenario.Species); LoadEcoregions(scenario.Ecoregions); Log.Info("Initializing landscape from ecoregions map \"{0}\" ...", scenario.EcoregionsMap); Ecoregions.Map ecoregionsMap = new Ecoregions.Map(scenario.EcoregionsMap, Model.Ecoregions); using (Landscape.IInputGrid <bool> grid = ecoregionsMap.OpenAsInputGrid()) { landscape = new Landscape.Landscape(grid); } landscapeMapDims = new Raster.Dimensions((int)landscape.Rows, (int)landscape.Columns); SiteVars.Initialize(ecoregionsMap); // Load and initialize plug-ins. Log.Info("Loading {0} plug-in ...", scenario.Succession.Info.Name); succession = PlugIns.Manager.Load <ISuccession>(scenario.Succession.Info); succession.Initialize(scenario.Succession.InitFile); succession.InitializeSites(scenario.InitialCommunities, scenario.InitialCommunitiesMap); IDisturbance[] disturbancePlugIns = LoadPlugIns <IDisturbance>(scenario.Disturbances); IOutput[] outputPlugIns = LoadPlugIns <IOutput>(scenario.Outputs); // Run those output plug-ins whose next time to run is 0. foreach (IOutput outPlugIn in GetPlugInsToRun <IOutput>(outputPlugIns, 0)) { outPlugIn.Run(0); } //******************// for Rob // Main time loop // //******************// // currentTime (years) for (int currentTime = 1; currentTime <= scenario.Duration; ++currentTime) { List <IDisturbance> distPlugInsToRun; distPlugInsToRun = GetPlugInsToRun <IDisturbance>(disturbancePlugIns, currentTime); bool isDistTimestep = distPlugInsToRun.Count > 0; List <IOutput> outPlugInsToRun; outPlugInsToRun = GetPlugInsToRun <IOutput>(outputPlugIns, currentTime); bool isOutTimestep = outPlugInsToRun.Count > 0; bool isSuccTimestep = succession.NextTimeToRun == currentTime; // If not a succession timestep, a disturance timestep or // an output timestep, then go to the next timestep. if (!(isSuccTimestep || isDistTimestep || isOutTimestep)) { continue; } Log.Info("Current time: {0}", currentTime); if (isDistTimestep) { if (scenario.DisturbancesRandomOrder) { distPlugInsToRun = Shuffle(distPlugInsToRun); } foreach (IDisturbance distPlugIn in distPlugInsToRun) { distPlugIn.Run(currentTime); } } if (isSuccTimestep || isDistTimestep) { IEnumerable <ActiveSite> sites; if (isSuccTimestep) { sites = Model.Landscape.ActiveSites; } else { sites = DisturbedSites(); } succession.AgeCohorts(sites, currentTime); succession.ComputeShade(sites); succession.ReproducePlants(sites); } // Run output plug-ins. foreach (IOutput outPlugIn in outPlugInsToRun) { outPlugIn.Run(currentTime); } if (!isSuccTimestep) { SiteVars.Disturbed.ActiveSiteValues = false; } } // main time loop }
RWFlag mode; // file open mode: Read or Write /// <summary> /// Create a file given specs /// </summary> public ErdasImageFile(string filename, Dimensions dimensions, int bandCount, System.TypeCode bandType, IMetadata metadata) { // set instance variables this.open = false; this.mode = RWFlag.Write; this.dimensions = dimensions; this.bandType = bandType; this.bandCount = bandCount; this.currPixel = 0; this.totalPixels = dimensions.Rows*dimensions.Columns; this.metadata = metadata; // if filename does not end in .gis or .lan throw exception string extension = Path.GetExtension(filename).ToLower(); if (!(extension.Equals(".gis")) && !(extension.Equals(".lan"))) throw new System.ApplicationException("Erdas file must have either GIS or LAN as extension"); // if dimensions are messed up throw exception if ((dimensions.Rows < 1) || (dimensions.Columns < 1)) throw new System.ApplicationException("Erdas file given invalid dimensions"); // if bandCount messed up throw exception if ((bandCount < 1) || (bandCount > 0xffff)) throw new System.ApplicationException("Erdas file given invalid band count"); // more bandCount checking if (extension.Equals(".gis")) { if (bandCount > 1) throw new System.ApplicationException("Erdas GIS files cannot support multiband images"); if (bandType != System.TypeCode.Byte) throw new System.ApplicationException("Erdas GIS files only suupport byte for bandtype"); } // if bandType not System.Byte or System.UInt16 throw exception if (bandType == System.TypeCode.Byte) this.bandSize = 1; else if (bandType == System.TypeCode.UInt16) this.bandSize = 2; else throw new System.ApplicationException("Erdas file given unsupported band type"); // open file for writing this.file = new FileStream(filename,FileMode.OpenOrCreate); this.fileWriter = new BinaryWriter(this.file); this.open = true; // write header (using metadata whenever possible) try { // sentinel byte[] sentinel = new byte[6]; sentinel[0] = (byte) 'H'; sentinel[1] = (byte) 'E'; sentinel[2] = (byte) 'A'; sentinel[3] = (byte) 'D'; sentinel[4] = (byte) '7'; sentinel[5] = (byte) '4'; this.fileWriter.Write(sentinel); // packing System.UInt16 ipack; if (bandType == System.TypeCode.Byte) ipack = 0; else ipack = 2; this.fileWriter.Write(ipack); // nbands System.UInt16 nbands = (System.UInt16)bandCount; this.fileWriter.Write(nbands); // unused for (int i = 0; i < 6; i++) this.fileWriter.Write((byte)0); // icols System.UInt32 icols = (System.UInt32)dimensions.Columns; this.fileWriter.Write(icols); // irows System.UInt32 irows = (System.UInt32)dimensions.Rows; this.fileWriter.Write(irows); // xstart System.Int32 xstart = 0; if ((metadata != null) && (metadata.TryGetValue<System.Int32>(RASTER_ULX,ref xstart))) { } this.fileWriter.Write(xstart); // ystart System.Int32 ystart = 0; if ((metadata != null) && (metadata.TryGetValue<System.Int32>(RASTER_ULY,ref ystart))) { } this.fileWriter.Write(ystart); // unused for (int i = 0; i < 56; i++) this.fileWriter.Write((byte)0); // maptyp System.UInt16 maptyp = 99; // 99 means NONE string projection = null; if ((metadata != null) && (metadata.TryGetValue<string>(PROJECTION,ref projection))) { int projNum = Projections.find(projection); if (projNum != -1) maptyp = (System.UInt16)projNum; } this.fileWriter.Write(maptyp); // nclass : calc if needed but never has been in past System.UInt16 nclass = 0; this.fileWriter.Write(nclass); // unused for (int i = 0; i < 14; i++) this.fileWriter.Write((byte)0); // iautyp : first need xcell and ycell and then acre System.Single xcell = 0; if ((metadata != null) && (metadata.TryGetValue<System.Single>(X_SCALE,ref xcell))) { } if (maptyp == 99) xcell = 0; System.Single ycell = 0; if ((metadata != null) && (metadata.TryGetValue<System.Single>(Y_SCALE,ref ycell))) { } if (maptyp == 99) ycell = 0; System.UInt16 iautyp = 0; System.Single acre = 0; switch (maptyp) // iautyp depends upon maptyp indirectly { case 0: // Lat/Long -> dist unit == degrees iautyp = 0; // default to no area unit break; case 2: // State Plane -> dist unit == feet iautyp = 1; // default to acres acre = xcell * ycell; // acre = sq.feet at this pt // so now convert to acres acre = (float) ((double)acre * 0.0000229568411386593); break; default: // dist unit == meters iautyp = 2; // default to hectares acre = xcell * ycell; // acre = sq.meters at this pt // so now convert to hectares acre *= 0.0001f; break; } this.fileWriter.Write(iautyp); // acre this.fileWriter.Write(acre); // xmap System.Single xmap = 0; if ((metadata != null) && (metadata.TryGetValue<System.Single>(WORLD_ULX,ref xmap))) { } this.fileWriter.Write(xmap); // ymap System.Single ymap = 0; if ((metadata != null) && (metadata.TryGetValue<System.Single>(WORLD_ULY,ref ymap))) { } this.fileWriter.Write(ymap); // xcell this.fileWriter.Write(xcell); // ycell this.fileWriter.Write(ycell); // now create pixel data as zeroes for now // many nested for loops avoids index calc overflows for (int row = 0; row < dimensions.Rows; row++) for (int bandNum = 0; bandNum < this.bandCount; bandNum++) for (int col = 0; col < dimensions.Columns; col++) for (int byteNum = 0; byteNum < this.bandSize; byteNum++) this.fileWriter.Write((byte)0); } catch (System.Exception) { Close(); throw; } }
/// <summary> /// Open an existing file /// </summary> public ErdasImageFile(string filename, RWFlag mode) { this.open = false; this.mode = mode; // if filename does not end in .gis or .lan throw exception string extension = Path.GetExtension(filename).ToLower(); if (!(extension.Equals(".gis")) && !(extension.Equals(".lan"))) throw new System.ApplicationException("Erdas file must have either GIS or LAN as extension"); // open file this.file = new FileStream(filename,FileMode.Open); this.fileReader = new BinaryReader(this.file); this.open = true; try { // prepare to build metadata while reading Metadata metadata = new Metadata(); // Read Header // if not start with "HEAD74" throw exception byte[] sentinel = fileReader.ReadBytes(6); if ((sentinel[0] != (byte)'H') || (sentinel[1] != (byte)'E') || (sentinel[2] != (byte)'A') || (sentinel[3] != (byte)'D') || (sentinel[4] != (byte)'7') || (sentinel[5] != (byte)'4')) throw new System.ApplicationException(filename+" is not an ERDAS 7.4 compatible image file"); // packing System.UInt16 ipack = this.fileReader.ReadUInt16(); if ((ipack != 0) && (ipack != 2)) throw new System.ApplicationException("Only 8 and 16 bit bands are supported by Erdas reader"); // nbands System.UInt16 nbands = this.fileReader.ReadUInt16(); // unused byte[] unused = this.fileReader.ReadBytes(6); // icols System.UInt32 icols = this.fileReader.ReadUInt32(); // irows System.UInt32 irows = this.fileReader.ReadUInt32(); // xstart System.Int32 xstart = this.fileReader.ReadInt32(); metadata[RASTER_ULX] = xstart; // ystart System.Int32 ystart = this.fileReader.ReadInt32(); metadata[RASTER_ULY] = ystart; // unused unused = this.fileReader.ReadBytes(56); // maptyp System.UInt16 maptyp = this.fileReader.ReadUInt16(); string projection = Projections.find(maptyp); if (projection != null) metadata[PROJECTION] = projection; if (maptyp == 0) metadata[SCALE_UNITS] = "degrees"; else if (maptyp == 2) metadata[SCALE_UNITS] = "feet"; else metadata[SCALE_UNITS] = "meters"; // nclass : calc if needed but never has been in past System.UInt16 nclass = this.fileReader.ReadUInt16(); // unused unused = this.fileReader.ReadBytes(14); // iautyp System.UInt16 iautyp = this.fileReader.ReadUInt16(); // acre System.Single acre = this.fileReader.ReadSingle(); // xmap System.Single xmap = this.fileReader.ReadSingle(); metadata[WORLD_ULX] = xmap; // ymap System.Single ymap = this.fileReader.ReadSingle(); metadata[WORLD_ULY] = ymap; // xcell System.Single xcell = this.fileReader.ReadSingle(); metadata[X_SCALE] = xcell; // ycell System.Single ycell = this.fileReader.ReadSingle(); metadata[Y_SCALE] = ycell; // construct instance variables based upon hedaer info this.dimensions = new Dimensions((int)irows,(int)icols); if (ipack == 0) { this.bandType = System.TypeCode.Byte; this.bandSize = 1; } else // ipack == 2 due to earlier screening { this.bandType = System.TypeCode.UInt16; this.bandSize = 2; } this.bandCount = nbands; this.currPixel = 0; this.totalPixels = (int)irows * (int)icols; this.metadata = metadata; if (mode == RWFlag.Write) { this.fileReader.Close(); this.fileReader = null; // need to reopen stream - fileReader.Close() shuts it this.file = new FileStream(filename,FileMode.Open); this.fileWriter = new BinaryWriter(this.file); } } catch (System.Exception) { Close(); throw; } }