Hi,
I have a table with about 25000 rows (features) and I would like to know how I should build the WMS plugin to make sure that each request will only target the feature within the BB of the request? When I do execute a SQL request against my table I have a very good response time but the WMS plug-in is kinda slow and I cannot figure it out yet…
thanks a lot.
jm.
My plugin:
usingSystem;usingSystem.Collections.Generic;usingSystem.Collections.ObjectModel;usingSystem.Drawing;usingSystem.Globalization;usingSystem.IO;usingSystem.Linq;usingSystem.Text;usingSystem.Web;usingThinkGeo.MapSuite.Core;usingThinkGeo.MapSuite.WmsServerEdition;
namespaceWmsPlugin {internalclassAqueductGlobalMapsAvailableBlueWater : WmsLayerPlugin {// This method is only called once per style and crs. In it you should create your// layers and add them to the MapConfiguration. If you want to use tile caching you// can also specif that in the MapConfiguration under the TileCache property.// If you have setup multiple styles or projections this method will get called for// each unique combination
privateconststringPlugName ="AqueductGlobalMapsAvailableBlueWater";privateconststringAqueductGlobalMapsPath = @"K:\AqueductGlobalMaps\global_dl_20130620.shp";privateconststringWorldLayerFilePath = @"K:\DEPLOYMENT_SPHMCT\World\Human\cntry02.shp";privateconststringFileRoot = @"R:\AqueductGlobalMaps" + PlugName + @"";privateconststringBoundinboxFilePath = FileRoot +"BoundingBox.bin";privateconststringOutputShapeFilePath = FileRoot + PlugName +".shp";privateconstNumberStyles Styles = NumberStyles.AllowExponent | NumberStyles.Number;
protectedoverrideMapConfiguration GetMapConfigurationCore(stringstyle,stringcrs) {var mapconf =newMapConfiguration();var bitmapTileCache =newFileBitmapTileCache {CacheDirectory = @"R:\Cache"+ PlugName, CacheId = PlugName};mapconf.TileCache = bitmapTileCache;mapconf.TileCache.ImageFormat = TileImageFormat.Png;
var backgroundLayer =newBackgroundLayer(newGeoSolidBrush(GeoColor.SimpleColors.White));var worldLayer =newShapeFileFeatureLayer(WorldLayerFilePath, ShapeFileReadWriteMode.ReadOnly);
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle =AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Transparent,GeoColor.StandardColors.LightGray, 1);worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;worldLayer.DrawingQuality = DrawingQuality.HighQuality;
try{
if(!Directory.Exists(FileRoot)) {Directory.CreateDirectory(FileRoot);}
MsSql2008FeatureLayer inputShapeFile = BuildSqlOverlay("sql",@"data source=DEVSQL14\DEV2;initial catalog=DUSGEODATA;User Id=*****;Password=*****;Packet Size=16384;multipleactiveresultsets=True;connect timeout=120;App=EntityFramework","dbo.AqueductGlobalMapsAvailableBlueWater","geomFixed");
#region Create Styles
Collection<GeoColor> colorsInQualityFamily =GeoColor.GetColorsInHueFamily(GeoColor.FromArgb(255, GeoColor.SimpleColors.LightBlue), 16);
var classBreakStyle =newClassBreakStyle("styleValue") {BreakValueInclusion = BreakValueInclusion.IncludeValue};
classBreakStyle.ClassBreaks.Add(newClassBreak(0.0D, AreaStyles.NoData1));
classBreakStyle.ClassBreaks.Add(newClassBreak(1.0D,newAreaStyle {FillSolidBrush =newGeoSolidBrush(colorsInQualityFamily[0]),OutlinePen =newGeoPen(GeoColor.StandardColors.LightGray, 1)}));classBreakStyle.ClassBreaks.Add(newClassBreak(2.0D,newAreaStyle {FillSolidBrush =newGeoSolidBrush(colorsInQualityFamily[3]),OutlinePen =newGeoPen(GeoColor.StandardColors.LightGray, 1)}));classBreakStyle.ClassBreaks.Add(newClassBreak(3.0D,newAreaStyle {FillSolidBrush =newGeoSolidBrush(colorsInQualityFamily[6]),OutlinePen =newGeoPen(GeoColor.StandardColors.LightGray, 1)}));classBreakStyle.ClassBreaks.Add(newClassBreak(4.0D,newAreaStyle {FillSolidBrush =newGeoSolidBrush(colorsInQualityFamily[12]),OutlinePen =newGeoPen(GeoColor.StandardColors.LightGray, 1)}));classBreakStyle.ClassBreaks.Add(newClassBreak(5.0D,newAreaStyle {FillSolidBrush =newGeoSolidBrush(colorsInQualityFamily[15]),OutlinePen =newGeoPen(GeoColor.StandardColors.LightGray, 1)}));
classBreakStyle.ClassBreaks.Add(newClassBreak(6.0D, AreaStyles.NoData1));
#endregion
#region Apply Style to shape file
inputShapeFile.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(LineStyles.CreateSimpleLineStyle(GeoColor.StandardColors.LightGray, 1, LineDashStyle.Solid,false));inputShapeFile.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(PointStyles.CreateSimplePointStyle(PointSymbolType.Square, GeoColor.SimpleColors.Black,GeoColor.SimpleColors.Black, 1, 10));inputShapeFile.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(classBreakStyle);inputShapeFile.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
#endregion
mapconf.Layers.Add("BackgroundLayer", backgroundLayer);mapconf.Layers.Add("WorldLayer", worldLayer);mapconf.Layers.Add(PlugName, inputShapeFile);}catch(Exception ex) {Trace("Exception", ex.Message);Trace("StackTrace", ex.StackTrace.ToString(CultureInfo.InvariantCulture));Trace("Source", ex.Source.ToString(CultureInfo.InvariantCulture));}
BrowerCacheExpiration =newTimeSpan(0, 0, 0);WmsQueryMode = WmsQueryMode.Queryable;
returnmapconf;}
// This method gets called on every amp request sent to the server. In the parameters we pass the// map request which includes the bounding box, image size etc. We also pass you the map configuration// which includes all the static layers. In this method you can make any data changes or do anything// dynamic you wantprotectedoverrideBitmap GetMapCore(GetMapRequest getMapRequest, MapConfiguration mapConfiguration,HttpContext context) {context.Response.Cache.SetCacheability(HttpCacheability.Public);context.Response.Expires = 1440*1000;returnbase.GetMapCore(getMapRequest, mapConfiguration, context);}
// In this method you need to return the name of the Layer that WMS will expose.// You will use this name on the client to specify the layer you want to consumeprotectedoverridestringGetNameCore() {returnPlugName;}
protectedoverrideGeographyUnit GetGeographyUnitCore(stringcrs) {constGeographyUnit geographyUnit = GeographyUnit.Meter;returngeographyUnit;}
// In this method you need to return the projections that are supported by your data.// It is your responsability to project the data in the MapConfiguration for each projection// type you specify here.protectedoverrideCollection<string> GetProjectionsCore() {var projections =newCollection<string> {"EPSG:900913"};returnprojections;}
// In this method you need to return the bounding box of the layer.protectedoverrideRectangleShape GetBoundingBoxCore(stringcrs) {var bb =newFeature("POLYGON((-20037397.9519 18429147.1567,-20037397.9519 -7540091.4503,20037507.0672 -7540091.4503,20037507.0672 18429147.1567,-20037397.9519 18429147.1567))");return(bb.GetShape().GetBoundingBox());}
privatestaticvoidTrace(stringf,stringm) {using(var writer =newBinaryWriter(File.Open(FileRoot + f +".dat",FileMode.Create))) {writer.Write(m);}}
privateMsSql2008FeatureLayer BuildSqlOverlay(stringfeatureLayerName,stringconnectionstring,stringtableName,stringcolumnName) {var inMemoryFeatureLayer =newMsSql2008FeatureLayer {Name = featureLayerName,ConnectionString = connectionstring,TableName = tableName,CustomGeometryColumnName = columnName,DatabaseConnectionMode = DatabaseConnectionMode.KeepOpen,Srid = 900913,DrawingQuality = DrawingQuality.HighQuality,FeatureIdColumn ="Id"//WhereClause = "where Id <= 4115"};return(inMemoryFeatureLayer);}}}