 <?xml-stylesheet type="text/css" href="https://www.esdm.co.uk/Data/style/rss1.css" ?> <?xml-stylesheet type="text/xsl" href="https://www.esdm.co.uk/Data/style/rss1.xsl" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
  <channel>
    <title>The knowledge base blog</title>
    <link>https://www.esdm.co.uk/knowledge</link>
    <description />
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>mojoPortal Blog Module</generator>
    <language>en-GB</language>
    <ttl>120</ttl>
    <atom:link href="https://www.esdm.co.uk/Blog/RSS.aspx?p=138~108~9" rel="self" type="application/rss+xml" />
    <itunes:owner />
    <itunes:explicit>no</itunes:explicit>
    <item>
      <title>When MapServer refuses to run in an ASP.NET Core MVC site (401 - unauthorized)</title>
      <description><![CDATA[<p>Well that was two hours I won’t get back, but I’ll make a note here in case it helps anyone else. I had simply overlooked one of those many tiny things…</p><p>We use MapServer as a lightweight GIS engine in many of our products, giving us WMS/WFS API endpoints for a wide range of purposes. When upgrading the <a href="https://colchesterheritage.co.uk" target="_blank">Colchester Heritage Explorer website</a>, an ASP.NET Core MVC site made with <a href="https://www.cloudscribe.com" target="_blank">cloudscribe</a> and <a href="https://hbsmrdocumentation.esdm.co.uk/hbsmr-webapi" target="_blank">HBSMR WEB/API</a> components, I dived in to configure and test the MapServer instance. I followed our usual processes, enabled the CGI extension to execute, setting folder permissions to allow MapServer to write out log files, configured our secure MapServer Proxy component, etc. </p><p>But it wasn’t working. </p><p>One of our first tests of a MapServer instance is to browse to the location of the main MapServer executable, in this case the address was:</p><p>https://colchesterheritage.co.uk/wwwroot/MapServer/Scripts/mapserv.exe </p><p>but instead of a nice diagnostic response, I got “401 – Unauthorized: Access is denied due to invalid credentials”:</p><p><img width="640" height="116" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_160.png" border="0"></p><p>This was very puzzling, as I already had this working perfectly in a parallel test site, on the same server with identical configuration in every respect – or so I thought. Both sites were using an application pool with Identity set to ApplicationPoolIdentity, folder permissions were all good for this identity, there were no ip restrictions, and no reason I could see for it not to work.</p><p>Except that I’d forgotten about the Anonymous Authentication Credentials… in IIS select the site &gt; Authentication &gt; select Anonymous Authentication and click “Edit…” &gt; I found the default setting:</p><p><img width="640" height="328" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_161.png" border="0"></p><p>And of course I had not set up permissions for this user to access the location of the MapServer files. So there are two solutions: a) <em>less preferred</em>: add the IUSR account at the root of site with default permissions:</p><p><img width="378" height="457" title="image" style="margin: 0px; border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_162.png" border="0"></p><p>(if I were using this solution I would also tick “Deny” for the “Write” setting off bottom of that image);</p><p>or b) <em>preferred</em>: change the Anonymous Authentication Credentials for the site to the Application pool identity:</p><p><img width="640" height="330" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_163.png" border="0"></p><p>After making this change, on browsing to our MapServer executable I saw the expected response “Noquery information to decode. QUERY_STRING is set, but empty. ” which means the CGI application is working. </p><p><strong>Phew – problem solved!</strong></p><p>My next step in hardening this site is to block this direct access, and route all requests through a secured proxy, so the above URL to the exe won’t work by the time you read this if we’ve done our security right.</p><p>To see the working result, check out the maps within the <a href="https://colchesterheritage.co.uk" target="_blank">Colchester Heritage Explorer</a>, for example this map of the historic buildings and sites that are <a href="https://colchesterheritage.co.uk/map?center=100120.11461153519,6780076.084676751&amp;zoom=16&amp;baselayer=OpenStreetMap&amp;opacity=1&amp;panel=overlays&amp;overlays=LocalList&amp;overlaysoff=RegisteredParksAndGardens,ConservationAreas,ListedBuildings,ScheduledMonuments,Events,Monuments" target="_blank">included on the Colchester “Local List”</a>.</p><p>And here’s a rather nice map of WW2 pillboxes and related defensive sites around Colchester, generated by a MapServer WFS request in response to a <a href="https://colchesterheritage.co.uk/globalsearch/index?q=pillboxes" target="_blank">a free text search on “pillboxes”</a>:</p><p><img width="559" height="480" title="image" style="border: 0px currentcolor; border-image: none; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_164.png" border="0"></p><p>I hope this helps someone, and please feel free to add comments below.</p><br /><a href='https://www.esdm.co.uk/when-mapserver-refuses-to-run-in-an-aspnet-core-mvc-site-401-unauthorized'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/when-mapserver-refuses-to-run-in-an-aspnet-core-mvc-site-401-unauthorized'>...</a>]]></description>
      <link>https://www.esdm.co.uk/when-mapserver-refuses-to-run-in-an-aspnet-core-mvc-site-401-unauthorized</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/when-mapserver-refuses-to-run-in-an-aspnet-core-mvc-site-401-unauthorized</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/when-mapserver-refuses-to-run-in-an-aspnet-core-mvc-site-401-unauthorized</guid>
      <pubDate>Sat, 19 Oct 2019 10:55:24 GMT</pubDate>
    </item>
    <item>
      <title>Mapserver returning WFS attributes scrambled when using msplugin_mssql2008 plugin</title>
      <description><![CDATA[<p>We recently upgraded Mapserver to the current version for a project because we wanted the WFS id field to be populated in geojson which required a recent version of (OGR &gt;=2.3) which was included in mapserver build 7.2.1</p><p>All went well and we modified the mapserver geojson output format to specify the field we wanted to use (originally named id in our case) but adding in the line: FORMATOPTION "LCO:ID_FIELD=id"</p><blockquote><p>OUTPUTFORMAT<br>&nbsp;&nbsp; NAME "geojson"<br>&nbsp;&nbsp; DRIVER "OGR/GEOJSON"<br>&nbsp;&nbsp; MIMETYPE "application/json; subtype=geojson"<br>&nbsp;&nbsp; FORMATOPTION "STORAGE=stream"<br>&nbsp;&nbsp; FORMATOPTION "FORM=SIMPLE"<br>&nbsp;&nbsp; FORMATOPTION "LCO:COORDINATE_PRECISION=0"<br>&nbsp;&nbsp; FORMATOPTION "LCO:ID_FIELD=id"<br>
END</p></blockquote><p>The field “id” needed to be included in the relevant map layer in the gml_include_items e.g.:</p><blockquote><p> "gml_include_items"&nbsp;&nbsp;&nbsp;&nbsp; "name,recsubtype,recsubtypecode,rectype,ref,uid,id"</p></blockquote><p>After those changes – all seemed to be going well and the id was appearing in our WFS return</p><p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_151.png"><img width="244" height="52" title="image" style="margin: 0px; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_122.png" border="0"></a></p><p>However when we looked at some of the other attributes we noticed scrambled characters (these had been fine with the previous version of mapserver). e.g. rectype in screenshot below</p><p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_152.png"><img width="244" height="57" title="image" style="margin: 0px; display: inline; background-image: none;" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_123.png" border="0"></a></p><p>Our data was coming from SQL server using the msplugin_mssql2008 plugin– and if we set debug in the mapserver layer and looked at the log we saw:</p><blockquote><p><em>msConvertWideStringToUTF8(): General error message. Unable to convert string in encoding 'UCS-2LE' to UTF8 An invalid multibyte sequence has been encountered in the input</em></p></blockquote><p>So it looked as it something was going wrong in the unicode translation.&nbsp; The workaround was refreshingly simple – we just had to alter the view that the data was being pulled from to force the conversion e.g. change:</p><blockquote><p>‘Site’</p><p>to:</p><p>CONVERT(nvarchar(1),N’Site’)</p></blockquote><p>then all was well again.</p><br /><a href='https://www.esdm.co.uk/mapserver-returning-wfs-attributes-scrambled-when-using-msplugin_mssql2008-plugin'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/mapserver-returning-wfs-attributes-scrambled-when-using-msplugin_mssql2008-plugin'>...</a>]]></description>
      <link>https://www.esdm.co.uk/mapserver-returning-wfs-attributes-scrambled-when-using-msplugin_mssql2008-plugin</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/mapserver-returning-wfs-attributes-scrambled-when-using-msplugin_mssql2008-plugin</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/mapserver-returning-wfs-attributes-scrambled-when-using-msplugin_mssql2008-plugin</guid>
      <pubDate>Thu, 21 Feb 2019 12:54:32 GMT</pubDate>
    </item>
    <item>
      <title>How to hide the MapServer map file location on IIS (without writing any code)</title>
      <description><![CDATA[<p>We posted some notes a few days ago on <a href="https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows" target="_blank">how to set up MapServer WMS/WFS server on IIS</a>. Someone called Dennis has commented appreciatively, but asked how to hide the location of the .map file and <a href="http://mapserver.org/ogc/wms_server.html#changing-the-online-resource-url" target="_blank">create a cleaner URL with a cgi-wrapper, as described in the MapServer documentation</a>. Well that documentation page does tell you how to do it on IIS, with ASP script, but here’s a much simpler way that requires no hacking.</p>

<p>Aside: I should say that what follows is not what we normally do in our real applications – we usually use ASP.Net .ashx handlers to relay requests through the root of our web sites, which also helps to avoid cross-domain problems with GetFeatureInfo responses and WFS, but that’s another story! This post is in reaction to Dennis’s request for help, and because I wanted to check this approach is viable.</p>

<p>I’ve posted before on <a href="https://www.esdm.co.uk/presenting-geoserver-on-port-80-on-a-windows-iis-server" target="_blank">how to use URL Rewrite to give GeoServer a friendly URL on IIS</a>, and we’re going to use the same technique here, so first ensure you have the necessaries installed.</p>

<p>You should also already have a working WMS/WFS – we created this one in the previous post:</p>

<p><a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map" title="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map</a></p>

<p>which was fine, but a) the URL reveals some information about the structures on the web server, and b) the URL is a bit ugly.</p>

<p>So decide what address you want for your MapServer service (remembering this will be specific right down to the map file). I’m using “mapservertestwrapper.esdm.co.uk” which I have pointed at the web server in question.</p>

<p>Create a new web site in IIS with this URL as a host header (you’ll first need to create an empty “physical” folder for the site to point at – add a readme.config file explaining what it’s for).</p>

<p>Now open URL Rewrite and create a reverse proxy inbound rule, entering the real service address as the forwarding address:</p>

<p><img alt="Creating the reverse proxy inbound rule" border="0" height="480" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_97.png" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Creating the reverse proxy inbound rule" width="476" /></p>

<p>OK now we should be able to see our MapServer on the new URL. However, when we visit <a href="http://mapservertestwrapper.esdm.co.uk/" title="http://mapservertestwrapper.esdm.co.uk/">http://mapservertestwrapper.esdm.co.uk/</a> we get this feedback in the browser:</p>

<p>msLoadMap(): Regular expression error. MS_DEFAULT_MAPFILE_PATTERN validation failed. msEvalRegex(): Regular expression error. String failed expression test.</p>

<p>The fix is to re-edit the inbound rule, and remove the final “/” in the “rewrite URL”, going from:</p>

<p>http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map/{R:1}</p>

<p>to:</p>

<p>http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map{R:1}</p>

<p>Now we should get sensible MapServer feedback in the browser (conditioned by a template specified in the map file).</p>

<p>Now let’s see if we can do a GetCapabilities request… turns out our URL has to be this:</p>

<p><a href="http://mapservertestwrapper.esdm.co.uk/?service=wms&amp;version=1.3.0&amp;request=getcapabilities" title="http://mapservertestwrapper.esdm.co.uk/?service=wms&amp;version=1.3.0&amp;request=getcapabilities">http://mapservertestwrapper.esdm.co.uk/?service=wms&amp;version=1.3.0&amp;request=getcapabilities</a></p>

<p>Yes it works, but a) that’s a slightly odd URL with “/?”, and b) the response contains the original service addresses, again revealing information about our server.</p>

<p>To fix a), we go back and edit our inbound rule again, and change the “pattern” from “(.*)” to “map1(.*)” (without the quotes of course). Now our service URL becomes:</p>

<p><a href="http://mapservertestwrapper.esdm.co.uk/map1?service=wms&amp;version=1.3.0&amp;request=getcapabilities" title="http://mapservertestwrapper.esdm.co.uk/map1?service=wms&amp;version=1.3.0&amp;request=getcapabilities">http://mapservertestwrapper.esdm.co.uk/map1?service=wms&amp;version=1.3.0&amp;request=getcapabilities</a></p>

<p>Ah yes that’s much nicer, and now of course we see we can manage lots of .map files within one web site simply by setting up in inbound rule for each, with an appropriate pattern and target.</p>

<p>To fix b) we can edit the metadata in the .map file to set this:</p>

<p>"wms_onlineresource"&nbsp;&nbsp;&nbsp; "http://mapservertestwrapper.esdm.co.uk/map1"</p>

<p>This works fine, returning this within the GetCapabilities:</p>

<p><a>&lt;OnlineResource xlink:href="http://mapservertestwrapper.esdm.co.uk/map1?" xmlns:xlink="http://www.w3.org/1999/xlink"/&gt;</a></p>

<p>And I can confirm this creates a working map in QGIS, with map requests like this <a href="https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler" target="_blank">visible in Fiddler</a>:</p>

<p><a href="http://mapservertestwrapper.esdm.co.uk/map1?SERVICE=WMS&amp;VERSION=1.3.0&amp;REQUEST=GetMap&amp;BBOX=52801.44371538766426966,3347.3560407145996578,657116.82161524775438011,428145.51874091033823788&amp;CRS=EPSG:27700&amp;WIDTH=1020&amp;HEIGHT=717&amp;LAYERS=grid&amp;STYLES=&amp;FORMAT=image/png&amp;DPI=96&amp;MAP_RESOLUTION=96&amp;FORMAT_OPTIONS=dpi:96&amp;TRANSPARENT=TRUE" title="http://mapservertestwrapper.esdm.co.uk/map1?SERVICE=WMS&amp;VERSION=1.3.0&amp;REQUEST=GetMap&amp;BBOX=52801.44371538766426966,3347.3560407145996578,657116.82161524775438011,428145.51874091033823788&amp;CRS=EPSG:27700&amp;WIDTH=1020&amp;HEIGHT=717&amp;LAYERS=grid&amp;STYLES=&amp;FORMAT=image/png&amp;DPI=96&amp;MAP_RESOLUTION=96&amp;FORMAT_OPTIONS=dpi:96&amp;TRANSPARENT=TRUE&#10;">http://mapservertestwrapper.esdm.co.uk/map1?SERVICE=WMS&amp;VERSION=1.3.0&amp;REQUEST=GetMap&amp;BBOX=52801.44371538766426966,3347.3560407145996578,657116.82161524775438011,428145.51874091033823788&amp;CRS=EPSG:27700&amp;WIDTH=1020&amp;HEIGHT=717&amp;LAYERS=grid&amp;STYLES=&amp;FORMAT=image/png&amp;DPI=96&amp;MAP_RESOLUTION=96&amp;FORMAT_OPTIONS=dpi:96&amp;TRANSPARENT=TRUE</a></p>

<p><img alt="image" border="0" height="426" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_98.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" width="640" /></p>

<p>And a quick test shows that info clicking (GetFeatureInfo) and legends work too:</p>

<p>e.g. <a href="http://mapservertestwrapper.esdm.co.uk/map1?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=grid&amp;format=image/png&amp;STYLE=default" title="http://mapservertestwrapper.esdm.co.uk/map1?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=grid&amp;format=image/png&amp;STYLE=default">http://mapservertestwrapper.esdm.co.uk/map1?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=grid&amp;format=image/png&amp;STYLE=default</a></p>

<p>gives this:</p>

<p><img alt="GetLegendGraphic image" src="http://mapservertestwrapper.esdm.co.uk/map1?version=1.3.0&amp;service=WMS&amp;request=GetLegendGraphic&amp;sld_version=1.1.0&amp;layer=grid&amp;format=image/png&amp;STYLE=default" title="GetLegendGraphic image" /></p>

<p>There you go Dennis, we have working OGC services from MapServer with nice clean URLs, a simple architecture for adding new services with their own map files, and no leaking of details about our directory structures.</p>

<p>&nbsp;</p>

<h3>Footnote…</h3>

<p>I’m not completely keen on the last bit, having to change the wms_onlineresource, as this means the original service is now broken (depending on whether the mapping client makes us of this, which QGIS likes to). Another way <em>should be</em>&nbsp; to create an outbound URL Rewrite rule to rewrite any references to the original URL with the new one. However, after a bit of pfaffing with this, I’m pretty sure there’s a bug in URL Rewrite that means outbound rewriting doesn’t work for attributes containing colons, and ours is “xlink:href”. Incidentally setting up the outbound rules for custom tags is a bit of an adventure through the UI, and there is a bit of escaping to do for the backslashes and question mark in the URL (<font style="background-color: rgb(255, 255, 0);">highlighted</font> below) as URL Rewrite is doing regular expressions so you might as well get down and dirty in the web.config located in the “dummy” folder we created for the new web site we created earlier. So this is my outbound rule that <em>doesn’t work,</em> but should when someone fixes the bug!</p>

<p><font face="Courier New">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;configuration&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;system.webServer&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;rewrite&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;rules&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;rule name="ReverseProxyInboundRule2" stopProcessing="true"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;match url="map1(.*)" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action type="Rewrite" url="</font><a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map{R:1}&quot;"><font face="Courier New">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map{R:1}"</font></a><font face="Courier New"> /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/rules&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;outboundRules&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsXML" enabled="true"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;match filterByTags="CustomTags" customTags="OGC GetCapabilities" pattern="^http(s)?://mapservertest.esdm.co.uk/scripts/mapserv.exe<font style="background-color: rgb(255, 255, 0);">\?map=D:\\Websites\\mapservertest\\map\\</font>mapfiletest.map(.*)" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;action type="Rewrite" value="http{R:1}://mapservertestwrapper.esdm.co.uk/map1{R:2}" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/rule&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;preConditions&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;preCondition name="ResponseIsHtml1"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/preCondition&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;preCondition name="ResponseIsXML"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/xml" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/preCondition&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/preConditions&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;customTags&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tags name="OGC GetCapabilities"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;tag name="OnlineResource" attribute="<font style="background-color: rgb(255, 0, 0);">xlink:href</font>" /&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/tags&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/customTags&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/outboundRules&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/rewrite&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/system.webServer&gt;<br />
&lt;/configuration&gt;</font></p>

<p>&nbsp;</p>

<p>The <font style="background-color: rgb(255, 0, 0);">red bit</font> is the bit affected by the bug I think, unless someone can point out how this should be escaped/expressed to make it work?</p>
<br /><a href='https://www.esdm.co.uk/how-to-hide-the-mapserver-map-file-location-on-iis'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-hide-the-mapserver-map-file-location-on-iis'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-hide-the-mapserver-map-file-location-on-iis</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-hide-the-mapserver-map-file-location-on-iis</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-hide-the-mapserver-map-file-location-on-iis</guid>
      <pubDate>Sat, 12 Apr 2014 11:29:00 GMT</pubDate>
    </item>
    <item>
      <title>How to install the latest version of Mapserver as a Windows CGI application</title>
      <description><![CDATA[<p>This is intended to be a simple guide to producing a working MapServer CGI installation on Windows and IIS, suitable for serving up Web Mapping Services (WMS) or Web Feature Services (WFS), from the available MapServer download packages. It has been written by James and Crispin bringing together our collective experiences, but it is not guaranteed to be 100% fool proof! Please feel free to add any extra tips as comments below.</p>

<p><span style="display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: &quot;Open Sans&quot;,sans-serif; font-size: 19px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">{See notes below for additional/modified steps for MapServer 8 vs MapServer 7.</span><span style="display: inline !important; float: none; background-color: transparent; color: rgb(51, 51, 51); font-family: &quot;Open Sans&quot;,sans-serif; font-size: 19px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">}</span></p>

<p>We tend to structure our MapServer instance as a \MapServer folder with four or five subfolders. One of these is a "scripts" folder, where we put all the executables and dlls plus their essential reference files.</p>

<h3>Creating the \scripts folder</h3>

<p>The best source for current builds has the files structured for ease of compilation not deployment, containing everything and the kitchen sink, and also requiring PATH variables to be set. Normally we don't need all the files in the downloads, plus we don't like setting environment variables as we usually run multiple instances of MapServer on the same web server, so here is how to assemble the required files into one folder that will run without any.</p>

<ul>
	<li>Go to <a href="http://www.gisinternals.com/sdk/" title="http://www.gisinternals.com/sdk/">http://www.gisinternals.com/sdk/</a>&nbsp;</li>
	<li>If you want the latest stable build (which you probably do) go to the section named “GDAL and MapServer latest release versions:” and download MSVC2022 (x64) –release (currently <a href="https://www.gisinternals.com/query.html?content=filelist&amp;file=release-1930-x64-gdal-3-9-1-mapserver-8-2-0.zip">release-1930-x64-gdal-3-9-1-mapserver-8-2-0</a>)&nbsp;</li>
	<li>When you click on the link you will get a list of options – you want the top one "Compiled binaries in a single .zip package" e.g.&nbsp; <a href="https://download.gisinternals.com/sdk/downloads/release-1930-x64-gdal-3-9-1-mapserver-8-2-0.zip">release-1930-x64-gdal-3-9-1-mapserver-8-2-0.zip</a> – this is about 25MB.</li>
	<li>There are additional installers on the same page if you need to use some of the specific third party proprietary file formats (e.g. FileGDB, MrSID etc) but you can come back and get these once you have map server up and running</li>
</ul>

<p>Once you have downloaded unzip the file into a temporary folder.&nbsp; You will see a directory structure within the \bin folder like:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_91.png"><img alt="image" border="0" height="100" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_73.png" style="border-width: 0px; margin: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" width="244" /></a></p>

<p>We are looking to extract all the relevant files into a new scripts folder which we can reference from IIS – so create yourself a scripts folder wherever you want it.&nbsp; Then copy:</p>

<ol>
	<li>All the files (not folders) from root of ~\bin\</li>
	<li>mapserv.exe from C~\bin\ms\apps (Note: there are other utilities in here you might want to use – e.g. legend, shp2img etc – but these are not normally needed for a standard web install)</li>
	<li>If you are using mapscript to communicate with mapserver (not normally needed if using CGI mapserver for WMS service etc) – you also need mapscript.dll and mapscript_csharp.dll from ~\bin\ms\csharp</li>
	<li>If referencing SQL server 2008 spatial data – copy the&nbsp; ~\bin\ms\plugins\mssql2008 folder to your scripts folder (~\scripts\mssql2008 ).</li>
	<li>Create a folder called ~\proj&nbsp;and copy the contents of ~\bin\proj9\share folder into it. Remember to reference this path from your config file (Mapserver 8) or map file.</li>
	<li>Copy the contents of ~\bin\gdal\plugins into a new folder ~\scripts\gdalplugins. {Note @ 04th April 2018 remove these two files if you do not have Oracle installed:&nbsp;gdal_GEOR.dll and&nbsp;ogr_OCI.dll }.</li>
	<li>Copy the contents of ~\bin\gdal-data to your scripts folder <em>(I suspect you can place this elsewhere – but then you probably have to set path variables).</em></li>
</ol>

<p>You should end up with something looking like:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_92.png"><img alt="image" border="0" height="98" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_74.png" style="border-width: 0px; margin: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="image" width="244" /></a></p>

<h3>Getting it working in IIS</h3>

<p>MapServer can run as a web site or as a virtual directory within another web site.</p>

<ol>
	<li>Once the web site or virtual directory has been created, with its folder path pointing at the MapServer folder, open the "Handler Mappings" for the \scripts subfolder, then click "Edit Feature Permissions..." and switch on "Script" and "Execute". The MapServer folder, plus the other subfolders should have “Read”, “Script” and “Execute” disabled.</li>
	<li>For MapServer 8, add a FastCGI handler for Mapserver by creating a web.config file in the \scripts subfolder and pasting in:
	<pre id="codecell5">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;configuration&gt;
    &lt;system.webServer&gt;
        &lt;handlers&gt;
            &lt;add name="MapServerFastCgi" path="*" verb="*" type="" modules="FastCgiModule" scriptProcessor="C:\Mapserver\bin\mapserv.exe"
            resourceType="Unspecified" requireAccess="Script" allowPathInfo="true" preCondition=""  /&gt;
        &lt;/handlers&gt;
        &lt;caching enabled="true" enableKernelCache="true" /&gt;
    &lt;/system.webServer&gt;
&lt;/configuration&gt;</pre>
	</li>
	<li>Permit the MapServer executable (mapserv.exe) to run as a CGI application. In IIS 10.0, select the web server root node, then double-click "ISAPI and CGI Restrictions", then Add... Browse to mapserv.exe, give it the appropriate name, and tick "allow extension path to execute".<br />
	<img alt="MapServer CGI web service extension" border="0" height="205" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_93.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="MapServer CGI web service extension" width="360" /></li>
	<li>Create a \Mapserver\tmp folder, and set its permissions to give the anonymous web site user account Modify rights. We configure our map files to write logging information and output temporary images into this folder.</li>
	<li>Create a \MapServer\map folder to contain the *.map file(s).</li>
	<li>We create a \MapServer\data folder for any local datasets (other than database connections).</li>
	<li>For MapServer 8, create a mapserver.conf file in the \Mapserver folder and paste in:
	<pre id="codecell5">
	#
        # Sample MapServer 8.0 Config File
	#

	CONFIG

	&nbsp; #
&nbsp;         # Environment variables
	&nbsp; #

	&nbsp; ENV

	&nbsp; &nbsp; #
	&nbsp; &nbsp; # Limit Mapfile Access
	&nbsp; &nbsp; #

	&nbsp; &nbsp; MS_MAP_NO_PATH "1"
	&nbsp; &nbsp; # MS_MAP_PATTERN "^/opt/mapserver" ## required when referencing mapfiles by path
	&nbsp; &nbsp; # MS_MAP_BAD_PATTERN "[/\\]{2}|[/\\]?\\.+[/\\]|,"

	&nbsp; &nbsp; #
	&nbsp; &nbsp; # Global Log/Debug Setup
	&nbsp; &nbsp; #

	&nbsp; &nbsp; # MS_DEBUGLEVEL "5"
	&nbsp; &nbsp; # MS_ERRORFILE "/opt/mapserver/logs/mapserver.log"

	&nbsp; &nbsp; #
	&nbsp; &nbsp; # Proj Library
	&nbsp; &nbsp; #

	&nbsp; &nbsp; PROJ_LIB "[FolderPath]/proj"

	&nbsp; &nbsp; #
	&nbsp; &nbsp; # Default Map
	&nbsp; &nbsp; #

	&nbsp; &nbsp; # MS_MAPFILE "/opt/mapserver/test/test.map"
	
	&nbsp; &nbsp; # disable POST requests (allowed by default, any value will do)
	&nbsp; &nbsp; # MS_NO_POST "1"

	&nbsp; &nbsp; #
	&nbsp; &nbsp; # Other Options
	&nbsp; &nbsp; #

	&nbsp; &nbsp; # MS_ENCRYPTION_KEY "/opt/mapserver/mykey.txt"
	&nbsp; &nbsp; # MS_USE_GLOBAL_FT_CACHE 1 # use a global font cache
	&nbsp; &nbsp; # MS_PDF_CREATION_DATE "01/02/2022" # PDF create date metadata
	&nbsp; &nbsp; # MS_MAPFILE_PATTERN "\.map$"
	&nbsp; &nbsp; # MS_XMLMAPFILE_XSLT "/path/to/mapfile.xsl"
	&nbsp; &nbsp; # MS_MODE "BROWSE" # default mode for CGI calls
	&nbsp; &nbsp; # MS_OPENLAYERS_JS_URL "http://openlayers.org/api/OpenLayers.js"

	&nbsp; &nbsp; MS_TEMPPATH "[FolderPath]/tmp"

	&nbsp; &nbsp; # MS_MAX_OPEN_FILES 200 # maximum number of open files allowed on Windows

	&nbsp; END


	&nbsp; #
	&nbsp; # Map aliases
	&nbsp; #

	&nbsp; MAPS
	&nbsp; &nbsp; "[MapFileName]" "[FolderPath]/map/[MapFile].map"
	&nbsp; END

END	&nbsp;&nbsp;&nbsp;
</pre>
	</li>
	<li>For MapServer 8, edit the default config to:
	<ol>
		<li>Replace [FolderPath] with the path to the \Mapserver folder</li>
		<li>Replace [MapFileName] with the map name to appear in the URL. <strong>NB. This must be in double quotes</strong></li>
		<li>Replace [MapFile] with the name of the .map file in the \MapServer\map folder</li>
		<li>Add additional map files to MAPS if required e.g. Staging / Production</li>
	</ol>
	</li>
	<li>For MapServer 8, go to the IIS root and open FastCGI Settings,&nbsp;then&nbsp;click Add Application. Enter the full path, then click on "Environment Variables" and click on the "..." button. Click Add. In the properties box on the right, enter Name as <strong>MAPSERVER_CONFIG_FILE</strong>&nbsp;and value as the full path to \Mapserver\mapserver.conf</li>
	<li><img alt="" src="data:image/png;base64,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" /></li>
	<li>It should now be possible to browser to mapserv.exe e.g. <a href="http://mywebsite.com/scripts/mapserv.exe">http://mywebsite.com/scripts/mapserv.exe</a> If the CGI/FastCGI is configured correctly you will see this output in the browser: “No query information to decode. QUERY_STRING is set, but empty. ”.</li>
</ol>

<h3>Creating a map file</h3>

<p>Now we have a working installation of MapServer, but it won’t do anything useful until we have created a map file. This is not the place for a map file tutorial – it’s a massive topic and there is ample documentation here <a href="http://mapserver.org/documentation.html#mapfile" title="http://mapserver.org/documentation.html#mapfile">http://mapserver.org/documentation.html#mapfile</a></p>

<p>However it can be a little daunting getting started, so here’s a simple example that creates a WMS for a simple polygon shapefile – a grid of the 1:10,000 map sheet tiles covering England and Wales, with a single attribute [location] which contains the path to an Ordnance Survey raster image file. So we create this text file: "D:\websites\MapServerTest\map\mapfiletest.map" containing:</p>

<p><font face="Courier New">MAP<br />
NAME TEST<br />
EXTENT 0 0 800000 1300000<br />
UNITS METERS<br />
SHAPEPATH "D:\websites\MapServerTest\data"</font></p>

<p><font face="Courier New">#PROJ_LIB Not needed for MapServer 8</font></p>

<p><font face="Courier New">CONFIG "PROJ_LIB" "D:\websites\MapServerTest\proj\nad"<br />
CONFIG "MS_ERRORFILE" "..\tmp\ms_error.config"<br />
# Activate this setting to write diagnostic output to the errorfile for each WMS request<br />
#DEBUG 5<br />
FONTSET fonts.txt<br />
MAXSIZE 100000</font></p>

<p><font face="Courier New">OUTPUTFORMAT<br />
&nbsp;&nbsp; NAME png<br />
&nbsp;&nbsp; DRIVER "AGG/PNG"<br />
&nbsp;&nbsp; MIMETYPE "image/png"<br />
&nbsp;&nbsp; IMAGEMODE RGBA # RGBA<br />
&nbsp;&nbsp; EXTENSION "png"<br />
&nbsp;&nbsp; TRANSPARENT ON<br />
&nbsp;&nbsp; # these setting greatly reduce the size of the PNG image<br />
&nbsp;&nbsp; FORMATOPTION "QUANTIZE_FORCE=on"<br />
&nbsp;&nbsp; FORMATOPTION "QUANTIZE_COLORS=256"<br />
END</font></p>

<p><font face="Courier New">LEGEND<br />
&nbsp;&nbsp;&nbsp; STATUS OFF<br />
&nbsp;&nbsp;&nbsp; KEYSIZE 18 12<br />
&nbsp;&nbsp;&nbsp; TRANSPARENT OFF<br />
&nbsp;&nbsp;&nbsp; LABEL<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TYPE BITMAP<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SIZE MEDIUM<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COLOR 0 0 89<br />
&nbsp;&nbsp;&nbsp; END<br />
END</font></p>

<p><font face="Courier New">PROJECTION<br />
&nbsp;&nbsp;&nbsp; "init=epsg:27700"<br />
END</font></p>

<p><font face="Courier New">WEB<br />
&nbsp;&nbsp;&nbsp; IMAGEPATH "..\\tmp\\"<br />
&nbsp;&nbsp;&nbsp; IMAGEURL "../tmp/"<br />
&nbsp;&nbsp;&nbsp; METADATA<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_srs"&nbsp;&nbsp;&nbsp; "EPSG:27700 EPSG:4326 EPSG:900913 EPSG:3857"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_onlineresource"&nbsp;&nbsp;&nbsp; "</font><a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map&amp;&quot;"><font face="Courier New">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map&amp;"</font></a><br />
<font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_title"&nbsp;&nbsp;&nbsp; "Test Map"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_abstract"&nbsp;&nbsp;&nbsp; "Test Map"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "WMS_FEATURE_INFO_MIME_TYPE"&nbsp;&nbsp;&nbsp; "text/html"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "ows_include_items" "all"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "ows_enable_request"&nbsp;&nbsp; "*" # REQUIRED for MapServer 6 to enable WMS and WFS<br />
&nbsp;&nbsp;&nbsp; END<br />
&nbsp;&nbsp;&nbsp; TEMPLATE "esdmBrowse.html"<br />
END</font></p>

<p><font face="Courier New">LAYER<br />
&nbsp;&nbsp;&nbsp; # Activate this setting to write diagnostic output to the errorfile for each WMS request (for this layer only)<br />
&nbsp;&nbsp;&nbsp; #DEBUG 5<br />
&nbsp;&nbsp;&nbsp; NAME "grid"<br />
&nbsp;&nbsp;&nbsp; STATUS ON<br />
&nbsp;&nbsp;&nbsp; TYPE POLYGON<br />
&nbsp;&nbsp;&nbsp; DATA "10kRasterTileIndex"<br />
&nbsp;&nbsp;&nbsp; PROJECTION<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "init=epsg:27700"<br />
&nbsp;&nbsp;&nbsp; END<br />
&nbsp;&nbsp;&nbsp; DUMP True<br />
&nbsp;&nbsp;&nbsp; TEMPLATE "gridinfotemplate.html"<br />
&nbsp;&nbsp;&nbsp; METADATA<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_title"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "grid"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "wms_srs"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "EPSG:27700 EPSG:4326 EPSG:900913 EPSG:3857"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "ows_include_items" "all"<br />
&nbsp;&nbsp;&nbsp; END<br />
&nbsp;&nbsp;&nbsp; CLASS<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NAME 'grid'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STYLE<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OUTLINECOLOR 50 50 50<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WIDTH 1<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; END<br />
&nbsp;&nbsp;&nbsp; END<br />
END</font></p>

<p><font face="Courier New">END</font></p>

<p>Once the map file has been created, the root address of your WMS will be the web URL of the MapServer executable, with map file passed as a parameter. This will either be a path for MapServer 7 or a map file name from MAPS for MapServer 8. This should match the wms_onlineresource in the map file, so in this test case it is <a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map" title="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map</a>&nbsp;or&nbsp;<a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map" title="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=M</a>apFileTest</p>

<h4>Templates</h4>

<p>The map file references two external “templates”.</p>

<p>ESDMBrowse.html contains:</p>

<p><font face="Courier New">&lt;!-- MapServer Template --&gt;<br />
BROWSE|[version]|[id]|[img]|[ref]|[legend]|[scalebar]|[queryfile]|[map]|[mapx]|[mapy]|[mapext]|[minx]|[miny]|[maxx]|[maxy]|[layers]|[toggle_layers]|[mapwidth]|[mapheight]|[shpminx]|[shpminy]|[shpmaxx]|[shpmaxy]|[shpmidx]|[shpmidy]^</font></p>

<p>This template is not essential for creating a simple WMS, but it does serve useful diagnostic purposes. If you browse to the map file with a URL like this <a href="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map" title="http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map">http://mapservertest.esdm.co.uk/scripts/mapserv.exe?map=D:\Websites\mapservertest\map\mapfiletest.map</a> this template shapes the output, in this case reporting the MapServer version and the names of some test images created in the \tmp folder. If anything is badly wrong with the map file or folder permissions, this will report diagnostic information to help fix the issue. In our map file above the output images will be blank, because no layers are set to STATUS DEFAULT.</p>

<p>And the gridinfotemplate.html file contains:</p>

<p><font face="Courier New">&lt;!-- MapServer Template --&gt;<br />
&lt;p&gt;Location: [location]&lt;/p&gt;</font></p>

<p>This is used to shape the output to an “info click” (i.e. GetFeatureInfo WMS request) when it is configured to return data in html format. Again this is a large topic so I’ll leave it there.</p>

<p>NB the first line of each template may be only a comment in XML terms, but without it MapServer will choke – keep it in.</p>

<h4>Testing the WMS</h4>

<p>We should now have a working WMS, but we need to test it. This can be done with any software that can display a WMS, including MapInfo Professional, Quantum GIS, ArcGIS, Google Earth,and numerous others. I’m using QGIS 2.0.1 for this test.</p>

<p>Under the Layer menu choose to “Add WMS/WMTS layer”, then click “New”, and enter the full URL to the map file and a name for the service:</p>

<p><img alt="QGIS WMS server configuration" border="0" height="454" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_94.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="QGIS WMS server configuration" width="491" /></p>

<p>Then on the dialogue you return to when you “OK” this one, click Connect, and you should see your layer available to select:</p>

<p><img alt="QGIS WMS layer configuration" border="0" height="469" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_95.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="QGIS WMS layer configuration" width="640" /></p>

<p>Use this dialogue to set the desired coordinate system too – our example supports output in Ordnance Survey GB (EPSG:27700), WGS84 (EPSG:4326), or Google spherical mercator (EPSG:900913/3857).</p>

<p>Use the “Add” button, and you should see something like this:</p>

<p><img alt="QGIS showing our test WMS of UK map grid squares" border="0" height="426" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_96.png" style="border: 0px currentColor; border-image: none; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="QGIS showing our test WMS of UK map grid squares" width="640" /></p>
<br /><a href='https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-install-the-latest-version-of-mapserver-on-windows</guid>
      <pubDate>Tue, 18 Mar 2014 09:01:00 GMT</pubDate>
    </item>
    <item>
      <title>How to supply default values to MapServer runtime variables (using version 6.0x)</title>
      <description><![CDATA[<p>MapServer allows certain elements of the map file to be altered at runtime by passing in variables on the URL. This only applies when MapServer is running as a CGI application, and is documented here: <a title="http://mapserver.org/cgi/runsub.html" href="http://mapserver.org/cgi/runsub.html" target="_blank">http://mapserver.org/cgi/runsub.html</a>. We use this to allow client-side filtering in applications such as our <a title="exeGesIS Web Map Toolkit" href="https://www.esdm.co.uk/web-map-toolkit" target="_blank">Web Map Toolkit</a>, for example passing in a URL parameter that is used in a FILTER on a LAYER, or in an EXPRESSION in a CLASS.</p> <p>When used in either of these ways, the calling application may want to clear the filter entirely, <em>i.e.</em> supply no value at runtime. To avoid this returning no data, or breaking the map completely, MapServer permits setting default values for the variables as documented here: <a title="Default values if not provided in the URL" href="http://mapserver.org/cgi/runsub.html#default-values-if-not-provided-in-the-url" target="_blank">Default values if not provided in the URL</a>. However, we have found this simply does not work as stated (using MapServer 6.01 anyway). We have tried setting the default value in a VALIDATION block positioned in the WEB section or in a LAYER, and while the pattern validation works in both cases, the default value does not.</p> <p>Here’s a hypothetical example of what does not work for us (using a variable “year”):</p> <p>VALIDATION</p> <p>&nbsp; 'year' '^[0-9]{4}$'</p> <p>&nbsp; 'default_year' '2014'</p> <p>END</p> <p>And here’s what we find <em>does</em> work, moving the settings into the METADATA section of the layer:</p> <p>LAYER  <p>&nbsp; …  <p>&nbsp;&nbsp; METADATA&nbsp;&nbsp;&nbsp;&nbsp; <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; … other stuff…  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'year_validation_pattern' '^[0-9]{4}$'  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'default_year' '2014'  <p>&nbsp;&nbsp; END  <p>When I get time I need to check this on a more up-to-date version of MapServer, because I see this in the <a title="migration documentation for version 6.4" href="http://mapserver.org/MIGRATION_GUIDE.html#mapserver-6-2-to-6-4-migration" target="_blank">migration documentation for version 6.4</a>: “Validation patterns cannot be specified in metadata blocks (i.e. using xxx_validation_pattern and default_xxx metadata entries), use VALIDATION blocks”.  <p>This did make me wonder whether 6.0 was never intended to work with the default values inside VALIDATION blocks, but a trawl of the <a href="http://mapserver.org/MapServer-60.pdf" target="_blank">MapServer 6.0 documentation</a> shows that it was.&nbsp; Let’s hope they’ve fixed it!</p><br /><a href='https://www.esdm.co.uk/how-to-supply-default-values-to-mapserver-runtime-variables-using-version-60x'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/how-to-supply-default-values-to-mapserver-runtime-variables-using-version-60x'>...</a>]]></description>
      <link>https://www.esdm.co.uk/how-to-supply-default-values-to-mapserver-runtime-variables-using-version-60x</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/how-to-supply-default-values-to-mapserver-runtime-variables-using-version-60x</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/how-to-supply-default-values-to-mapserver-runtime-variables-using-version-60x</guid>
      <pubDate>Mon, 17 Mar 2014 12:32:44 GMT</pubDate>
    </item>
    <item>
      <title>Calling a secured WMS / WFS service from mapserver</title>
      <description><![CDATA[<p>Mapserver can be used in a cascading manner to call to other services, potentially combining them and maybe re-projecting before serving out again.</p>

<p>Reasons for this might include:</p>

<ul>
	<li>Re-projecting the map</li>
	<li>Accessing a secured WMS/WFS and then protecting it a different way</li>
	<li>Serving a WMS / WFS map out in a different way</li>
</ul>

<p>This is all relatively simple using standard mapserver .MAP file if the WMS / WFS services you are calling to are unsecured.&nbsp; Then its simply a case of a layer like:</p>

<blockquote>
<p>&nbsp;<br />
LAYER</p>

<p>NAME "MyLayer"<br />
DEBUG 5<br />
&nbsp; TYPE RASTER<br />
&nbsp; STATUS ON<br />
&nbsp; CONNECTION <a href="http://somedomain.com/WMSServer">http://somedomain.com/WMSServer</a><br />
&nbsp; CONNECTIONTYPE WMS<br />
&nbsp; METADATA<br />
&nbsp;&nbsp;&nbsp; "wms_title"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "OSI"<br />
&nbsp;&nbsp;&nbsp; "wms_srs"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "EPSG:27700 EPSG:4326 EPSG:54004 EPSG:3978 EPSG:3857 EPSG:900913"<br />
&nbsp;&nbsp;&nbsp; "wms_name"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "1,2,3,4,5,6,7,8,9"<br />
&nbsp;&nbsp;&nbsp; "wms_server_version"&nbsp; "1.1.1"<br />
&nbsp;&nbsp;&nbsp; "wms_format"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "image/png"<br />
&nbsp;&nbsp;&nbsp; "wms_enable_request"&nbsp; "*"<br />
&nbsp; END<br />
&nbsp; PROJECTION<br />
&nbsp;&nbsp;&nbsp;&nbsp; "init=epsg:900913"<br />
&nbsp; END<br />
&nbsp;<br />
END</p>
</blockquote>

<p>However if the service you are calling is secured it gets a whole load more complicated.&nbsp; You might (as I did initially) think that all you have to do is change the map file to include the authorisation details such as</p>

<blockquote>
<p>&nbsp;<br />
LAYER</p>

<p>NAME "MySecuredLayer"<br />
DEBUG 5<br />
&nbsp; TYPE RASTER<br />
&nbsp; STATUS ON<br />
&nbsp; CONNECTION <a href="https://somedomain.com/WMSServer">https://somedomain.com/WMSServer</a><br />
&nbsp; CONNECTIONTYPE WMS<br />
&nbsp; METADATA<br />
&nbsp;&nbsp;&nbsp; "wms_title"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "OSI"<br />
&nbsp;&nbsp;&nbsp; "wms_srs"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "EPSG:27700 EPSG:4326 EPSG:54004 EPSG:3978 EPSG:3857 EPSG:900913"<br />
&nbsp;&nbsp;&nbsp; "wms_name"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "1,2,3,4,5,6,7,8,9"<br />
&nbsp;&nbsp;&nbsp; "wms_server_version"&nbsp; "1.1.1"<br />
&nbsp;&nbsp;&nbsp; "wms_format"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "image/jpeg"<br />
&nbsp;&nbsp;&nbsp; "wms_auth_username"&nbsp;&nbsp; "myUserName"<br />
&nbsp;&nbsp;&nbsp; "wms_auth_password"&nbsp;&nbsp; "myPassword"&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; "wms_auth_type"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "basic"<br />
&nbsp;&nbsp;&nbsp; "wms_enable_request"&nbsp; "*"<br />
&nbsp; END<br />
&nbsp; PROJECTION<br />
&nbsp;&nbsp;&nbsp;&nbsp; "init=epsg:900913"<br />
&nbsp; END<br />
&nbsp;<br />
END</p>
</blockquote>

<p>Unfortunately that in itself doesn’t work (though the map file itself is correct).&nbsp; You are very strongly recommended to make sure you have DEBUG setup – at least while testing.&nbsp; So in addition to specifying the DEBUG level in the layer – you also need to include in the overall header of the MAP file a path to the log file</p>

<blockquote>
<p>CONFIG "MS_ERRORFILE" "C:\\Mapserver\\ms_log.txt"<br />
DEBUG 5</p>
</blockquote>

<p>Running the above map file will create errors in the log file:</p>

<p><strong><em>HTTP: request failed with curl error code 60 (SSL certificate problem, verify that the CA cert is OK. Details:<br />
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed) for </em></strong><a href="https://somedomain.com/WMSServer"><strong><em>https://somedomain.com/WMSServer</em></strong></a><strong><em>…</em></strong></p>

<p>(If you get an error:</p>

<p><strong>&nbsp;<em>msHTTPExecuteRequests(): HTTP request error. HTTP: request failed with curl error code 1 (Protocol https not supported or disabled in libcurl)</em></strong></p>

<p>Then you have a version of mapserver that is not compiled with the correct support and you need to change your version of mapserver (see below))</p>

<p>Basically the secure WMS call uses cURL libraries to do the call – and you have to register the certificate from the service you are calling.</p>

<h1>What you need to do:</h1>

<h2>Make sure your version of mapserver supports https</h2>

<p>Make sure you have a version of mapserver that supports https calls.&nbsp; Tamas builds (<a href="http://www.gisinternals.com/sdk/" title="http://www.gisinternals.com/sdk/">http://www.gisinternals.com/sdk/</a>) seem to include the required libraries. I used release-1500-gdal-1-10-0-mapserver-6-2-1.zip though I’m sure other versions would work as well</p>

<h2>Get the security certificate</h2>

<p>Use OpenSSL (whcih is included in the mapserver distribution in bin\curl)</p>

<blockquote>
<p>openssl s_client –connect somedomain:443 &gt; c:\Temp\cert.txt</p>
</blockquote>

<p>If all goes well – the cert.txt file will look something like this – and you need the bits from -----BEGIN CERTIFICATE-----&nbsp; to&nbsp; -----END CERTIFICATE-----</p>

<p>CONNECTED(00000190)<br />
---<br />
Certificate chain<br />
0 s:/OU=Domain Control Validated/OU=COMODO SSL Wildcard/CN=*.osi.ie<br />
&nbsp;&nbsp; i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO SSL CA<br />
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO SSL CA<br />
&nbsp;&nbsp; i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root<br />
---<br />
Server certificate<br />
-----BEGIN CERTIFICATE-----<br />
MIIE5DCCA8ygAwIBAgIQOhI8AlhJBZcVfKqx4ruAnzANBgkqhkiG9w0BAQUFADBw<br />
.<br />
9WspBdI6j1t8l+ZZGe1PXBIBaHlpXuazvlC5FpU93bKt7zaEJ1iU5XjIwB/H4ys1<br />
Hsch6g7YXnw=<br />
-----END CERTIFICATE-----<br />
subject=/OU=Domain Control Validated/OU=COMODO SSL Wildcard/CN=*.osi.ie<br />
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO SSL CA<br />
---<br />
No client certificate CA names sent<br />
---<br />
SSL handshake has read 2675 bytes and written 536 bytes<br />
---<br />
New, TLSv1/SSLv3, Cipher is AES256-SHA<br />
Server public key is 2048 bit<br />
Secure Renegotiation IS NOT supported<br />
Compression: NONE<br />
Expansion: NONE<br />
SSL-Session:<br />
&nbsp;&nbsp;&nbsp; Protocol&nbsp; : TLSv1<br />
&nbsp;&nbsp;&nbsp; Cipher&nbsp;&nbsp;&nbsp; : AES256-SHA<br />
&nbsp;&nbsp;&nbsp; Session-ID: 5F65EE6F4E78B564620101A5A706E7A259375B2277F430BC4578395780D14458<br />
&nbsp;&nbsp;&nbsp; Session-ID-ctx:<br />
&nbsp;&nbsp;&nbsp; Master-Key: 1C992E7CC5DFE1AF7B2D87295954D6A73A740E71BD81A2DB68546E61C055D0089FF1C91FB761F64CFE1BBD20B8411AE3<br />
&nbsp;&nbsp;&nbsp; Key-Arg&nbsp;&nbsp; : None<br />
&nbsp;&nbsp;&nbsp; PSK identity: None<br />
&nbsp;&nbsp;&nbsp; PSK identity hint: None<br />
&nbsp;&nbsp;&nbsp; Start Time: 1391380021<br />
&nbsp;&nbsp;&nbsp; Timeout&nbsp;&nbsp; : 300 (sec)<br />
&nbsp;&nbsp;&nbsp; Verify return code: 20 (unable to get local issuer certificate)<br />
---</p>

<h2>Add the security certificate to your local store</h2>

<p>I copied the default file from bin\curl\curl-ca-bundle.crt into the main mapserver cgi-bin (or scripts) folder</p>

<p>Edit the curl-ca-bundle.crt file and add in your certificate (the bits from -----BEGIN CERTIFICATE-----&nbsp; to&nbsp; -----END CERTIFICATE-----)</p>

<h2>Test your certificate</h2>

<p>Check Curl.exe is in the same folder as your curl-ca-bundle.crt</p>

<p>1) I tested first with a call to getCapabilities:</p>

<blockquote>
<p>curl -u MyUsername:MyPassword&nbsp;<a href="https://SomeDomain.com:443/WMSServer?REQUEST=GetCapabilities%26SERVICE=WMS">https://SomeDomain.com:443/WMSServer?REQUEST=GetCapabilities%26SERVICE=WMS</a></p>
</blockquote>

<p>(Note I had to swap &amp; for %26 0 i.e. url encode)</p>

<p>If this has worked you should see a normal getCapabilities text response</p>

<p>2) I then tested with an image call:</p>

<blockquote>
<p>curl -u MyUsername:MyPassword&nbsp;<a href="https://SomeDomain.com:443/WMSServer?LAYERS=1%26REQUEST=GetMap%26SERVICE=WMS">https://SomeDomain.com:443/WMSServer?LAYERS=1%26REQUEST=GetMap%26SERVICE=WMS</a> ……</p>
</blockquote>

<p>If this works you should see a load of extended characters returned (i.e. an image displayed in the command window!)</p>

<h2>Set a windows environment variable to point at the certificate store file</h2>

<p>Previous tests have simply used the file in the same folder as the curl.exe, but when running for real mapserver must know where to find the certificate file.</p>

<p>Set the CURL_CA_BUNDLE environment variable to point at the certificate file</p>

<p>e.g. C:\Mapserver\cgi-bin\curl-ca-bundle.crt</p>

<p>Then you need to reboot the server to make sure the new environment setting is correctly used</p>

<h2>Then test your map file</h2>

<p>Now – at last – the map file which you thought should work originally should actually work and return you an image.</p>

<blockquote>
<p>&nbsp;<br />
LAYER</p>

<p>NAME "MySecuredLayer"<br />
DEBUG 5<br />
&nbsp; TYPE RASTER<br />
&nbsp; STATUS ON<br />
&nbsp; CONNECTION <a href="https://somedomain.com/WMSServer">https://somedomain.com/WMSServer</a><br />
&nbsp; CONNECTIONTYPE WMS<br />
&nbsp; METADATA<br />
&nbsp;&nbsp;&nbsp; "wms_title"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "OSI"<br />
&nbsp;&nbsp;&nbsp; "wms_srs"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "EPSG:27700 EPSG:4326 EPSG:54004 EPSG:3978 EPSG:3857 EPSG:900913"<br />
&nbsp;&nbsp;&nbsp; "wms_name"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "1,2,3,4,5,6,7,8,9"<br />
&nbsp;&nbsp;&nbsp; "wms_server_version"&nbsp; "1.1.1"<br />
&nbsp;&nbsp;&nbsp; "wms_format"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "image/jpeg"<br />
&nbsp;&nbsp;&nbsp; "wms_auth_username"&nbsp;&nbsp; "myUserName"<br />
&nbsp;&nbsp;&nbsp; "wms_auth_password"&nbsp;&nbsp; "myPassword"&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; "wms_auth_type"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "basic"<br />
&nbsp;&nbsp;&nbsp; "wms_enable_request"&nbsp; "*"<br />
&nbsp; END<br />
&nbsp; PROJECTION<br />
&nbsp;&nbsp;&nbsp;&nbsp; "init=epsg:900913"<br />
&nbsp; END<br />
&nbsp;<br />
END</p>
</blockquote>

<p>If you look in the log file you should see:</p>

<blockquote>
<p>Using CURL_CA_BUNDLE=C:\Mapserver\cgi-bin\curl-ca-bundle.crt</p>
</blockquote>

<p>If not – check your environment variable setting</p>

<h2>Other references</h2>

<p>The above was put together from a variety of sources – including those below– useful additional refs include:</p>

<p><a href="http://geographika.co.uk/setting-up-a-secure-cascading-wms-on-mapserver" title="http://geographika.co.uk/setting-up-a-secure-cascading-wms-on-mapserver">http://geographika.co.uk/setting-up-a-secure-cascading-wms-on-mapserver</a></p>

<p><a href="http://www.mapserver.org/ogc/wxs_secure.html" title="http://www.mapserver.org/ogc/wxs_secure.html">http://www.mapserver.org/ogc/wxs_secure.html</a></p>

<p><a href="http://trac.osgeo.org/mapserver/ticket/3070" title="http://trac.osgeo.org/mapserver/ticket/3070">http://trac.osgeo.org/mapserver/ticket/3070</a></p>
<br /><a href='https://www.esdm.co.uk/calling-a-secured-wms--wfs-service-from-mapserver'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/calling-a-secured-wms--wfs-service-from-mapserver'>...</a>]]></description>
      <link>https://www.esdm.co.uk/calling-a-secured-wms--wfs-service-from-mapserver</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/calling-a-secured-wms--wfs-service-from-mapserver</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/calling-a-secured-wms--wfs-service-from-mapserver</guid>
      <pubDate>Mon, 03 Feb 2014 23:31:00 GMT</pubDate>
    </item>
    <item>
      <title>MapServer Templates: Item tags to modify output data</title>
      <description><![CDATA[<p>
	You can add item tags to the [] in MapServer template files. Useful for tidying number fields, strings etc and coping with NULL fields</p>
<ul class="simple">
	<li>
		name: the name of the attribute to be exposed</li>
	<li>
		format: a simple string containing the token(s) $value, default format is the result of any processing</li>
	<li>
		nullformat: string to return if value is NULL or empty (length=0)</li>
	<li>
		uc: convert string to upper case</li>
	<li>
		lc: convert string to lower case</li>
	<li>
		substr: perform a perl-like substring operation by providing offset, and optionally length (un-implemented as of 3/13/07)</li>
	<li>
		commify: add commas to a numeric string (12345 would become 12,345), note, supports only North American notation at the moment</li>
	<li>
		escape: what type of escaping to do (default is html), permissible values would be html, url, none</li>
	<li>
		precision: number of decimals to retain after the decimal point</li>
	<li>
		pattern: regular expression that must validate (against the column value) to process the tag</li>
</ul>
<p>
	Example: [item name=SUM_MB_N precision=2]</p>
<p>
	<a href="http://mapserver.org/development/rfc/ms-rfc-9.html">http://mapserver.org/development/rfc/ms-rfc-9.html</a></p>
<br /><a href='https://www.esdm.co.uk/mapserver-templates-item-tags-to-modify-output-data'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/mapserver-templates-item-tags-to-modify-output-data'>...</a>]]></description>
      <link>https://www.esdm.co.uk/mapserver-templates-item-tags-to-modify-output-data</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/mapserver-templates-item-tags-to-modify-output-data</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/mapserver-templates-item-tags-to-modify-output-data</guid>
      <pubDate>Thu, 12 Jul 2012 15:43:00 GMT</pubDate>
    </item>
    <item>
      <title>Inspecting web service requests from Quantum GIS with Fiddler</title>
      <description><![CDATA[<p>When connecting to any mapping web service, such as a WMS of WFS, just occasionally things don’t work first time (or is that just me…?).&nbsp; When this happens it is useful to be able to inspect the HTTP requests/responses for clues.</p> <p>Our HTTP inspection tool of choice is of course <a href="http://www.fiddler2.com" target="_blank">Fiddler</a>, however if you open this while using QGIS to connect to a web service, you see… nothing. So you need to tell QGIS to pass requests through a proxy, using Host = localhost and Port 8888 as shown below:</p> <p>QGIS menu Settings &gt; Options &gt; Network:</p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="QGIS proxy options" border="0" alt="QGIS proxy options" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_7.png" width="644" height="416"></p> <p>Requests now start appearing in Fiddler.</p> <p>However, there’s a small gotcha… once set into this mode, requests fail entirely if Fiddler is not running.&nbsp; A WMS will simply fail to draw, and connecting to a WMS server gives this error:</p> <blockquote> <p>Could not understand the response. The wms provider said:  <p>Download of capabilities failed: Connection refused</p></blockquote> <p>This cost me half an hour this morning, having forgotten that I had set QGIS into this mode a few days ago, grrr.&nbsp; Here we are after I’d remembered the solution, showing a WMS of archaeological sites recorded by the National Trust, in Snowdonia, Wales.</p> <p><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Archaeological sites in Snowdonia, Wales" border="0" alt="Archaeological sites in Snowdonia, Wales" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_9.png" width="496" height="484"></p><br /><a href='https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler'>...</a>]]></description>
      <link>https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/inspecting-web-service-requests-from-quantum-gis-with-fiddler</guid>
      <pubDate>Mon, 04 Jun 2012 07:33:04 GMT</pubDate>
    </item>
    <item>
      <title>Tilecache: how to stop tilecache_seed.py bailing out with HTTP 502 errors</title>
      <description><![CDATA[<p>We are using TileCache <a title="http://tilecache.org/" href="http://tilecache.org/">http://tilecache.org/</a> to create caches of Ordnance Survey data of various flavours, for use in high demand web sites. We are tending to pre-seed the caches, then access them directly from disk, as this gives the best overall performance. However building the caches for the larger map scales is a significant task, requiring many days of processing and hundreds of gigabytes of storage.</p> <p>This post addresses a particular problem – the pre-seeding routines failing intermittently with HTTP 502 errors.</p> <p>Pre-seeding is carried out on the command line, issuing a command like this:</p> <p>D:\Websites\UKBaseMap\scripts\tilecache\tilecache-2.11\tilecache_seed.py --bbox=0,0,600000,1300000 OSOpenOSGB 0 10</p> <p>where OSOpenOSGB refers to a config section in tilecache.cfg (which in turn points at the WMS), and “0 10” means process levels 0 to 9.</p> <p>The normal tilecache_seed.py looks like this:</p> <p>================</p><pre class="csharpcode"><span class="rem">#!/usr/bin/env python</span>

<span class="rem"># BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors</span>
<span class="str">""</span><span class="str">"This is intended to be run as a command line tool. See the accompanying
   README file or man page for details."</span><span class="str">""</span>

import TileCache.Client

TileCache.Client.main()</pre>
<p>================
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</p>
<p>But we have been finding that this fails intermittently with errors being raised, like:</p>
<p><font size="2" face="Courier New">urllib2.HTTPError: HTTP Error 502: Bad Gateway</font><br></p>
<p>We do not know the root cause, but apparently the CGI MapServer WMS is simply failing to respond sometimes, and unfortunately this causes the cache seeding process to stop. We are seeing this at varying intervals, from every 5 minutes to every couple of hours. Enough to completely disrupt the construction of a large cache.</p>
<p>So, in my first foray into Python goodness, I’ve enhanced tilecache_seed.py a little to recover from the failures and continue until the caching finished without an error:</p>
<p>================</p><pre class="csharpcode"><span class="rem">#!/usr/bin/env python</span>

<span class="rem"># BSD Licensed, Copyright (c) 2006-2010 TileCache Contributors</span>
<span class="str">""</span><span class="str">"This is intended to be run as a command line tool. See the accompanying
   README file or man page for details."</span><span class="str">""</span>

<span class="rem"># amended CF 22/2/2012 to resume after errors urllib2.HTTPError: HTTP Error 502: Bad Gateway</span>
import time
import TileCache.Client
i = 1
<span class="kwrd">while</span> i &gt; 0:
    try:
        i = 0
        TileCache.Client.main() <span class="rem"># do the work</span>
    except:
        i = 1
        print <span class="str">'HTTPError occurred - resuming processing...'</span>
        f = open(<span class="str">'errorlog.txt'</span>, <span class="str">'a'</span>) <span class="rem"># open file for appending</span>
        f.write(<span class="str">'HTTP Error occurred at: '</span> + time.strftime(<span class="str">'%x %X'</span>) + <span class="str">'\n'</span>)
        f.close()
        time.sleep( 1 ) <span class="rem"># have a rest to let MapServer recover from whatever was troubling it</span>
        <span class="kwrd">continue</span> <span class="rem"># resume the loop</span>
    <span class="kwrd">else</span>:
        print <span class="str">'Processing completed!'</span> # no error was encountered</pre>
<p>================
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
</p>
<p>This also logs the occurrence of errors into a log file like this:</p>
<p>HTTP Error occurred at: 02/23/12 23:50:00</p>
<p>The caching now bashes on regardless of intermittent errors. However, best to avoid the –f flag on the command line as this will re-start the job from the beginning and re-create all tiles, therefore may never complete if errors are occurring regularly.</p><br /><a href='https://www.esdm.co.uk/tilecache-how-to-stop-tilecache_seedpy-bailing-out-with-http-502-errors'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/tilecache-how-to-stop-tilecache_seedpy-bailing-out-with-http-502-errors'>...</a>]]></description>
      <link>https://www.esdm.co.uk/tilecache-how-to-stop-tilecache_seedpy-bailing-out-with-http-502-errors</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/tilecache-how-to-stop-tilecache_seedpy-bailing-out-with-http-502-errors</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/tilecache-how-to-stop-tilecache_seedpy-bailing-out-with-http-502-errors</guid>
      <pubDate>Fri, 24 Feb 2012 00:31:05 GMT</pubDate>
    </item>
    <item>
      <title>Further load testing of GeoServer and MapServer (and tilecache)</title>
      <description><![CDATA[<p>My previous load testing of GeoServer and MapServer involved requesting just one 256x256 pixel map across all the virtual user sessions. In this test, GeoServer performed stunningly well so long as no re-projection was involved, when it performed terribly. This test may not be realistic, because this is not how a real interactive map would load the server when under load from many users. Also, we might have hit a sweetspot where GeoServer always caches in memory the last map (or something).</p> <p>To run a more realistic test I spread the virtual users across 10 different map requests in different parts of the country (i.e. on different underlying map image files).</p>Each test ran for 100 seconds, starting with 10 virtual users, increasing by 10 every 10 seconds. The tilecache image was of course cached and simply being retrieved from disk. All tests were using the same web server, with files on the same drive.  <p><em>Note: the vertical scale differs in each graph to fit the observed values.</em></p> <h3>With re-projection into Spherical Mercator, 100 virtual users</h3> <table border="1" cellspacing="0" cellpadding="2" width="600"> <tbody> <tr> <td valign="top" width="150">&nbsp;</td> <td valign="top" width="150"><strong>GeoServer</strong></td> <td valign="top" width="150"><strong>MapServer</strong></td> <td valign="top" width="150"><strong>Tilecache</strong></td></tr> <tr> <td valign="top" width="150">Transactions</td> <td valign="top" width="150">1283</td> <td valign="top" width="150">770</td> <td valign="top" width="150">2301</td></tr> <tr> <td valign="top" width="150">Errors</td> <td valign="top" width="150">0</td> <td valign="top" width="150">0</td> <td valign="top" width="150">0</td></tr> <tr> <td valign="top" width="150">Average response time (seconds)</td> <td valign="top" width="150">3.5</td> <td valign="top" width="150">6.7</td> <td valign="top" width="150">2.2</td></tr> <tr> <td valign="top" width="150">95% response time (seconds)</td> <td valign="top" width="150">15.9</td> <td valign="top" width="150">23.6</td> <td valign="top" width="150">8.7</td></tr> <tr> <td valign="top" width="150">Response graph</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_9.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_9.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_10.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_10.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_11.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_11.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Transactions per second</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_1.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_1.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_2.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_2.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Sample image</td> <td valign="top" width="150"><img src="http://62.197.41.154:8080/geoserver/ESDM_UK_BaseMaps/wms?LAYERS=ESDM_UK_BaseMaps%3A50KRasterColour&amp;FORMAT=image%2Fpng&amp;SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;STYLES=&amp;SRS=EPSG%3A900913&amp;BBOX=-374235.69121719,6787608.1097078,-371789.7063125,6790054.0946125&amp;WIDTH=256&amp;HEIGHT=256"></td> <td valign="top" width="150"><img src="http://www.esdmwms.no-ip.co.uk/scripts/mapserv.exe?map=D:\Websites\UKBaseMap\map\UKBaseMap.map&amp;LAYERS=OSLicensed&amp;FORMAT=image%2Fpng&amp;SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;STYLES=&amp;SRS=EPSG%3A900913&amp;BBOX=-374235.69121719,6787608.1097078,-371789.7063125,6790054.0946125&amp;WIDTH=256&amp;HEIGHT=256"></td> <td valign="top" width="150">Same as MapServer (because created with MapServer)</td></tr> <tr> <td valign="top" width="150">Comments</td> <td valign="top" width="150">Horrible image, but blistering performance until 70 users, then major outage for about 20 seconds, then resumed.</td> <td valign="top" width="150">Lovely image, moderate performance; also suffered a pause in service once usage went over 60 sessions.</td> <td valign="top" width="150">Reassuring performance</td></tr></tbody></table> <p>Note: sometimes GeoServer simply fails to re-project rasters correctly:</p> <p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="GeoServer failing to re-project OS 50K rasters" border="0" alt="GeoServer failing to re-project OS 50K rasters" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_8.png" width="244" height="215"></a></p>         <h3>Without re-projection, 100 virtual users</h3> <table border="1" cellspacing="0" cellpadding="2" width="602"> <tbody> <tr> <td valign="top" width="150">&nbsp;</td> <td valign="top" width="150"><strong>GeoServer</strong></td> <td valign="top" width="150"><strong>MapServer</strong></td> <td valign="top" width="150"><strong>Tilecache</strong></td></tr> <tr> <td valign="top" width="150">Transactions</td> <td valign="top" width="150">2476</td> <td valign="top" width="150">554</td> <td valign="top" width="150">2877</td></tr> <tr> <td valign="top" width="150">Errors</td> <td valign="top" width="150">10</td> <td valign="top" width="150">0</td> <td valign="top" width="150">2</td></tr> <tr> <td valign="top" width="150">Average response time (seconds)</td> <td valign="top" width="150">2.0</td> <td valign="top" width="150">7.1</td> <td valign="top" width="150">1.8</td></tr> <tr> <td valign="top" width="150">95% response time (seconds)</td> <td valign="top" width="150">5.6</td> <td valign="top" width="150">18.9</td> <td valign="top" width="150">5.6</td></tr> <tr> <td valign="top" width="150">Response graph</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_12.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_12.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_13.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_13.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_14.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_14.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Transactions per second</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_3.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_3.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_4.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_4.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_5.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_5.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Sample image</td> <td valign="top" width="150"><img src="http://62.197.41.154:8080/geoserver/ESDM_UK_BaseMaps/wms?LAYERS=ESDM_UK_BaseMaps%3A50KRasterColour&amp;FORMAT=image%2Fpng&amp;SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;STYLES=&amp;SRS=EPSG%3A27700&amp;BBOX=330240,524800,331520,526080&amp;WIDTH=256&amp;HEIGHT=256"></td> <td valign="top" width="150"><img src="http://www.esdmwms.no-ip.co.uk/scripts/mapserv.exe?map=D:\Websites\UKBaseMap\map\UKBaseMap.map&amp;LAYERS=OSLicensed&amp;FORMAT=image%2Fpng&amp;SERVICE=WMS&amp;VERSION=1.1.1&amp;REQUEST=GetMap&amp;STYLES=&amp;SRS=EPSG%3A27700&amp;BBOX=330240,524800,331520,526080&amp;WIDTH=256&amp;HEIGHT=256"></td> <td valign="top" width="150">Same as MapServer (because created with MapServer)</td></tr> <tr> <td valign="top" width="150">Comments</td> <td valign="top" width="150">Image quality the same as MapServer. A few errors crept in when the number of virtual sessions hit 100. Apart from this, remarkable performance.</td> <td valign="top" width="150">Stuttering performance once loading goes beyond about 30 virtual users. No errors, but slow.</td> <td valign="top" width="150">Reassuring performance, but only a whisker faster than GeoServer.<br>Interesting that the tilecache is faster in 27700 than in 900913 – I think this is simply because the images on disk are larger (presumably because rotated and re-sampled from the originals).</td></tr></tbody></table>          <p>I then ran the tests again with less extreme loading, this time only 50 virtual users ramping up over 50 seconds.</p> <h3>With re-projection into Spherical Mercator, 50 virtual users</h3> <table border="1" cellspacing="0" cellpadding="2" width="600"> <tbody> <tr> <td valign="top" width="150">&nbsp;</td> <td valign="top" width="150"><strong>GeoServer</strong></td> <td valign="top" width="150"><strong>MapServer</strong></td> <td valign="top" width="150"><strong>Tilecache</strong></td></tr> <tr> <td valign="top" width="150">Transactions</td> <td valign="top" width="150">1033</td> <td valign="top" width="150">491</td> <td valign="top" width="150">1138</td></tr> <tr> <td valign="top" width="150">Errors</td> <td valign="top" width="150">0</td> <td valign="top" width="150">0</td> <td valign="top" width="150">0</td></tr> <tr> <td valign="top" width="150">Average response time (seconds)</td> <td valign="top" width="150">1.3</td> <td valign="top" width="150">2.8</td> <td valign="top" width="150">1.1</td></tr> <tr> <td valign="top" width="150">95% response time (seconds)</td> <td valign="top" width="150">2.7</td> <td valign="top" width="150">10.7</td> <td valign="top" width="150">3.5</td></tr> <tr> <td valign="top" width="150">Response graph</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_15.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_15.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_16.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_16.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_17.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_17.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Transactions per second</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_6.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_6.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_7.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_7.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_8.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_8.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Comments</td> <td valign="top" width="150">Impressive performance – but we need to find a way of making the image look less horrible</td> <td valign="top" width="150">Lovely image, moderate performance.</td> <td valign="top" width="150">Reassuring performance, though some very slow responses for a few tiles, and the 95% figure is worse than GeoServer.</td></tr></tbody></table> <p>&nbsp;</p>         <h3>Without re-projection, 50 virtual users</h3> <table border="1" cellspacing="0" cellpadding="2" width="602"> <tbody> <tr> <td valign="top" width="150">&nbsp;</td> <td valign="top" width="150"><strong>GeoServer</strong></td> <td valign="top" width="150"><strong>MapServer</strong></td> <td valign="top" width="150"><strong>Tilecache</strong></td></tr> <tr> <td valign="top" width="150">Transactions</td> <td valign="top" width="150">1152</td> <td valign="top" width="150">319</td> <td valign="top" width="150">1364</td></tr> <tr> <td valign="top" width="150">Errors</td> <td valign="top" width="150">0</td> <td valign="top" width="150">0</td> <td valign="top" width="150">&nbsp;</td></tr> <tr> <td valign="top" width="150">Average response time (seconds)</td> <td valign="top" width="150">1.2</td> <td valign="top" width="150">4.3</td> <td valign="top" width="150">1.0</td></tr> <tr> <td valign="top" width="150">95% response time (seconds)</td> <td valign="top" width="150">2.2</td> <td valign="top" width="150">15.2</td> <td valign="top" width="150">2.7</td></tr> <tr> <td valign="top" width="150">Response graph</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_18.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_18.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_19.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_19.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_20.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times" border="0" alt="All_Transactions_response_times" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_20.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Transactions per second</td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_9.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_9.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_10.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_10.png" width="244" height="103"></a></td> <td valign="top" width="150"><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_11.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="All_Transactions_response_times_intervals" border="0" alt="All_Transactions_response_times_intervals" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_intervals_thumb_11.png" width="244" height="103"></a></td></tr> <tr> <td valign="top" width="150">Comments</td> <td valign="top" width="150">Very impressive</td> <td valign="top" width="150">Very unimpressive. I don’t really understand how MapServer can be slower when not re-projecting than when it is, but this is a consistent pattern.</td> <td valign="top" width="150">Although the average response is faster than GeoServer, there were enough slow ones to make the overall 95% figure worse. i.e. for overall reliably fast performance, GeoServer beats a tilecache in this test.</td></tr></tbody></table>             <h3>Conclusions</h3> <p>These tests were a far more realistic simulation of real-world loading than the previous single-tile test. </p> <p>MapServer wins on image quality when re-projecting, but as before this probably means we have not found the way to make GeoServer re-sample nicely. </p> <p>Also MapServer was the only service to sail through all tests without any errors. Unfortunately previous tests showed that it can fail on some OS raster tiles though, regardless of load.</p> <p>For speed, GeoServer wins by a mile in these tests. In fact it is almost as fast as a tilecache when hit with up to around 70 concurrent virtual users. After that it start throwing errors and collapsing (so presumably needs more server power than we are giving it). But this does beg the question whether we really need to build a tilecache for rasters that are being served in their native projection – perhaps a GeoServer service would be adequate where the service is not expecting much usage.</p> <p>When I have time, I’ll repeat similar tests working against various vector data sources.</p><br /><a href='https://www.esdm.co.uk/further-load-testing-of-geoserver-and-mapserver-and-tilecache'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/further-load-testing-of-geoserver-and-mapserver-and-tilecache'>...</a>]]></description>
      <link>https://www.esdm.co.uk/further-load-testing-of-geoserver-and-mapserver-and-tilecache</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/further-load-testing-of-geoserver-and-mapserver-and-tilecache</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/further-load-testing-of-geoserver-and-mapserver-and-tilecache</guid>
      <pubDate>Sun, 29 Jan 2012 15:50:33 GMT</pubDate>
    </item>
    <item>
      <title>MapServer and GeoServer (and tilecache) comparison serving Ordnance Survey raster maps</title>
      <description><![CDATA[<p>
	With two WMS running off identical data on the same server, I thought it would be interesting to compare speeds and the map output. So I lined up a map request with identical parameters to both services and ran them through Fiddler a few times (to get an idea of the response times).</p>
<h3>
	Output quality and performance</h3>
<table border="1" cellpadding="2" cellspacing="0" width="600">
	<tbody>
		<tr>
			<td valign="top" width="200">
				&nbsp;</td>
			<td valign="top" width="200">
				<strong>GeoServer</strong></td>
			<td valign="top" width="200">
				<strong>MapServer</strong></td>
		</tr>
		<tr>
			<td valign="top" width="200">
				Response time</td>
			<td valign="top" width="200">
				0.8 to 1.0 seconds with USE_JAI_IMAGEREAD=true<br />
				0.6 to 1.3 seconds with<br />
				USE_JAI_IMAGEREAD=false</td>
			<td valign="top" width="200">
				0.4 to 0.6 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="200">
				Image size</td>
			<td valign="top" width="200">
				63,574 bytes</td>
			<td valign="top" width="200">
				78,327 bytes</td>
		</tr>
		<tr>
			<td valign="top" width="200">
				The map</td>
			<td valign="top" width="200">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/esdm_uk_basemaps-50krastercolour%5B4%5D.png"><img alt="ESDM_UK_BaseMaps-50KRasterColour[4]" border="0" height="516" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/esdm_uk_basemaps-50krastercolour%5B4%5D_thumb.png" style="border-width: 0px; margin: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="ESDM_UK_BaseMaps-50KRasterColour[4]" width="276" /></a></td>
			<td valign="top" width="200">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv%5B4%5D.png"><img alt="mapserv[4]" border="0" height="516" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv%5B4%5D_thumb.png" style="border-width: 0px; margin: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="mapserv[4]" width="276" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="200">
				Quality</td>
			<td valign="top" width="200">
				Adequate, but quite fractured</td>
			<td valign="top" width="200">
				Lovely</td>
		</tr>
		<tr>
			<td valign="top" width="200">
				Comments</td>
			<td valign="top" width="200">
				A significantly slower response than MapServer, and a worse image.<br />
				I couldn’t find any difference between the different re-sampling methods, perhaps suggesting that the settings were not taking effect (I’ve seen GeoServer GUI issues like this a couple of times now, requiring diving into the XML config files). Later – yes the settings were present in the XML config, but seem to make no difference to the output.</td>
			<td valign="top" width="200">
				Faster and much nicer image.<br />
				If we turn off bilinear re-sampling, then the response time improves to around 0.3 seconds and the image deteriorates slightly as shown below (becoming similar in quality to the GeoServer map).<br />
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapservca53l4zs_thumb%5B3%5D.png"><img alt="mapservCA53L4ZS_thumb[3]" border="0" height="516" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapservca53l4zs_thumb%5B3%5D_thumb.png" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="mapservCA53L4ZS_thumb[3]" width="276" /></a></td>
		</tr>
	</tbody>
</table>
<p>
	Oh dear this is not looking good for GeoServer. But is it the whole story? Next I compared them in a more realistic scenario, as base maps in OpenLayers, trying both single tile and multi-tile modes. I configured the map to view the 1:50,000 mapping at a scale where no re-sampling could occur.</p>
<table border="1" cellpadding="2" cellspacing="0" width="671">
	<tbody>
		<tr>
			<td valign="top" width="256">
				&nbsp;</td>
			<td valign="top" width="144">
				<strong>GeoServer</strong></td>
			<td valign="top" width="269">
				<strong>MapServer</strong></td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Response time multi-tile (30 tiles each 256x256 pixels)</td>
			<td valign="top" width="144">
				0.2 to 1.2 seconds, but on average a shade faster</td>
			<td valign="top" width="269">
				0.3 to 0.7 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Response time single-tile (1725 x 1173 pixels)</td>
			<td valign="top" width="144">
				4 to 6 seconds</td>
			<td valign="top" width="269">
				3 to 5 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Image size (typical 256x256 tile)</td>
			<td valign="top" width="144">
				30,447 bytes</td>
			<td valign="top" width="269">
				22,674 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Image size (1725 x 1173 pixels)</td>
			<td valign="top" width="144">
				646,681 bytes</td>
			<td valign="top" width="269">
				690,494 bytes</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				The map (256x256 tile)</td>
			<td valign="top" width="144">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/geoserv_256tile.png"><img alt="geoserv_256tile" border="0" height="260" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/geoserv_256tile_thumb.png" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="geoserv_256tile" width="260" /></a></td>
			<td valign="top" width="269">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv_256tile.png"><img alt="mapserv_256tile" border="0" height="260" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv_256tile_thumb.png" style="border-width: 0px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="mapserv_256tile" width="260" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Quality</td>
			<td valign="top" width="144">
				Very good</td>
			<td valign="top" width="269">
				Very good (pretty much identical)</td>
		</tr>
	</tbody>
</table>
<p>
	OK so now it is looking better for GeoServer; when there is no re-sampling it can return identical images to MapServer, though slightly larger, and performance is pretty similar and possibly quicker.</p>
<h3>
	Output quality and performance when re-projecting</h3>
<p>
	Now time to see how they cope with serving the maps into a different coordinate system, and in particular the global spherical Mercator used in Google and Bing Maps.</p>
<table border="1" cellpadding="2" cellspacing="0" width="671">
	<tbody>
		<tr>
			<td valign="top" width="256">
				&nbsp;</td>
			<td valign="top" width="144">
				<strong>GeoServer</strong></td>
			<td valign="top" width="269">
				<strong>MapServer</strong></td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Response time multi-tile (30 tiles each 256x256 pixels)</td>
			<td valign="top" width="144">
				0.2 to 1.2 seconds</td>
			<td valign="top" width="269">
				0.1 to 0.5 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Response time single-tile (1725 x 1173 pixels)</td>
			<td valign="top" width="144">
				10 seconds</td>
			<td valign="top" width="269">
				6 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Image size (typical 256x256 tile)</td>
			<td valign="top" width="144">
				29,169 bytes</td>
			<td valign="top" width="269">
				37,261 seconds</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Image size (1725 x 1173 pixels)</td>
			<td valign="top" width="144">
				1,041,098 bytes</td>
			<td valign="top" width="269">
				982,050 bytes</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				The map (256x256 tile)</td>
			<td valign="top" width="144">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/geoserv_900913.png"><img alt="geoserv_900913" border="0" height="260" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/geoserv_900913_thumb.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="geoserv_900913" width="260" /></a></td>
			<td valign="top" width="269">
				<p>
					<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv_900913.png"><img alt="mapserv_900913" border="0" height="260" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/mapserv_900913_thumb.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="mapserv_900913" width="260" /></a></p>
			</td>
		</tr>
		<tr>
			<td valign="top" width="256">
				Quality</td>
			<td valign="top" width="144">
				Pretty horrible</td>
			<td valign="top" width="269">
				Very good</td>
		</tr>
	</tbody>
</table>
<p>
	With default settings, GeoServer produces horrible output when re-projecting the raster maps. But this does need more investigation when I found out how to make it use different re-sampling algorithms.</p>
<h3>
	Performance under load</h3>
<p>
	Now time to see how they perform under load using multi-mechanize. I chose to compare MapServer, GeoServer and a tilecache at returning a 256x256 tile in EPSG:900913 (i.e. re-projecting on-the-fly). Each test ran for 100 seconds, starting with 10 virtual users, increasing by 10 every 10 seconds. The tilecache image was of course cached and simply being retrieved from disk. All tests were using the same web server, with files on the same drive.</p>
<p>
	<em>Note: the vertical scale differs in each graph to fit the observed values.</em></p>
<table border="1" cellpadding="2" cellspacing="0" width="600">
	<tbody>
		<tr>
			<td valign="top" width="150">
				&nbsp;</td>
			<td valign="top" width="150">
				<strong>GeoServer</strong></td>
			<td valign="top" width="150">
				<strong>MapServer</strong></td>
			<td valign="top" width="150">
				<strong>Tilecache</strong></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions</td>
			<td valign="top" width="150">
				381</td>
			<td valign="top" width="150">
				556</td>
			<td valign="top" width="150">
				2188</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Errors</td>
			<td valign="top" width="150">
				57</td>
			<td valign="top" width="150">
				0</td>
			<td valign="top" width="150">
				0</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Average response time</td>
			<td valign="top" width="150">
				6.1</td>
			<td valign="top" width="150">
				6.5</td>
			<td valign="top" width="150">
				2.3</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				95% response time</td>
			<td valign="top" width="150">
				26.8</td>
			<td valign="top" width="150">
				17.6</td>
			<td valign="top" width="150">
				5.1</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Response graph</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_1.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_1.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_2.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_2.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions per second</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_1.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_1.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_2.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_2.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Comments</td>
			<td valign="top" width="150">
				Completely broken after about 80 seconds – had to re-start GeoServer</td>
			<td valign="top" width="150">
				No errors, but significantly disrupted performance</td>
			<td valign="top" width="150">
				Slight slow-down under high load, but very reassuring performance</td>
		</tr>
	</tbody>
</table>
<p>
	GeoServer clearly could not stand up to more than about 30 virtual users when re-projecting the maps, and ultimately the service stalled completely requiring a re-start.</p>
<p>
	I tried the tests again requesting the maps in OSGB so that the service did not involve re-projection. I also reduced the number of virtual users to 50. The results were quite surprising…</p>
<table border="1" cellpadding="2" cellspacing="0" width="602">
	<tbody>
		<tr>
			<td valign="top" width="150">
				&nbsp;</td>
			<td valign="top" width="150">
				<strong>GeoServer</strong></td>
			<td valign="top" width="150">
				<strong>MapServer</strong></td>
			<td valign="top" width="150">
				<strong>Tilecache</strong></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions</td>
			<td valign="top" width="150">
				2018</td>
			<td valign="top" width="150">
				1114</td>
			<td valign="top" width="150">
				2197</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Errors</td>
			<td valign="top" width="150">
				0</td>
			<td valign="top" width="150">
				0</td>
			<td valign="top" width="150">
				0</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Average response time</td>
			<td valign="top" width="150">
				1.3</td>
			<td valign="top" width="150">
				2.4</td>
			<td valign="top" width="150">
				1.1</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				95% response time</td>
			<td valign="top" width="150">
				2.4</td>
			<td valign="top" width="150">
				9.1</td>
			<td valign="top" width="150">
				2.5</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Response graph</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_3.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_3.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_4.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_4.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_5.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_5.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions per second</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_3.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_3.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_4.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_4.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_5.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_5.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Comments</td>
			<td valign="top" width="150">
				Impeccable!</td>
			<td valign="top" width="150">
				Much better than when re-projecting, but only half as good as GeoServer.</td>
			<td valign="top" width="150">
				Only fractionally better than GeoServer</td>
		</tr>
	</tbody>
</table>
<p>
	This is a hugely impressive result for GeoServer. My guess is that it is employing server-side in-memory caching, and because all my requests were identical the responses were very fast. MapServer on the other hand has to start a CGI process of each request and presumably cannot benefit from an in-memory cache.</p>
<p>
	When re-projecting on the other hand, perhaps it does not use a cache. And because all the GeoServer operations are running as one process, it is restricted to one virtual processor on our server whereas each MapServer exe can grab one for itself. Certainly when running these tests the server was running at about 40-80% CPU with MapServer, compared to 7% with GeoServer.</p>
<p>
	I ran this test again with the number of virtual users doubled back to 100, and GeoServer came through almost unscathed, this time processing 2072 transactions though with 3 errors.</p>
<table border="1" cellpadding="2" cellspacing="0" width="602">
	<tbody>
		<tr>
			<td valign="top" width="150">
				&nbsp;</td>
			<td valign="top" width="150">
				<strong>GeoServer</strong></td>
			<td valign="top" width="150">
				<strong>MapServer</strong></td>
			<td valign="top" width="150">
				<strong>Tilecache</strong></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions</td>
			<td valign="top" width="150">
				2072</td>
			<td valign="top" width="150">
				907</td>
			<td valign="top" width="150">
				2234</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Errors</td>
			<td valign="top" width="150">
				3</td>
			<td valign="top" width="150">
				0</td>
			<td valign="top" width="150">
				0</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Average response time</td>
			<td valign="top" width="150">
				2.4</td>
			<td valign="top" width="150">
				5.9</td>
			<td valign="top" width="150">
				2.3</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				95% response time</td>
			<td valign="top" width="150">
				5.9</td>
			<td valign="top" width="150">
				25.6</td>
			<td valign="top" width="150">
				4.8</td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Response graph</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_6.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_6.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_7.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_7.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_8.png"><img alt="All_Transactions_response_times" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_response_times_thumb_8.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_response_times" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Transactions per second</td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_6.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_6.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_7.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_7.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
			<td valign="top" width="150">
				<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_8.png"><img alt="All_Transactions_throughput" border="0" height="103" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/all_transactions_throughput_thumb_8.png" style="border: 0px currentColor; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="All_Transactions_throughput" width="244" /></a></td>
		</tr>
		<tr>
			<td valign="top" width="150">
				Comments</td>
			<td valign="top" width="150">
				Wow</td>
			<td valign="top" width="150">
				Suffering, but no errors</td>
			<td valign="top" width="150">
				The best as expected</td>
		</tr>
	</tbody>
</table>
<p>
	I suspect this test may not predict real-world behaviour with lots of users requesting different WMS maps, where I suspect GeoServer would lose its advantage, but it is interesting anyway.</p>
<p>
	NB I had GeoServer running with AllowMultithreading=true</p>
<h3>
	Summary</h3>
<p>
	If the maps need to be re-projected then use MapServer – both performance and output quality are vastly superior. In a site that is going to get any significant load it is unwise to re-project raster mapping on-the-fly anyway, and it should definitely be cached. In this case the&nbsp;WMS performance doesn’t matter so much but output quality is paramount, so MapServer it is.&nbsp; If I find a way of making GeoServer produce nice looking output I’ll come back and revise this post!</p>
<p>
	If no re-projection is required, then simple observation has the two roughly equal under light load. The maps looked almost identical, and performance was close. GeoServer had the advantage for me in that it didn’t suffer from MapServer’s tendency to choke on some requests; in practice this meant I went over my entire OSGB cache again with a GeoServer WMS as the source, to plug the gaps left by the MapServer service.</p>
<p>
	Under heavy (albeit contrived) load, the crucial factor was whether or not there was any re-projection involved. Without re-projection GeoServer produced astonishing performance, thrashing MapServer and nearly matching a tilecache. Introduce re-projection however, and GeoServer collapses to the extent that it can crash entirely – not good when it is running all your mapping services. MapServer never broke, and despite some gaps and slow responses, it managed to struggle through all tests without a single error.</p>
<p>
	So out of this experience I think we need to be using both, depending on the purpose.</p>
<p>
	Next to test performance on vector layers, including file based GIS formats and spatial databases…</p>
<br /><a href='https://www.esdm.co.uk/mapserver-and-geoserver-and-tilecache-comparison-serving-ordnance-survey-raster-maps'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/mapserver-and-geoserver-and-tilecache-comparison-serving-ordnance-survey-raster-maps'>...</a>]]></description>
      <link>https://www.esdm.co.uk/mapserver-and-geoserver-and-tilecache-comparison-serving-ordnance-survey-raster-maps</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/mapserver-and-geoserver-and-tilecache-comparison-serving-ordnance-survey-raster-maps</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/mapserver-and-geoserver-and-tilecache-comparison-serving-ordnance-survey-raster-maps</guid>
      <pubDate>Sat, 21 Jan 2012 17:53:00 GMT</pubDate>
    </item>
    <item>
      <title>Serving Ordnance Survey rasters with GeoServer and MapServer - some irks and quirks</title>
      <description><![CDATA[<p>
	I’ve been preparing a <a href="http://tilecache.org/" target="_blank" title="http://tilecache.org/">tilecache</a> of UK Ordnance Survey mapping for a couple of big projects, combining Open Data with licensed Landranger (1:50,000) and Explorer (1:25,000) mapping. The tilecache utility consumes and generates its cache from a WMS of the mapping, and fir this I’ve done most of the work using MapServer. However I’ve hit some stubborn problems with a few areas of mapping, for example this area where I have a blank strip enclosing a tile boundary. The original tiles are fine, but for some reason when render by MapServer we get this blank area.</p>
<p>
	<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_3.png"><img alt="Blank strip in Ordnance Survey 50K WMS from MapServer" border="0" height="204" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_4.png" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Blank strip in Ordnance Survey 50K WMS from MapServer" width="244" /></a></p>
<p>
	In another couple of areas, the WMS requests to MapServer simply failed with this error sequence:</p>
<p>
	<font face="Courier New" size="1">[Sat Jan 21 09:30:02 2012].785000 msDrawRasterLayerLow(OS50KColourRaster): entering.<br />
	[Sat Jan 21 09:30:02 2012].791000 msResampleGDALToMap in effect: cellsize = 5.000000<br />
	[Sat Jan 21 09:30:02 2012].792000 msDrawGDAL(OS50KColourRaster): using RAW_WINDOW=3509 0 491 652, dst=0,0,491,652<br />
	[Sat Jan 21 09:30:02 2012].792000 msDrawGDAL(): red,green,blue,alpha bands = 1,0,0,0<br />
	[Sat Jan 21 09:30:02 2012].891000 msResampleGDALToMap in effect: cellsize = 5.000000<br />
	[Sat Jan 21 09:30:02 2012].892000 msDrawGDAL(OS50KColourRaster): using RAW_WINDOW=3509 3348 491 652, dst=0,0,491,652<br />
	[Sat Jan 21 09:30:02 2012].892000 msDrawGDAL(): red,green,blue,alpha bands = 1,0,0,0<br />
	[Sat Jan 21 09:30:02 2012].998000 msResampleGDALToMap in effect: cellsize = 5.000000<br />
	[Sat Jan 21 09:30:02 2012].998000 msDrawGDAL(OS50KColourRaster): using RAW_WINDOW=0 0 812 652, dst=0,0,812,652<br />
	[Sat Jan 21 09:30:02 2012].998000 msDrawGDAL(): red,green,blue,alpha bands = 1,0,0,0<br />
	[Sat Jan 21 09:30:03 2012].122000 msResampleGDALToMap in effect: cellsize = 5.000000<br />
	[Sat Jan 21 09:30:03 2012].122000 msDrawGDAL(OS50KColourRaster): using RAW_WINDOW=0 3348 812 652, dst=0,0,812,652<br />
	[Sat Jan 21 09:30:03 2012].122000 msDrawGDAL(): red,green,blue,alpha bands = 1,0,0,0<br />
	[Sat Jan 21 09:30:03 2012].148000 GetBlockRef failed at X block offset 0, Y block offset 499: Unable to access file. GDALDatasetRasterIO() failed: drawGDAL()<br />
	[Sat Jan 21 09:30:03 2012].149000 msDrawMap(): Image handling error. Failed to draw layer named 'OS50KColourRaster'.<br />
	[Sat Jan 21 09:30:03 2012].149000 freeLayer(): freeing layer at 024265B0.</font></p>
<p>
	again the underlying images were apparently fine.</p>
<p>
	And of course this has left gaps in the tile cache.</p>
<p>
	So, in order to overcome these issues I am setting up the WMS using GeoServer to see if that can fill the gaps.</p>
<p>
	My starting point is a folder containing the TIFF images, each with a .TFW world file.</p>
<p>
	Gotchas:</p>
<p>
	There are <a href="http://docs.geoserver.org/stable/en/user/tutorials/image_mosaic_plugin/imagemosaic.html" target="_blank" title="instructions here">instructions for setting up a raster WMS in GeoServer here</a>, but here is my summary with details of where things can go wrong:</p>
<ul>
	<li>
		Create a workspace, in my case “ESDM_UK_BaseMaps” with a namespace of “<a href="https://www.ordnancesurvey.co.uk/" title="https://www.ordnancesurvey.co.uk/">https://www.ordnancesurvey.co.uk/</a>”</li>
	<li>
		Create a store – this will equate with one type of map, in this case the Landranger 1:50,000 colour raster.</li>
	<li>
		Choose ImageMosaic as the type of store</li>
	<li>
		Select the workspace, and give the store a name, in this case “OS50K”</li>
	<li>
		For the connection parameters, enter the folder that contains the images, in my case “file:D:\MapData\OrdnanceSurvey\50KRasterColour”</li>
	<li>
		GeoServer will then automatically scan the folder and create a shapefile index for the tiles (or “granules” as they bizarrely call them). At this point I was confronted with this error message “Could not list layers for this store, an error occurred retrieving them: Unable to acquire a reader for this coverage with format: ImageMosaic”.</li>
</ul>
<p>
	This is a commonly observed error by all accounts with lots of fairly grumpy exchanges among GeoServer users and developers about how to reproduce it and what might be the causes. It seems it can be raised by a raft of different issues. So I returned to a close reading of the instructions and also found <a href="http://www.adrianwalker.org/2010/08/using-ordnance-survey-open-data-street.html" target="_blank" title="Adrian Walker’s blog">Adrian Walker’s useful blog</a> post about configuring OS maps in GeoServer.</p>
<p>
	It turns out I had two problems:</p>
<p>
	First the .TFW extension must be lower case. So in a command prompt run</p>
<p>
	<font face="Courier New" size="2">ren *.TFW *.tfw</font></p>
<p>
	(note that the image file extension does not have to be lower case)</p>
<p>
	Second, GeoServer needs a .prj file for every image (not required by MapServer).</p>
<p>
	These can be generated using a python script (thanks to Adrian Walker again for this tip):</p>
<pre class="csharpcode">
import glob
content = <span class="str">'PROJCS["OSGB 1936 / British National Grid", GEOGCS["OSGB 1936", DATUM["OSGB_1936", SPHEROID["Airy 1830",6377563.396,299.3249646, AUTHORITY["EPSG","7001"]], AUTHORITY["EPSG","6277"]], PRIMEM["Greenwich",0, AUTHORITY["EPSG","8901"]], UNIT["degree",0.01745329251994328, AUTHORITY["EPSG","9122"]], AUTHORITY["EPSG","4277"]], UNIT["metre",1, AUTHORITY["EPSG","9001"]], PROJECTION["Transverse_Mercator"], PARAMETER["latitude_of_origin",49], PARAMETER["central_meridian",-2], PARAMETER["scale_factor",0.9996012717], PARAMETER["false_easting",400000], PARAMETER["false_northing",-100000], AUTHORITY["EPSG","27700"], AXIS["Easting",EAST], AXIS["Northing",NORTH]]'</span>
tifs = glob.glob(<span class="str">'*.tif'</span>) 
<span class="kwrd">for</span> tif <span class="kwrd">in</span> tifs:  
    prj = tif.split(<span class="str">'.'</span>)[0] + <span class="str">'.prj'</span>  
    file = open(prj,<span class="str">'w'</span>)  
    file.writelines(content)  
    file.close()</pre>
<p>
	<style type="text/css">
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }	</style>
</p>
<p>
	After resolving these issues, it was necessary to return to step 2 above to create the store, but I got the error again! OK, GeoServer had created the index shapefile already, and it was bad due to the missing prj and tfw files; unfortunately GeoServer will not overwrite this file so I had to manually delete the files (the shapefile is named after the store, and comprises seven files with various extensions).&nbsp; After that, creating the store worked fine.</p>
<p>
	Hint: if you examine the .prj file in a text editor and it looks like this, then you need to bin it and start again:</p>
<p>
	<font face="Courier New" size="2">LOCAL_CS["Generic cartesian 2D",<br />
	LOCAL_DATUM["Unknow", 0],<br />
	UNIT["m", 1.0],<br />
	AXIS["x", EAST],<br />
	AXIS["y", NORTH]]</font></p>
<p>
	So on clicking “Save” for the new store, it showed a twirly for a couple of minutes while creating the index shapefile, and then transfers you to the New Layer page, showing the new layer that can be published (it names the layer after the folder containing the images). From there it is a simple matter to complete the configuration of the layer.</p>
<p>
	Note: I think I could have configured a single store one folder higher up, and this would have included each subfolder of TIFFs as a separate layer.</p>
<h3>
	Outcome</h3>
<p>
	Once I had finally got my GeoServer WMS up and running it was time to see whether could fills the gaps in my tilecache…. and I’m very pleased to say yes it could!</p>
<p>
	<a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_4.png"><img alt="1:50K OS map from GeoServer, with no gap" border="0" height="204" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_5.png" style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="1:50K OS map from GeoServer, with no gap" width="244" /></a></p>
<p>
	I’ve posted separately about performance and image quality from the two servers.</p>
<br /><a href='https://www.esdm.co.uk/ordnance-survey-raster-with-geoserver-and-mapserver-some-irks-and-quirks'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/ordnance-survey-raster-with-geoserver-and-mapserver-some-irks-and-quirks'>...</a>]]></description>
      <link>https://www.esdm.co.uk/ordnance-survey-raster-with-geoserver-and-mapserver-some-irks-and-quirks</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/ordnance-survey-raster-with-geoserver-and-mapserver-some-irks-and-quirks</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/ordnance-survey-raster-with-geoserver-and-mapserver-some-irks-and-quirks</guid>
      <pubDate>Sat, 21 Jan 2012 09:46:00 GMT</pubDate>
    </item>
    <item>
      <title>Getting MapServer to work on IIS7.5 Server 2008</title>
      <description><![CDATA[<p>Text below is reproduced from:&nbsp;<a href="http://mas-kono-tes.blogspot.com/2011/03/getting-mapserver-to-work-on-iis75.html">http://mas-kono-tes.blogspot.com/2011/03/getting-mapserver-to-work-on-iis75.html</a>&nbsp;and gives a reasonable overview of how to install mapserver - especially how to navigate IIS 7 menu options.</p>

<p>and CGI install:&nbsp;<a href="http://blogs.iis.net/thomad/archive/2010/04/04/how-to-run-a-cgi-program-under-iis-7-0-or-iis-7-5.aspx">http://blogs.iis.net/thomad/archive/2010/04/04/how-to-run-a-cgi-program-under-iis-7-0-or-iis-7-5.aspx</a></p>

<p>Note: &nbsp;setting paths and env variables is not normally necessary and in fact can be dangerous on systems hosting multiple versions of mapserver&nbsp; or related applications.</p>

<h3>Getting MapServer to work on IIS7.5 Server 2008</h3>

<p>For some reason there doesn't seem to be a lot of documentation on how to install MapServer on IIS7 +. This entry will only cover installation on Windows Server 2008 R2 SP1 (x64) with IIS 7.5.</p>

<p><br />
1. First install&nbsp;<a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a5c84275-3b97-4ab7-a40d-3802b2af5fc2&amp;displaylang=en">Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)</a>.Even though the machine is running Server 2008 (x64) the MapServer binaries that I am using is from MS4W which is for x86. (I have not tried to get the 64 bit version working yet).<br />
<br />
2. From Server Manager select Roles and add the web server role with the following Role services:&nbsp;<br />
&nbsp;</p>

<p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Application Development</p>

<p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .NET Extensibility</p>

<p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CGI</p>

<p>·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ISAPI Extensions</p>

<p>3. Get the MS4W zip file (<a href="http://maptools.org/ms4w/index.phtml?page=downloads.html">ms4w_3.0.1.zip</a>)and extract it to the root directory, (i used C:\ms4w)<br />
<br />
4. Following the instructions&nbsp;<a href="http://www.osgeo.org/pipermail/mapserver-users/2007-November/026549.html">here</a>, I created a separate folder (c:\MapServer) and copied the follow folders into this directory: c:\ms4w\Apache\cgi-bin, C:\ms4w\gdaldata, C:\ms4w\gdalplugins, C:\ms4w\proj and C:\ms4w\tools.</p>

<p><br />
5. Copy the C:\ms4w\setenv.bat file into c:\MapServer and modify it as follows and then run it.</p>

<p>@ECHO OFF<br />
&nbsp;</p>

<p>set PATH=c:\MapServer\\cgi-bin; C:\MapServer\tools\gdal-ogr; C:\MapServer\\tools\mapserv; C:\MapServer\tools\shapelib; C:\MapServer\proj\bin; C:\MapServer\tools\shp2tile; C:\MapServer\tools\shpdiff; C:\MapServer\tools\avce00;<br />
echo GDAL, mapserv, PROJ, and shapelib dll paths set<br />
<br />
set GDAL_DATA=C:\MapServer\gdaldata<br />
echo GDAL_DATA path set<br />
<br />
set GDAL_DRIVER_PATH=C:\MapServer\gdalplugins<br />
echo GDAL_DRIVER_PATH set<br />
<br />
set PROJ_LIB=C:\MapServer\proj\nad<br />
echo PROJ_LIB set<br />
<br />
:ALL_DONE<br />
<br />
6. Right click the C:\MapServer folder, go to the security tab and add the IIS_IUSRS account with Read &amp; execute permissions.<br />
<br />
7. In IIS create a new Website. I called mine Mapping and turned off the default Website. To get CGI working I used the instructions from&nbsp;<a href="http://blogs.iis.net/thomad/archive/2010/04/04/how-to-run-a-cgi-program-under-iis-7-0-or-iis-7-5.aspx">here</a>.</p>

<p align="center">&nbsp;</p>

<p>8. In IIS click on the machine node and select the "ISAPI/CGI restrictions" icon from the Feature view. Select Add and choose C:\MapServer\cgi-bin\MapServ.exe as the "ISAPI or CGI path" and tick the check box for "Allow extension path to execute".<br />
<br />
9. In the Mapping website add a virtual directory (I called mine "cgi") and set the physical path to C:\MapServer\cgi-bin.<br />
&nbsp;&nbsp;<br />
10. Select the newly created cgi virtual directory and select the "Handler Mappings" icon in the Feature view. Click the Edit Feature Permissions link in the action menu and check the box "Execute".<br />
<br />
11. If you now navigate to http://localhost/cgi/mapserv.exe you should see the message:<br />
<br />
No query information to decode. QUERY_STRING is set, but empty<br />
<br />
which means you map server is up and running.<br />
<br />
12. To try out a demo, I created C:\MapServer\apps\Sample directories and then added the example1-1.map file from "<a href="http://maptools.org/dl/ms4w/mapserv_demo_ms4w.zip">MapServer Itasca Demo Application</a>". I also added a Data directory inside sample and added states_ugl.dbf, states_ugl.shp and states_ugl.shx into it. The paths in example1-1.map file needed to be updated to point to the right locations and then you can browse to it using&nbsp;<br />
http://localhost/cgi/mapserv.exe?map=C:/MapServer/apps/sample/example1-1.map&amp;layer=states&amp;mode=map<br />
<br />
Hopefully these instructions may help somebody out. There maybe security issues with this setup so its up to you to figure it out and fix them.</p>
<br /><a href='https://www.esdm.co.uk/getting-mapserver-to-work-on-iis75-server-2008'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/getting-mapserver-to-work-on-iis75-server-2008'>...</a>]]></description>
      <link>https://www.esdm.co.uk/getting-mapserver-to-work-on-iis75-server-2008</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/getting-mapserver-to-work-on-iis75-server-2008</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/getting-mapserver-to-work-on-iis75-server-2008</guid>
      <pubDate>Sat, 12 Nov 2011 10:18:00 GMT</pubDate>
    </item>
    <item>
      <title>Mapserver 6 and regular expressions</title>
      <description><![CDATA[<p>In earlier versions of mapserver you might have a regular expression that looked like:</p>
<p style="padding-left: 30px;">EXPRESSION ('[HAB_TYPE]' =~/^A1.1/) </p>
<p> If you try this with mapserver 6 however (especially on large datasets) you can get several mapserver threads starting - each of which ended up consuming 2GB RAM on the server - and never finishing</p>
<p>Changing the expression to:</p>
<p style="padding-left: 30px;">EXPRESSION ('[HAB_TYPE]'  ~ '^A1.1') </p>
<p> fixes it.</p>
<p>This is a nasty issue as most changes to the map file are "breaking" changes so it just doesn't work.  This does run - but appears to kill the server.</p><br /><a href='https://www.esdm.co.uk/mapserver-6-and-regular-expressions'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/mapserver-6-and-regular-expressions'>...</a>]]></description>
      <link>https://www.esdm.co.uk/mapserver-6-and-regular-expressions</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/mapserver-6-and-regular-expressions</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/mapserver-6-and-regular-expressions</guid>
      <pubDate>Tue, 08 Nov 2011 15:42:00 GMT</pubDate>
    </item>
  </channel>
</rss>