[xep-support] Next installment of Cool Tools

Kevin Brown kevin at renderx.com
Fri Jun 26 12:57:38 PDT 2009


As promised, I wanted to stimulate thought and exchange new ideas about
things that can be accomplished. Today's installment is a complete XSL
template for generating a Google map image on the fly. 

<disclaimer>You should always review Google's policy and check with them
about how you intend to use such a tool. Google has restrictions about what
you can do with such things. This is provided to this group for educational
purposes only.</disclaimer>

This is a general set of xsl templates to generate a Google Map from source
address information. This process works by first submitting the address to
the Google Geocoding Service which returns an XML file containing additional
information. This additional information includes the latitude and longitude
of the specified location. This XML is loaded into a variable which is an
internal XML document and the nodes processed to extract the needed data.
The coordinates are parsed from the XML document and passed to the Google
staticmap API to generate an image with a marker at the address provided.
Various other parameters can be set including the zoom factor,image size and
maptype.

Given a simple fragment like this:

        <address>
            <line1>228+Hamilton+Ave</line1>
            <city>Palo+Alto</city>
            <state>CA</state>
            <zip>94301</zip>
            <zoom>15</zoom>
            <width>640</width>
            <height>440</height>
            <maptype>roadmap</maptype>
        </address>

and a template like this:

    <xsl:template match="address">
            <xsl:variable name="url">
                <xsl:call-template name="getGoogleMap">
                    <xsl:with-param name="address" select="line1" />
                    <xsl:with-param name="city" select="city" />
                    <xsl:with-param name="state" select="state" />
                    <xsl:with-param name="zip" select="zip" />
                    <xsl:with-param name="zoom" select="zoom"/>
                    <xsl:with-param name="size.width" select="width"/>
                    <xsl:with-param name="size.height" select="height"/>
                    <xsl:with-param name="maptype" select="maptype"/>
                </xsl:call-template>
            </xsl:variable>

        <fo:block margin-left="0pt" margin-top="0pt" line-height="0pt"
text-align="center">
            <fo:external-graphic src="url({$url})" />
        </fo:block>   
   </xsl:template>

The variable $url is filled with the URL to generate the map. Note this is
just a test, one would normally include zoom, possibly size and even maptype
in the actual XSL and not pass them from XML. 

Below is the style sheet, if you want a copy with comments in place just
email me at kevin at renderx.com or Karl Stubsjoen (stubsjoen at renderx.com) and
either of us would be happy to send it along.

*****************************
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:kml="http://earth.google.com/kml/2.0" version="1.0">
    <!-- This is a general set of xsl templates to generate a Google Map
from source
         address information. This process works by first submitting the
address
         to the Google Geocoding Service which returns an XML file
containing
         additional information including the latitude and longitude of the 
         specified location. This XML is loaded into an internal XML
document
         and the nodes processed to extract data.
         
         The coordinates are parsed from the XML document and passed to the
         Google staticmap API to generate an image with a marker at the 
         address provided.
         
         Various other parameters can be set including the zoom factor,
         image size and maptype.
         
         This style sheet was created by Karl Stubsjoen and Kevin Brown from
         RenderX. Feel free to use as you please and of course check with 
         the Google website for their terms of using their services.
    -->     
    <!-- 
        Set your own Google maps API key here. You can get your own key
from:
        http://code.google.com/apis/maps/signup.html
     -->
    <xsl:param name="api-key">MAPS_API_KEY</xsl:param>
    <xsl:template name="getGoogleMap">
        <!-- Sets the zoom factor for the map: Approximate values are 18 =
street, 15 town, 6 state, 1 world -->
        <xsl:param name="zoom">18</xsl:param>
        <!-- Sets the width and height in px of the returned image -->
        <xsl:param name="size.width">400</xsl:param>
        <xsl:param name="size.height">400</xsl:param>
        <!-- Sets the type of map to produce, one of: 
            roadmap (default)
            mobile
            satellite
            terrain
            hybrid
            mapmaker-roadmap
            mapmaker-hybrid -->
        <xsl:param name="maptype">roadmap</xsl:param>
        <!-- Other parameters to pass to the Geocoding service to get
latitude and longitude for the address -->
        <xsl:param name="address"/>
        <xsl:param name="city"/>
        <xsl:param name="state"/>
        <xsl:param name="zip"/>
        <xsl:variable name="document">
            <xsl:text>http://maps.google.com/maps/geo?q=</xsl:text>
            <xsl:if test="string($address)">
                <xsl:value-of select="$address"/>
                <xsl:text>+</xsl:text>
            </xsl:if>
            <xsl:if test="string($city)">
                <xsl:value-of select="$city"/>
                <xsl:text>+</xsl:text>
            </xsl:if>
            <xsl:if test="string($state)">
                <xsl:value-of select="$state"/>
                <xsl:text>+</xsl:text>
            </xsl:if>
            <xsl:if test="string($zip)">
                <xsl:value-of select="$zip"/>
            </xsl:if>
 
<xsl:text>&amp;output=xml&amp;oe=utf8&amp;sensor=false&amp;key=</xsl:text>
            <xsl:value-of select="$api-key"/>
        </xsl:variable>
        <xsl:variable name="maps" select="document($document)"/>
        <xsl:apply-templates
 
select="$maps/kml:kml/kml:Response/kml:Placemark[1]/kml:Point/kml:coordinate
s">
            <xsl:with-param name="zoom" select="$zoom"/>
            <xsl:with-param name="size.width" select="$size.width"/>
            <xsl:with-param name="size.height" select="$size.height"/>
            <xsl:with-param name="key" select="$api-key"/>
            <xsl:with-param name="maptype" select="$maptype"/>
        </xsl:apply-templates>
    </xsl:template>
    <xsl:template match="kml:coordinates">
        <xsl:param name="zoom"/>
        <xsl:param name="size.width"/>
        <xsl:param name="size.height"/>
        <xsl:param name="key" select="$api-key"/>
        <xsl:param name="sensor">false</xsl:param>
        <xsl:param name="maptype"/>
        <xsl:variable name="longitude" select="substring-before(., ',')"/>
        <xsl:variable name="latitude.parse" select="substring-after(.,
',')"/>
        <xsl:variable name="latitude"
select="substring-before($latitude.parse, ',')"/>
        <xsl:call-template name="build.static-map">
            <xsl:with-param name="maptype"
select="$maptype"></xsl:with-param>
            <xsl:with-param name="latitude" select="$latitude"/>
            <xsl:with-param name="longitude" select="$longitude"/>
            <xsl:with-param name="size.height" select="$size.height"/>
            <xsl:with-param name="size.width" select="$size.width"/>
            <xsl:with-param name="zoom" select="$zoom"/>
            <xsl:with-param name="key" select="$api-key"/>
        </xsl:call-template>
    </xsl:template>
    <xsl:template name="build.static-map">
        <xsl:param name="longitude"/>
        <xsl:param name="latitude"/>
        <xsl:param name="zoom"/>
        <xsl:param name="size.width"/>
        <xsl:param name="size.height"/>
        <xsl:param name="key" select="$api-key"/>
        <xsl:param name="maptype"/>
        <xsl:param name="sensor">false</xsl:param>
        <xsl:param name="markers" select="concat($latitude, ',',
$longitude)"/>
        <xsl:param name="size"
select="concat($size.width,'x',$size.height)"/>
        <xsl:variable name="coordinates" select="concat($latitude, ',',
$longitude)"/>
        <xsl:text>http://maps.google.com/staticmap</xsl:text>
        <xsl:text>?center=</xsl:text>
        <xsl:value-of select="$coordinates"/>
        <xsl:text>&amp;zoom=</xsl:text>
        <xsl:value-of select="$zoom"/>
        <xsl:text>&amp;size=</xsl:text>
        <xsl:value-of select="$size"/>
        <xsl:text>&amp;key=</xsl:text>
        <xsl:value-of select="$key"/>
        <xsl:text>&amp;sensor=</xsl:text>
        <xsl:value-of select="$sensor"/>
        <xsl:text>&amp;markers=</xsl:text>
        <xsl:value-of select="$markers"/>
        <xsl:text>&amp;maptype=</xsl:text>
        <xsl:value-of select="$maptype"/>
    </xsl:template>
</xsl:stylesheet>

-------------------
(*) To unsubscribe, send a message with words 'unsubscribe xep-support'
in the body of the message to majordomo at renderx.com from the address
you are subscribed from.
(*) By using the Service, you expressly agree to these Terms of Service http://www.renderx.com/terms-of-service.html



More information about the Xep-support mailing list