<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5074699861565622759</id><updated>2012-02-16T10:43:50.458-08:00</updated><category term='raster'/><category term='sig'/><category term='gis'/><category term='geoprocessing'/><category term='gearscape'/><category term='ggl2'/><category term='extrude'/><title type='text'>GGL2</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-8387331239486117139</id><published>2012-02-08T02:56:00.000-08:00</published><updated>2012-02-08T05:09:37.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='extrude'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Extruding buildings</title><content type='html'>In this post we will see how to extrude buildings so we get a 3D layer from a 2D layer. For this purpose we will create this algorithm:&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #f0f0f0; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(204, 204, 204); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(204, 204, 204); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: dashed; border-top-width: 1px; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;alg extrude(FeatureCollection buildings) returns FeatureCollection {&lt;br /&gt;  double height = 20;&lt;br /&gt;  geometry prev;&lt;br /&gt;  FeatureCollection ret;&lt;br /&gt;&lt;br /&gt;  foreach building in buildings {&lt;br /&gt;      process building/the_geom coordinates as g do {&lt;br /&gt;          if (prev is not null) {&lt;br /&gt;              x0 = ST_X(prev);&lt;br /&gt;              y0 = ST_Y(prev);&lt;br /&gt;              x1 = ST_X(g);&lt;br /&gt;              y1 = ST_Y(g);&lt;br /&gt;&lt;br /&gt;              face = POLYGON((x0 y0 0, x0 y0 height, x1 y1 height, x1 y1 0, x0 y0 0));&lt;br /&gt;              add { id = autonumeric(), the_geom = face } to ret;&lt;br /&gt;          }&lt;br /&gt;          prev = g;&lt;br /&gt;      }&lt;br /&gt;      prev = null;&lt;br /&gt;  }&lt;br /&gt;  return ret;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;It may seem a little difficult to understand at first, but we will take a look at each part of the algorithm and we will see that it's not that complicated.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;As we can see, our algorithm will receive a feature collection with 2D buildings and will return another feature collection. The returning collection will have one 3D building face for each edge in the original collection. This is, if we provide a square building, we will receive four 3D walls.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;First, we set the height for the buildings (constant for all buildings) and declare the returning collection &lt;i&gt;ret&lt;/i&gt;. Also, we declare a &lt;i&gt;prev&lt;/i&gt; geometry variable where we will store a coordinate we need for the calculations. We will see it later.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;  double height = 20;&lt;br /&gt;  geometry prev;&lt;br /&gt;  FeatureCollection ret;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;Next, we iterate over each building in the collection and, for each building, we iterate over each coordinate&lt;/div&gt;&lt;br /&gt;&lt;pre style="background-attachment: initial; background-clip: initial; background-color: #f0f0f0; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(204, 204, 204); border-bottom-style: dashed; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(204, 204, 204); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: dashed; border-top-width: 1px; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow-x: auto; overflow-y: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;  foreach building in buildings {&lt;br /&gt;      process building/the_geom coordinates as g do {&lt;br /&gt;          if (prev is not null) {&lt;br /&gt;              x0 = ST_X(prev);&lt;br /&gt;              y0 = ST_Y(prev);&lt;br /&gt;              x1 = ST_X(g);&lt;br /&gt;              y1 = ST_Y(g);&lt;br /&gt;&lt;br /&gt;              face = POLYGON((x0 y0 0, x0 y0 height, x1 y1 height, x1 y1 0, x0 y0 0));&lt;br /&gt;              add { id = autonumeric(), the_geom = face } to ret;&lt;br /&gt;          }&lt;br /&gt;          prev = g;&lt;br /&gt;      }&lt;br /&gt;      prev = null;&lt;br /&gt;  }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;With this last &lt;i&gt;process&lt;/i&gt; statement, what we do is to process each coordinate in &lt;i&gt;building/the_geom&lt;/i&gt;. Then, inside the &lt;i&gt;process&lt;/i&gt; expression, let's ignore the &lt;i&gt;if&lt;/i&gt; statement for a moment and focus on this: &lt;/div&gt;&lt;br /&gt;&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;  prev = g;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;Each time we process a coordinate inside each building, we store that coordinate in the &lt;i&gt;prev&lt;/i&gt; variable. So, if we use the current coordinate (&lt;i&gt;g&lt;/i&gt;) and the previous coordinate (&lt;i&gt;prev&lt;/i&gt;), we can have each edge in the original collection. All we need to do is to extrude that edge and add it to the returning collection.&lt;br /&gt;&lt;br /&gt;Note also that once we have finished processing the coordinates of a building, we set&amp;nbsp;&lt;i&gt;prev&lt;/i&gt;&amp;nbsp;to null again so the&amp;nbsp;&lt;i&gt;is null&lt;/i&gt;&amp;nbsp;check is true for the first coordinate in the next building.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;And finally, let's take a look at the &lt;i&gt;if&lt;/i&gt; statement, where the magic happens:&lt;/div&gt;&lt;br /&gt;&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;    if (prev is not null) {&lt;br /&gt;      x0 = ST_X(prev);&lt;br /&gt;      y0 = ST_Y(prev);&lt;br /&gt;      x1 = ST_X(g);&lt;br /&gt;      y1 = ST_Y(g);&lt;br /&gt;&lt;br /&gt;      face = POLYGON((x0 y0 0, x0 y0 height, x1 y1 height, x1 y1 0, x0 y0 0));&lt;br /&gt;      add { id = autonumeric(), the_geom = face } to ret;&lt;br /&gt;  }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;First, we check that &lt;i&gt;prev&lt;/i&gt; is not null. Since we cannot extrude a wall from a single point, it will be null for the first coordinate on each building. Then, we get the x and y coordinates for the current and previous edge points and create a geometry using WKT. Finally, we add a new feature with a unique id (the &lt;i&gt;autonumeric &lt;/i&gt;algorithm returns a different integer for each call) and the extruded geometry to the returning collection.&lt;br /&gt;&lt;br /&gt;And now, here is an example of how to use this algorithm with some data. We used the Vancouver building footprints from [1]:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"&gt;&lt;code style="color: black; word-wrap: normal;"&gt;import ggl.shp;&lt;br /&gt;import ggl.util;&lt;br /&gt;import org.examples.extrude;&lt;br /&gt;&lt;br /&gt;read SHP 'buildings/buildings.shp' to shp;&lt;br /&gt;buildings = shp select(the_geom = shp/the_geom, id = autonumeric());&lt;br /&gt;faces = extrude(buildings);&lt;br /&gt;write SHP faces to '/tmp/faces.shp';&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;And if we visualize the result in gvSIG:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-lIjaJwZYxFM/TzJzrfiCPoI/AAAAAAAAAAQ/Lqxwk_A7IWs/s1600/extrusion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="191" src="http://4.bp.blogspot.com/-lIjaJwZYxFM/TzJzrfiCPoI/AAAAAAAAAAQ/Lqxwk_A7IWs/s320/extrusion.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;It was not that difficult, ¿right? Now you can try to use a layer with different heights for each building, or even create buildings with ceilings ;-) Also, if you have questions, suggestions or any other applications for this algorithm, we will be glad to hear on the project mailing lists.&lt;br /&gt;&lt;br /&gt;-----&lt;br /&gt;[1]&amp;nbsp;&lt;a href="http://data.vancouver.ca/datacatalogue/index.htm"&gt;http://data.vancouver.ca/datacatalogue/index.htm&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-8387331239486117139?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/8387331239486117139/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2012/02/extruding-buildings.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8387331239486117139'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8387331239486117139'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2012/02/extruding-buildings.html' title='Extruding buildings'/><author><name>Victorzinho</name><uri>http://www.blogger.com/profile/04921355347979175260</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-lIjaJwZYxFM/TzJzrfiCPoI/AAAAAAAAAAQ/Lqxwk_A7IWs/s72-c/extrusion.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-8163626775434360373</id><published>2011-11-17T09:46:00.000-08:00</published><updated>2011-11-17T23:06:45.604-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='raster'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Raster processing</title><content type='html'>It's been a long time since we last wrote a post. I've been involved in other projects and I've had no time to work on GGL2. Now we're preparing the workshop at the gvSIG conference and we have made a great breakthrough by adding raster capabilities to the language.&lt;br /&gt;&lt;br /&gt;Now it is possible to read raster data from ASCII grid files, TIFFs and JPEGs and access the individual samples:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;read ASC '/tmp/dem.asc' to mydem;&lt;br /&gt;show dem[10, 10];&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;The value at a specific world point can be accessed easily as well. Say "mypoint" is the geometry containing the point we're interested in, the following code woulf give the raster value for that point:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;show dem at(ST_X(mypoint), ST_Y(mypoint))&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;But the hardest part have been the "rexp" expressions. Rexp stands for Raster EXPressions and as it may be taken for "regular expression", we are tempted to change it to "rop" for Raster OPeration. Anyway, it's called Rexp during this post.&lt;br /&gt;&lt;br /&gt;Rexps lets the user filter the samples of a raster. For example, say we just want to have the samples in our dem that are higher than 100 meters:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;result = rexp dem do (h) {&lt;br /&gt; if (h &amp;gt; 100) {&lt;br /&gt;   return h;&lt;br /&gt; } else {&lt;br /&gt;   return null;&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;In the previous construction&lt;br /&gt;&lt;ol&gt;&lt;li&gt;"rexp dem" means "I want to process raster stored in 'dem' variable".&lt;/li&gt;&lt;li&gt;"do (h)" says "let 'h' be any sample of the input raster".&lt;/li&gt;&lt;li&gt;The code between curly brackets return the value of the sample for the output raster.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;a href="http://3.bp.blogspot.com/-nVsZIOGZnDk/TsYDAIlOonI/AAAAAAAAAzM/PXpMKdjROLs/s1600/Screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 170px;" src="http://3.bp.blogspot.com/-nVsZIOGZnDk/TsYDAIlOonI/AAAAAAAAAzM/PXpMKdjROLs/s320/Screenshot.png" alt="" id="BLOGGER_PHOTO_ID_5676227681185604210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;When the sample expression is simple enough it is possible to use the more concise "eval" syntax. For example, the following code produces the shadow of the dem in the north direction:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;result = rexp dem eval (h| h[-1, -1] + 2*h[0, -1] &lt;br /&gt;  + h[1, -1] &lt;br /&gt;  + h - h[-1, 1] - 2*h[0, 1] - h[1, 1])&lt;/pre&gt;&lt;/blockquote&gt;It is possible to involve more rasters, georreference them, etc.&lt;br /&gt;&lt;br /&gt;If you think rexp is cool, please note that it's not my idea but I copied it from Jiffle, a raster specific language from the &lt;span style="font-weight: bold;"&gt;super&lt;/span&gt; jaitools project[1].&lt;br /&gt;&lt;br /&gt;There is a lot of work ahead: supporting more raster formats, optimizing the execution, etc. But ah! when I think how much did it took to do all these operations in GGL1 I get so happy...&lt;br /&gt;&lt;br /&gt;More on this at the &lt;a href="http://jornadas.gvsig.org/"&gt;gvSIG International Conference&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1] http://jaitools.org/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-8163626775434360373?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/8163626775434360373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/11/raster-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8163626775434360373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8163626775434360373'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/11/raster-processing.html' title='Raster processing'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-nVsZIOGZnDk/TsYDAIlOonI/AAAAAAAAAzM/PXpMKdjROLs/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-3814582677620334508</id><published>2011-08-22T02:53:00.000-07:00</published><updated>2011-08-30T08:00:02.540-07:00</updated><title type='text'>XML processing</title><content type='html'>The new 2.0M2 release will be out soon. One of the main reasons to start the development of the second version of the GGL language was the difficulties to access XML data (and any hierarchical data in general) with GGL1 "flat table" model.&lt;br /&gt;&lt;br /&gt;This task will be much more easy with GGL2 so let's take a look.&lt;br /&gt;&lt;br /&gt;In previous posts we've seen how to access element(feature) attributes using the '/' operator like this:&lt;br /&gt;&lt;blockquote&gt;show myshape/the_geom&lt;/blockquote&gt;The big difference with GGL1 is that elements attributes may be also complex elements so that the slash operator can be used several times in the same expression, provided that the data structure being accessed has those levels of hierarchy:&lt;br /&gt;&lt;blockquote&gt;show car/engine/brand&lt;br /&gt;&lt;/blockquote&gt;As, typically, this hierarchical data will be stored in XML files, GGL2 provides a generic XML reader which means that... yes: GGL2 can read any* XML file. For example, in the following code we show the "lat" and "lon" attributes of every point in every route in a GPX file:&lt;br /&gt;&lt;blockquote&gt;import ggl.xml;&lt;br /&gt;&lt;br /&gt;read XML '/tmp/fells_loop.gpx' to gpx;&lt;br /&gt;&lt;br /&gt;points = gpx/rte/rtept;&lt;br /&gt;&lt;br /&gt;foreach p in points {&lt;br /&gt;    show p/@lat + ', ' + p/@lon;&lt;br /&gt;}&lt;br /&gt;&lt;/blockquote&gt;Another example of the use of XML in GGL2 is the storage of a Shapefile as XML:&lt;br /&gt;&lt;blockquote&gt;import ggl.xml;&lt;br /&gt;import ggl.shp;&lt;br /&gt;&lt;br /&gt;read SHP '/tmp/lineas.shp' to lineas;&lt;br /&gt;&lt;br /&gt;elem = {linea=lineas};&lt;br /&gt;&lt;br /&gt;write XML elem to '/tmp/out.xml';&lt;br /&gt;&lt;/blockquote&gt;The previous code produces the following XML file:&lt;br /&gt;&lt;blockquote&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;root xmlns="http://www.gearscape.org/xmlio" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br /&gt;   xmlns:gml="http://www.opengis.net/gml/3.2" xsi:schemaLocation="http://www.gearscape.org/xmlio out.xsd"&amp;gt;&lt;br /&gt;   &amp;lt;linea&amp;gt;&lt;br /&gt;       &amp;lt;the_geom&amp;gt;&lt;br /&gt;           &amp;lt;gml:MultiCurve gml:id="_0"&amp;gt;&lt;br /&gt;               &amp;lt;gml:curveMember&amp;gt;&lt;br /&gt;                   &amp;lt;gml:LineString gml:id="_1"&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;29.749046840958705 68.23897058823553&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;32.352498638344336 70.79517505787064&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;33.847724332788786 68.72824542143272&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                   &amp;lt;/gml:LineString&amp;gt;&lt;br /&gt;               &amp;lt;/gml:curveMember&amp;gt;&lt;br /&gt;           &amp;lt;/gml:MultiCurve&amp;gt;&lt;br /&gt;       &amp;lt;/the_geom&amp;gt;&lt;br /&gt;       &amp;lt;ID&amp;gt;-5.0&amp;lt;/ID&amp;gt;&lt;br /&gt;   &amp;lt;/linea&amp;gt;&lt;br /&gt;   &amp;lt;linea&amp;gt;&lt;br /&gt;       &amp;lt;the_geom&amp;gt;&lt;br /&gt;           &amp;lt;gml:MultiCurve gml:id="_2"&amp;gt;&lt;br /&gt;               &amp;lt;gml:curveMember&amp;gt;&lt;br /&gt;                   &amp;lt;gml:LineString gml:id="_3"&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;32.352498638344336 70.79517505787064&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;34.61292807053388 68.45558661832814&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;36.78540305010905 67.91421568627474&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                   &amp;lt;/gml:LineString&amp;gt;&lt;br /&gt;               &amp;lt;/gml:curveMember&amp;gt;&lt;br /&gt;           &amp;lt;/gml:MultiCurve&amp;gt;&lt;br /&gt;       &amp;lt;/the_geom&amp;gt;&lt;br /&gt;       &amp;lt;ID&amp;gt;-1.0&amp;lt;/ID&amp;gt;&lt;br /&gt;   &amp;lt;/linea&amp;gt;&lt;br /&gt;   &amp;lt;linea&amp;gt;&lt;br /&gt;       &amp;lt;the_geom&amp;gt;&lt;br /&gt;           &amp;lt;gml:MultiCurve gml:id="_4"&amp;gt;&lt;br /&gt;               &amp;lt;gml:curveMember&amp;gt;&lt;br /&gt;                   &amp;lt;gml:LineString gml:id="_5"&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;30.25038722086067 70.4233419713374&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;30.742932155501194 71.04781858489949&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;31.10354541122015 70.34418296398445&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;30.63738681236394 69.7988653577753&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;31.886340039488125 69.27993408735045&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;32.16779428785414 69.99236515352693&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                       &amp;lt;gml:pos&amp;gt;32.352498638344336 70.79517505787064&amp;lt;/gml:pos&amp;gt;&lt;br /&gt;                   &amp;lt;/gml:LineString&amp;gt;&lt;br /&gt;               &amp;lt;/gml:curveMember&amp;gt;&lt;br /&gt;           &amp;lt;/gml:MultiCurve&amp;gt;&lt;br /&gt;       &amp;lt;/the_geom&amp;gt;&lt;br /&gt;       &amp;lt;ID&amp;gt;3.0&amp;lt;/ID&amp;gt;&lt;br /&gt;   &amp;lt;/linea&amp;gt;&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;br /&gt;&lt;/blockquote&gt;which, you'll guess, is standard GML.&lt;br /&gt;&lt;br /&gt;With this functionality we've accomplished the last of the aims that motivated the remake of the language. Some usability and performance issues remain to be solved but we're almost at the end of the road. Soon we'll have a new release and then: courses, workshops, etc.&lt;br /&gt;&lt;br /&gt;* Any XML file which schema is understood by the GGL2 XML reader. It's a work in progress and there is no support for some rare (and not so rare) XSD constructions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-3814582677620334508?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/3814582677620334508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/08/xml-processing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3814582677620334508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3814582677620334508'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/08/xml-processing.html' title='XML processing'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-7165392919219791627</id><published>2011-06-23T09:15:00.000-07:00</published><updated>2011-06-27T04:05:11.752-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Processing geometries</title><content type='html'>As said in the post about data types, geometries are simple data types at the same level strings are. Typically this means that they are treated as a whole and there is no way to mess around with the internal components of those values.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, in case of GGL2 there is a special construction to process the geometry coordinates individually: the "process coordinates" block.&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;g = LINESTRING(0 0, 10 10);&lt;/div&gt;&lt;div&gt;process g coordinates as coordinate {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;show coordinate;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;These construction lets us process all the coordinates of a geometry, but there's more. If a "replace" statement is used inside the code block it will replace the values of that coordinate with the values specified in that same statement. For example, this makes possible to modify internally a geometry to translate all the coordinates of a geometry with an offset:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;process geom coordinates as c {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;x = ST_X(c) + deltaX;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;y = ST_Y(c) + deltaY;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;replace x y z;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;And the previous code conveniently packaged:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;alg ST_Translate(geometry geom, double deltaX, double deltaY) returns geometry {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;process geom coordinates as c {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;x = ST_X(c) + deltaX;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;y = ST_Y(c) + deltaY;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;z = ST_Z(c) + deltaZ;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;replace x y z;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return geom;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;This method can be used with a single geometry:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;blockquote&gt;show ST_Translate(POINT(0 0), 10, 10);&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;but also in a "select" statement to process all the elements in a table:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;show myShape select (f| ST_Translate(f/the_geom, 10, 10));&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;Another interesting algorithm may be the ST_Transform one, that performs coordinate system transformations on the geometries. As we'll see in the next post, it is possible to call Java code from GGL2 so it would be relatively easy to implement it using geotools... or proj4.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-7165392919219791627?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/7165392919219791627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/06/processing-geometries.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/7165392919219791627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/7165392919219791627'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/06/processing-geometries.html' title='Processing geometries'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-8382963201180286288</id><published>2011-06-14T00:53:00.000-07:00</published><updated>2011-06-20T02:32:03.336-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Packaging and reusing algorithms</title><content type='html'>&lt;div&gt;Now that I've shown you some little tricks with GGL2 it's time to see how we can package some of these tricks for a later use.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Consider the previous post example, the grid creation:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;grid = [as geometry];&lt;/div&gt;&lt;div&gt;width = 100;&lt;/div&gt;&lt;div&gt;height = 100;&lt;/div&gt;&lt;div&gt;foreach x1 in 0 .. 1000 step width {&lt;/div&gt;&lt;div&gt;  foreach y1 in 0 .. 1000 step height {&lt;/div&gt;&lt;div&gt;    double x2 = x1 + width;&lt;/div&gt;&lt;div&gt;    double y2 = y1 + height;&lt;/div&gt;&lt;div&gt;    geometry polygon = POLYGON((x1 y1, x2 y1, x2 y2, x1 y2, x1 y1));&lt;/div&gt;&lt;div&gt;    add polygon to grid; &lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;It creates a grid that covers the (0, 0)-(1000, 1000) extent with cells 100x100 big. Having such a piece of code may be useful, but having to change manually the values of the extent or the size of the cell is not handy. The solution are "algorithms":&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;div&gt;library ggl.grid;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;import ggl.geom;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;alg createGrid(double cellWidth, double cellHeight, geometry extent) returns sequenceof geometry {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;grid = [ as geometry ];&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;foreach x in ST_MinX(extent) .. ST_MaxX(extent) step cellWidth {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;foreach y in ST_MinY(extent) .. ST_MaxY(extent) step cellHeight {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;double x_ = x + cellWidth;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;double y_ = y + cellHeight;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;geometry polygon = POLYGON((x y, x_ y, x_ y_, x y_, x y));&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;add polygon to grid;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;return grid;&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Algorithms are contained in libraries that are declared as seen in the first statement. As we'll use some algorithms defined in the "ggl.geom" library we need to import it with the second statement. The rest of the code is similar to the previous post, but wrapped in the algorithm declaration, which defines the "variable" parts of the code as parameters so that it is possible to call the same algorithm with different values. In this concrete example, the parameters are "cellWidth", "cellHeight" and "extent".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is possible to "call" the algorithm by naming it and passing the concrete values between parenthesis. For example, we could create a grid to cover the (0, 0)-(10, 1) extent with cells 1x1 big:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;div&gt;import ggl.grid;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;myGrid = createGrid(1, 1, POLYGON((0 0, 10 0, 10 1, 0 1, 0 0)));&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;A last note, GGL2 editor can be connected to GIS instances, such as GearScape (and soon gvSIG), making it possible to reference the layers in the GIS instance by their name. In such scenario, it's very simple to create a grid that covers the whole extent of a layer:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;import ggl.grid;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;grid = createGrid(100, 100, ST_Extent(myLayer/the_geom));&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;In a next post we'll see some polymorphic features that are very useful when packaging algorithms. We'll also take a look at the possibility to call Java code from GGL2.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-8382963201180286288?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/8382963201180286288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/06/packaging-and-reusing-algorithms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8382963201180286288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/8382963201180286288'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/06/packaging-and-reusing-algorithms.html' title='Packaging and reusing algorithms'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-3631304906934048388</id><published>2011-06-13T08:23:00.000-07:00</published><updated>2011-06-14T02:23:26.607-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Create grid</title><content type='html'>&lt;div&gt;&lt;div&gt;Create grid&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In a previous post I showed how it was possible to create a polygon using variables inside the WKT expressions. Now we'll see how it is possible to create a grid in few lines of GGL2 code.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Consider that we want to create a grid which cell size is 100x100 and that covers the (0, 0)-(1000, 1000) extent. By using two nested loops that run from 0 to 1000 in increments of 100 it is possible to obtain the upper left corner of every cell:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;foreach x1 in 0 .. 1000 step 100 {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; foreach y1 in 0 .. 1000 step 100 {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; show x1 + ', ' + y1;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Now in the body of the inner loop we can create a cell using pseudo WKT and add it to a resulting collection:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;grid = [as geometry];&lt;/div&gt;&lt;div&gt;width = 100;&lt;/div&gt;&lt;div&gt;height = 100;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;foreach x1 in 0 .. 1000 step width {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; foreach y1 in 0 .. 1000 step height {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; &lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;double x2 = x1 + width;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  double y2 = y1 + height;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  geometry polygon = POLYGON((x1 y1, x2 y1, x2 y2, x1 y2, x1 y1));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;  add polygon to grid; &lt;/span&gt;&lt;/div&gt;&lt;div style="white-space: normal; "&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="white-space: pre; "&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Simple, right? The only thing that may worth explaining is the creation of an empty sequence in the first line... but that will be another post. I'll also show how to package this as an algorithm and to use the extent of an existing data source as the area to cover with the grid.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-3631304906934048388?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/3631304906934048388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/06/create-grid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3631304906934048388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3631304906934048388'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/06/create-grid.html' title='Create grid'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-6390052998855742320</id><published>2011-05-28T00:54:00.000-07:00</published><updated>2011-06-06T01:03:52.814-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Type system (II)</title><content type='html'>&lt;div&gt;&lt;div&gt;In the previous post we saw the different basic data types available in GGL2. In this one we'll take a look at the composite ones.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are two posibilities to compose a type: elements and sequences.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;Elements are tuples of pairs name=value and typically can be understood as "rows" in a table. For example, in GGL2, a feature read from a shapefile that has an integer attribute called &lt;i&gt;id&lt;/i&gt; would be an element with a geometric child called &lt;i&gt;the_geom&lt;/i&gt; and a numeric one called &lt;i&gt;id&lt;/i&gt;. The element values can be accessed with the &lt;i&gt;/ &lt;/i&gt;(slash) operator followed by the name of the child:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;Feature f = ...;&lt;/div&gt;&lt;div&gt;show f/the_geom;&lt;/div&gt;&lt;div&gt;show f/id;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;On the other side, sequences are just that, a sequence of values of a concrete type (either basic or composite). So, if elements can represent shapefile features, sequences of elements can represent the whole shapefile.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are a lot of constructions to process sequences (that may be shapefiles, postgis tables, etc.). For example, it is possible to filter them to show the elements in the shapefile that have an &lt;i&gt;id&lt;/i&gt; lower than 10, or to sort them:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;show myShape filter( f| f/id &amp;lt; 10);&lt;/div&gt;&lt;div&gt;show myShape sort( f| f/id);&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Finally, note that these constructions are not limited to sequences of elements, they can be applied to any sequence, for example, sequences of ints:&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;sequenceof int myInts = [1, 2, 3, 5, 7, 9, 11, 13];&lt;/div&gt;&lt;div&gt;show myInts filter( i| i &amp;lt; 10);&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;The best part of the GGL2 type system is that elements can contain sequences of other elements and, therefore, hierarchical data structures (GPX, GML based formats) will be accessible from GGL2 without problems. I've done no test yet so... that will be another post.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-6390052998855742320?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/6390052998855742320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/05/type-system-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/6390052998855742320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/6390052998855742320'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/05/type-system-ii.html' title='Type system (II)'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-3293153906899205196</id><published>2011-05-27T09:26:00.000-07:00</published><updated>2011-06-06T00:57:26.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Type system (I)</title><content type='html'>&lt;div&gt;As GGL2 is a language to treat data, it is specially important to have a type system able to represent the data structutes that are going to be processed. As many other languages, GGL2 lets the user define variables that are strongly typed, this is, that can only contain values of their type (there are exceptions, though).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;GGL2 variables can be of simple built-in types or a composite of one or more GGL2 types. In this post, only simple types will be explained. So, for example, it is possible to have numeric and textual variables and initialize them to integer and textual values:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;int a = 2;&lt;/div&gt;&lt;div&gt;string text = 'hello';&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;but, as it is a language to process spatial data, "geometry" is also a basic type and it is possible to have geometric variables and initialize them to geometric literals. What are geometric literals? Well, kind of Well Known Text:&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;geometry g = POLYGON((0 0, 10 0, 10 10, 0 10, 0 0));&lt;/div&gt;&lt;div&gt;geometry p = POINT(0 0);&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The good thing about these WKT literals is that, indeed, they are not literals. I don't want to go deeper on language terminology but, as long as you can use variables in pseudo WKT expressions, they are no longer literals:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;int ten = 10;&lt;/div&gt;&lt;div&gt;geometry g = POLYGON((0 0, ten 0, ten ten, 0 ten, 0 0));&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;In a next post I'll take advantage of this feature to do some cool things with very few code. Stay tunned!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, enough about technical details, lets go a little thoughtful: What value do variables give to the language?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Well, consider the buffer in a previous post:&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;myshape select (f| the_geom=ST_Buffer(f/@the_geom, 10), id=f/@id);&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;With variables (and loops) we can create several buffers easily:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;foreach &lt;b&gt;size&lt;/b&gt; in &lt;b&gt;0 .. 100 step 10&lt;/b&gt; {&lt;/div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;myshape select (f| the_geom=ST_Buffer(f/@the_geom, &lt;b&gt;size&lt;/b&gt;), id=f/@id);&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;This can be performed in SQL aswell but, IMHO, GGL2 code is easier to produce, read, and therefore, maintain.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A last point on variables, although GGL2 is strongly typed it is possible to declare a variable with, apparently, no type:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;a = 2;&lt;/div&gt;&lt;div&gt;text = 'helo';&lt;/div&gt;&lt;div&gt;p = POINT(0 0);&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;BUT, this doesn't mean that the variable has no type. Indeed, GGL2 takes the type from the right part of the assignation so it is clear that &lt;i&gt;a&lt;/i&gt; is an int, &lt;i&gt;text&lt;/i&gt; is a string and &lt;i&gt;p&lt;/i&gt; is a geometry. This may seem a worthless functionality, but as types get more complicated it is VERY useful.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-3293153906899205196?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/3293153906899205196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/05/type-system-i.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3293153906899205196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/3293153906899205196'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/05/type-system-i.html' title='Type system (I)'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-4603969246373169521</id><published>2011-05-26T02:08:00.001-07:00</published><updated>2011-06-06T00:57:37.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Hello buffer world</title><content type='html'>As hello world is very simple with GGL2:&lt;div&gt;&lt;blockquote&gt;show 'hello world';&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;I'm going to show something more complicated: the omnipresent buffer.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;import ggl.geom;&lt;/div&gt;&lt;div&gt;import ggl.shp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;read SHP '/tmp/mishape.shp' to myshape;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;result = myshape select (f| the_geom=ST_Buffer(f/@the_geom, 10), id=f/@id);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;write SHP result to '/tmp/test.shp';&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;div style="text-align: left;"&gt;The first two lines import the necessary libraries containing shapefile reader and writer and algorithms to process the geometries. After that, the read statement stores in &lt;i&gt;myshape&lt;/i&gt; the contents of the shapefile. Then a &lt;i&gt;select&lt;/i&gt; predicate is used to select the buffer of the &lt;i&gt;@the_geom&lt;/i&gt; attribute (field) and the &lt;i&gt;@id&lt;/i&gt; attribute as it is.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;The &lt;i&gt;select&lt;/i&gt; predicate iterates over the elements of the shapefile sequence and transforms them as specified between parenthesis. There, the current element is named &lt;i&gt;f &lt;/i&gt;and the attributes of the resulting element are the left side of the assignments:&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;blockquote&gt;@the_geom=ST_Buffer(f/@the_geom, 10), @id=f/@id&lt;/blockquote&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Finally the result is assigned to a &lt;i&gt;result&lt;/i&gt; variable that is written in the last statement to &lt;i&gt;/tmp/test.shp&lt;/i&gt;.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Basically it's the same that can be accomplished with a SQL select statement, only that a different syntax is used.&lt;/div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-4603969246373169521?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/4603969246373169521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/05/hello-buffer-world.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/4603969246373169521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/4603969246373169521'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/05/hello-buffer-world.html' title='Hello buffer world'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5074699861565622759.post-5282297918948966117</id><published>2011-05-25T12:01:00.000-07:00</published><updated>2011-05-26T02:05:21.701-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geoprocessing'/><category scheme='http://www.blogger.com/atom/ns#' term='gis'/><category scheme='http://www.blogger.com/atom/ns#' term='gearscape'/><category scheme='http://www.blogger.com/atom/ns#' term='sig'/><category scheme='http://www.blogger.com/atom/ns#' term='ggl2'/><title type='text'>Welcome to GGL2 blog</title><content type='html'>In this blog I'll present some examples of what can be done with the next release of GGL2 language. As soon as new constructions are developped I'll put here a post with some examples of what can be done by using it.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thus, I expect to give some informal insight on what the first release of the language will do. I hope this will make people increasingly excited and cry of joy at the moment of the release.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'll also raise &lt;i&gt;a priori&lt;/i&gt; questions about the best construction to solve a particular kind of problem so that comments in that post can propose ideas that can be implemented later. Your collaboration is very much welcome.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you don't know what GGL2 is you can take a look here: http://www.gearscape.org/&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5074699861565622759-5282297918948966117?l=ggl-two.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ggl-two.blogspot.com/feeds/5282297918948966117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ggl-two.blogspot.com/2011/05/welcome-to-ggl2-blog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/5282297918948966117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5074699861565622759/posts/default/5282297918948966117'/><link rel='alternate' type='text/html' href='http://ggl-two.blogspot.com/2011/05/welcome-to-ggl2-blog.html' title='Welcome to GGL2 blog'/><author><name>Fernando González Cortés</name><uri>http://www.blogger.com/profile/11629131160883674253</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
