<data xmlns="">
<url>http://tile.openstreetmap.org/10/525/336.png</url>
</data>
<output ref="url"/>
http://tile.openstreetmap.org/10/525/336.png
<output ref="url" mediatype="image/*"/>
http://<site>/<zoom>/<x>/<y>.png http://tile.openstreetmap.org/10/525/336.png
<instance>
<map xmlns="">
<site>http://tile.openstreetmap.org/</site>
<zoom>10</zoom>
<x>525</x>
<y>336</y>
<url/>
</map>
</instance>
<bind nodeset="url"
calculate="concat(../site, ../zoom, '/', ../x, '/', ../y, '.png')"/>
<input ref="zoom"><label>zoom</label></input>
<trigger> <label>→</label> <setvalue ev:event="DOMActivate" ref="x" value=". + 1"/> </trigger>
<bind nodeset="scale"
calculate="power(2, 26 - ../zoom)"/>
<bind nodeset="x"
calculate="floor(../posx div ../scale)"/>
<bind nodeset="y"
calculate="floor(../posy div ../scale)"/>
<bind nodeset="offx"
calculate="0 - floor(((../posx - ../x * ../scale) div ../scale)*../tilesize)" />
<bind nodeset="offy"
calculate="0 - floor(((../posy - ../y * ../scale) div ../scale)*../tilesize)" />
<div style="margin-left: {offx}px; margin-top: {offy}px">...
<mouse>
<x/><y/><state/>
</mouse>
<action ev:event="mousemove">
<setvalue ref="mouse/x" value="event('clientX')"/>
<setvalue ref="mouse/y" value="event('clientY')"/>
</action>
<action ev:event="mousedown"> <setvalue ref="mouse/state">down</setvalue> </action> <action ev:event="mouseup"> <setvalue ref="mouse/state">up</setvalue> </action>
<bind nodeset="mouse/cursor"
calculate="if(../state='up', 'pointer', 'move')"/>
<div style="cursor: {cursor}">...
<mouse>
<x/><y/><state/><cursor/>
<start><x/><y/></start>
<end><x/><y/></end>
<move><x/><y/></move>
</mouse>
<action ev:event="mousedown">
<setvalue ref="mouse/state">down</setvalue>
<setvalue ref="mouse/start/x" value="event('clientX')"/>
<setvalue ref="mouse/start/y" value="event('clientY')"/>
</action>
<bind ref="mouse/end/x"
calculate="if(mouse/state = 'down', mouse/x, .)"/>
<bind ref="mouse/end/y"
calculate="if(mouse/state = 'down', mouse/y, .)"/>
<bind ref="mouse/move/x"
calculate="mouse/end/x - mouse/start/x"/>
<bind ref="mouse/move/y"
calculate="mouse/end/y - mouse/start/y"/>
<lastx/><lasty/>
<bind ref="posx"
calculate="../lastx - ../mouse/move/x*(../scale div ../tilesize)"/>
<bind ref="posy"
calculate="../lasty - ../mouse/move/y*(../scale div ../tilesize)"/>
<action ev:event="mouseup">
<setvalue ref="lastx" value="posx"/>
<setvalue ref="lasty" value="posy"/>
<setvalue ref="mouse/start/x" value="mouse/end/x"/>
<setvalue ref="mouse/start/y" value="mouse/end/y"/>
</action>
<select1 ref="site">
<label>Map</label>
<item>
<label>Standard</label>
<value>http://tile.openstreetmap.org/</value>
</item>
<item>
<label>Cycle</label>
<value>http://tile.opencyclemap.org/cycle/</value>
</item>
<item>
<label>Transport</label>
<value>http://tile2.opencyclemap.org/transport/</value>
</item>
...
</select1>
In around 150 lines, we have coded a complete draggable map application.
The application is largely declarative: it says WHAT should happen, now HOW to do it.
We let the computer do more of the work.
The savings are immense.