Archive for the ‘ArcGIS Server’ Category

ArcGIS Server Virtual Earth Tile Server vs. ArcIMS

February 4, 2008

Time to change the name Dave.

     

using System;
using System.Text;
using ArcDeveloper.TileServer.Interfaces;
using System.Net;
using System.IO;
using System.Xml;
using System.Drawing;
using System.Drawing.Imaging;   

namespace ArcDeveloper.TileServer.ArcIMS
{
    public class ArcImsTileProvider : ITileProvider
    {
        ///
        /// Private member containing the web service url
        ///
        private string _webServiceUrl = "";   

        ///
        /// Constructor that takes a web service Url
        ///
        ///
        public ArcImsTileProvider(string webServiceUrl)
        {
            _webServiceUrl = webServiceUrl;
        }   

        ///
        /// Get the tile image
        ///
        ///
        ///
        ///
        /// Tile data stream
        public System.IO.MemoryStream GetTile(ITileExtent extent, int tileHeight, int tileWidth)
        {
            MemoryStream returnStream = null;   

            try
            {
                string axl = getAXL(extent, tileHeight, tileWidth);
                Stream responseStream = PostData(_webServiceUrl, axl);
                XmlDocument xd = new XmlDocument();
                xd.Load(responseStream);
                string imgURL = xd.GetElementsByTagName("OUTPUT")[0].Attributes["url"].Value;
                responseStream.Close();   

                Bitmap bm = new Bitmap(new WebClient().OpenRead(imgURL));
                returnStream = new MemoryStream();
                bm.Save(returnStream, ImageFormat.Png);
            }
            catch(Exception e)
            {
                Bitmap bm = GetMessageTile(e.Message);
                returnStream = new MemoryStream();
                bm.Save(returnStream, ImageFormat.Png);
            }   

            return returnStream;
        }   

        ///
        /// Gets the ArcIMS GetImage AXL request.
        ///
        ///
        ///
        ///
        /// GetImage ArcIMS AXL request
        private string getAXL(ITileExtent extent, int tileHeight, int tileWidth)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
            sb.Append("<ARCXML version=\"1.1\">");
            sb.Append("<REQUEST>");
            sb.Append("<GET_IMAGE>");
            sb.Append("<PROPERTIES>");
            sb.Append("<ENVELOPE minx=\"" + extent.lon2 + "\" miny=\"" + extent.lat2 + "\" maxx=\"" + extent.lon + "\" maxy=\"" + extent.lat + "\" />");
            sb.Append("<IMAGESIZE height=\"" + tileHeight + "\" width=\"" + tileWidth + "\" />");
            sb.Append("</PROPERTIES>");
            sb.Append("</GET_IMAGE>");
            sb.Append("</REQUEST>");
            sb.Append("</ARCXML>");
            return sb.ToString();
        }   

        ///
        /// Gets a tile with an error message burned into it.
        ///
        /// The message.
        /// An error message PNG
        private Bitmap GetMessageTile(string message)
        {
            Bitmap tile = new Bitmap(Properties.Resources.blankTile);
            Graphics graphics = Graphics.FromImage(tile);
            Font drawFont = new Font("Arial", 12);
            SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.Black);
            SizeF len = graphics.MeasureString(message, drawFont);
            graphics.DrawString(message, drawFont, drawBrush, new PointF(10, 10));
            graphics.Dispose();
            return tile;
        }   

        ///
        /// Does an HTTP Post, returning a stream.
        ///
        /// The URL to post to
        /// The data to post
        /// The Http response stream
        private Stream PostData(string sURL, string postData)
        {
            HttpWebRequest webReq = null;
            HttpWebResponse response = null;
            Stream requestStream = null;
            StreamWriter writer = null;
            Stream responseStream = null;
            try
            {
                webReq = (HttpWebRequest)WebRequest.Create(sURL);
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                webReq.Timeout = 0xea60;
                webReq.AllowAutoRedirect = true;
                requestStream = webReq.GetRequestStream();
                writer = new StreamWriter(requestStream);
                writer.Write(postData);
                writer.Flush();
                writer.Close();
                requestStream.Close();
                response = (HttpWebResponse)webReq.GetResponse();
                responseStream = ((HttpWebResponse)webReq.GetResponse()).GetResponseStream();
            }
            finally
            {
                if (writer != null) writer.Close();
            }
            return responseStream;
        }   

    }
}   

Winners: Python-fearing .NET folks still using ArcIMS.  All six of you!

Losers: “ArcGIS Server Virtual Earth Tile Server” as a name.  Die.

Scrappad: ArcGIS Server 9.2 With A Reverse Proxy

April 16, 2007

There’s a nice write-up on Scrappad concerning Configuring ArcGIS Server 9.2 For .NET To Work With A Reverse Proxy .

It references an ESRI article that talks about using Apache for the reverse proxy. Scrappad recommends Microsoft’s ISA server for the same deal. If you’re in an IIS setting and that’s outside your price range, I recommend taking a look at the article I wrote on proxying ArcIMS traffic using ASP.NET HttpHandlers.

Register all the Web ADF Samples with IIS at Once

March 29, 2007

You know the drill… if you’re creating an ASP.Net web application, you need to configure its folder as an application within IIS. 

ArcGIS Server comes with 52 samples ADF web applications, 26 in C#, 26 in VB.Net.  Stick them into folders within your web root, and you’ll have 52 error messages telling you to configure your 52 folders as IIS applications.

Here’s a rough VBS script that walks your web root, wiring up an IIS application anywhere it sees web.config file:

FixAspxRoots.vbs

Dim IISroot
Dim objFSO
Set objFSO = CreateObject(”Scripting.FileSystemObject”)
Set IISroot = GetObject(”IIS://localhost/W3SVC/1/ROOT”)
objStartFolder = IISroot.path
WScript.Echo “Scanning for web.config files below ” + objStartFolder
ExamineSubfolders objFSO.GetFolder(objStartFolder)
IISroot.SetInfo()

Sub ExamineSubFolders(Folder)
 If (objFSO.FileExists(Folder.path + “\web.config”)) Then AddvirtualDir Folder.Path, Folder.name
 For Each Subfolder in Folder.SubFolders
  ExamineSubFolders Subfolder
 Next
End Sub
Sub AddVirtualDir(folderPath, folderName)

 Dim iispath
 Dim VirtualDir
 
 
 iisPath = replace(mid(folderPath, len(objStartFolder)+2), “\”, “/”)
 
 Set VirtualDir = Nothing
 On Error Resume Next
 Set VirtualDir = GetObject(”IIS://localhost/W3SVC/1/ROOT/” & iispath)
 On Error Goto 0
 If Not VirtualDir Is Nothing Then
  If (VirtualDir.class = “IISWebVirtualDir”) Then
   ’I'm assuming that this should be a webdir, not a vdir
   WScript.Echo “killing vdir ” & iispath
   Set IISParent = GetObject(VirtualDir.Parent)
   IISParent.Delete VirtualDir.class, VirtualDir.name
   IISParent.SetInfo()
   WScript.Echo “Creating IIsWebDirectory ” & iispath
   Set VirtualDir = IISroot.Create(”IIsWebDirectory”, iispath)
  Else
   WScript.Echo “updating  ” & VirtualDir.class & ” ” & iispath
  End If
 Else
  WScript.Echo “Creating IIsWebDirectory ” & iispath
  Set VirtualDir = IISroot.Create(”IIsWebDirectory”, iispath)
 End If
 ’I have no idea what half these settings mean
 VirtualDir.AppIsolated = 0
 VirtualDir.AppFriendlyName = folderName
 VirtualDir.AccessScript = true
 VirtualDir.AccessRead = true
 VirtualDir.SetInfo
 VirtualDir.AppCreate2 1
 VirtualDir.SetInfo
End Sub