Example #1
0
        protected override AbstractGetFeatureInfoResponse CreateFeatureInfo(Map map,
                                                                            IEnumerable <string> requestedLayers,
                                                                            float x, float y,
                                                                            int featureCount,
                                                                            string cqlFilter,
                                                                            int pixelSensitivity,
                                                                            WmsServer.InterSectDelegate intersectDelegate)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendFormat("GetFeatureInfo results:{0}", NewLine);
            foreach (string requestLayer in requestedLayers)
            {
                ICanQueryLayer        layer = GetQueryLayer(map, requestLayer);
                IFeatureCollectionSet fds;
                if (!TryGetData(map, x, y, pixelSensitivity, intersectDelegate, layer, cqlFilter, out fds))
                {
                    sb.AppendFormat("Search returned no results on layer: {0}{1}", requestLayer, NewLine);
                    continue;
                }

                sb.AppendFormat("Layer: '{0}'{1}", requestLayer, NewLine);
                sb.AppendFormat("Featureinfo:{0}", NewLine);
                var    table    = fds[0];
                string rowsText = GetRowsText(table, featureCount);
                sb.Append(rowsText).Append(NewLine);
            }
            return(new GetFeatureInfoResponsePlain(sb.ToString()));
        }
Example #2
0
        /// <summary>
        /// Performs query on layer if it is of <see cref="ICanQueryLayer"/>
        /// </summary>
        /// <param name="layer">The layer to query</param>
        /// <param name="pt">The point to perform the query on</param>
        private void QueryLayer(ILayer layer, PointF pt)
        {
            if (layer is ICanQueryLayer)
            {
                ICanQueryLayer queryLayer = layer as ICanQueryLayer;

                Envelope bbox = new Envelope(
                    _map.ImageToWorld(pt, true)).Grow(_map.PixelSize * 5);
                FeatureDataSet ds = new FeatureDataSet();
                queryLayer.ExecuteIntersectionQuery(bbox, ds);
                if (MapQueried != null)
                {
                    if (ds.Tables.Count > 0)
                    {
                        MapQueried(ds.Tables[0]);
                    }
                    else
                    {
                        MapQueried(new FeatureDataTable());
                    }
                }
                if (MapQueriedDataSet != null)
                {
                    MapQueriedDataSet(ds);
                }
            }
        }
        private static IEnumerable <GeoJSON> QueryData(BoundingBox bbox, ICanQueryLayer layer)
        {
            if (layer == null)
            {
                throw new ArgumentNullException("layer");
            }

            // Query for data
            FeatureDataSet ds = new FeatureDataSet();

            layer.ExecuteIntersectionQuery(bbox, ds);
            IEnumerable <GeoJSON> data = GeoJSONHelper.GetData(ds);

            // Reproject geometries if needed
            IMathTransform transform = null;

            if (layer is VectorLayer)
            {
                ICoordinateTransformation transformation = (layer as VectorLayer).CoordinateTransformation;
                transform = transformation == null ? null : transformation.MathTransform;
            }
            if (transform != null)
            {
                GeometryFactory gf = new GeometryFactory();
                data = data.Select(d =>
                {
                    Geometry converted = GeometryTransform.TransformGeometry(d.Geometry, transform, gf);
                    d.SetGeometry(converted);
                    return(d);
                });
            }
            return(data);
        }
Example #4
0
        private static IEnumerable<GeoJSON> QueryData(BoundingBox bbox, ICanQueryLayer layer)
        {
            if (layer == null)
                throw new ArgumentNullException("layer");

            // Query for data
            FeatureDataSet ds = new FeatureDataSet();
            layer.ExecuteIntersectionQuery(bbox, ds);
            IEnumerable<GeoJSON> data = GeoJSONHelper.GetData(ds);

            // Reproject geometries if needed
            IMathTransform transform = null;
            if (layer is VectorLayer)
            {
                ICoordinateTransformation transformation = (layer as VectorLayer).CoordinateTransformation;
                transform = transformation == null ? null : transformation.MathTransform;
            }
            if (transform != null)
            {
                GeometryFactory gf = new GeometryFactory();
                data = data.Select(d =>
                    {
                        Geometry converted = GeometryTransform.TransformGeometry(d.Geometry, transform, gf);
                        d.SetGeometry(converted);
                        return d;
                    });
            }
            return data;
        }
Example #5
0
        /// <summary>
        /// Check if the layer can be queried and retrieve data, if there is any.
        /// </summary>
        protected bool TryGetData(Map map,
                                  float x, float y,
                                  int pixelSensitivity,
                                  WmsServer.InterSectDelegate intersectDelegate,
                                  ICanQueryLayer queryLayer,
                                  string cqlFilter,
                                  out IFeatureCollectionSet fds)
        {
            if (!queryLayer.IsQueryEnabled)
            {
                fds = null;
                return(false);
            }

            float queryBoxMinX = x - pixelSensitivity;
            float queryBoxMinY = y - pixelSensitivity;
            float queryBoxMaxX = x + pixelSensitivity;
            float queryBoxMaxY = y + pixelSensitivity;

            Coordinate minXY    = map.ImageToWorld(new PointF(queryBoxMinX, queryBoxMinY));
            Coordinate maxXY    = map.ImageToWorld(new PointF(queryBoxMaxX, queryBoxMaxY));
            Envelope   queryBox = new Envelope(minXY, maxXY);

            fds = new FeatureCollectionSet();
            queryLayer.ExecuteIntersectionQuery(queryBox, fds);

            if (fds.Count == 0)
            {
                return(false);
            }

            var table = fds[0];

            if (intersectDelegate != null)
            {
                fds.Remove(table);
                fds.Add(intersectDelegate(table, queryBox));
                table = fds[0];
            }

            // filter the rows with the CQLFilter if one is provided
            if (cqlFilter != null)
            {
                var toKeep = table.Clone();
                foreach (var feature in table)
                {
                    if (CqlFilter(feature, cqlFilter))
                    {
                        toKeep.Add(feature);
                    }
                }
                fds.Remove(table);
                fds.Add(toKeep);
            }

            return(fds[0].Count > 0);
        }
Example #6
0
        protected override AbstractGetFeatureInfoResponse CreateFeatureInfo(Map map,
                                                                            IEnumerable <string> requestedLayers,
                                                                            float x, float y,
                                                                            int featureCount,
                                                                            string cqlFilter,
                                                                            int pixelSensitivity,
                                                                            WmsServer.InterSectDelegate intersectDelegate)
        {
            List <GeoJSON> items = new List <GeoJSON>();

            foreach (string requestLayer in requestedLayers)
            {
                ICanQueryLayer queryLayer = GetQueryLayer(map, requestLayer);
                FeatureDataSet fds;
                if (!TryGetData(map, x, y, pixelSensitivity, intersectDelegate, queryLayer, cqlFilter, out fds))
                {
                    continue;
                }

                IEnumerable <GeoJSON> data = GeoJSONHelper.GetData(fds);
                // reproject geometries if needed
                IMathTransform transform = null;
                if (queryLayer is VectorLayer)
                {
                    ICoordinateTransformation transformation = (queryLayer as VectorLayer).CoordinateTransformation;
                    if (transformation != null)
                    {
                        transform = transformation.MathTransform;
                    }
                }

                if (transform != null)
                {
#if DotSpatialProjections
                    throw new NotImplementedException();
#else
                    data = data.Select(d =>
                    {
                        IGeometry converted = GeometryTransform.TransformGeometry(d.Geometry, transform, map.Factory);
                        d.SetGeometry(converted);
                        return(d);
                    });
#endif
                }
                items.AddRange(data);
            }

            StringWriter sb = new StringWriter();
            GeoJSONWriter.Write(items, sb);
            return(new GetFeatureInfoResponseJson(sb.ToString()));
        }
Example #7
0
        /// <summary>
        /// Check if the layer can be queried and retrieve data, if there is any.
        /// </summary>
        protected bool TryGetData(Map map,
            float x, float y,
            int pixelSensitivity,
            WmsServer.InterSectDelegate intersectDelegate,
            ICanQueryLayer queryLayer,
            string cqlFilter,
            out FeatureDataSet fds)
        {
            if (!queryLayer.IsQueryEnabled)
            {
                fds = null;
                return false;
            }

            float queryBoxMinX = x - pixelSensitivity;
            float queryBoxMinY = y - pixelSensitivity;
            float queryBoxMaxX = x + pixelSensitivity;
            float queryBoxMaxY = y + pixelSensitivity;

            Coordinate minXY = map.ImageToWorld(new PointF(queryBoxMinX, queryBoxMinY));
            Coordinate maxXY = map.ImageToWorld(new PointF(queryBoxMaxX, queryBoxMaxY));
            Envelope queryBox = new Envelope(minXY, maxXY);

            fds = new FeatureDataSet();
            queryLayer.ExecuteIntersectionQuery(queryBox, fds);

            FeatureTableCollection tables = fds.Tables;
            FeatureDataTable table = tables[0];
            if (intersectDelegate != null)
                tables[0] = intersectDelegate(table, queryBox);

            // filter the rows with the CQLFilter if one is provided
            if (cqlFilter != null)
            {
                DataRowCollection rows = table.Rows;
                for (int i = rows.Count - 1; i >= 0; i--)
                {
                    FeatureDataRow row = (FeatureDataRow)rows[i];
                    bool b = CqlFilter(row, cqlFilter);
                    if (!b)
                        rows.RemoveAt(i);
                }
            }

            bool res = tables.Count > 0 && table.Rows.Count > 0;
            return res;
        }
Example #8
0
        protected override AbstractGetFeatureInfoResponse CreateFeatureInfo(Map map,
                                                                            IEnumerable <string> requestedLayers,
                                                                            float x, float y,
                                                                            int featureCount,
                                                                            string cqlFilter,
                                                                            int pixelSensitivity,
                                                                            WmsServer.InterSectDelegate intersectDelegate)
        {
            StringBuilder sb = new StringBuilder();

            foreach (string requestLayer in requestedLayers)
            {
                ICanQueryLayer        layer = GetQueryLayer(map, requestLayer);
                IFeatureCollectionSet fds;
                if (!TryGetData(map, x, y, pixelSensitivity, intersectDelegate, layer, cqlFilter, out fds))
                {
                    continue;
                }

                var           table = fds[0];
                var           attributeDefinition = table[0].Factory.AttributesDefinition;
                StringBuilder sbTable             = new StringBuilder();
                sbTable.AppendFormat("<tr>{0}", NewLine);
                foreach (IFeatureAttributeDefinition col in attributeDefinition)
                {
                    sbTable.AppendFormat("<th>{0}</th>{1}", col.AttributeName, NewLine);
                }
                sbTable.AppendFormat("</tr>{0}", NewLine);
                string rowsText = GetRowsText(table, featureCount);
                sbTable.Append(rowsText);

                string tpl = TableTemplate.
                             Replace("{{LAYER_NAME}}", requestLayer).
                             Replace("{{LAYER_TABLE}}", sbTable.ToString());
                sb.AppendFormat("{0}\n{1}\n", tpl, "<br />");
            }


            string html = HtmlTemplate.Replace("{{HTML_BODY}}", sb.ToString());

            return(new GetFeatureInfoResponseHtml(html));
        }
Example #9
0
        public void linq_should_work_with_feature_collections()
        {
            Envelope world = new Envelope(-180, 180, -90, 90);

            ILayer layer = Map.GetLayerByName("poly_landmarks");

            Assert.That(layer, Is.Not.Null);
            Assert.That(layer, Is.InstanceOf <ICanQueryLayer>());

            IFeatureCollectionSet data  = new FeatureCollectionSet();
            ICanQueryLayer        query = (ICanQueryLayer)layer;

            query.ExecuteIntersectionQuery(world, data);

            foreach (IFeatureCollection table in data)
            {
                Assert.That(table, Is.Not.Null);
                Assert.That(table, Is.Not.Empty);
                IList <IFeature> list = table.ToList();
                Assert.That(list, Is.Not.Null);
            }
        }
Example #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)
        {
            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)
                            {
                                SharpMap.Data.FeatureDataSet fds = new SharpMap.Data.FeatureDataSet();
                                queryLayer.ExecuteIntersectionQuery(p.GetBoundingBox(), fds);
                                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");
            }
        }
Example #11
0
        public override void Handle()
        {
            string layers      = this.context.Request.Params["LAYERS"];
            string styles      = this.context.Request.Params["STYLES"];
            string crs         = this.context.Request.Params["CRS"];
            string queryBBOX   = this.context.Request.Params["BBOX"];
            string queryWidth  = this.context.Request.Params["WIDTH"];
            string queryHeight = this.context.Request.Params["HEIGHT"];
            string format      = this.context.Request.Params["FORMAT"];
            string queryLayers = this.context.Request.Params["QUERY_LAYERS"];
            string infoFormat  = this.context.Request.Params["INFO_FORMAT"];
            string xAxis       = this.context.Request.Params["X"];
            string yAxis       = this.context.Request.Params["Y"];
            string iParam      = this.context.Request.Params["I"];
            string jParam      = this.context.Request.Params["J"];

            if (layers == null)
            {
                WmsException.ThrowWmsException("Required parameter LAYERS not specified");
                return;
            }

            if (styles == null)
            {
                WmsException.ThrowWmsException("Required parameter STYLES not specified");
                return;
            }

            if (crs == null)
            {
                WmsException.ThrowWmsException("Required parameter CRS not specified");
                return;
            }

            if (!this.Check(String.Format("EPSG:{0}", this.map.Layers[0].SRID), crs))
            {
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidCRS,
                                               "CRS not supported");
                return;
            }

            if (queryBBOX == null)
            {
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                               "Required parameter BBOX not specified");
                return;
            }

            if (queryWidth == null)
            {
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                               "Required parameter WIDTH not specified");
                return;
            }

            if (queryHeight == null)
            {
                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.InvalidDimensionValue,
                                               "Required parameter HEIGHT not specified");
                return;
            }

            if (format == null)
            {
                WmsException.ThrowWmsException("Required parameter FORMAT not specified");
                return;
            }

            if (queryLayers == null)
            {
                WmsException.ThrowWmsException("Required parameter QUERY_LAYERS not specified");
                return;
            }

            if (infoFormat == 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 1.1.1 services)
            if (xAxis == null && iParam == null)
            {
                WmsException.ThrowWmsException("Required parameter I not specified");
                return;
            }

            if (yAxis == null && jParam == null)
            {
                WmsException.ThrowWmsException("Required parameter J not specified");
                return;
            }

            try
            {
                //sets the map size to the size of the client in order to calculate the coordinates of the projection of the client
                this.map.Size = new Size(Convert.ToInt16(queryWidth), Convert.ToInt16(queryHeight));
            }
            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 = this.ParseBBOX(queryBBOX);

            if (bbox == null)
            {
                WmsException.ThrowWmsException("Invalid parameter BBOX");
                return;
            }

            this.map.ZoomToBox(bbox);
            //sets the point clicked by the client
            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 (xAxis != null)
            {
                try { x = Convert.ToSingle(xAxis); }
                catch { WmsException.ThrowWmsException("Invalid parameters for I"); }
            }
            if (iParam != null)
            {
                try { x = Convert.ToSingle(iParam); }
                catch { WmsException.ThrowWmsException("Invalid parameters for I"); }
            }
            //same procedure for J (Y)
            if (yAxis != null)
            {
                try { y = Convert.ToSingle(yAxis); }
                catch { WmsException.ThrowWmsException("Invalid parameters for J"); }
            }
            if (jParam != null)
            {
                try { y = Convert.ToSingle(jParam); }
                catch { WmsException.ThrowWmsException("Invalid parameters for J"); }
            }

            Point p = this.map.ImageToWorld(new PointF(x, y));
            int   fc;

            try
            {
                fc = Convert.ToInt16(this.context.Request.Params["FEATURE_COUNT"]);
                if (fc < 1)
                {
                    fc = 1;
                }
            }
            catch { fc = 1; }

            String vstr = "GetFeatureInfo results: \n";

            string[] requestLayers = queryLayers.Split(new[] { ',' });
            foreach (string item in requestLayers)
            {
                bool found = false;

                foreach (ILayer mapLayer in this.map.Layers)
                {
                    if (!String.Equals(mapLayer.LayerName, item,
                                       StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    found = true;

                    if (!(mapLayer is ICanQueryLayer))
                    {
                        continue;
                    }

                    ICanQueryLayer layer   = mapLayer as ICanQueryLayer;
                    bool           enabled = layer.Enabled && layer.IsQueryEnabled;
                    if (!enabled)
                    {
                        continue;
                    }

                    Single         queryBoxMinX = x - (this.pixelSensitivity);
                    Single         queryBoxMinY = y - (this.pixelSensitivity);
                    Single         queryBoxMaxX = x + (this.pixelSensitivity);
                    Single         queryBoxMaxY = y + (this.pixelSensitivity);
                    Point          minXY        = this.map.ImageToWorld(new PointF(queryBoxMinX, queryBoxMinY));
                    Point          maxXY        = this.map.ImageToWorld(new PointF(queryBoxMaxX, queryBoxMaxY));
                    BoundingBox    queryBox     = new BoundingBox(minXY, maxXY);
                    FeatureDataSet fds          = new FeatureDataSet();
                    layer.ExecuteIntersectionQuery(queryBox, fds);
                    if (this.intersectDelegate != null)
                    {
                        fds.Tables[0] = this.intersectDelegate(fds.Tables[0], queryBox);
                    }

                    if (fds.Tables.Count != 0)
                    {
                        if (fds.Tables[0].Rows.Count != 0)
                        {
                            //if featurecount < fds...count, select smallest bbox, because most likely to be clicked
                            vstr = String.Format("{0}\n Layer: '{1}'\n Featureinfo:\n", vstr, item);
                            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++)
                            {
                                FeatureDataRow fdr = fds.Tables[0].Rows[l] as 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 = String.Format("{0} '{1}'", vstr, fds.Tables[0].Rows[keys[k]].ItemArray[j].ToString());
                                }
                                if ((k + 1) < fc)
                                {
                                    vstr = String.Format("{0},\n", vstr);
                                }
                            }
                        }
                        else
                        {
                            vstr = String.Format("{0}\nSearch returned no results on layer: {1} ", vstr, item);
                        }
                    }
                    else
                    {
                        vstr = String.Format("{0}\nSearch returned no results on layer: {1}", vstr, item);
                    }
                }
                if (found)
                {
                    continue;
                }

                WmsException.ThrowWmsException(WmsException.WmsExceptionCode.LayerNotDefined,
                                               String.Format("Unknown layer '{0}'", item));
                return;
            }

            this.context.Response.Clear();
            this.context.Response.ContentType = "text/plain";
            this.context.Response.Charset     = "windows-1252";
            this.context.Response.Write(vstr);
            this.context.Response.Flush();
            this.context.Response.End();
        }
Example #12
0
        /// <summary>
        /// Check if the layer can be queried and retrieve data, if there is any.
        /// </summary>
        protected bool TryGetData(Map map,
            float x, float y,
            int pixelSensitivity,
            WmsServer.InterSectDelegate intersectDelegate,
            ICanQueryLayer queryLayer,
            string cqlFilter,
            out IFeatureCollectionSet fds)
        {
            if (!queryLayer.IsQueryEnabled)
            {
                fds = null;
                return false;
            }

            float queryBoxMinX = x - pixelSensitivity;
            float queryBoxMinY = y - pixelSensitivity;
            float queryBoxMaxX = x + pixelSensitivity;
            float queryBoxMaxY = y + pixelSensitivity;

            Coordinate minXY = map.ImageToWorld(new PointF(queryBoxMinX, queryBoxMinY));
            Coordinate maxXY = map.ImageToWorld(new PointF(queryBoxMaxX, queryBoxMaxY));
            Envelope queryBox = new Envelope(minXY, maxXY);

            fds = new FeatureCollectionSet();
            queryLayer.ExecuteIntersectionQuery(queryBox, fds);

            if (fds.Count == 0)
                return false;

            var table = fds[0];
            if (intersectDelegate != null)
            {
                fds.Remove(table);
                fds.Add(intersectDelegate(table, queryBox));
                table = fds[0];
            }

            // filter the rows with the CQLFilter if one is provided
            if (cqlFilter != null)
            {
                var toKeep = table.Clone();
                foreach (var feature in table)
                {
                    if (CqlFilter(feature, cqlFilter))
                        toKeep.Add(feature);
                }
                fds.Remove(table);
                fds.Add(toKeep);
            }

            return fds[0].Count > 0;
        }