Class for generating the WmsCapabilities Xml
Esempio n. 1
0
		/// <summary>
		/// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
		/// </summary>
		/// <remarks>
		/// <para>
		/// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
		/// and support the basic operations "GetCapabilities" and "GetMap"
		/// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
		/// GetFeatureInfo operation for querying.
		/// </para>
		/// <example>
		/// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
		/// <code lang="C#">
		/// void page_load(object o, EventArgs e)
		/// {
		///		//Get the path of this page
		///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
		///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
		///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
		///		
		///		// The following service descriptions below are not strictly required by the WMS specification.
		///		
		///		// Narrative description and keywords providing additional information 
		///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
		///		description.Keywords.Add("bird");
		///		description.Keywords.Add("roadrunner");
		///		description.Keywords.Add("ambush");
		///		
		///		//Contact information 
		///		description.ContactInformation.PersonPrimary.Person = "John Doe";
		///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
		///		description.ContactInformation.Address.AddressType = "postal";
		///		description.ContactInformation.Address.Country = "Neverland";
		///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
		///		//Impose WMS constraints
		///		description.MaxWidth = 1000; //Set image request size width
		///		description.MaxHeight = 500; //Set image request size height
		///		
		///		//Call method that sets up the map
		///		//We just add a dummy-size, since the wms requests will set the image-size
		///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
		///		
		///		//Parse the request and create a response
		///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
		/// }
		/// </code>
		/// </example>
		/// </remarks>
		/// <param name="map">Map to serve on WMS</param>
		/// <param name="description">Description of map service</param>
		public static void ParseQueryString(SharpMap.Map map, Capabilities.WmsServiceDescription description)
		{
			if (map == null)
				throw (new ArgumentException("Map for WMS is null"));
			if (map.Layers.Count == 0)
				throw (new ArgumentException("Map doesn't contain any layers for WMS service"));

			if (System.Web.HttpContext.Current == null)
				throw (new ApplicationException("An attempt was made to access the WMS server outside a valid HttpContext"));

			System.Web.HttpContext context = System.Web.HttpContext.Current;

			//IgnoreCase value should be set according to the VERSION parameter
			//v1.3.0 is case sensitive, but since it causes a lot of problems with several WMS clients, we ignore casing anyway.
			bool ignorecase = true; 

			//Check for required parameters
			//Request parameter is mandatory
			if (context.Request.Params["REQUEST"] == null)
				{ WmsException.ThrowWmsException("Required parameter REQUEST not specified"); return; }
			//Check if version is supported
			if (context.Request.Params["VERSION"] != null)
			{
				if (String.Compare(context.Request.Params["VERSION"], "1.3.0", ignorecase) != 0)
					{ WmsException.ThrowWmsException("Only version 1.3.0 supported"); return; }
			}
			else //Version is mandatory if REQUEST!=GetCapabilities. Check if this is a capabilities request, since VERSION is null
			{
				if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) != 0)
					{ WmsException.ThrowWmsException("VERSION parameter not supplied"); return; }
			}

			//If Capabilities was requested
			if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) == 0)
			{
        GetCapabilities(map, ref description, context);
			}
			else if (String.Compare(context.Request.Params["REQUEST"], "GetMap", ignorecase) == 0) //Map requested
			{
        GetMap(map, ref description, context, ignorecase);
			}
      else if (String.Compare(context.Request.Params["REQUEST"], "getfeatureinfo", ignorecase) == 0) //Map requested
      {
        GetFeatureInfo(map, context);
      }
      else
        WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Invalid request");
		}
Esempio n. 2
0
        /// <summary>
        /// Generates a capabilities file from a map object for use in WMS services
        /// </summary>
        /// <remarks>The capabilities document uses the v1.3.0 OpenGIS WMS specification</remarks>
        /// <param name="map">The map to create capabilities for</param>
        /// <param name="serviceDescription">Additional description of WMS</param>
        /// <returns>Returns XmlDocument describing capabilities</returns>
        public static XmlDocument GetCapabilities(Map map, Capabilities.WmsServiceDescription serviceDescription)
        {
            XmlDocument capabilities = new XmlDocument();


            //Set XMLSchema
            //capabilities.Schemas.Add(GetCapabilitiesSchema());

            //Instantiate an XmlNamespaceManager object.
            //System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(capabilities.NameTable);
            //xmlnsManager.AddNamespace(xlinkNamespaceURI, "urn:Books");

            //Insert XML tag
            capabilities.InsertBefore(capabilities.CreateXmlDeclaration("1.0", "UTF-8", string.Empty),
                                      capabilities.DocumentElement);
            capabilities.AppendChild(
                capabilities.CreateComment("Capabilities generated by SharpMap v. " +
                                           Assembly.GetExecutingAssembly().GetName().Version));
            //Create root node
            XmlNode RootNode = capabilities.CreateNode(XmlNodeType.Element, "WMS_Capabilities", wmsNamespaceURI);
            RootNode.Attributes.Append(CreateAttribute("version", "1.3.0", capabilities));

            XmlAttribute attr = capabilities.CreateAttribute("xmlns", "xsi", "http://www.w3.org/2000/xmlns/");
            attr.InnerText = "http://www.w3.org/2001/XMLSchema-instance";
            RootNode.Attributes.Append(attr);

            RootNode.Attributes.Append(CreateAttribute("xmlns:xlink", xlinkNamespaceURI, capabilities));
            XmlAttribute attr2 = capabilities.CreateAttribute("xsi", "schemaLocation",
                                                              "http://www.w3.org/2001/XMLSchema-instance");
            attr2.InnerText = "http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd";
            RootNode.Attributes.Append(attr2);

            //Build Service node
            RootNode.AppendChild(GenerateServiceNode(ref serviceDescription, capabilities));

            //Build Capability node
            RootNode.AppendChild(GenerateCapabilityNode(map, capabilities, serviceDescription.PublicAccessURL));

            capabilities.AppendChild(RootNode);

            //TODO: Validate output against schema

            return capabilities;
        }
Esempio n. 3
0
 /// <summary>
 /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
 /// and support the basic operations "GetCapabilities" and "GetMap"
 /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
 /// GetFeatureInfo operation for querying.
 /// </para>
 /// <example>
 /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
 /// <code lang="C#">
 /// void page_load(object o, EventArgs e)
 /// {
 ///		//Get the path of this page
 ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
 ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
 ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
 ///		
 ///		// The following service descriptions below are not strictly required by the WMS specification.
 ///		
 ///		// Narrative description and keywords providing additional information 
 ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
 ///		description.Keywords.Add("bird");
 ///		description.Keywords.Add("roadrunner");
 ///		description.Keywords.Add("ambush");
 ///		
 ///		//Contact information 
 ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
 ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
 ///		description.ContactInformation.Address.AddressType = "postal";
 ///		description.ContactInformation.Address.Country = "Neverland";
 ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
 ///		//Impose WMS constraints
 ///		description.MaxWidth = 1000; //Set image request size width
 ///		description.MaxHeight = 500; //Set image request size height
 ///		
 ///		//Call method that sets up the map
 ///		//We just add a dummy-size, since the wms requests will set the image-size
 ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
 ///		
 ///		//Parse the request and create a response
 ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
 /// }
 /// </code>
 /// </example>
 /// </remarks>
 /// <param name="map">Map to serve on WMS</param>
 /// <param name="description">Description of map service</param>
 /// <param name="intersectDelegate">Delegate for Getfeatureinfo intersecting, when null, the WMS will default to ICanQueryLayer implementation</param>
 public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description, int pixelSensitivity, InterSectDelegate intersectDelegate)
 {
     _intersectDelegate = intersectDelegate;
     if (pixelSensitivity > 0)
         _pixelSensitivity = pixelSensitivity;
     ParseQueryString(map, description);
 }
Esempio n. 4
0
        /// <summary>
        /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
        /// and support the basic operations "GetCapabilities" and "GetMap"
        /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
        /// GetFeatureInfo operation for querying.
        /// </para>
        /// <example>
        /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
        /// <code lang="C#">
        /// void page_load(object o, EventArgs e)
        /// {
        ///		//Get the path of this page
        ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
        ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
        ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
        ///		
        ///		// The following service descriptions below are not strictly required by the WMS specification.
        ///		
        ///		// Narrative description and keywords providing additional information 
        ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
        ///		description.Keywords.Add("bird");
        ///		description.Keywords.Add("roadrunner");
        ///		description.Keywords.Add("ambush");
        ///		
        ///		//Contact information 
        ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
        ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
        ///		description.ContactInformation.Address.AddressType = "postal";
        ///		description.ContactInformation.Address.Country = "Neverland";
        ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
        ///		//Impose WMS constraints
        ///		description.MaxWidth = 1000; //Set image request size width
        ///		description.MaxHeight = 500; //Set image request size height
        ///		
        ///		//Call method that sets up the map
        ///		//We just add a dummy-size, since the wms requests will set the image-size
        ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
        ///		
        ///		//Parse the request and create a response
        ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        /// <param name="map">Map to serve on WMS</param>
        /// <param name="description">Description of map service</param>
        public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description)
        {
            if (_pixelSensitivity ==-1)
                _pixelSensitivity = 1;
            if (map == null)
                throw (new ArgumentException("Map for WMS is null"));
            if (map.Layers.Count == 0)
                throw (new ArgumentException("Map doesn't contain any layers for WMS service"));

            if (HttpContext.Current == null)
                throw (new ApplicationException(
                    "An attempt was made to access the WMS server outside a valid HttpContext"));

            HttpContext context = HttpContext.Current;

            //IgnoreCase value should be set according to the VERSION parameter
            //v1.3.0 is case sensitive, but since it causes a lot of problems with several WMS clients, we ignore casing anyway.
            bool ignorecase = true;

            //Check for required parameters
            //Request parameter is mandatory
            if (context.Request.Params["REQUEST"] == null)
            {
                WmsException.ThrowWmsException("Required parameter REQUEST not specified");
                return;
            }
            //Check if version is supported
            if (context.Request.Params["VERSION"] != null)
            {
                if (String.Compare(context.Request.Params["VERSION"], "1.3.0", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("Only version 1.3.0 supported");
                    return;
                }
            }
            else
            //Version is mandatory if REQUEST!=GetCapabilities. Check if this is a capabilities request, since VERSION is null
            {
                if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("VERSION parameter not supplied");
                    return;
                }
            }

            //If Capabilities was requested
            if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) == 0)
            {
                //Service parameter is mandatory for GetCapabilities request
                if (context.Request.Params["SERVICE"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter SERVICE not specified");
                    return;
                }

                if (String.Compare(context.Request.Params["SERVICE"], "WMS") != 0)
                    WmsException.ThrowWmsException(
                        "Invalid service for GetCapabilities Request. Service parameter must be 'WMS'");

                XmlDocument capabilities = Capabilities.GetCapabilities(map, description);
                context.Response.Clear();
                context.Response.ContentType = "text/xml";
                XmlWriter writer = XmlWriter.Create(context.Response.OutputStream);
                capabilities.WriteTo(writer);
                writer.Close();
                context.Response.End();
            }
            else if (String.Compare(context.Request.Params["REQUEST"], "GetFeatureInfo", ignorecase) == 0) //FeatureInfo Requested
            {
                if (context.Request.Params["LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter LAYERS not specified");
                    return;
                }
                if (context.Request.Params["STYLES"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter STYLES not specified");
                    return;
                }
                if (context.Request.Params["CRS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter CRS not specified");
                    return;
                }
                else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].TargetSRID)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported");
                    return;
                }
                if (context.Request.Params["BBOX"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter BBOX not specified");
                    return;
                }
                if (context.Request.Params["WIDTH"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter WIDTH not specified");
                    return;
                }
                if (context.Request.Params["HEIGHT"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter HEIGHT not specified");
                    return;
                }
                if (context.Request.Params["FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter FORMAT not specified");
                    return;
                }
                if (context.Request.Params["QUERY_LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter QUERY_LAYERS not specified");
                    return;
                }
                if (context.Request.Params["INFO_FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter INFO_FORMAT not specified");
                    return;
                }
                //parameters X&Y are not part of the 1.3.0 specification, but are included for backwards compatability with 1.1.1 (OpenLayers likes it when used together with wms1.1.1 services)
                if (context.Request.Params["X"] == null && context.Request.Params["I"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter I not specified");
                    return;
                }
                if (context.Request.Params["Y"] == null && context.Request.Params["J"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter J not specified");
                    return;
                }
                //sets the map size to the size of the client in order to calculate the coordinates of the projection of the client
                try
                {
                    map.Size = new System.Drawing.Size(System.Convert.ToInt16(context.Request.Params["WIDTH"]), System.Convert.ToInt16(context.Request.Params["HEIGHT"]));
                }
                catch
                {
                    WmsException.ThrowWmsException("Invalid parameters for HEIGHT or WITDH");
                    return;
                }
                //sets the boundingbox to the boundingbox of the client in order to calculate the coordinates of the projection of the client
                BoundingBox bbox = ParseBBOX(context.Request.Params["bbox"]);
                if (bbox == null)
                {
                    WmsException.ThrowWmsException("Invalid parameter BBOX");
                    return;
                }
                map.ZoomToBox(bbox);
                //sets the point clicked by the client
                SharpMap.Geometries.Point p = new SharpMap.Geometries.Point();
                Single x = 0;
                Single y = 0;
                //tries to set the x to the Param I, if the client send an X, it will try the X, if both fail, exception is thrown
                if (context.Request.Params["X"] != null)
                    try
                    {
                        x = System.Convert.ToSingle(context.Request.Params["X"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                if (context.Request.Params["I"] != null)
                    try
                    {
                        x = System.Convert.ToSingle(context.Request.Params["I"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                //same procedure for J (Y)
                if (context.Request.Params["Y"] != null)
                    try
                    {
                        y = System.Convert.ToSingle(context.Request.Params["Y"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                if (context.Request.Params["J"] != null)
                    try
                    {
                        y = System.Convert.ToSingle(context.Request.Params["J"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                p = map.ImageToWorld(new System.Drawing.PointF(x, y));
                int fc;
                try
                {
                    fc = System.Convert.ToInt16(context.Request.Params["FEATURE_COUNT"]);
                    if (fc < 1)
                        fc = 1;
                }
                catch
                {
                    fc = 1;
                }
                //default to text if an invalid format is requested
                string infoFormat = context.Request.Params["INFO_FORMAT"];
                string cqlFilter = null;
                if (context.Request.Params["CQL_FILTER"] != null)
                {
                    cqlFilter = context.Request.Params["CQL_FILTER"];
                }

                string vstr = "";
                string[] requestLayers = context.Request.Params["QUERY_LAYERS"].Split(new[] { ',' });
                if (String.Compare(context.Request.Params["INFO_FORMAT"], "text/json", ignorecase) == 0)
                {
                    vstr = CreateFeatureInfoGeoJSON(map, requestLayers, x, y, fc, cqlFilter);
                    context.Response.ContentType = "text/json";
                }
                else
                {
                    vstr = CreateFeatureInfoPlain(map, requestLayers, x, y, fc, cqlFilter);
                    context.Response.ContentType = "text/plain";
                }
                context.Response.Clear();                
                context.Response.Charset = "windows-1252";
                context.Response.Write(vstr);
                context.Response.Flush();
                context.Response.End();
            }
            else if (String.Compare(context.Request.Params["REQUEST"], "GetMap", ignorecase) == 0) //Map requested
            {
                //Check for required parameters
                if (context.Request.Params["LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter LAYERS not specified");
                    return;
                }
                if (context.Request.Params["STYLES"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter STYLES not specified");
                    return;
                }
                if (context.Request.Params["CRS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter CRS not specified");
                    return;
                }
                else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].TargetSRID)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported");
                    return;
                }
                if (context.Request.Params["BBOX"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter BBOX not specified");
                    return;
                }
                if (context.Request.Params["WIDTH"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter WIDTH not specified");
                    return;
                }
                if (context.Request.Params["HEIGHT"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter HEIGHT not specified");
                    return;
                }
                if (context.Request.Params["FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter FORMAT not specified");
                    return;
                }

                //Set background color of map
                if (String.Compare(context.Request.Params["TRANSPARENT"], "TRUE", ignorecase) == 0)
                    map.BackColor = Color.Transparent;
                else if (context.Request.Params["BGCOLOR"] != null)
                {
                    try
                    {
                        map.BackColor = ColorTranslator.FromHtml(context.Request.Params["BGCOLOR"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameter BGCOLOR");
                        return;
                    }
                    ;
                }
                else
                    map.BackColor = Color.White;

                //Get the image format requested
                ImageCodecInfo imageEncoder = GetEncoderInfo(context.Request.Params["FORMAT"]);
                if (imageEncoder == null)
                {
                    WmsException.ThrowWmsException("Invalid MimeType specified in FORMAT parameter");
                    return;
                }

                //Parse map size
                int width = 0;
                int height = 0;
                if (!int.TryParse(context.Request.Params["WIDTH"], out width))
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Invalid parameter WIDTH");
                    return;
                }
                else if (description.MaxWidth > 0 && width > description.MaxWidth)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                   "Parameter WIDTH too large");
                    return;
                }
                if (!int.TryParse(context.Request.Params["HEIGHT"], out height))
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Invalid parameter HEIGHT");
                    return;
                }
                else if (description.MaxHeight > 0 && height > description.MaxHeight)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                   "Parameter HEIGHT too large");
                    return;
                }
                map.Size = new Size(width, height);

                BoundingBox bbox = ParseBBOX(context.Request.Params["bbox"]);
                if (bbox == null)
                {
                    WmsException.ThrowWmsException("Invalid parameter BBOX");
                    return;
                }
                map.PixelAspectRatio = (width / (double)height) / (bbox.Width / bbox.Height);
                map.Center = bbox.GetCentroid();
                map.Zoom = bbox.Width;
				//set Styles for layers
                //first, if the request ==  STYLES=, set all the vectorlayers with Themes not null the Theme to the first theme from Themes
                if (String.IsNullOrEmpty(context.Request.Params["STYLES"]))
                {
                    foreach (ILayer layer in map.Layers)
                    {
                        if (layer.GetType() == typeof(VectorLayer))
                        {
                            if ((layer as VectorLayer).Themes != null)
                            {
                                if ((layer as VectorLayer).Themes.Count > 0)
                                {
                                    foreach (KeyValuePair<string, SharpMap.Rendering.Thematics.ITheme> kvp in (layer as VectorLayer).Themes)
                                    {
                                        (layer as VectorLayer).Theme = kvp.Value;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (!String.IsNullOrEmpty(context.Request.Params["LAYERS"]))
                    {
                        string[] layerz = context.Request.Params["LAYERS"].Split(new[] { ',' });
                        string[] styles = context.Request.Params["STYLES"].Split(new[] { ',' });
                        //test whether the lengt of the layers and the styles is the same. WMS spec is unclear on what to do if there is no one-to-one correspondence
                        if (layerz.Length == styles.Length)
                        {
                            foreach (ILayer layer in map.Layers)
                            {
                                if (layer.GetType() == typeof(VectorLayer))
                                {
                                    if ((layer as VectorLayer).Themes != null)
                                    {
                                        if ((layer as VectorLayer).Themes.Count > 0)
                                        {
                                            for (int i = 0; i < layerz.Length; i++)
                                            {
                                                if (String.Equals(layer.LayerName, layerz[i], StringComparison.InvariantCultureIgnoreCase))
                                                {
                                                    //take default style if style is empty
                                                    if (styles[i] =="")
                                                    {
                                                        foreach (KeyValuePair<string, SharpMap.Rendering.Thematics.ITheme> kvp in (layer as VectorLayer).Themes)
                                                        {
                                                            (layer as VectorLayer).Theme = kvp.Value;
                                                            break;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        if ((layer as VectorLayer).Themes.ContainsKey(styles[i]))
                                                        {
                                                            (layer as VectorLayer).Theme = (layer as VectorLayer).Themes[styles[i]];
                                                        }
                                                        else
                                                        {
                                                            WmsException.ThrowWmsException(WmsException.WmsExceptionCode.StyleNotDefined, "Style not advertised for this layer");
                                                        }
                                                    }
                                                }                                                
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                if (context.Request.Params["CQL_FILTER"] != null)
                {
                    foreach (ILayer layer in map.Layers)
                    {
                        if (layer.GetType() == typeof(VectorLayer))
                        {
                            if (typeof(SharpMap.Data.Providers.FilterProvider).IsAssignableFrom((layer as VectorLayer).DataSource.GetType()))
                            {
                                SharpMap.Data.Providers.FilterProvider shape = (SharpMap.Data.Providers.FilterProvider)(layer as VectorLayer).DataSource;
                                shape.FilterDelegate = new Data.Providers.FilterProvider.FilterMethod(delegate(SharpMap.Data.FeatureDataRow row) { return CQLFilter(row, context.Request.Params["CQL_FILTER"]); });
                            }
                        }
                        else if(layer.GetType() == typeof(LabelLayer))
                        {
                            if (typeof(SharpMap.Data.Providers.FilterProvider).IsAssignableFrom((layer as VectorLayer).DataSource.GetType()))
                            {
                                SharpMap.Data.Providers.FilterProvider shape = (SharpMap.Data.Providers.FilterProvider)(layer as VectorLayer).DataSource;
                                shape.FilterDelegate = new Data.Providers.FilterProvider.FilterMethod(delegate(SharpMap.Data.FeatureDataRow row) { return CQLFilter(row, context.Request.Params["CQL_FILTER"]); });
                            }
                        }
                    }
                }

                //Set layers on/off
                if (!String.IsNullOrEmpty(context.Request.Params["LAYERS"]))
                //If LAYERS is empty, use default layer on/off settings
                {
                    string[] layers = context.Request.Params["LAYERS"].Split(new[] { ',' });
                    if (description.LayerLimit > 0)
                    {
                        if (layers.Length == 0 && map.Layers.Count > description.LayerLimit ||
                            layers.Length > description.LayerLimit)
                        {
                            WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                           "Too many layers requested");
                            return;
                        }
                    }
                    foreach (ILayer layer in map.Layers)
                        layer.Enabled = false;
                    foreach (string layer in layers)
                    {
                        //SharpMap.Layers.ILayer lay = map.Layers.Find(delegate(SharpMap.Layers.ILayer findlay) { return findlay.LayerName == layer; });
                        ILayer lay = null;
                        for (int i = 0; i < map.Layers.Count; i++)
                            if (String.Equals(map.Layers[i].LayerName, layer,
                                              StringComparison.InvariantCultureIgnoreCase))
                                lay = map.Layers[i];


                        if (lay == null)
                        {
                            WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined,
                                                           "Unknown layer '" + layer + "'");
                            return;
                        }
                        else
                            lay.Enabled = true;
                    }
                }
                //Render map
                Image img = map.GetMap();

                //Png can't stream directy. Going through a memorystream instead
                MemoryStream MS = new MemoryStream();
                img.Save(MS, imageEncoder, null);
                img.Dispose();
                byte[] buffer = MS.ToArray();
                context.Response.Clear();
                context.Response.ContentType = imageEncoder.MimeType;
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                //context.Response.End();
            }
            else
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Invalid request");
        }
Esempio n. 5
0
    /// <summary>
    /// 
    /// </summary>
    /// <param name="map"></param>
    /// <param name="description"></param>
    /// <param name="context"></param>
    /// <param name="ignorecase"></param>
    private static void GetMap(SharpMap.Map map, ref Capabilities.WmsServiceDescription description, System.Web.HttpContext context, bool ignorecase)
    {
      string QueryString = context.Request.QueryString.ToString();
      System.Diagnostics.Debug.WriteLine(context.Request.QueryString);
      if (RequestIsCached(QueryString))
      {
        SendCachedData(context);
      }
      else
      {
        bool MapIsStatic = true;
        //Check for required parameters
        if (context.Request.Params["LAYERS"] == null)
        { WmsException.ThrowWmsException("Required parameter LAYERS not specified"); return; }
        if (context.Request.Params["STYLES"] == null)
        { WmsException.ThrowWmsException("Required parameter STYLES not specified"); return; }
        if (context.Request.Params["CRS"] == null)
        { WmsException.ThrowWmsException("Required parameter CRS not specified"); return; }
        else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].SRID.ToString())
        { WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported"); return; }
        if (context.Request.Params["BBOX"] == null)
        { WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter BBOX not specified"); return; }
        if (context.Request.Params["WIDTH"] == null)
        { WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter WIDTH not specified"); return; }
        if (context.Request.Params["HEIGHT"] == null)
        { WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter HEIGHT not specified"); return; }
        if (context.Request.Params["FORMAT"] == null)
        { WmsException.ThrowWmsException("Required parameter FORMAT not specified"); return; }

        //Set background color of map
        if (String.Compare(context.Request.Params["TRANSPARENT"], "TRUE", ignorecase) == 0)
          map.BackColor = System.Drawing.Color.Transparent;
        else if (context.Request.Params["BGCOLOR"] != null)
        {
          try { map.BackColor = System.Drawing.ColorTranslator.FromHtml(context.Request.Params["BGCOLOR"]); }
          catch { WmsException.ThrowWmsException("Invalid parameter BGCOLOR"); return; };
        }
        else
          map.BackColor = System.Drawing.Color.White;

        //Get the image format requested
        System.Drawing.Imaging.ImageCodecInfo imageEncoder = GetEncoderInfo(context.Request.Params["FORMAT"]);
        if (imageEncoder == null)
        {
          WmsException.ThrowWmsException("Invalid MimeType specified in FORMAT parameter");
          return;
        }

        //Parse map size
        int width = 0;
        int height = 0;
        if (!int.TryParse(context.Request.Params["WIDTH"], out width))
        {
          WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Invalid parameter WIDTH");
          return;
        }
        else if (description.MaxWidth > 0 && width > description.MaxWidth)
        {
          WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Parameter WIDTH too large");
          return;
        }
        if (!int.TryParse(context.Request.Params["HEIGHT"], out height))
        {
          WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Invalid parameter HEIGHT");
          return;
        }
        else if (description.MaxHeight > 0 && height > description.MaxHeight)
        {
          WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Parameter HEIGHT too large");
          return;
        }
        map.Size = new System.Drawing.Size(width, height);

        SharpMap.Geometries.BoundingBox bbox = ParseBBOX(context.Request.Params["bbox"]);
        if (bbox == null)
        {
          WmsException.ThrowWmsException("Invalid parameter BBOX");
          return;
        }
        map.PixelAspectRatio = ((double)width / (double)height) / (bbox.Width / bbox.Height);
        map.Center = bbox.GetCentroid();
        map.Zoom = bbox.Width;

        //Set layers on/off
        if (context.Request.Params["LAYERS"] != "") //If LAYERS is empty, use default layer on/off settings
        {
          string[] layers = context.Request.Params["LAYERS"].Split(new char[] { ',' });
          if (description.LayerLimit > 0)
          {
            if (layers.Length == 0 && map.Layers.Count > description.LayerLimit ||
              layers.Length > description.LayerLimit)
            {
              WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Too many layers requested");
              return;
            }
          }
          foreach (SharpMap.Layers.ILayer layer in map.Layers)
            layer.Enabled = false;
          foreach (string layer in layers)
          {
            SharpMap.Layers.ILayer lay = map.Layers.Find(delegate(SharpMap.Layers.ILayer findlay) { return findlay.LayerName == layer; });
            if (lay == null)
            {
              WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined, "Unknown layer '" + layer + "'");
              return;
            }
            else
            {
              lay.Enabled = true;
              if (lay is SharpMap.Layers.VectorLayer)
              {
                if (!((lay as SharpMap.Layers.VectorLayer).DataSource is SharpMap.Data.Providers.ShapeFile))
                {
                  MapIsStatic = false;
                }
              }
            }
          }
        }
        //Render map
        System.Drawing.Image img = map.GetMap();

        //Png can't stream directy. Going through a memorystream instead
        System.IO.MemoryStream MS = new System.IO.MemoryStream();
        img.Save(MS, imageEncoder, null);
        img.Dispose();
        byte[] buffer = MS.ToArray();
        context.Response.Clear();
        context.Response.ContentType = imageEncoder.MimeType;
        context.Response.OutputStream.Write(buffer, 0, buffer.Length);
        if (MapIsStatic)
          SaveCachedData(QueryString, imageEncoder.MimeType, buffer);

        context.Response.End();

      }
    }
Esempio n. 6
0
    /// <summary>
    /// 
    /// </summary>
    /// <param name="map"></param>
    /// <param name="description"></param>
    /// <param name="context"></param>
    private static void GetCapabilities(SharpMap.Map map, ref Capabilities.WmsServiceDescription description, System.Web.HttpContext context)
    {
      //Service parameter is mandatory for GetCapabilities request
      if (context.Request.Params["SERVICE"] == null)
      { WmsException.ThrowWmsException("Required parameter SERVICE not specified"); return; }

      if (String.Compare(context.Request.Params["SERVICE"], "WMS") != 0)
        WmsException.ThrowWmsException("Invalid service for GetCapabilities Request. Service parameter must be 'WMS'");


      System.Xml.XmlDocument capabilities = Wms.Capabilities.GetCapabilities(map, description);
      context.Response.Clear();
      context.Response.ContentType = "text/xml";
      System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(context.Response.OutputStream);
      capabilities.WriteTo(writer);
      writer.Close();
      context.Response.End();
    }
Esempio n. 7
0
 /// <summary>
 /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
 /// and support the basic operations "GetCapabilities" and "GetMap"
 /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
 /// GetFeatureInfo operation for querying.
 /// </para>
 /// <example>
 /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
 /// <code lang="C#">
 /// void page_load(object o, EventArgs e)
 /// {
 ///		//Get the path of this page
 ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
 ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
 ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
 ///		
 ///		// The following service descriptions below are not strictly required by the WMS specification.
 ///		
 ///		// Narrative description and keywords providing additional information 
 ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
 ///		description.Keywords.Add("bird");
 ///		description.Keywords.Add("roadrunner");
 ///		description.Keywords.Add("ambush");
 ///		
 ///		//Contact information 
 ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
 ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
 ///		description.ContactInformation.Address.AddressType = "postal";
 ///		description.ContactInformation.Address.Country = "Neverland";
 ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
 ///		//Impose WMS constraints
 ///		description.MaxWidth = 1000; //Set image request size width
 ///		description.MaxHeight = 500; //Set image request size height
 ///		
 ///		//Call method that sets up the map
 ///		//We just add a dummy-size, since the wms requests will set the image-size
 ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
 ///		
 ///		//Parse the request and create a response
 ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
 /// }
 /// </code>
 /// </example>
 /// </remarks>
 /// <param name="map">Map to serve on WMS</param>
 /// <param name="description">Description of map service</param>
 ///<param name="pixelSensitivity"> </param>
 ///<param name="intersectDelegate">Delegate for Getfeatureinfo intersecting, when null, the WMS will default to ICanQueryLayer implementation</param>
 public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description, int pixelSensitivity, InterSectDelegate intersectDelegate)
 {
     IntersectDelegate = intersectDelegate;
     if (pixelSensitivity > 0)
         PixelSensitivity = pixelSensitivity;
     ParseQueryString(map, description, new Context(HttpContext.Current));
 }
Esempio n. 8
0
        /// <summary>
        /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
        /// and support the basic operations "GetCapabilities" and "GetMap"
        /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
        /// GetFeatureInfo operation for querying.
        /// </para>
        /// <example>
        /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
        /// <code lang="C#">
        /// void page_load(object o, EventArgs e)
        /// {
        ///		//Get the path of this page
        ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
        ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
        ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
        ///		
        ///		// The following service descriptions below are not strictly required by the WMS specification.
        ///		
        ///		// Narrative description and keywords providing additional information 
        ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
        ///		description.Keywords.Add("bird");
        ///		description.Keywords.Add("roadrunner");
        ///		description.Keywords.Add("ambush");
        ///		
        ///		//Contact information 
        ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
        ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
        ///		description.ContactInformation.Address.AddressType = "postal";
        ///		description.ContactInformation.Address.Country = "Neverland";
        ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
        ///		//Impose WMS constraints
        ///		description.MaxWidth = 1000; //Set image request size width
        ///		description.MaxHeight = 500; //Set image request size height
        ///		
        ///		//Call method that sets up the map
        ///		//We just add a dummy-size, since the wms requests will set the image-size
        ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
        ///		
        ///		//Parse the request and create a response
        ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        /// <param name="map">Map to serve on WMS</param>
        /// <param name="description">Description of map service</param>
        /// <param name="context">The context the <see cref="WmsServer"/> is running in.</param>
        public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description, IContext context)
        {
            const StringComparison @case = StringComparison.InvariantCultureIgnoreCase;
            IContextRequest request = context.Request;
            IContextResponse response = context.Response;
            try
            {
                if (PixelSensitivity < 0)
                    PixelSensitivity = 1;
                if (map == null)
                    throw new WmsArgumentException("Map for WMS is null");
                if (map.Layers.Count == 0)
                    throw new WmsArgumentException("Map doesn't contain any layers for WMS service");

                string req = request.GetParam("REQUEST");
                if (req == null)
                    throw new WmsParameterNotSpecifiedException("REQUEST");

                IHandler handler;
                if (String.Equals(req, "GetCapabilities", @case))
                    handler = new GetCapabilities(description);
                else if (String.Equals(req, "GetFeatureInfo", @case))
                {
                    // use text/plain as default handler
                    // let the default handler validate params
                    string format = request.GetParam("INFO_FORMAT") ?? String.Empty;
                    GetFeatureInfoParams @params = new GetFeatureInfoParams(PixelSensitivity,
                        IntersectDelegate, FeatureInfoResponseEncoding);
                    if (String.Equals(format, "text/json", @case))
                        handler = new GetFeatureInfoJson(description, @params);
                    else if (String.Equals(format, "text/html", @case))
                        handler = new GetFeatureInfoHtml(description, @params);
                    else handler = new GetFeatureInfoPlain(description, @params);
                }
                else if (String.Equals(req, "GetMap", @case))
                    handler = new GetMap(description);
                else
                {
                    string s = String.Format("Invalid request: {0}", req);
                    throw new WmsOperationNotSupportedException(s);
                }

                IHandlerResponse result = handler.Handle(map, request);
                result.WriteToContextAndFlush(response);
            }
            catch (WmsExceptionBase ex)
            {
                ex.WriteToContextAndFlush(response);
            }
        }
Esempio n. 9
0
		/// <summary>
		/// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
		/// </summary>
		/// <remarks>
		/// <para>
		/// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
		/// and support the basic operations "GetCapabilities" and "GetMap"
		/// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
		/// GetFeatureInfo operation for querying.
		/// </para>
		/// <example>
		/// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
		/// <code lang="C#">
		/// void page_load(object o, EventArgs e)
		/// {
		///		//Get the path of this page
		///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
		///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
		///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
		///		
		///		// The following service descriptions below are not strictly required by the WMS specification.
		///		
		///		// Narrative description and keywords providing additional information 
		///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
		///		description.Keywords.Add("bird");
		///		description.Keywords.Add("roadrunner");
		///		description.Keywords.Add("ambush");
		///		
		///		//Contact information 
		///		description.ContactInformation.PersonPrimary.Person = "John Doe";
		///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
		///		description.ContactInformation.Address.AddressType = "postal";
		///		description.ContactInformation.Address.Country = "Neverland";
		///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
		///		//Impose WMS constraints
		///		description.MaxWidth = 1000; //Set image request size width
		///		description.MaxHeight = 500; //Set image request size height
		///		
		///		//Call method that sets up the map
		///		//We just add a dummy-size, since the wms requests will set the image-size
		///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
		///		
		///		//Parse the request and create a response
		///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
		/// }
		/// </code>
		/// </example>
		/// </remarks>
		/// <param name="map">Map to serve on WMS</param>
		/// <param name="description">Description of map service</param>
		public static void ParseQueryString(SharpMap.Map map, Capabilities.WmsServiceDescription description)
		{
			if (map == null)
				throw (new ArgumentException("Map for WMS is null"));
			if (map.Layers.Count == 0)
				throw (new ArgumentException("Map doesn't contain any layers for WMS service"));

			if (System.Web.HttpContext.Current == null)
				throw (new ApplicationException("An attempt was made to access the WMS server outside a valid HttpContext"));

			System.Web.HttpContext context = System.Web.HttpContext.Current;

			//IgnoreCase value should be set according to the VERSION parameter
			//v1.3.0 is case sensitive, but since it causes a lot of problems with several WMS clients, we ignore casing anyway.
			bool ignorecase = true; 

			//Check for required parameters
			//Request parameter is mandatory
			if (context.Request.Params["REQUEST"] == null)
				{ WmsException.ThrowWmsException("Required parameter REQUEST not specified"); return; }
			//Check if version is supported
			if (context.Request.Params["VERSION"] != null)
			{
				if (String.Compare(context.Request.Params["VERSION"], "1.3.0", ignorecase) != 0)
					{ WmsException.ThrowWmsException("Only version 1.3.0 supported"); return; }
			}
			else //Version is mandatory if REQUEST!=GetCapabilities. Check if this is a capabilities request, since VERSION is null
			{
				if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) != 0)
					{ WmsException.ThrowWmsException("VERSION parameter not supplied"); return; }
			}

			//If Capabilities was requested
			if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) == 0)
			{
				//Service parameter is mandatory for GetCapabilities request
				if (context.Request.Params["SERVICE"] == null)
				{ WmsException.ThrowWmsException("Required parameter SERVICE not specified"); return; }

				if (String.Compare(context.Request.Params["SERVICE"], "WMS") != 0)
					WmsException.ThrowWmsException("Invalid service for GetCapabilities Request. Service parameter must be 'WMS'");

				System.Xml.XmlDocument capabilities = Wms.Capabilities.GetCapabilities(map, description);
				context.Response.Clear();
				context.Response.ContentType = "text/xml";
				System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(context.Response.OutputStream);
				capabilities.WriteTo(writer);
				writer.Close();
				context.Response.End();
			}
			else if (String.Compare(context.Request.Params["REQUEST"], "GetMap", ignorecase) == 0) //Map requested
			{
				//Check for required parameters
				if (context.Request.Params["LAYERS"] == null)
					{ WmsException.ThrowWmsException("Required parameter LAYERS not specified"); return; }
				if (context.Request.Params["STYLES"] == null)
					{ WmsException.ThrowWmsException("Required parameter STYLES not specified"); return; }
				if (context.Request.Params["CRS"] == null)
					{ WmsException.ThrowWmsException("Required parameter CRS not specified"); return; }
				else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].SRID.ToString())
					{ WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported"); return; }
				if (context.Request.Params["BBOX"] == null)
					{ WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter BBOX not specified"); return; }
				if (context.Request.Params["WIDTH"] == null)
					{ WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter WIDTH not specified"); return; }
				if (context.Request.Params["HEIGHT"] == null)
					{ WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Required parameter HEIGHT not specified"); return; }
				if (context.Request.Params["FORMAT"] == null)
					{ WmsException.ThrowWmsException("Required parameter FORMAT not specified"); return; }

				//Set background color of map
				if (String.Compare(context.Request.Params["TRANSPARENT"], "TRUE", ignorecase) == 0)
					map.BackColor = System.Drawing.Color.Transparent;
				else if (context.Request.Params["BGCOLOR"] != null)
				{
					try { map.BackColor = System.Drawing.ColorTranslator.FromHtml(context.Request.Params["BGCOLOR"]); }
					catch { WmsException.ThrowWmsException("Invalid parameter BGCOLOR"); return; };
				}
				else
					map.BackColor = System.Drawing.Color.White;

				//Get the image format requested
				System.Drawing.Imaging.ImageCodecInfo imageEncoder = GetEncoderInfo(context.Request.Params["FORMAT"]);
				if (imageEncoder == null)
				{
					WmsException.ThrowWmsException("Invalid MimeType specified in FORMAT parameter");
					return;
				}

				//Parse map size
				int width = 0;
				int height = 0;
				if (!int.TryParse(context.Request.Params["WIDTH"], out width))
				{
					WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Invalid parameter WIDTH");
					return;
				}
				else if (description.MaxWidth > 0 && width > description.MaxWidth)
				{
					WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Parameter WIDTH too large");
					return;
				} 
				if (!int.TryParse(context.Request.Params["HEIGHT"], out height))
				{
					WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue, "Invalid parameter HEIGHT");
					return;
				}
				else if (description.MaxHeight > 0 && height > description.MaxHeight)
				{
					WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Parameter HEIGHT too large");
					return;
				}
				map.Size = new System.Drawing.Size(width, height);

				IEnvelope bbox = ParseBBOX(context.Request.Params["bbox"]);
				if (bbox == null)
				{
					WmsException.ThrowWmsException("Invalid parameter BBOX");
					return;
				}
				map.PixelAspectRatio = ((double)width / (double)height) / (bbox.Width / bbox.Height);
				map.Center = bbox.Centre;
				map.Zoom = bbox.Width;

				//Set layers on/off
				if (!String.IsNullOrEmpty(context.Request.Params["LAYERS"])) //If LAYERS is empty, use default layer on/off settings
				{
					string[] layers = context.Request.Params["LAYERS"].Split(new char[] { ',' });
					if(description.LayerLimit>0)
					{
						if (layers.Length == 0 && map.Layers.Count > description.LayerLimit ||
							layers.Length > description.LayerLimit)
						{
							WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Too many layers requested");
							return;
						}
					}
                    foreach (SharpMap.Layers.ILayer layer in map.Layers)
						layer.Enabled = false;
                    foreach (string layer in layers)
                    {

                        //SharpMap.Layers.ILayer lay = map.Layers.Find(delegate(SharpMap.Layers.ILayer findlay) { return findlay.LayerName == layer; });
                        SharpMap.Layers.ILayer lay = null;
                        for (int i = 0; i < map.Layers.Count; i++)
                            if (String.Equals(map.Layers[i].Name, layer, StringComparison.InvariantCultureIgnoreCase))
                                 lay = map.Layers[i];

                        if (lay == null)
						{
							WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined, "Unknown layer '" + layer + "'");
							return;
						}
						else
							lay.Enabled = true;
                    }
				}

				//Render map
				System.Drawing.Image img = map.Render();

				//Png can't stream directy. Going through a memorystream instead
				System.IO.MemoryStream MS = new System.IO.MemoryStream();
				img.Save(MS, imageEncoder, null);
				img.Dispose();
				byte[] buffer = MS.ToArray();
				context.Response.Clear();
				context.Response.ContentType = imageEncoder.MimeType;
				context.Response.OutputStream.Write(buffer, 0, buffer.Length);
				context.Response.End();
			}
			else
				WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Invalid request");
		}
Esempio n. 10
0
 /// <summary>
 /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
 /// and support the basic operations "GetCapabilities" and "GetMap"
 /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
 /// GetFeatureInfo operation for querying.
 /// </para>
 /// <example>
 /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
 /// <code lang="C#">
 /// void page_load(object o, EventArgs e)
 /// {
 ///		//Get the path of this page
 ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
 ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
 ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
 ///		
 ///		// The following service descriptions below are not strictly required by the WMS specification.
 ///		
 ///		// Narrative description and keywords providing additional information 
 ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
 ///		description.Keywords.Add("bird");
 ///		description.Keywords.Add("roadrunner");
 ///		description.Keywords.Add("ambush");
 ///		
 ///		//Contact information 
 ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
 ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
 ///		description.ContactInformation.Address.AddressType = "postal";
 ///		description.ContactInformation.Address.Country = "Neverland";
 ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
 ///		//Impose WMS constraints
 ///		description.MaxWidth = 1000; //Set image request size width
 ///		description.MaxHeight = 500; //Set image request size height
 ///		
 ///		//Call method that sets up the map
 ///		//We just add a dummy-size, since the wms requests will set the image-size
 ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
 ///		
 ///		//Parse the request and create a response
 ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
 /// }
 /// </code>
 /// </example>
 /// </remarks>
 /// <param name="map">Map to serve on WMS</param>
 /// <param name="description">Description of map service</param>
 public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description)
 {
     ParseQueryString(map, description, 1, null);
 }
Esempio n. 11
0
        /// <summary>
        /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
        /// and support the basic operations "GetCapabilities" and "GetMap"
        /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
        /// GetFeatureInfo operation for querying.
        /// </para>
        /// <example>
        /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
        /// <code lang="C#">
        /// void page_load(object o, EventArgs e)
        /// {
        ///		//Get the path of this page
        ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
        ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
        ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
        ///		
        ///		// The following service descriptions below are not strictly required by the WMS specification.
        ///		
        ///		// Narrative description and keywords providing additional information 
        ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. 
        ///     High-quality maps showing roadrunner nests and possible ambush locations.";
        ///		description.Keywords.Add("bird");
        ///		description.Keywords.Add("roadrunner");
        ///		description.Keywords.Add("ambush");
        ///		
        ///		//Contact information 
        ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
        ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
        ///		description.ContactInformation.Address.AddressType = "postal";
        ///		description.ContactInformation.Address.Country = "Neverland";
        ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
        ///		//Impose WMS constraints
        ///		description.MaxWidth = 1000; //Set image request size width
        ///		description.MaxHeight = 500; //Set image request size height
        ///		
        ///		//Call method that sets up the map
        ///		//We just add a dummy-size, since the wms requests will set the image-size
        ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
        ///		
        ///		//Parse the request and create a response
        ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        /// <param name="map">Map to serve on WMS</param>
        /// <param name="description">Description of map service</param>
        ///<param name="pixelSensitivity">Tolerance for GetFeatureInfo requests</param>
        ///<param name="intersectDelegate">Delegate for Getfeatureinfo intersecting, when null, the WMS will default to ICanQueryLayer implementation</param>
        public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description, int pixelSensitivity, InterSectDelegate intersectDelegate)
        {
            _pixelSensitivity = pixelSensitivity;
            _intersectDelegate = intersectDelegate;

            if (map == null)
                throw (new ArgumentException("Map for WMS is null"));
            if (map.Layers.Count == 0)
                throw (new ArgumentException("Map doesn't contain any layers for WMS service"));

            if (HttpContext.Current == null)
                throw new ApplicationException("An attempt was made to access the WMS server outside a valid HttpContext");

            HttpContext context = HttpContext.Current;

            //IgnoreCase value should be set according to the VERSION parameter
            //v1.3.0 is case sensitive, but since it causes a lot of problems with several WMS clients, we ignore casing anyway.
            const bool ignorecase = true;

            //Collect parameters
            string request = context.Request.Params["REQUEST"];
            string version = context.Request.Params["VERSION"];

            //Check for required parameters
            //Request parameter is mandatory            
            if (request == null)
            {
                WmsException.ThrowWmsException("Required parameter REQUEST not specified");
                return;
            }

            //Check if version is supported            
            if (version != null)
            {
                if (String.Compare(version, "1.3.0", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("Only version 1.3.0 supported");
                    return;
                }
            }
            else
            {
                //Version is mandatory if REQUEST!=GetCapabilities. Check if this is a capabilities request, since VERSION is null
                if (String.Compare(request, "GetCapabilities", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("VERSION parameter not supplied");
                    return;
                }
            }

            HandlerParams @params = new HandlerParams(context, map, description, ignorecase);
            GetFeatureInfoParams infoParams = new GetFeatureInfoParams(_pixelSensitivity, _intersectDelegate);

            IWmsHandler handler = null;
            if (String.Compare(request, "GetCapabilities", ignorecase) == 0)
                handler = new GetCapabilities(@params);
            else if (String.Compare(request, "GetFeatureInfo", ignorecase) == 0)
                handler = new GetFeatureInfo(@params, infoParams);
            else if (String.Compare(request, "GetMap", ignorecase) == 0)
                handler = new GetMap(@params);

            if (handler == null)
            {
                WmsException.ThrowWmsException(
                    WmsException.WmsExceptionCode.OperationNotSupported, String.Format("Invalid request: {0}", request));
            }
            else handler.Handle();
        }
Esempio n. 12
0
        /// <summary>
        /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
        /// and support the basic operations "GetCapabilities" and "GetMap"
        /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
        /// GetFeatureInfo operation for querying.
        /// </para>
        /// <example>
        /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
        /// <code lang="C#">
        /// void page_load(object o, EventArgs e)
        /// {
        ///		//Get the path of this page
        ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
        ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
        ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
        ///		
        ///		// The following service descriptions below are not strictly required by the WMS specification.
        ///		
        ///		// Narrative description and keywords providing additional information 
        ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
        ///		description.Keywords.Add("bird");
        ///		description.Keywords.Add("roadrunner");
        ///		description.Keywords.Add("ambush");
        ///		
        ///		//Contact information 
        ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
        ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
        ///		description.ContactInformation.Address.AddressType = "postal";
        ///		description.ContactInformation.Address.Country = "Neverland";
        ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
        ///		//Impose WMS constraints
        ///		description.MaxWidth = 1000; //Set image request size width
        ///		description.MaxHeight = 500; //Set image request size height
        ///		
        ///		//Call method that sets up the map
        ///		//We just add a dummy-size, since the wms requests will set the image-size
        ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
        ///		
        ///		//Parse the request and create a response
        ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        /// <param name="map">Map to serve on WMS</param>
        /// <param name="description">Description of map service</param>
        public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description)
        {
            if (HttpContext.Current == null)
                throw (new ApplicationException(
                    "An attempt was made to access the WMS server outside a valid HttpContext"));

            ParseQueryString(map, description, HttpContext.Current);
        }
Esempio n. 13
0
        /// <summary>
        /// Generates a WMS 1.3.0 compliant response based on a <see cref="SharpMap.Map"/> and the current HttpRequest.
        /// </summary>
        /// <remarks>
        /// <para>
        /// The Web Map Server implementation in SharpMap requires v1.3.0 compatible clients,
        /// and support the basic operations "GetCapabilities" and "GetMap"
        /// as required by the WMS v1.3.0 specification. SharpMap does not support the optional
        /// GetFeatureInfo operation for querying.
        /// </para>
        /// <example>
        /// Creating a WMS server in ASP.NET is very simple using the classes in the SharpMap.Web.Wms namespace.
        /// <code lang="C#">
        /// void page_load(object o, EventArgs e)
        /// {
        ///		//Get the path of this page
        ///		string url = (Request.Url.Query.Length>0?Request.Url.AbsoluteUri.Replace(Request.Url.Query,""):Request.Url.AbsoluteUri);
        ///		SharpMap.Web.Wms.Capabilities.WmsServiceDescription description =
        ///			new SharpMap.Web.Wms.Capabilities.WmsServiceDescription("Acme Corp. Map Server", url);
        ///		
        ///		// The following service descriptions below are not strictly required by the WMS specification.
        ///		
        ///		// Narrative description and keywords providing additional information 
        ///		description.Abstract = "Map Server maintained by Acme Corporation. Contact: [email protected]. High-quality maps showing roadrunner nests and possible ambush locations.";
        ///		description.Keywords.Add("bird");
        ///		description.Keywords.Add("roadrunner");
        ///		description.Keywords.Add("ambush");
        ///		
        ///		//Contact information 
        ///		description.ContactInformation.PersonPrimary.Person = "John Doe";
        ///		description.ContactInformation.PersonPrimary.Organisation = "Acme Inc";
        ///		description.ContactInformation.Address.AddressType = "postal";
        ///		description.ContactInformation.Address.Country = "Neverland";
        ///		description.ContactInformation.VoiceTelephone = "1-800-WE DO MAPS";
        ///		//Impose WMS constraints
        ///		description.MaxWidth = 1000; //Set image request size width
        ///		description.MaxHeight = 500; //Set image request size height
        ///		
        ///		//Call method that sets up the map
        ///		//We just add a dummy-size, since the wms requests will set the image-size
        ///		SharpMap.Map myMap = MapHelper.InitializeMap(new System.Drawing.Size(1,1));
        ///		
        ///		//Parse the request and create a response
        ///		SharpMap.Web.Wms.WmsServer.ParseQueryString(myMap,description);
        /// }
        /// </code>
        /// </example>
        /// </remarks>
        /// <param name="map">Map to serve on WMS</param>
        /// <param name="description">Description of map service</param>
        public static void ParseQueryString(Map map, Capabilities.WmsServiceDescription description)
        {
            _pixelSensitivity = 1;
            if (map == null)
                throw (new ArgumentException("Map for WMS is null"));
            if (map.Layers.Count == 0)
                throw (new ArgumentException("Map doesn't contain any layers for WMS service"));

            if (HttpContext.Current == null)
                throw (new ApplicationException(
                    "An attempt was made to access the WMS server outside a valid HttpContext"));

            HttpContext context = HttpContext.Current;

            //IgnoreCase value should be set according to the VERSION parameter
            //v1.3.0 is case sensitive, but since it causes a lot of problems with several WMS clients, we ignore casing anyway.
            bool ignorecase = true;

            //Check for required parameters
            //Request parameter is mandatory
            if (context.Request.Params["REQUEST"] == null)
            {
                WmsException.ThrowWmsException("Required parameter REQUEST not specified");
                return;
            }
            //Check if version is supported
            if (context.Request.Params["VERSION"] != null)
            {
                if (String.Compare(context.Request.Params["VERSION"], "1.3.0", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("Only version 1.3.0 supported");
                    return;
                }
            }
            else
            //Version is mandatory if REQUEST!=GetCapabilities. Check if this is a capabilities request, since VERSION is null
            {
                if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) != 0)
                {
                    WmsException.ThrowWmsException("VERSION parameter not supplied");
                    return;
                }
            }

            //If Capabilities was requested
            if (String.Compare(context.Request.Params["REQUEST"], "GetCapabilities", ignorecase) == 0)
            {
                //Service parameter is mandatory for GetCapabilities request
                if (context.Request.Params["SERVICE"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter SERVICE not specified");
                    return;
                }

                if (String.Compare(context.Request.Params["SERVICE"], "WMS") != 0)
                    WmsException.ThrowWmsException(
                        "Invalid service for GetCapabilities Request. Service parameter must be 'WMS'");

                XmlDocument capabilities = Capabilities.GetCapabilities(map, description);
                context.Response.Clear();
                context.Response.ContentType = "text/xml";
                XmlWriter writer = XmlWriter.Create(context.Response.OutputStream);
                capabilities.WriteTo(writer);
                writer.Close();
                context.Response.End();
            }
            else if (String.Compare(context.Request.Params["REQUEST"], "GetFeatureInfo", ignorecase) == 0) //FeatureInfo Requested
            {
                if (context.Request.Params["LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter LAYERS not specified");
                    return;
                }
                if (context.Request.Params["STYLES"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter STYLES not specified");
                    return;
                }
                if (context.Request.Params["CRS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter CRS not specified");
                    return;
                }
                else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].SRID)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported");
                    return;
                }
                if (context.Request.Params["BBOX"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter BBOX not specified");
                    return;
                }
                if (context.Request.Params["WIDTH"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter WIDTH not specified");
                    return;
                }
                if (context.Request.Params["HEIGHT"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter HEIGHT not specified");
                    return;
                }
                if (context.Request.Params["FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter FORMAT not specified");
                    return;
                }
                if (context.Request.Params["QUERY_LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter QUERY_LAYERS not specified");
                    return;
                }
                if (context.Request.Params["INFO_FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter INFO_FORMAT not specified");
                    return;
                }
                //parameters X&Y are not part of the 1.3.0 specification, but are included for backwards compatability with 1.1.1 (OpenLayers likes it when used together with wms1.1.1 services)
                if (context.Request.Params["X"] == null && context.Request.Params["I"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter I not specified");
                    return;
                }
                if (context.Request.Params["Y"] == null && context.Request.Params["J"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter J not specified");
                    return;
                }
                //sets the map size to the size of the client in order to calculate the coordinates of the projection of the client
                try
                {
                    map.Size = new System.Drawing.Size(System.Convert.ToInt16(context.Request.Params["WIDTH"]), System.Convert.ToInt16(context.Request.Params["HEIGHT"]));
                }
                catch
                {
                    WmsException.ThrowWmsException("Invalid parameters for HEIGHT or WITDH");
                    return;
                }
                //sets the boundingbox to the boundingbox of the client in order to calculate the coordinates of the projection of the client
                BoundingBox bbox = ParseBBOX(context.Request.Params["bbox"]);
                if (bbox == null)
                {
                    WmsException.ThrowWmsException("Invalid parameter BBOX");
                    return;
                }
                map.ZoomToBox(bbox);
                //sets the point clicked by the client
                SharpMap.Geometries.Point p = new SharpMap.Geometries.Point();
                Single x = 0;
                Single y = 0;
                //tries to set the x to the Param I, if the client send an X, it will try the X, if both fail, exception is thrown
                if (context.Request.Params["X"] != null)
                    try
                    {
                        x = System.Convert.ToSingle(context.Request.Params["X"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                if (context.Request.Params["I"] != null)
                    try
                    {
                        x = System.Convert.ToSingle(context.Request.Params["I"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                //same procedure for J (Y)
                if (context.Request.Params["Y"] != null)
                    try
                    {
                        y = System.Convert.ToSingle(context.Request.Params["Y"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                if (context.Request.Params["J"] != null)
                    try
                    {
                        y = System.Convert.ToSingle(context.Request.Params["J"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameters for I");
                    }
                p = map.ImageToWorld(new System.Drawing.PointF(x, y));
                int fc;
                try
                {
                    fc = System.Convert.ToInt16(context.Request.Params["FEATURE_COUNT"]);
                    if (fc < 1)
                        fc = 1;
                }
                catch
                {
                    fc = 1;
                }
                String vstr = "GetFeatureInfo results: \n";
                string[] requestLayers = context.Request.Params["QUERY_LAYERS"].Split(new[] { ',' });
                foreach (string requestLayer in requestLayers)
                {
                    bool found = false;
                    foreach (ILayer mapLayer in map.Layers)
                    {
                        if (String.Equals(mapLayer.LayerName, requestLayer,
                                          StringComparison.InvariantCultureIgnoreCase))
                        {
                            found = true;
                            if (!(mapLayer is ICanQueryLayer)) continue;

                            ICanQueryLayer queryLayer = mapLayer as ICanQueryLayer;
                            if (queryLayer.IsQueryEnabled)
                            {
                                Single queryBoxMinX = x - (_pixelSensitivity);
                                Single queryBoxMinY = y - (_pixelSensitivity);
                                Single queryBoxMaxX = x + (_pixelSensitivity);
                                Single queryBoxMaxY = y + (_pixelSensitivity);
                                SharpMap.Geometries.Point minXY = map.ImageToWorld(new System.Drawing.PointF(queryBoxMinX, queryBoxMinY));
                                SharpMap.Geometries.Point maxXY = map.ImageToWorld(new System.Drawing.PointF(queryBoxMaxX, queryBoxMaxY));
                                BoundingBox queryBox = new BoundingBox(minXY, maxXY);
                                SharpMap.Data.FeatureDataSet fds = new SharpMap.Data.FeatureDataSet();
                                queryLayer.ExecuteIntersectionQuery(queryBox, fds);
								if (_intersectDelegate != null)
                                {
                                    fds.Tables[0] = _intersectDelegate(fds.Tables[0], queryBox);
                                }
                                if (fds.Tables.Count == 0)
                                {
                                    vstr = vstr + "\nSearch returned no results on layer: " + requestLayer;
                                }
                                else
                                {
                                    if (fds.Tables[0].Rows.Count == 0)
                                    {
                                        vstr = vstr + "\nSearch returned no results on layer: " + requestLayer + " ";
                                    }
                                    else
                                    {
                                        //if featurecount < fds...count, select smallest bbox, because most likely to be clicked
                                        vstr = vstr + "\n Layer: '" + requestLayer + "'\n Featureinfo:\n";
                                        int[] keys = new int[fds.Tables[0].Rows.Count];
                                        double[] area = new double[fds.Tables[0].Rows.Count];
                                        for (int l = 0; l < fds.Tables[0].Rows.Count; l++)
                                        {
                                            SharpMap.Data.FeatureDataRow fdr = fds.Tables[0].Rows[l] as SharpMap.Data.FeatureDataRow;
                                            area[l] = fdr.Geometry.GetBoundingBox().GetArea();
                                            keys[l] = l;
                                        }
                                        Array.Sort(area, keys);
                                        if (fds.Tables[0].Rows.Count < fc)
                                        {
                                            fc = fds.Tables[0].Rows.Count;
                                        }
                                        for (int k = 0; k < fc; k++)
                                        {
                                            for (int j = 0; j < fds.Tables[0].Rows[keys[k]].ItemArray.Length; j++)
                                            {
                                                vstr = vstr + " '" + fds.Tables[0].Rows[keys[k]].ItemArray[j].ToString() + "'";
                                            }
                                            if ((k + 1) < fc)
                                                vstr = vstr + ",\n";
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (found == false)
                    {
                        WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined,
                                                       "Unknown layer '" + requestLayer + "'");
                        return;
                    }
                }
                context.Response.Clear();
                context.Response.ContentType = "text/plain";
                context.Response.Charset = "windows-1252";
                context.Response.Write(vstr);
                context.Response.Flush();
                context.Response.End();
            }
            else if (String.Compare(context.Request.Params["REQUEST"], "GetMap", ignorecase) == 0) //Map requested
            {
                //Check for required parameters
                if (context.Request.Params["LAYERS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter LAYERS not specified");
                    return;
                }
                if (context.Request.Params["STYLES"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter STYLES not specified");
                    return;
                }
                if (context.Request.Params["CRS"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter CRS not specified");
                    return;
                }
                else if (context.Request.Params["CRS"] != "EPSG:" + map.Layers[0].SRID)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS, "CRS not supported");
                    return;
                }
                if (context.Request.Params["BBOX"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter BBOX not specified");
                    return;
                }
                if (context.Request.Params["WIDTH"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter WIDTH not specified");
                    return;
                }
                if (context.Request.Params["HEIGHT"] == null)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Required parameter HEIGHT not specified");
                    return;
                }
                if (context.Request.Params["FORMAT"] == null)
                {
                    WmsException.ThrowWmsException("Required parameter FORMAT not specified");
                    return;
                }

                //Set background color of map
                if (String.Compare(context.Request.Params["TRANSPARENT"], "TRUE", ignorecase) == 0)
                    map.BackColor = Color.Transparent;
                else if (context.Request.Params["BGCOLOR"] != null)
                {
                    try
                    {
                        map.BackColor = ColorTranslator.FromHtml(context.Request.Params["BGCOLOR"]);
                    }
                    catch
                    {
                        WmsException.ThrowWmsException("Invalid parameter BGCOLOR");
                        return;
                    }
                    ;
                }
                else
                    map.BackColor = Color.White;

                //Get the image format requested
                ImageCodecInfo imageEncoder = GetEncoderInfo(context.Request.Params["FORMAT"]);
                if (imageEncoder == null)
                {
                    WmsException.ThrowWmsException("Invalid MimeType specified in FORMAT parameter");
                    return;
                }

                //Parse map size
                int width = 0;
                int height = 0;
                if (!int.TryParse(context.Request.Params["WIDTH"], out width))
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Invalid parameter WIDTH");
                    return;
                }
                else if (description.MaxWidth > 0 && width > description.MaxWidth)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                   "Parameter WIDTH too large");
                    return;
                }
                if (!int.TryParse(context.Request.Params["HEIGHT"], out height))
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                                   "Invalid parameter HEIGHT");
                    return;
                }
                else if (description.MaxHeight > 0 && height > description.MaxHeight)
                {
                    WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                   "Parameter HEIGHT too large");
                    return;
                }
                map.Size = new Size(width, height);

                BoundingBox bbox = ParseBBOX(context.Request.Params["bbox"]);
                if (bbox == null)
                {
                    WmsException.ThrowWmsException("Invalid parameter BBOX");
                    return;
                }
                map.PixelAspectRatio = (width / (double)height) / (bbox.Width / bbox.Height);
                map.Center = bbox.GetCentroid();
                map.Zoom = bbox.Width;

                //Set layers on/off
                if (!String.IsNullOrEmpty(context.Request.Params["LAYERS"]))
                //If LAYERS is empty, use default layer on/off settings
                {
                    string[] layers = context.Request.Params["LAYERS"].Split(new[] { ',' });
                    if (description.LayerLimit > 0)
                    {
                        if (layers.Length == 0 && map.Layers.Count > description.LayerLimit ||
                            layers.Length > description.LayerLimit)
                        {
                            WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported,
                                                           "Too many layers requested");
                            return;
                        }
                    }
                    foreach (ILayer layer in map.Layers)
                        layer.Enabled = false;
                    foreach (string layer in layers)
                    {
                        //SharpMap.Layers.ILayer lay = map.Layers.Find(delegate(SharpMap.Layers.ILayer findlay) { return findlay.LayerName == layer; });
                        ILayer lay = null;
                        for (int i = 0; i < map.Layers.Count; i++)
                            if (String.Equals(map.Layers[i].LayerName, layer,
                                              StringComparison.InvariantCultureIgnoreCase))
                                lay = map.Layers[i];


                        if (lay == null)
                        {
                            WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined,
                                                           "Unknown layer '" + layer + "'");
                            return;
                        }
                        else
                            lay.Enabled = true;
                    }
                }
                //Render map
                Image img = map.GetMap();

                //Png can't stream directy. Going through a memorystream instead
                MemoryStream MS = new MemoryStream();
                img.Save(MS, imageEncoder, null);
                img.Dispose();
                byte[] buffer = MS.ToArray();
                context.Response.Clear();
                context.Response.ContentType = imageEncoder.MimeType;
                context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                context.Response.End();
            }
            else
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.OperationNotSupported, "Invalid request");
        }