 <?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~8" rel="self" type="application/rss+xml" />
    <itunes:owner />
    <itunes:explicit>no</itunes:explicit>
    <item>
      <title>GeoServer WFS fails on SQL Server tables/views with GUID data type</title>
      <description><![CDATA[<p>Just a quick note that might be useful to some.</p>

<h4>The problem...</h4>

<p>If you publish a SQL Server (in this case 2014) table or view with a GUID field using GeoServer (version&nbsp;2.10), it will fail to make&nbsp; a valid WFS because the &amp;request=DescribeFeatureType response <em>will not include these layers</em>.</p>

<p>This manifests itself in various ways depending on the client, but in QGIS on trying to load the layer into the map we get this in the "Log Messages Panel":</p>

<blockquote>
<p>Analysis of DescribeFeatureType response failed for url&nbsp; srsname='EPSG:27700' typename=xxx:yyyurl='https://mysite.com/myworkspace/wfs' version='1.0.0' table="" sql=: it is probably a schema for Complex Features</p>
</blockquote>

<p>which had me puzzled for quite some time!</p>

<h4>The solution...</h4>

<p>Changing the data source view to include this field with</p>

<p>CAST(myGUID AS varchar(36)) AS myGUID</p>

<p>then hitting "Reload feature type" in the GeoServer layer configuration screen fixes it. This changes the field data type from "UUID" to "string" in that screen. Or just omit the field entirely.</p>

<p>My guess is this will not help transactional WFS, but I have not tested this. Overall, GUIDs are still best avoided in GIS-land as they are so poorly supported by the database drivers.</p>
<br /><a href='https://www.esdm.co.uk/geoserver-wfs-fails-on-sql-server-tablesviews-with-guid-data-type'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/geoserver-wfs-fails-on-sql-server-tablesviews-with-guid-data-type'>...</a>]]></description>
      <link>https://www.esdm.co.uk/geoserver-wfs-fails-on-sql-server-tablesviews-with-guid-data-type</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/geoserver-wfs-fails-on-sql-server-tablesviews-with-guid-data-type</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/geoserver-wfs-fails-on-sql-server-tablesviews-with-guid-data-type</guid>
      <pubDate>Wed, 11 Jan 2017 22:23:00 GMT</pubDate>
    </item>
    <item>
      <title>Using R with spatial data</title>
      <description><![CDATA[<p>&nbsp;</p> <p>R is a cross platform statistical package which is becoming extremely widely used.&nbsp; It is modular and so there are all sorts of add ins available, including a number of sophisticated tools for spatial analysis some of which run considerably faster than Arc / MapInfo.&nbsp; Organisations are also starting to move to this for spatial analysis as its cheaper but more relevantly doesn’t suffer from the endless version changes that ArcGIS is particular forces on people.</p> <p>R is generally used for a wide range of statistics – but also has the option to generate publication quality graphs (pdfs or images)</p> <h1>Getting started</h1> <p>R can be downloaded here: <a href="http://www.r-project.org/">http://www.r-project.org/</a></p> <p>Its also suggested (on Windows) to use r studio - <a href="http://www.rstudio.com/">http://www.rstudio.com/</a> which gives a more friendly IDE</p> <p>R is a scripted tool – so it can be a steep learning curve but there are endless examples on the web to help get started.</p> <h1>Spatial example using OGR</h1> <p>This syntax is a little obscure – but potentially of considerable use for a wide range of spatial data.&nbsp; Reading from shapefiles (or any other OGR supported datasource is easy / possible)</p> <h2>Read data from SQL server</h2> <p>#download and load rgdal libraries<br>install.packages("rgdal")<br>library(rgdal)</p> <p>#Use ogrinfo to get information about a shape file called stations<br>ogrInfo("C:/ToFile/RNLI/data", "Stations")</p> <p>#List the spatial layers available in a SQL server database<br>#Note you must have the standard OGR tables geometry_columns and spatial_ref_sys present and populated in your database<br>#Some people say you need a DSN as well – not sure you do …<br>ogrListLayers("MSSQL:server=SQL2008;database=CMSI-NE;trusted_connection=yes") </p> <p>#Read a table of polygon objects into a new sitesPoly object<br>#Then plot them on a map<br>#N.B.&nbsp; You can’t have binary data in your table – so if you do create a view or somesuch<br>sitesPoly &lt;- readOGR(dsn='MSSQL:server=SQL2008;database=CMSI-NE;trusted_connection=true', layer='SitesGeom') <br>plot(sitesPoly) </p> <p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_84.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_70.png" width="244" height="171"></a></p> <p>#Select just one record from the layer<br>oneSite = subset(sitesPoly, sitesPoly$MI_PRINX == 420)</p> <p>#Make sure the layer is assigned the correct projection<br>proj4string(oneSite) = CRS("+init=epsg:27700")</p> <p>#Transform the layer to another projection<br>oneSite_latlong = spTransform(oneSite, CRS("+init=epsg:4326"))</p> <p>#Load another library which contains some world boundaries<br>#Load up coast and countries outlines<br>library(rworldmap)<br>data(coastsCoarse)<br>data(countriesLow)</p><pre>&nbsp;</pre>
<p>#plot countries outline limiting extent to Europe<br>plot(countriesLow, xlim = c(-10, 10), ylim = c(45, 60), legend = F)</p>
<p>#Add sites onto existing map setting colours</p>
<p>proj4string(sitesPoly_ll) = CRS("+init=epsg:27700")<br>sitesPoly_ll = spTransform(sitesPoly, CRS("+init=epsg:4326"))<br>plot(sitesPoly_ll, col = "red", border="red", Add=T)</p>
<p>&nbsp;</p>
<h2>Use a different library to do some plotting</h2>
<p>install.packages("maps")<br>install.packages("mapdata")<br>library(maps)<br>library(mapsdata)</p>
<p>#Select polygons making up UK and plot<br>#Then plot a point on top<br>map('worldHires',<br>&nbsp;&nbsp;&nbsp; c('UK', 'Ireland', 'Isle of Man','Isle of Wight','Wales:Anglesey'),<br>&nbsp;&nbsp;&nbsp; xlim=c(-11,3), ylim=c(49,60.9))<br>points(-1.615672,54.977768,col=2,pch=18)</p>
<p><a href="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_85.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://www.esdm.co.uk/Data/Sites/1/media/wlw/image_thumb_71.png" width="244" height="170"></a></p><br /><a href='https://www.esdm.co.uk/using-r-with-spatial-data'></a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/using-r-with-spatial-data'>...</a>]]></description>
      <link>https://www.esdm.co.uk/using-r-with-spatial-data</link>
      <author>()</author>
      <comments>https://www.esdm.co.uk/using-r-with-spatial-data</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/using-r-with-spatial-data</guid>
      <pubDate>Sat, 28 Dec 2013 12:53:39 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>Some jottings on SQL Azure and GIS</title>
      <description><![CDATA[<p>I have set up a SQL Azure 90 day trial (as of 18th November) to test whether ArcSquirrel can work with Azure. This was prompted by an email from Robert Cheetham, CEO at Azavea, who is investigating cloud solutions for their Cicero product. Here are some notes about</p>

<ol>
	<li>setting up and accessing SQL Azure databases</li>
	<li>using SQL Azure with ArcGIS + ArcSquirrel and MapLink</li>
	<li>using SQL Azure with Quantum GIS and MapServer.</li>
</ol>

<h4>Azure Management Portal</h4>

<p>Although I’ve never set up any cloud services before (other than <a href="http://www.arvixe.com/" target="_blank" title="Arvixe web site">Arvixe web hosting</a>) it was incredibly easy to setup a trial SQL Azure subscription (“Windows Azure Platform Introductory Special”), create a database, and add some firewall rules to control access. I didn’t dig deep, but the “Management Portal” seems nice and simple:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_10.png"><img alt="Azure Management Portal" border="0" height="188" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_4.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Azure Management Portal" width="244" />&nbsp;</a></p>

<p>It helpfully tells you your connection string for ADO.Net, ODBC and PHP (passwords not included!):</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_8.png"><img alt="SQL Azure connection strings" border="0" height="180" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_3.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure connection strings" width="244" />&nbsp;</a></p>

<p>See this page for <a href="http://www.microsoft.com/windowsazure/offers/popup/popup.aspx?lang=en&amp;locale=en-gb&amp;offer=ms-azr-0018p&amp;no-rewrite=true" target="_blank" title="Details of the Windows Azure Platform Introductory Special">details of the Windows Azure Platform Introductory Special</a> including what you get for no charge and the pricing for the rest.</p>

<h4>MapLink, ArcSquirrel and Azure</h4>

<p>Hartmut connected up our MapLink to the database and pushed some spatial data into my Azure database from ArcGIS – 20,000 polygons took about 75 minutes.&nbsp; Hartmut had the layers drawing in ArcMAP, performing as well as in a normal SQL Server instance apparently, with only minor mods to our code to make the initial connection. However editing will not work without some more tweaks - MapLink and ArcSquirrel rely on some SQL metadata that is a little different on Azure.</p>

<h4>SQL Server Management Studio and MS Access</h4>

<p>Connecting with SSMS is simple, however you get reduced functionality – for example you cannot right-click &gt; edit top 200 records or anything, so quick edits of a small table need to be done with SQL or in MS Access or some other client. Fortunately connecting with MS Access (ODBC + SQL Native Client 10) is also simple, and&nbsp; the Azure database behaves just like a local SQL instance – remarkable querying speed (all things considered), though slower inserts (10,000 records took something like 15 minutes). NB you cannot directly link a spatial table into Access because it doesn’t recognize the geometry data type; but to update attributes you can link a view.</p>

<p>Also, in SSMS you get no designer tools, e.g. for creating a view; everything has to be done with T-SQL.</p>

<h4>SQL Azure Database Manager</h4>

<p>After writing the above I found the database manager in the Azure control panel, which has functionality similar to SSMS, including the ability to edit the tables*:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_12.png"><img alt="SQL Azure database manager" border="0" height="154" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_5.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure database manager" width="244" />&nbsp;</a></p>

<p>* spatial data types not supported for view or edit.</p>

<p>You get a designer for creating/modifying tables, but views and stored procedures are T-SQL only.</p>

<h4>MapServer, OGR and Azure</h4>

<p>Next I wanted to try serving the data through MapServer, and viewing/editing the data in Quantum GIS or MapInfo.&nbsp; MapServer and QGIS require the “geometry_columns” and “spatial_ref_sys” tables, and the easiest way to create these is to push some data in with ogr2ogr.</p>

<p>So I tried this from one of our London servers. I loaded a few hundred linear features, but got four errors like “INSERT command for new feature failed… incorrect syntax…”. On checking the results, a) while the geometries had loaded fine, all the attribute fields were NULL, and b) the spatial_ref_sys table was empty.&nbsp; I had four attribute fields, so my guess is that each syntax error was one field update across all records using a join on the incoming data.</p>

<p>Next I hooked up a MapServer WMS to my SQL Azure tables. MapServer had no trouble connecting to my Azure tables, but initially wouldn’t draw anything…&nbsp; on investigating I found that ogr2ogr had not correctly set the SRID of the geometries, so I had to update them “manually” with:</p>

<pre class="csharpcode">
<span class="kwrd">update</span> esdm_waters <span class="kwrd">set</span> ogr_geometry.STSrid = 4326</pre>
<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>(which, incidentally, took 1 minute 52 seconds for 788 rows, demonstrating that updating an Azure database ain’t quick).</p>

<p>Clearly OGR needs a little work to do on SQL Azure support, but this was enough to get me going.</p>

<p>The WMS worked, so to challenge it a little more I set up another WMS onto a table with about 8000 sub-tidal habitat polygons, showing red in this OpenLayers map:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_2.png"><img alt="MapServer WMS from SQL Azure table" border="0" height="127" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="MapServer WMS from SQL Azure table" width="244" />&nbsp;</a></p>

<p>And here showing the rivers WMS as well (blue lines):</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_4.png"><img alt="MapServer WMS from SQL Azure table" border="0" height="127" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_1.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="MapServer WMS from SQL Azure table" width="244" />&nbsp;</a></p>

<p>Performance of these two layers was perfectly acceptable, though actually about 100% slower than the same WMS working from a local SQL Server 2008 Express instance. It would be interesting to see what it could do with MapServer also running on Azure.</p>

<p>I also tried a WFS – again, performance was acceptable though significantly slower than running with a local SQL instance (though I didn’t do strict comparisons).</p>

<h4>Quantum GIS and SQL Azure</h4>

<p>I found this really helpful blog post to get started: <a href="http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/" title="http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/">http://woostuff.wordpress.com/2011/03/13/opening-ms-sql-spatial-in-qgis/</a></p>

<p>Adding the layers requires some python script, but I’m sure someone will write a GUI plugin for QGIS soon.</p>

<p>First make sure you are running a version of QGIS that has GDAL/OGR 1.8 libraries – I’m on 1.7.0 which is OK.</p>

<p>Open the Plugins menu &gt; Python Console</p>

<p>and type in these two commands (modified for your data):</p>

<pre class="csharpcode">
uri = <span class="str">"MSSQL:server={serverName};database={databaseName};tables={tableName};trusted_connection=yes"</span>
qgis.utils.iface.addVectorLayer(uri,<span class="str">'{yourLayerNameHere}'</span>,<span class="str">'ogr'</span>)
</pre>
<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>In my case:</p>

<pre class="csharpcode">
uri = <span class="str">"MSSQL:server=tcp:a0awtn7gg9.database.windows.net;database=ArcSquirrel1;tables=esdm_waters;Uid=exegesis@a0awtn7gg9;Pwd=myPassword;"</span>
qgis.utils.iface.addVectorLayer(uri,<span class="rem">'Rivers','ogr')</span>
</pre>

<pre class="csharpcode">
Without any fuss my rivers dataset appeared:</pre>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_14.png"><img alt="SQL Azure table in Quantum GIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_6.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure table in Quantum GIS" width="244" />&nbsp;</a></p>

<p>And I can create and edit features and their attributes, here adding a test line off the Hebrides:</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_16.png"><img alt="Editing SQL Azure features in QGIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_7.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Editing SQL Azure features in QGIS" width="244" />&nbsp;</a></p>

<p>And to prove it, here’s my new feature in OpenLayers…</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_18.png"><img alt="Edited features from QGIS and SQL Azure" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_8.png" style="margin: 0px; width: 244px; height: 127px; padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="Edited features from QGIS and SQL Azure" />&nbsp;</a></p>

<p>And finally, here we have the habitat polygons (EPSG:27700) colour coded by habitat type, as well as the rivers (EPSG:4326), in QGIS. Polygon editing also worked fine, once I’d worked out why my new polygons kept vanishing (doh, classified symbols).</p>

<p><a href="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_20.png"><img alt="SQL Azure polygons thematically mapped in QGIS" border="0" height="237" src="https://www.esdm.co.uk/Data/Sites/1/Windows-Live-Writer/Some-jottings-on-SQL-Azure-and-GIS_5C47/image_thumb_9.png" style="padding-top: 0px; padding-right: 0px; padding-left: 0px; display: inline; background-image: none;" title="SQL Azure polygons thematically mapped in QGIS" width="244" />&nbsp;</a></p>

<p>Lots to think about, and I look forward to editing the same data with ArcGIS and ArcSquirrel soon…</p>
<br /><a href='https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis'>...</a>]]></description>
      <link>https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/some-jottings-on-sql-azure-and-gis</guid>
      <pubDate>Sat, 19 Nov 2011 11:42:00 GMT</pubDate>
    </item>
    <item>
      <title>Don't forget the PG tip</title>
      <description><![CDATA[<p>
	When opening a PostGIS datasource using the OGR C# wrapper in .Net, the connection string must have "PG:" prefix, as follows:</p>
<p>
	...</p>
<p>
	Imports OSGeo.OGR</p>
<p>
	...</p>
<p>
	Dim drv As OSGeo.OGR.Driver = OSGeo.OGR.Ogr.GetDriverByName("PostgreSQL")<br />
	Dim connStr as string = "<strong>PG:</strong>dbname='myDB' host='192.168.etc.etc' port='5433' user='foo' password='bar'"<br />
	Dim ds As OSGeo.OGR.DataSource&nbsp; = drv.Open(connStr, 0)</p>
<br /><a href='https://www.esdm.co.uk/dont-forget-the-pg'>Crispin Flower</a>&nbsp;&nbsp;<a href='https://www.esdm.co.uk/dont-forget-the-pg'>...</a>]]></description>
      <link>https://www.esdm.co.uk/dont-forget-the-pg</link>
      <author>crispin.flower@idoxgroup.com (Crispin Flower)</author>
      <comments>https://www.esdm.co.uk/dont-forget-the-pg</comments>
      <guid isPermaLink="true">https://www.esdm.co.uk/dont-forget-the-pg</guid>
      <pubDate>Tue, 15 Nov 2011 09:07: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>