[mapserver-users] Raster input file delete access prohibited by MapScript

Anzel, Phil - Fort Collins, CO Phil.Anzel at ftc.usda.gov
Thu Jan 20 10:13:34 EST 2011


All,

I have an application that uses the MapScript API under C# to create map images. Without exiting the application, I need to delete the input raster (JPEG) files that have been used in the image creation. Deletion of the input files is not possible until the application terminates. 

Appended below is a stripped-down C# program that reads a mapfile which references a JPEG file for raster input. After the image is drawn, each layer in the mapObj is closed and removed. An attempt is made to delete the input file; an exception results from this attempt. The program was written in C#, compiled in Visual Studio 2010 running under Windows XP 2002 SP3. The problem occurs with both MapServer versions 5.6.3 and 5.7 (libraries as of December 15, 2010).

Can you help? I'm guessing that the input JPG file is opened for reading by MapServer and is never explicitly closed, even when the layer is closed. Is there a method defined in the API that will force the closure, if that is even the situation? 

Thanks in advance,

- Phil Anzel
  Web Soil Survey Developer
  Vistronix Inc., under contract to USDA/NCS/ITC

Attachments:
1. Console output from running the program.
2. The C# source code.
3. The mapfile.
4. The world file for the input JPEG file
5. The input JPEG file (attached as a separate file; note that virtually any JPEG file could be used, such as the sample provided by Microsoft, "C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water lilies.jpg").


Attachment #1: Console output from running the program.

Creating output image file C:\msTest\working\m01.jpg.
Closing and removing layer 1: center_point.
Closing and removing layer 0: jpg_input.
Disposing of map and image objects.
Failure: unable to delete working copy of input JPG file.
The process cannot access the file 'C:\msTest\working\input.jpg' 
because it is being used by another process.


Attachment #2: The C# source code.

using System;
using System.IO;
// For MapServer 5.6.3 on the test host, a reference is needed to:
//  C:\ms4w\Apache\cgi-bin\mapscript\csharp\mapscript_csharp.dll
using OSGeo.MapServer;

namespace TestApp
{
 /// <summary>
 /// Demonstrate that the JPG file that is used as raster input
 /// for drawing a MapServer image via the SWIG MapScrit API can 
 /// not be deleted while the application is running.
 /// </summary>
 /// <remarks>
 /// In order to run this code,
 /// 1. Include a reference to the appropriate mapscript_csharp.dll file.
 /// 2. Change the PATH definition (below) to point to the MapServer 
 ///   libraries.
 /// 3. Create directories C:\msTest\resource and C:\msTest\working.
 /// 4. Place the input JPEG, World and Map files into C:\msTest\resource.
 /// </remarks>
 class Program
 {
  static void Main(string[] args)
  {
   // Names of the directories and files
   string resourceDir = @"C:\msTest\resource\";
   string workingDir = @"C:\msTest\working\";
   string inputFile = "input";
   string mapFile = "m01";
   string resourceJpg = Path.Combine(resourceDir, inputFile + ".jpg");
   string workingJpg =  Path.Combine(workingDir, inputFile + ".jpg");
   string resourceWld = Path.Combine(resourceDir, inputFile + ".wld");
   string workingWld =  Path.Combine(workingDir, inputFile + ".wld");
   string resourceMap = Path.Combine(resourceDir, mapFile + ".map");
   string outputImage = Path.Combine(workingDir, mapFile + ".jpg");
   // Copy input JPG and WLD files to working directory
   // (allow overwriting if already in working directory).
   File.Copy(resourceJpg, workingJpg, true);
   File.Copy(resourceWld, workingWld, true);

   // We need a good PATH for MapScript library loading.
   Environment.SetEnvironmentVariable("PATH",
    @"C:\ms4w\Apache\cgi-bin;C:\ms4w\Apache\cgi-bin\mapscript\csharp;"
    + Environment.GetEnvironmentVariable("PATH"));

   // Load the map file into a new mapObj, draw it 
   // and save as output image file.
   mapObj map = new mapObj(resourceMap);
   imageObj image = map.draw();
   byte[] img = image.getBytes();
   using (MemoryStream ms = new MemoryStream(img))
   {
    using (FileStream fs = File.Open(outputImage, FileMode.OpenOrCreate, FileAccess.ReadWrite))
    {
     Console.WriteLine("Creating output image file {0}.", outputImage);
     fs.Write(img, 0, img.Length);
    }
   }

   // Explicitly close and remove each layer.
   int iLayer = map.numlayers;
   while (iLayer > 0)
   {
    iLayer--;
    layerObj layer = map.getLayer(iLayer);
    Console.WriteLine("Closing and removing layer {0}: {1}.", iLayer, layer.name);
    layer.close();
    map.removeLayer(iLayer);
   }
   // Dispose of the image and map objects
   Console.WriteLine("Disposing of map and image objects.");
   image.Dispose();
   map.Dispose();

   // Delete the working JPG file
   try
   {
    File.Delete(@"C:\msTest\working\input.jpg");
    Console.WriteLine("Success: working copy of input JPG file deleted.");
   }
   catch (Exception ex)
   {
    Console.WriteLine("Failure: unable to delete working copy of input JPG file.");
    Console.WriteLine(ex.Message);
   }
  }
 }
}


Attachment 3: The mapfile.

map
  imagetype jpeg
  status on
  size 256 256
  extent -11686915.8766903 4935997.53854354 -11682023.9068801 4940889.50835379
  imagecolor 255 255 255

  layer
    name jpg_input
    data 'C:\msTest\working\input.jpg'
    type raster
    status on
  end

  symbol
    name default-marker
    type ellipse
    points 1 1 end
    filled true
  end

  layer # a big red dot so we know this is MapServer output
    name center_point
    status on
    type point
    feature
      points -11684469.8917852 4938443.52344866 end
    end
    class
      style
        color 255 0 0
        size 25
        symbol default-marker
      end
    end
  end
end


Attachment 4: The world file for the input JPEG file.

19.1092570712941
0.0000000000
0.0000000000
-19.1092570712941
-11686915.8766903
4940889.50835379


Attachment 5: The input JPEG file 

...attached as a separate file to this email message. Note that virtually any JPEG file could be used, such as the sample provided by Microsoft, "C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Water lilies.jpg".

-------------- next part --------------
A non-text attachment was scrubbed...
Name: input.jpg
Type: image/jpeg
Size: 178954 bytes
Desc: input.jpg
Url : http://lists.osgeo.org/pipermail/mapserver-users/attachments/20110120/a4ced2d6/input-0001.jpg


More information about the mapserver-users mailing list