[xsl] grouping and merging problem

Subject: [xsl] grouping and merging problem
From: Sylvain Rouillard <RouillardSy@xxxxxxxx>
Date: Tue, 22 Nov 2005 14:10:39 +0100
Hi list!

This is my first post in here and I'm really new to XSLT things, so I hope my 
question will not sound too dumb. I've been googling around a lot and I 
cannot find anything similar enough to my problem, hence me comming here.

I am using xslt 1.0 to transform an xml file into an svg image. Basically, the 
xml file is a map of pixels (//row), with an @x, @y and @Altitude, and I 
render each pixel with a square (<rect>) positionned at (@x,@y) with an 
opacity proportionnal to the altitude. An exemple of my xml input and of the 
xslt I use is given below.

The next step for me is to trim the output size, by merging neighbour pixels 
that have the same opacity (ie altitudes that are close enough from each 
other to be rendered by the same opacity on screen). To approach this 
problem, I decided that I would try and merge only the pixels on a same row 
(same @y), so that I don't have to be bi-directionnal. So, ideally, in the 
for-each loop, I should test if the next pixel in the loop has the same 
opacity as the current one. If not, then I can just output the same rect with 
width=3 and height=3. If the next pixel has the same opacity, then I should 
test the one after and so forth (until the end of the row), and output a rect 
with an appropriate width attribute. In this case, the subsequent pixels 
(//row) that have been covered in a previous enlarged rect should be skipped.

I hope this makes sense, feel free to ask more details otherwise.

To address this, I have been trying to make a loop (iterative call for a 
template) and to play with either position() or preceding-sibling:: and 
folowing-sibling:: with no success. I've been thinking of a key() approach 
too.

So, what approach would you recommand for this issue? Any advice on how to 
address this would be welcome, or even some kind of code structure.

Thanks in advance.

Here is a sample of my xml data:

<?xml version="1.0" standalone="yes"?>
<Schema1>
  <row District_ID="1" Altitude="4.759967" x="21" y="0" />
  <row District_ID="2" Altitude="4.95421362" x="24" y="0" />
  <row District_ID="3" Altitude="4.73068953" x="27" y="0" />
  <row District_ID="4" Altitude="4.50744247" x="30" y="0" />
  <row District_ID="5" Altitude="4.5243144" x="33" y="0" />
  <row District_ID="6" Altitude="4.68397236" x="36" y="0" />
  <row District_ID="7" Altitude="4.787261" x="39" y="0" />
  <row District_ID="8" Altitude="4.49287128" x="18" y="3" />
  <row District_ID="9" Altitude="4.69453526" x="21" y="3" />
  ...
</Schema1>

And here is the xslt file i use so far:

<?xml version="1.0" encoding="iso-8859-15"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                xmlns:svg="http://www.w3.org/2000/svg";>
  <xsl:output
    method="xml"
    version="1.0"
    encoding="ISO-8859-1"
    omit-xml-declaration="yes"
    standalone="yes"
    indent="no"
    media-type="image/svg+xml"/>

  <xsl:param name="LandID" select="0"/>
  
  <xsl:variable name="minX">
    <xsl:for-each select="//row/@x">
      <xsl:sort data-type="number" order="ascending"/>
      <xsl:if test="position()=1">
        <xsl:value-of select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="minY">
    <xsl:for-each select="//row/@y">
      <xsl:sort data-type="number" order="ascending"/>
      <xsl:if test="position()=1">
        <xsl:value-of select="."/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="maxX">
    <xsl:for-each select="//row/@x">
      <xsl:sort data-type="number" order="descending"/>
      <xsl:if test="position()=1">
        <xsl:value-of select=". + 3"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="maxY">
    <xsl:for-each select="//row/@y">
      <xsl:sort data-type="number" order="descending"/>
      <xsl:if test="position()=1">
        <xsl:value-of select=". + 3"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:template match="/">
    <xsl:element name="svg:svg">
      <xsl:attribute name="version">
        <xsl:value-of select="'1.1'" />
      </xsl:attribute>
      <xsl:attribute name="id">
        <xsl:value-of select="concat($LandID,'_Districts')" />
      </xsl:attribute>
      <xsl:attribute name="viewBox">
        <xsl:value-of select="concat(string($minX),' ',string($minY),' 
',string($maxX - $minX),' ',string($maxY - $minY))" />
      </xsl:attribute>
      <xsl:attribute name="shape-rendering">
        <xsl:value-of select="'optimizeSpeed'" />
      </xsl:attribute>

      <xsl:for-each select="//row">
        <xsl:sort select="@x"/>
        <xsl:sort select="@y"/>
        <xsl:element name="svg:rect">
          <xsl:attribute name="x">
            <xsl:value-of select="@x" />
          </xsl:attribute>
          <xsl:attribute name="y">
            <xsl:value-of select="@y" />
          </xsl:attribute>
          <xsl:attribute name="opacity">
            <xsl:value-of select="round(@Altitude * 10) div 100" />
          </xsl:attribute>
          <xsl:attribute name="width">
            <xsl:value-of select="3" />
          </xsl:attribute>
          <xsl:attribute name="height">
            <xsl:value-of select="3" />
          </xsl:attribute>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>  
</xsl:stylesheet> 

	

	
		
___________________________________________________________________________ 
Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger 
Tilichargez cette version sur http://fr.messenger.yahoo.com

Current Thread