<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Azavea Labs &#187; wms</title>
	<atom:link href="http://www.azavea.com/blogs/labs/tag/wms/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.azavea.com/blogs/labs</link>
	<description>Insight on what our engineers are doing</description>
	<lastBuildDate>Mon, 06 Feb 2012 22:32:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Using the CQL_FILTER parameter with OpenLayers WMS layers</title>
		<link>http://www.azavea.com/blogs/labs/2011/06/using-the-cql_filter-parameter-with-openlayers-wms-layers/</link>
		<comments>http://www.azavea.com/blogs/labs/2011/06/using-the-cql_filter-parameter-with-openlayers-wms-layers/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 20:33:20 +0000</pubDate>
		<dc:creator>Carissa Brittain</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[cql]]></category>
		<category><![CDATA[GeoServer]]></category>
		<category><![CDATA[openlayers]]></category>
		<category><![CDATA[wms]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=1528</guid>
		<description><![CDATA[I&#8217;ve used Openlayer&#8217;s Marker layer in several projects and have always just accepted that I can&#8217;t display more than around 500 markers at a time for a given query. Recently, I found another way. We&#8217;re using GeoServer as a WMS tile server for the tree and municipal boundary layers in PhillyTreeMap.org. GeoServer&#8217;s WMS implementation allows [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve used Openlayer&#8217;s <a title="The docs" href="http://dev.openlayers.org/apidocs/files/OpenLayers/Layer/Markers-js.html" target="_blank">Marker layer</a> in several projects and have always just accepted that I can&#8217;t display more than around <a title="... or 50 for IE" href="http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#Markers" target="_blank">500 markers at a time</a> for a given query. Recently, I found another way. We&#8217;re using <a href="http://docs.geoserver.org/latest/en/user/index.html" target="_blank">GeoServer</a> as a WMS tile server for the tree and municipal boundary layers in <a title="Is your tree in our database?" href="http://www.phillytreemap.org" target="_blank">PhillyTreeMap.org</a>. GeoServer&#8217;s WMS implementation allows an additional parameter in the url called <a title="With an example even!" href="http://docs.geoserver.org/latest/en/user/googleearth/features/filters.html?highlight=cql_filter#cql-filter" target="_blank">CQL_FILTER</a>. This parameter allows you to use a little language called Common Query Language, or CQL, to <a href="http://docs.geoserver.org/latest/en/user/tutorials/cql/cql_tutorial.html" target="_blank">apply data filters to the tiles</a> that GeoServer generates.  CQL is a plain text, human readable query language created by the OGC, but I like to think of it as an extremely limited third-cousin-by-adoption of SQL. I haven&#8217;t found too much in the way of documentation on this <a title="though maybe not this obscure..." href="http://www.farlang.com/gemstones/burnham-precious-stones/page_001" target="_blank">obscure little gem</a>, so here&#8217;s a rundown of how we used it to display search results in PhillyTreeMap.org.</p>
<p>If you look through the <a title="A tutorial with holes" href="http://docs.geoserver.org/latest/en/user/tutorials/cql/cql_tutorial.html" target="_blank">CQL and ECQL</a> page in GeoServer&#8217;s documentation, there are several examples but they don&#8217;t cover everything you can do with CQL. Basically, a CQL filter is a list of phrases similar to where clauses in SQL, separated by the combiner words AND or OR. You can use the following operators in a CQL phrase:</p>
<ul>
<li>Comparison operations: =, &lt;, &gt;, and combinations</li>
<li>Math expressions: +, -, *, /</li>
<li>NOT</li>
<li>IS, EXISTS</li>
<li>BETWEEN, BEFORE, AFTER</li>
<li>IN</li>
<li>LIKE</li>
<li>Geometric operators: CONTAINS, BBOX, DWITHIN, CROSS(ES), INTERSECT(S)</li>
</ul>
<p>Some of these operations have examples in the GeoServer documentation, and others can be inferred from the <a title="Fewer holes, but more obfuscated" href="http://docs.geotools.org/latest/userguide/library/cql/cql.html" target="_blank">GeoTools documentation</a> (the stuff in their CQL.toFilter() calls). CQL can also call any of GeoServer&#8217;s <a href="http://docs.geoserver.org/latest/en/user/filter/function_reference.html#filter-function-reference" target="_blank">filter functions</a>.You can add parenthesis as needed to affect the order the filters are evaluated in, just like in SQL.</p>
<p>CQL has a <a title="Just like strapping a rocket to..." href="http://www.alexross.com/CJ063.html" target="_blank">lot of power</a> for such a short spec, but it has a one very large deficiency that requires some database designing to avoid: the utter lack of join support. This makes sense when you consider that GeoServer doesn&#8217;t know about joins either. Ultimately, you&#8217;re using CQL against the GeoServer layer, not the underlying database structure. Building views or adding reference columns to the table GeoServer is accessing can help get around this.</p>
<p>In PhillyTreeMap.org, we use 4 types of CQL filters: id lookups using =, null checks using IS, date and integer ranges using BETWEEN and text searches using LIKE. Here are examples of those uses along with some array joining to get a valid CQL filter string at the end:</p>
<p><code>filter_list = []<br />
filter_list.append("species_id = 212")<br />
filter_list.append("height IS NULL")<br />
filter_list.append("dbh BETWEEN 10 and 20")<br />
filter_list.append("neighborhood_id_list LIKE '%42%' ")<br />
cql = ' AND '.join(filter_list)<br />
# should look like this: "species_id = 212 AND height IS NULL AND dbh BETWEEN 10 and 20 AND neighborhood_id_list LIKE '%42%' "<br />
</code></p>
<p>The above CQL filter would locate trees in a specific species, have no height value, only have dbh values between 10 and 20 inches and are in a particular neighborhood. The neighborhood_id_list filter would have been a join if this were written in standard SQL since neighborhoods and trees have a many-to-many relationship in our database. Since we can&#8217;t do joins, any time a tree is added or the location is updated, all of it&#8217;s related geographies&#8217; ids are added to a reference column on the tree, and used specifically for this type of query.</p>
<p>CQL is passed to GeoServer in the same way as any other WMS variable. We&#8217;re using openlayers, so most of the WMS configuration variables are already set when we create the layer. The WMS layer has a little method called <a href="http://dev.openlayers.org/docs/files/OpenLayers/Layer/WMS-js.html#OpenLayers.Layer.WMS.mergeNewParams" target="_blank">mergeNewParams</a> that lets us change those parameters after the layer has been initialized. It also automatically redraws the layer, so the changes take place immediately. To add CQL to the WMS call, just add the CQL_FILTER variable to the layer&#8217;s parameters and the layer should update.</p>
<p><code>wms_layer.mergeNewParams({'CQL_FILTER': "species_id = 212 AND height IS NULL AND dbh BETWEEN 10 and 20 AND neighborhood_id_list LIKE '%42%' "});<br />
</code></p>
<p>You can remove any filters by <a href="http://www.javascriptkit.com/jsref/other_operators.shtml" target="_blank">deleting the parameter</a> from the layer as if it was a normal javascript object. You&#8217;ll need to redraw the layer yourself before the change will be visible.</p>
<p><code>delete wms_layer.params.CQL_FILTER;<br />
wms_layer.redraw();<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2011/06/using-the-cql_filter-parameter-with-openlayers-wms-layers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MapServer wins FOSS4G 2009 WMS Shootout</title>
		<link>http://www.azavea.com/blogs/labs/2009/10/mapserver-wins-foss4g-2009-wms-shootout/</link>
		<comments>http://www.azavea.com/blogs/labs/2009/10/mapserver-wins-foss4g-2009-wms-shootout/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 19:39:28 +0000</pubDate>
		<dc:creator>David Zwarg</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[foss4g]]></category>
		<category><![CDATA[GeoServer]]></category>
		<category><![CDATA[mapserver]]></category>
		<category><![CDATA[wms]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=335</guid>
		<description><![CDATA[MapServer is back on top! The results of the WMS shootout at FOSS4G 2009 are out, and MapServer beats GeoServer in terms of speed. Though it begs the question: who would win a WMS shootout: WMS, WMS, WMS, WMS, or WMS? http://geoserver.org/display/GEOS/Welcome]]></description>
			<content:encoded><![CDATA[<p>MapServer is back on top! The results of the <a href="http://www.slideshare.net/gatewaygeomatics.com/wms-performance-shootout">WMS shootout at FOSS4G 2009</a> are out, and <a href="http://mapserver.org/">MapServer </a>beats <a href="http://geoserver.org/display/GEOS/Welcome">GeoServer</a> in terms of speed.</p>
<p>Though it begs the question: who <em>would</em> win a WMS shootout: <a href="http://www.wms.org/">WMS</a>, <a href="http://www.inventoryops.com/warehouse_management_systems.htm">WMS</a>, <a href="http://www.cellularatsea.com/">WMS</a>, <a href="http://www.google.com/finance?q=NYSE:WMS">WMS</a>, or <a href="http://www.wamfg.org/">WMS</a>?</p>
<div style="overflow: hidden;width: 1px;height: 1px">http://geoserver.org/display/GEOS/Welcome</div>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2009/10/mapserver-wins-foss4g-2009-wms-shootout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tricks &amp; Woes w/ WMS GetFeatureInfo</title>
		<link>http://www.azavea.com/blogs/labs/2009/04/tricks-woes-w-wms-getfeatureinfo/</link>
		<comments>http://www.azavea.com/blogs/labs/2009/04/tricks-woes-w-wms-getfeatureinfo/#comments</comments>
		<pubDate>Wed, 15 Apr 2009 21:07:45 +0000</pubDate>
		<dc:creator>Josh Marcus</dc:creator>
				<category><![CDATA[Posts]]></category>
		<category><![CDATA[arcgis]]></category>
		<category><![CDATA[ArcIMS]]></category>
		<category><![CDATA[GeoServer]]></category>
		<category><![CDATA[mapserver]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[wms]]></category>

		<guid isPermaLink="false">http://www.azavea.com/blogs/labs/?p=15</guid>
		<description><![CDATA[Here&#8217;s a trick that could be useful if you&#8217;re writing a simple map application in JavaScript that interacts with a WMS map service that you control, and your application needs information about a feature that the user has clicked on.   Did you know that you can cajole your WMS server to directly produce JSON (which [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a trick that could be useful if you&#8217;re writing a simple map application in JavaScript that interacts with a <a href="http://www.opengeospatial.org/standards/wms">WMS </a>map service that you control, and your application needs information about a feature that the user has clicked on.   Did you know that you can cajole your WMS server to directly produce <a href="http://www.json.org">JSON</a> (which is a very convenient way to receive data in a JS application) with feature information as a response to a WMS request?  I found this trick useful in <a href="http://africamap.harvard.edu">a recent application</a> as a simple approach, if one doesn&#8217;t mind wrangling with server configuration.  Unfortunately, it involves using an under-specified part of the WMS standard, so this recipe is also a good illustration of where the OGC WMS standard could be improved.</p>
<p>In the WMS specification, OGC defined an &#8220;optional&#8221; GetFeatureInfo request that returns feature information based on a pixel from a map.  It&#8217;s both useful and limiting that the request is based on the pixel &#8212; it&#8217;s useful in that you can just pass along the pixel that the user clicked on, but you don&#8217;t have a lot of control (without other trickery I won&#8217;t go into here).  But here&#8217;s the catch: the output format isn&#8217;t defined in the standard.  But here the problem becomes the opportunity &#8212; most WMS servers allow you can define your own output format, which includes JSON.</p>
<p>But again the problem returns to the fact that there isn&#8217;t a standard in place here:  different mapservers handle the output format definition differently.  MapServer has a very straightforward method &#8212; it will respond to a &#8220;text/html&#8221; request with three templates you can define: you can define a header template, a content template (that is repeated for each feature), and a footer template.  It will replace any attribute name surrounded with brackets with the value of the attribute.  So if you create a header.html file with a single left bracket (&#8216;[') and a footer.html with a single right bracket (']&#8216;) and then a template.html file that is something like:</p>
<blockquote><p>{<br />
id: &#8220;[id]&#8220;,<br />
attribute: &#8220;[attribute]&#8220;<br />
}</p></blockquote>
<p>you&#8217;ll get responses to your GetFeatureInfo request in proper JSON, e.g.:</p>
<blockquote><p>&#8220;[ { id: "123", attribute: "foo" }, { id: "456", attribute: "bar" } ]&#8220;</p></blockquote>
<p>GeoServer has a different structure for its GetFeatureInfo templates, which is <a href="http://geoserver.org/display/GEOSDOC/GetFeatureInfo+templates">described here</a> but the same basic approach works, with the major difference being that you create a single template with header and footer sections.  I&#8217;m not sure how it&#8217;s done with ArcGIS Server, but <a title="with ArcIMS" href="http://webhelp.esri.com/arcims/9.2/general/mergedProjects/wms_connect/wms_connector/get_featureinfo.htm">with ArcIMS</a> there are XSL files for each output format, and you could create one that generates JSON without too much trouble if you are familiar with XSL.  If someone figures out how to do this with ArcGIS Server, I&#8217;ve love to know.</p>
<p>Of course, what would <em>really</em> be fantastic would be if the OGC standard was extended to include a standard output format &#8212; I won&#8217;t even dare to dream for a standard way to define the output format.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.azavea.com/blogs/labs/2009/04/tricks-woes-w-wms-getfeatureinfo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

