[mapguide-users] EXAMPLE: Serving MapTiles directly

Kenneth Skovhede, GEOGRAF A/S ks at geograf.dk
Thu Feb 25 03:09:47 EST 2010


Wow, thanks.
Would you mind adding it to the CodeSamples?

For the IIS on XP problem, try this:
http://briancaos.wordpress.com/tag/adsutil/

PS: When you have using(), there is no need to close the stream explicitly.

Regards, Kenneth Skovhede, GEOGRAF A/S

On 24-02-2010 17:00, Pietro Ianniello wrote:
> Dear list,
> here is a simple ASP.NET <http://ASP.NET> ashx to server MapGuide 
> Tiles Directly.
>
> It' different from the one found on 
> "http://trac.osgeo.org/mapguide/wiki/CodeSamples/Tiles/ServingTilesViaHttp" 
> because it doesn't require any web server configuration.
> The only point is to use my ashx as a proxy to MapGuide.
> Testing would be nice. If it's all OK, and someone wants to post it on 
> wiki... or translate in PHP...
> BUT don't test it with a non server OS. For example in WindowsXP I get 
> lot of empty tiles. This is not the case with Windows Server 2003.
> REMINDER FOR ME: don't loose time! Test on real server OSs!
> NOTE: *call somewhere 
> "MapGuideApi.MgInitializeWebTier(MgMapHelper.WebconfigIniPhysicalPath);" 
> before using this handler!*
>            [*App_Start is a good choise*]
>
>
> Code:
>
> <%@ WebHandler Language="C#" Class="GetMGTiles" %>
> //#define LOG_WITH_LOG4NET
> using System;
> using System.Web;
>
> using System.Text;
> using System.Net;
> using System.Collections.Specialized;
> using MapGuideHelper;
> using OSGeo.MapGuide;
> using System.IO;
>
> //This is different from 
> [http://trac.osgeo.org/mapguide/wiki/CodeSamples/Tiles/ServingTilesViaHttp 
> ]
> //where the web server must be configured.
> //Here you use GetMGTiles.ashx as OpenLayers mapguide tiled layer 
> address [not HttpTile!].
> //NOTE: if you try this with a non server OS [such as WindowsXP] you 
> will certainly get missed tiles
> public class GetMGTiles : IHttpHandler
> {
>     #region Compile Time Configuration
>
>     private readonly int BUFF_SIZE = 20480;//4096
>
>     #endregion
>
>     #region Properties to be configured [if needed] on application start
>
>     private static string _tileDirectory = 
> "C:/OSGeo/MapGuide/Server/Repositories/TileCache/";
>     public static string TileDirectory
>     {
>         get { return _tileDirectory; }
>         set { _tileDirectory = value; }
>     }
>
>     private static string _imageFileFormat = ".png"; //depends on 
> "serverconfig.ini"
>     private static string _contentType = "image/png"; //depends on 
> "serverconfig.ini"
>     public static string ImageFileFormat
>     {
>         get { return _imageFileFormat; }
>         set
>         {
>             _contentType = String.Concat("image/", value);
>             _imageFileFormat = String.Concat(".", value);
>         }
>     }
>
>     private static double _tileRowsPerFolder = 30.0; //depends on 
> "serverconfig.ini"
>     private static int _tileRowsPerFolderInt = 30; //depends on 
> "serverconfig.ini"
>     public static int TileRowsPerFolder
>     {
>         get { return _tileRowsPerFolderInt; }
>         set { _tileRowsPerFolder = _tileRowsPerFolderInt = value; }
>     }
>     private static double _tileColumnsPerFolder = 30.0; //depends on 
> "serverconfig.ini"
>     private static int _tileColumnsPerFolderInt = 30; //depends on 
> "serverconfig.ini"
>     public static int TileColumnsPerFolder
>     {
>         get { return _tileColumnsPerFolderInt; }
>         set { _tileColumnsPerFolder = _tileColumnsPerFolderInt = value; }
>     }
>
>     #endregion
>
>     #region input request params
>
>     int _tileRow, _tileCol, _scaleIndex;
>     string _baseLayerGroupname;
>     string _mapDefinition;
>
>     #endregion
>
>     protected void ServeMgTile(HttpResponse response)
>     {
>         MgUserInformation userInfo = null;
>         MgSiteConnection siteConnection = null;
>         MgTileService tileService = null;
>         MgResourceIdentifier resIdent = null;
>         MgByteReader mgReader = null;
>         try
>         {
>             
> ///////MapGuideApi.MgInitializeWebTier(MgMapHelper.WebconfigIniPhysicalPath);
>             userInfo = new MgUserInformation("Anonymous", "");
>             siteConnection = new MgSiteConnection();
>             siteConnection.Open(userInfo);
>
>             tileService = 
> siteConnection.CreateService(MgServiceType.TileService) as MgTileService;
>             resIdent = new MgResourceIdentifier(_mapDefinition);
>             mgReader = tileService.GetTile(resIdent, 
> _baseLayerGroupname, _tileCol, _tileRow, _scaleIndex);
>
>             
> //--------------------------------------------------------------
>             //Debugging helper:
>             //  context.Response.Cache.SetNoStore();
>             //  context.Response.AppendHeader("Pragma", "no-cache");
>             
> //--------------------------------------------------------------
>
>             int readBytes;
>             byte[] buffer = new byte[BUFF_SIZE];
>             while ((readBytes = mgReader.Read(buffer, BUFF_SIZE)) > 0)
>             {
>                 response.OutputStream.Write(buffer, 0, readBytes);
>             }
>         }
>         finally
>         {
>             if (null != mgReader) mgReader.Dispose();
>             if (null != resIdent) resIdent.Dispose();
>             if (null != tileService) tileService.Dispose();
>             if (null != siteConnection) siteConnection.Dispose();
>             if (null != userInfo) userInfo.Dispose();
>         }
>     }
>
>     protected void StreamFile(string filePath, HttpResponse response)
>     {
>         //response.AddHeader("content-disposition", 
> String.Concat("attachment; filename=",Path.GetFileName(filePath)));
>         using (FileStream fileStream = new FileStream(filePath, 
> FileMode.Open, FileAccess.Read, FileShare.Read))
>         {
>             long fileSize = fileStream.Length;
> #if false
>             //all at once:
>             byte[] buffer = new byte[(int)fileSize];
>             fileStream.Read(buffer, 0, (int)fileStream.Length);
>             fileStream.Close();
>             response.BinaryWrite(buffer);
> #else
>             int readBytes;
>             byte[] buffer = new byte[BUFF_SIZE];
>             while ((readBytes = fileStream.Read(buffer, 0, BUFF_SIZE)) 
> > 0)
>             {
>                 response.OutputStream.Write(buffer, 0, readBytes);
>             }
>             fileStream.Close();
> #endif
>         }
>     }
>
>     public void ProcessRequest(HttpContext context)
>     {
>         try
>         {
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //Startup
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //It's always GET, but this costs nothing:
>             NameValueCollection nvInput = context.Request.HttpMethod 
> == "POST" ?
>                                                       
> context.Request.Form : nvInput = context.Request.QueryString;
> #if false
>             //string requestedUrl = context.Request.Path.ToLower();
>             if (nvInput == null) //it's never null
>             {
>                 context.Response.Clear();
>                 context.Response.ContentType = "text/plain";
>                 context.Response.Write("Hello World");
>                 return;
>             }
>             if (nvInput.Count == 0)//don't mind if is 0 => we will 
> just get null strings when trying to read them
>             {
>                 context.Response.Clear();
>                 context.Response.ContentType = "text/plain";
>                 context.Response.Write("Hello World");
>                 return;
>             }
> #endif
>             
> //---------------------------------------------------------------------------------------------------------------------
>
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //Input params reading
>             
> //---------------------------------------------------------------------------------------------------------------------
>             _mapDefinition = 
> HttpUtility.UrlDecode(nvInput["mapdefinition"]);
>             if (String.IsNullOrEmpty(_mapDefinition))
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>             if (nvInput["operation"].ToUpper() != "GETTILEIMAGE")
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>             //---------------------------------
>             //we don't read nvInput["version"]
>             //---------------------------------
>             _baseLayerGroupname = 
> HttpUtility.UrlDecode(nvInput["basemaplayergroupname"]);
>             if (String.IsNullOrEmpty(_baseLayerGroupname))
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>             if (!Int32.TryParse(nvInput["tilecol"], out _tileCol))
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>             if (!Int32.TryParse(nvInput["tilerow"], out _tileRow))
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>             if (!Int32.TryParse(nvInput["scaleindex"], out _scaleIndex))
>             {
>                 context.Response.StatusCode = 
> (int)HttpStatusCode.BadRequest;
>                 return;
>             }
>
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //Tile file name
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //The tiles base dir, if for example we want
>             //          
> "Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition"
>             // , is
>             //          "Samples_Sheboygan_MapsTiled_Sheboygan/"
>             string mapDefDir = _mapDefinition.Replace("Library://", 
> "").Replace("/", "_").Replace(".MapDefinition", "/");
>
>
>             //---------------------------------
>             //Taken from Openlayers:
>             int tileRowGroup = (int)(Math.Floor(Math.Abs(_tileRow / 
> _tileRowsPerFolder))) * TileRowsPerFolder;
>             int tileColGroup = (int)(Math.Floor(Math.Abs(_tileCol / 
> _tileColumnsPerFolder))) * TileColumnsPerFolder;
>             int imgPartA = _tileRow % TileRowsPerFolder;
>             int imgPartB = _tileCol % TileColumnsPerFolder;
>             //---------------------------------
>             StringBuilder sb = new StringBuilder(256);
>             sb.Append(_tileDirectory);
>             sb.Append(mapDefDir);
>             sb.Append("S");
>             sb.Append(this._scaleIndex);
>             sb.Append("/");
>             sb.Append(this._baseLayerGroupname);
>             sb.Append("/R");
>             sb.Append(tileRowGroup);
>             sb.Append("/C");
>             sb.Append(tileColGroup);
>             sb.Append("/");
>             sb.Append(imgPartA);
>             sb.Append("_");
>             sb.Append(imgPartB);
>             sb.Append(_imageFileFormat);
>             
> //---------------------------------------------------------------------------------------------------------------------
>
>             
> //---------------------------------------------------------------------------------------------------------------------
>             //We give file if possible, let mapGuide build the tile 
> otherwise
>             
> //---------------------------------------------------------------------------------------------------------------------
>             context.Response.ContentType = _contentType;
>             string file = sb.ToString();
>             if (System.IO.File.Exists(file))
>             {
>                 try
>                 {
> #if false
>                     context.Response.WriteFile(file);
> #else
>                     StreamFile(file, context.Response);
> #endif
>                 }
>                 catch (System.IO.IOException ex)
>                 {
>                     //FileExists is not enough:
>                     //MapGuide could possibly be writing the file 
> while we where trying to get access!!!!
> #if LOG_WITH_LOG4NET
>                     log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>                     logger.Error("GetMGTiles.ashx::ProcessRequest - 
> Tried StreamFile [System.IO.IOException] - serve file via MapGuide", ex);
> #endif
>                     ServeMgTile(context.Response);
>                 }
>
>                 context.Response.Flush();
>                 context.Response.Close();
>             }
>             else
>             {
>                 context.Response.ContentType = _contentType;
>                 ServeMgTile(context.Response);
>                 context.Response.Flush();
>                 context.Response.Close();
>             }
>         }
>         catch (ArgumentNullException ex)
>         {
>             log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>             logger.Error("GetMGTiles.ashx::ProcessRequest 
> [ArgumentNullException]", ex);
>
>             context.Response.StatusCode = (int)HttpStatusCode.NotFound;
>             System.Diagnostics.Trace.WriteLine(ex.ToString());
>         }
>         catch (System.Security.SecurityException ex)
>         {
> #if LOG_WITH_LOG4NET
>             log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>             logger.Error("GetMGTiles.ashx::ProcessRequest 
> [SecurityException]", ex);
> #endif
>             context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
>             System.Diagnostics.Trace.WriteLine(ex.ToString());
>         }
>         catch (UriFormatException ex)
>         {
> #if LOG_WITH_LOG4NET
>             log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>             logger.Error("GetMGTiles.ashx::ProcessRequest 
> [UriFormatException]", ex);
> #endif
>             context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
>             System.Diagnostics.Trace.WriteLine(ex.ToString());
>         }
>         catch (TimeoutException ex)
>         {
> #if LOG_WITH_LOG4NET
>             log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>             logger.Error("GetMGTiles.ashx::ProcessRequest 
> [TimeoutException]", ex);
> #endif
>             context.Response.StatusCode = 
> (int)HttpStatusCode.RequestTimeout;
>             System.Diagnostics.Trace.WriteLine(ex.ToString());
>         }
>         catch (Exception ex)
>         {
> #if LOG_WITH_LOG4NET
>             log4net.ILog logger = 
> log4net.LogManager.GetLogger("exceptions");
>             logger.Error("GetMGTiles.ashx::ProcessRequest 
> [Exception]", ex);
> #endif
>             context.Response.StatusCode = 
> (int)HttpStatusCode.InternalServerError;
>             System.Diagnostics.Trace.WriteLine(ex.ToString());
>         }
>     }
>
>     public bool IsReusable
>     {
>         get
>         {
>             return false;
>         }
>     }
>
> }
>
> ------------
> Test page [slightly modified from the wiki]
> Assumes GetMGTiles.ashx is accessible in 
> http://localhost/ash/GetMGTiles.ashx
> -----------
>
> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
> <html>
> <head>
> <title>Mapguide Http Tile Cache Demo</title>
>
> <script type="text/javascript" 
> src="http://www.openlayers.org/api/OpenLayers.js"></script>
>
> </head>
> <body onload="initTiled()">
>
> <script type="text/javascript">
>         var windowSize = 550; //200;//
>         var extent;
>
>         var addrs = "http://localhost/";
>         //var addrs = "http://192.168.1.247/";
>
>         var mg_url = addrs + 
> "mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&";
>         var http_url = addrs + "sheboyganTiles";
>         var my_proxy_url = addrs + "ash/GetMGTiles.ashx";
>         var mg_map, http_or_tileproxy_map;
>         var eventsLog = "";
>         var c = 0;
>         //var bUseHttpUrl = false; //http_url || my_proxy_url
>
>         function initTiled() {
>
>             document.getElementById('map_mg').style.width = windowSize;
>             document.getElementById('map_http').style.width = windowSize;
>
>             document.getElementById('map_mg').style.height = windowSize;
>             document.getElementById('map_http').style.height = windowSize;
>
>             OpenLayers.DOTS_PER_INCH = 96;
>
>             //extent = new 
> OpenLayers.Bounds(-87.865114442365922,43.665065564837931,-87.595394059497067,43.823852564430069); 
>
>             var extent = new OpenLayers.Bounds(-87.764986990963, 
> 43.691398128788, -87.6955215109, 43.79752000048);
>             var tempScales = [1000, 1930.6977300000001, 
> 3727.5937199999998, 7196.8567300000004, 13894.95494, 26826.95795, 
> 51794.746789999997, 100000];
>
>             var mapOptions = {
>                 maxExtent: extent,
>                 restrictedExtent: extent,
>                 scales: tempScales
>             };
>
>             var params = {
>                 mapdefinition: 
> 'Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition',
>                 basemaplayergroupname: "Base Layer Group"
>             }
>
>             mg_map = new OpenLayers.Map('map_mg', mapOptions);
>             http_or_tileproxy_map = new OpenLayers.Map('map_http', 
> mapOptions);
>
>             var mgOptions = {
>                 singleTile: false,
>                 useHttpTile: false,
>                 buffer: 1
>             }
>
>             /*var httpOptions = {
>                 singleTile: false,
>                 useHttpTile: true,
>                 buffer: 1
>             }*/
>
>             var myProxyOptions = {
>                 singleTile: false,
>                 useHttpTile: false,
>                 buffer: 1
>             }
>
>             mg_layer = new OpenLayers.Layer.MapGuide("MapGuide OS 
> tiled layer", mg_url, params, mgOptions);
>             //if (bUseHttpUrl) http_layer = new 
> OpenLayers.Layer.MapGuide("MapGuide OS tiled layer", http_url, params, 
> httpOptions);
>             //else
>             http_layer = new OpenLayers.Layer.MapGuide("MG OS proxy - 
> tiled layer", my_proxy_url, params, myProxyOptions);
>
>             mg_map.addLayer(mg_layer);
>
>             mg_map.addControl(new OpenLayers.Control.MousePosition());
>             http_or_tileproxy_map.addControl(new 
> OpenLayers.Control.MousePosition());
>
>             http_or_tileproxy_map.addLayer(http_layer);
>
>             mg_map.setCenter(extent.getCenterLonLat());
>             http_or_tileproxy_map.setCenter(extent.getCenterLonLat());
>
>             mg_map.events.register("zoomend", mg_map, setZoomHttp);
>             //http_or_tileproxy_map.events.register("zoomend", 
> http_or_tileproxy_map, setZoomMg);
>
>             mg_map.events.register("moveend", mg_map, moveHttp);
>             //http_or_tileproxy_map.events.register("moveend", 
> http_or_tileproxy_map, moveMg);
>
>         }
>
>         function moveHttp() {
>             if (mg_map.getCenter() != http_or_tileproxy_map.getCenter())
>                 http_or_tileproxy_map.setCenter(mg_map.getCenter());
>         }
>
>         function moveMg() {
>             if (mg_map.getCenter() != http_or_tileproxy_map.getCenter())
>                 mg_map.setCenter(http_or_tileproxy_map.getCenter());
>         }
>
>
>
>         function setZoomMg() {
>             if (mg_map.getZoom() != http_or_tileproxy_map.getZoom())
>                 mg_map.zoomTo(http_or_tileproxy_map.getZoom());
>         }
>         function setZoomHttp() {
>             if (mg_map.getZoom() != http_or_tileproxy_map.getZoom())
>                 http_or_tileproxy_map.zoomTo(mg_map.getZoom());
>
>         }
>
> </script>
>
> <div style="float: left">
> <h1>Served by Mapguide</h1>
> <div id="map_mg" style="border: medium inset Maroon; float: left; 
> background-color: #F5DEB3;">
> </div>
> <br />This cannot be proxied, it lacks cache headers
> </div>
> <div style="float: left">
> <h1>Served by Http</h1>
> <div id="map_http" style="border: medium inset Maroon; float: left; 
> background-color: #F5DEB3;">
> </div>
> <br />This is can be proxied by proxy servers
> </div>
> </body>
> </html>
>
>
>
>
> ------------
> [OFFTOPIC] A suggestion about MapGuide Installer -
>
> it would be nice that besides the installer, there was a zipped 
> archive with the installed files, to give the possibility of manually 
> installing MapGuide without running an installer. This could be 
> clearly set to UNSUPPORTED, and that no help would be given in the 
> list to who desires to use the zipped archive.
>
> This is because, in my opinion, one cannot understand the system, if 
> not by using a manual install. It's the path I followed when I for the 
> first time used MapGuide.
>
> To provide such a thing is very simple: install in C:\OsGeo, zip 
> folder and publish in "http://mapguide.osgeo.org/download". Only for 
> windows, linux always needs compilation because of different shared 
> objects between distributions.
>
> At this point one can extract the zip wherever she wants, change ini 
> files, set virtual directories, enable PHP, change folder permissions, 
> and the game is done!
> ------------
>
> Pietro Ianniello
>
>
> _______________________________________________
> mapguide-users mailing list
> mapguide-users at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapguide-users
>    
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/mapguide-users/attachments/20100225/58d5be3e/attachment.html


More information about the mapguide-users mailing list