<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"    
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<!-- (c) 2023, Trimble Inc. All rights reserved.                                               -->
<!-- Permission is hereby granted to use, copy, modify, or distribute this style sheet for any -->
<!-- purpose and without fee, provided that the above copyright notice appears in all copies   -->
<!-- and that both the copyright notice and the limited warranty and restricted rights notice  -->
<!-- below appear in all supporting documentation.                                             -->

<!-- TRIMBLE INC. PROVIDES THIS STYLE SHEET "AS IS" AND WITH ALL FAULTS.                       -->
<!-- TRIMBLE INC. SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY               -->
<!-- OR FITNESS FOR A PARTICULAR USE. TRIMBLE INC. DOES NOT WARRANT THAT THE                   -->
<!-- OPERATION OF THIS STYLE SHEET WILL BE UNINTERRUPTED OR ERROR FREE.                        -->

<xsl:output method="text" omit-xml-declaration="yes" encoding="UTF-8"/>

<!-- Set the numeric display details i.e. decimal point, thousands separator etc -->
<xsl:variable name="DecPt" select="'.'"/>    <!-- Change as appropriate for US/European -->
<xsl:variable name="GroupSep" select="','"/> <!-- Change as appropriate for US/European -->
<!-- Also change decimal-separator & grouping-separator in decimal-format below 
     as appropriate for US/European output -->
<xsl:decimal-format name="Standard" 
                    decimal-separator="."
                    grouping-separator=","
                    infinity="Infinity"
                    minus-sign="-"
                    NaN="?"
                    percent="%"
                    per-mille="&#2030;"
                    zero-digit="0" 
                    digit="#" 
                    pattern-separator=";" />

<xsl:variable name="DecPl0" select="'#0'"/>
<xsl:variable name="DecPl1" select="concat('#0', $DecPt, '0')"/>
<xsl:variable name="DecPl2" select="concat('#0', $DecPt, '00')"/>
<xsl:variable name="DecPl3" select="concat('#0', $DecPt, '000')"/>
<xsl:variable name="DecPl4" select="concat('#0', $DecPt, '0000')"/>
<xsl:variable name="DecPl5" select="concat('#0', $DecPt, '00000')"/>
<xsl:variable name="DecPl6" select="concat('#0', $DecPt, '00000')"/>
<xsl:variable name="DecPl8" select="concat('#0', $DecPt, '00000000')"/>
<xsl:variable name="DecPl10" select="concat('#0', $DecPt, '0000000000')"/>

<xsl:variable name="DegreesSymbol" select="'&#0176;'"/>
<xsl:variable name="MinutesSymbol"><xsl:text>'</xsl:text></xsl:variable>
<xsl:variable name="SecondsSymbol" select="'&quot;'"/>

<xsl:variable name="fileExt" select="'csv'"/>

<!-- User variable definitions - Appropriate fields are displayed on the       -->
<!-- Survey Controller screen to allow the user to enter specific values       -->
<!-- which can then be used within the style sheet definition to control the   -->
<!-- output data.                                                              -->
<!--                                                                           -->
<!-- All user variables must be identified by a variable element definition    -->
<!-- named starting with 'userField' (case sensitive) followed by one or more  -->
<!-- characters uniquely identifying the user variable definition.             -->
<!--                                                                           -->
<!-- The text within the 'select' field for the user variable description      -->
<!-- references the actual user variable and uses the '|' character to         -->
<!-- separate the definition details into separate fields as follows:          -->
<!-- For all user variables the first field must be the name of the user       -->
<!-- variable itself (this is case sensitive) and the second field is the      -->
<!-- prompt that will appear on the Survey Controller screen.                  -->
<!-- The third field defines the variable type - there are four possible       -->
<!-- variable types: Double, Integer, String and StringMenu.  These variable   -->
<!-- type references are not case sensitive.                                   -->
<!-- The fields that follow the variable type change according to the type of  -->
<!-- variable as follow:                                                       -->
<!-- Double and Integer: Fourth field = optional minimum value                 -->
<!--                     Fifth field = optional maximum value                  -->
<!--   These minimum and maximum values are used by the Survey Controller for  -->
<!--   entry validation.                                                       -->
<!-- String: No further fields are needed or used.                             -->
<!-- StringMenu: Fourth field = number of menu items                           -->
<!--             Remaining fields are the actual menu items - the number of    -->
<!--             items provided must equal the specified number of menu items. -->
<!--                                                                           -->
<!-- The style sheet must also define the variable itself, named according to  -->
<!-- the definition.  The value within the 'select' field will be displayed in -->
<!-- the Survey Controller as the default value for the item.                  -->

<!-- Need to use the select attribute for userField definitions and also include the -->
<!-- contents in single quotes so that the user information can be picked up by the  -->
<!-- Survey Controller and ASCII File Generator.  This means it is not possible to   -->
<!-- have text that includes any apostrophes (single quotes) in it.                  -->
<xsl:variable name="userField1" select="'latLongFmt|Latitude/Longitude format|stringMenu|2|DMS degrees|Decimal degrees'"/>
<xsl:variable name="latLongFmt" select="'DMS degrees'"/>
<xsl:variable name="userField2" select="'useSymbols|Use DMS symbols|stringMenu|2|Yes|No'"/>
<xsl:variable name="useSymbols" select="'Yes'"/>
<xsl:variable name="userField3" select="'useHemisphereChars|Use hemisphere characters|stringMenu|2|Yes|No'"/>
<xsl:variable name="useHemisphereChars" select="'Yes'"/>
<xsl:variable name="userField4" select="'fieldDelimiterID|Field delimiter|stringMenu|5|&lt;comma&gt;|&lt;semicolon&gt;|&lt;colon&gt;|&lt;space&gt;|&lt;tab&gt;'"/>
<xsl:variable name="fieldDelimiterID" select="'&lt;tab&gt;'"/>

<!-- **************************************************************** -->
<!-- Set global variables from the Environment section of JobXML file -->
<!-- **************************************************************** -->
<xsl:variable name="DistUnit"   select="/JOBFile/Environment/DisplaySettings/DistanceUnits" />
<xsl:variable name="AngleUnit"  select="/JOBFile/Environment/DisplaySettings/AngleUnits" />
<xsl:variable name="CoordOrder" select="/JOBFile/Environment/DisplaySettings/CoordinateOrder" />
<xsl:variable name="TempUnit"   select="/JOBFile/Environment/DisplaySettings/TemperatureUnits" />
<xsl:variable name="PressUnit"  select="/JOBFile/Environment/DisplaySettings/PressureUnits" />

<!-- Set the decimalDegrees based on the user option -->
<xsl:variable name="decimalDegrees">
  <xsl:choose>
    <xsl:when test="$latLongFmt = 'DMS degrees'">false</xsl:when>
    <xsl:otherwise>true</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup conversion factor for coordinate and distance values -->
<!-- Dist/coord values in JobXML file are always in metres -->
<xsl:variable name="DistConvFactor">
  <xsl:choose>
    <xsl:when test="$DistUnit='Metres'">1.0</xsl:when>
    <xsl:when test="$DistUnit='InternationalFeet'">3.280839895</xsl:when>
    <xsl:when test="$DistUnit='USSurveyFeet'">3.2808333333357</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup conversion factor for angular values -->
<!-- Angular values in JobXML file are always in decimal degrees -->
<xsl:variable name="AngleConvFactor">
  <xsl:choose>
    <xsl:when test="$AngleUnit='DMSDegrees'">1.0</xsl:when>
    <xsl:when test="$AngleUnit='Gons'">1.111111111111</xsl:when>
    <xsl:when test="$AngleUnit='Mils'">17.77777777777</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup boolean variable for coordinate order -->
<xsl:variable name="NECoords">
  <xsl:choose>
    <xsl:when test="$CoordOrder='North-East-Elevation'">true</xsl:when>
    <xsl:when test="$CoordOrder='X-Y-Z'">true</xsl:when>
    <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Setup conversion factor for pressure values -->
<!-- Pressure values in JobXML file are always in millibars (hPa) -->
<xsl:variable name="PressConvFactor">
  <xsl:choose>
    <xsl:when test="$PressUnit='MilliBar'">1.0</xsl:when>
    <xsl:when test="$PressUnit='InchHg'">0.029529921</xsl:when>
    <xsl:when test="$PressUnit='mmHg'">0.75006</xsl:when>
    <xsl:otherwise>1.0</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:variable name="includeAttributes" select="'true'"/>

<!-- Set up a variable to indicate whether there are any point        -->
<!-- descriptions assigned to any points - zero means no descriptions -->
<!-- Only need to check for number of Description1 elements since     -->
<!-- both the Description1 and Description2 elements are output if    -->
<!-- either has been defined for the point.                           -->
<xsl:variable name="nbrPtDescriptions">
  <xsl:value-of select="count(JOBFile/Reductions/Point/Description1)"/>
</xsl:variable>

<xsl:variable name="dmsSymbols">
  <xsl:if test="$useSymbols = 'Yes'">&#0176;'"</xsl:if>
  <xsl:if test="$useSymbols != 'Yes'">~</xsl:if>
</xsl:variable>

<xsl:variable name="northLbl">
  <xsl:if test="$useHemisphereChars = 'Yes'">N</xsl:if>
</xsl:variable>

<xsl:variable name="eastLbl">
  <xsl:if test="$useHemisphereChars = 'Yes'">E</xsl:if>
</xsl:variable>

<xsl:variable name="southLbl">
  <xsl:if test="$useHemisphereChars = 'Yes'">S</xsl:if>
  <xsl:if test="$useHemisphereChars != 'Yes'">-</xsl:if>
</xsl:variable>

<xsl:variable name="westLbl">
  <xsl:if test="$useHemisphereChars = 'Yes'">W</xsl:if>
  <xsl:if test="$useHemisphereChars != 'Yes'">-</xsl:if>
</xsl:variable>

<xsl:variable name="leadingLabel">
  <xsl:if test="$useHemisphereChars = 'Yes'">false</xsl:if>
  <xsl:if test="$useHemisphereChars != 'Yes'">true</xsl:if>
</xsl:variable>

<xsl:variable name="fieldDelimiter">
  <xsl:choose>
    <xsl:when test="$fieldDelimiterID = '&lt;comma&gt;'">,</xsl:when>
    <xsl:when test="$fieldDelimiterID = '&lt;semicolon&gt;'">;</xsl:when>
    <xsl:when test="$fieldDelimiterID = '&lt;colon&gt;'">:</xsl:when>
    <xsl:when test="$fieldDelimiterID = '&lt;space&gt;'"><xsl:value-of select="' '"/></xsl:when>
    <xsl:when test="$fieldDelimiterID = '&lt;tab&gt;'"><xsl:value-of select="'&#09;'"/></xsl:when>
    <xsl:otherwise>,</xsl:otherwise>
  </xsl:choose>
</xsl:variable>


<!-- **************************************************************** -->
<!-- ************************** Main Loop *************************** -->
<!-- **************************************************************** -->
<xsl:template match="/" >

  <!-- Select Reductions node to process -->
  <xsl:apply-templates select="JOBFile/Reductions/Point[WGS84]"/>

</xsl:template>


<!-- **************************************************************** -->
<!-- ****************** Reductions Point Output ********************* -->
<!-- **************************************************************** -->
<xsl:template match="Point">

  <!-- Output the point name -->
  <xsl:value-of select="Name"/>
  <xsl:value-of select="$fieldDelimiter"/>

  <!-- Output the WGS-84 latitude value -->
  <xsl:variable name="latStr">
    <xsl:call-template name="FormatLatLong">
      <xsl:with-param name="theAngle" select="WGS84/Latitude"/>
      <xsl:with-param name="dmsSymbols" select="$dmsSymbols"/>
      <xsl:with-param name="northLbl" select="$northLbl"/>
      <xsl:with-param name="eastLbl" select="$eastLbl"/>
      <xsl:with-param name="southLbl" select="$southLbl"/>
      <xsl:with-param name="westLbl" select="$westLbl"/>
      <xsl:with-param name="leadingLabel" select="$leadingLabel"/>
      <xsl:with-param name="decimalDegrees" select="$decimalDegrees"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="($decimalDegrees = 'false') and ($useSymbols != 'Yes')">
      <xsl:value-of select="translate($latStr, '~.', '.')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$latStr"/>
    </xsl:otherwise>
  </xsl:choose>

  <xsl:value-of select="$fieldDelimiter"/>

  <!-- Output the WGS-84 longitude value -->
  <xsl:variable name="longStr">
    <xsl:call-template name="FormatLatLong">
      <xsl:with-param name="theAngle" select="WGS84/Longitude"/>
      <xsl:with-param name="isLat">false</xsl:with-param>
      <xsl:with-param name="dmsSymbols" select="$dmsSymbols"/>
      <xsl:with-param name="northLbl" select="$northLbl"/>
      <xsl:with-param name="eastLbl" select="$eastLbl"/>
      <xsl:with-param name="southLbl" select="$southLbl"/>
      <xsl:with-param name="westLbl" select="$westLbl"/>
      <xsl:with-param name="leadingLabel" select="$leadingLabel"/>
      <xsl:with-param name="decimalDegrees" select="$decimalDegrees"/>
    </xsl:call-template>
  </xsl:variable>

  <xsl:choose>
    <xsl:when test="($decimalDegrees = 'false') and ($useSymbols != 'Yes')">
      <xsl:value-of select="translate($longStr, '~.', '.')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$longStr"/>
    </xsl:otherwise>
  </xsl:choose>

  <xsl:value-of select="$fieldDelimiter"/>

  <!-- Output the WGS-84 height value -->
  <xsl:value-of select="format-number(WGS84/Height * $DistConvFactor, $DecPl3, 'Standard')"/>
  <xsl:value-of select="$fieldDelimiter"/>

  <!-- Output the point code -->
  <xsl:value-of select="Code"/>

  <xsl:if test="$includeAttributes = 'true'">
    <xsl:apply-templates select="Features"/>
  </xsl:if>

  <!-- Finally output any descriptions assigned to this point -->
  <xsl:if test="$nbrPtDescriptions &gt; 0">  <!-- There are some descriptions assigned to points -->
    <xsl:if test="Description1">
      <xsl:value-of select="$fieldDelimiter"/>
      <xsl:value-of select="Description1"/>
    </xsl:if>
    <xsl:if test="Description2">
      <xsl:value-of select="$fieldDelimiter"/>
      <xsl:value-of select="Description2"/>
    </xsl:if>
  </xsl:if>

  <xsl:call-template name="NewLine"/> <!-- New line ready for next point -->

</xsl:template>


<!-- **************************************************************** -->
<!-- ************** Features and Attributes Output ****************** -->
<!-- **************************************************************** -->
<xsl:template match="Features">

  <xsl:for-each select="Feature">
    <!-- Output the feature name (there may be more than 1 feature associated -->
    <!-- with the point) so this will identify which feature the attrinbutes  -->
    <!-- are associated with.                                                 -->
    <xsl:value-of select="','"/>  <!-- Comma to separate feature name from code or previous feature -->
    <xsl:variable name="FeatName" select="@Name"/> <!-- Feature name -->
    <xsl:for-each select="Attribute">
      <xsl:if test="position() &gt; 1">
        <xsl:value-of select="$fieldDelimiter"/> <!-- Include a delimiter if not first attribute -->
      </xsl:if>
      <!-- Prefix each attribute name with the feature it belongs to followed by a ':' -->
      <xsl:value-of select="concat($FeatName, '-')"/>
      <xsl:value-of select="Name"/>
      <xsl:choose>
        <xsl:when test="$fieldDelimiter = ':'">=</xsl:when>   <!-- Don't use colon if it is the selected field delimiter -->
        <xsl:otherwise>:</xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="Value"/>
    </xsl:for-each>
  </xsl:for-each>

</xsl:template>


<!-- **************************************************************** -->
<!-- ********* Format latitude or Longitude in DMS Format *********** -->
<!-- **************************************************************** -->
<xsl:template name="FormatLatLong">
  <xsl:param name="theAngle"/>
  <xsl:param name="isLat" select="'true'"/>
  <xsl:param name="secDecPlaces" select="5"/>
  <xsl:param name="impliedDecimalPt" select="'false'"/>
  <xsl:param name="northLbl" select="'N'"/>
  <xsl:param name="eastLbl" select="'E'"/>
  <xsl:param name="southLbl" select="'S'"/>
  <xsl:param name="westLbl" select="'W'"/>
  <xsl:param name="leadingLabel" select="'false'"/>
  <xsl:param name="dmsSymbols">&#0176;'"</xsl:param>
  <xsl:param name="decimalDegrees" select="'false'"/>

  <xsl:choose>
    <!-- Null angle value -->
    <xsl:when test="string(number($theAngle)) = 'NaN'">
      <xsl:value-of select="format-number($theAngle, $DecPl3, 'Standard')"/> <!-- Use the defined null format output -->
    </xsl:when>
    <!-- There is a lat or long value -->
    <xsl:otherwise>
      <xsl:variable name="sign">
        <xsl:choose>
          <xsl:when test="$theAngle &lt; '0.0'">
            <xsl:choose>  <!-- Negative value -->
              <xsl:when test="$isLat = 'true'"><xsl:value-of select="$southLbl"/></xsl:when>
              <xsl:otherwise><xsl:value-of select="$westLbl"/></xsl:otherwise>
            </xsl:choose>
          </xsl:when>
          <xsl:otherwise> <!-- Positive value -->
            <xsl:choose>
              <xsl:when test="$isLat = 'true'"><xsl:value-of select="$northLbl"/></xsl:when>
              <xsl:otherwise><xsl:value-of select="$eastLbl"/></xsl:otherwise>
            </xsl:choose>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <!-- Convert to a positive angle before changing to DMS format -->
      <xsl:variable name="posAngle" select="concat(substring('-',2 - ($theAngle &lt; 0)), '1') * $theAngle"/>

      <xsl:variable name="latLongAngle">
        <xsl:choose>
          <xsl:when test="$decimalDegrees = 'false'">
            <xsl:call-template name="FormatDMSAngle">
              <xsl:with-param name="decimalAngle" select="$posAngle"/>
              <xsl:with-param name="secDecPlaces" select="$secDecPlaces"/>
              <xsl:with-param name="impliedDecimalPt" select="$impliedDecimalPt"/>
              <xsl:with-param name="dmsSymbols" select="$dmsSymbols"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>  <!-- Output as decimal degrees to 8 decimal places -->
            <xsl:value-of select="format-number($posAngle, $DecPl8, 'Standard')"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:variable>

      <xsl:choose>
        <xsl:when test="$leadingLabel = 'false'">
          <xsl:value-of select="concat($latLongAngle, $sign)"/>
        </xsl:when>
        <xsl:otherwise>  <!-- Trailing label -->
          <xsl:value-of select="concat($sign, $latLongAngle)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************** New Line Output ************************* -->
<!-- **************************************************************** -->
<xsl:template name="NewLine">
  <xsl:text>&#10;</xsl:text>
</xsl:template>


<!-- **************************************************************** -->
<!-- ********************** Format a DMS Angle ********************** -->
<!-- **************************************************************** -->
<xsl:template name="FormatDMSAngle">
  <xsl:param name="decimalAngle"/>
  <xsl:param name="secDecPlaces" select="0"/>
  <xsl:param name="useSymbols" select="'true'"/>
  <xsl:param name="impliedDecimalPt" select="'false'"/>
  <xsl:param name="dmsSymbols">&#0176;'"</xsl:param>

  <xsl:variable name="degreesSymbol">
    <xsl:choose>
      <xsl:when test="$useSymbols = 'true'"><xsl:value-of select="substring($dmsSymbols, 1, 1)"/></xsl:when>  <!-- Degrees symbol ° -->
      <xsl:otherwise>
        <xsl:if test="$impliedDecimalPt != 'true'">.</xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="minutesSymbol">
    <xsl:choose>
      <xsl:when test="$useSymbols = 'true'"><xsl:value-of select="substring($dmsSymbols, 2, 1)"/></xsl:when>
      <xsl:otherwise></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="secondsSymbol">
    <xsl:choose>
      <xsl:when test="$useSymbols = 'true'"><xsl:value-of select="substring($dmsSymbols, 3, 1)"/></xsl:when>
      <xsl:otherwise></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="sign">
    <xsl:if test="$decimalAngle &lt; '0.0'">-1</xsl:if>
    <xsl:if test="$decimalAngle &gt;= '0.0'">1</xsl:if>
  </xsl:variable>

  <xsl:variable name="posDecimalDegrees" select="number($decimalAngle * $sign)"/>

  <xsl:variable name="positiveDecimalDegrees">  <!-- Ensure an angle very close to 360° is treated as 0° -->
    <xsl:choose>
      <xsl:when test="(360.0 - $posDecimalDegrees) &lt; 0.00001">
        <xsl:value-of select="0"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$posDecimalDegrees"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="decPlFmt">
    <xsl:choose>
      <xsl:when test="$secDecPlaces = 0"><xsl:value-of select="''"/></xsl:when>
      <xsl:when test="$secDecPlaces = 1"><xsl:value-of select="'.0'"/></xsl:when>
      <xsl:when test="$secDecPlaces = 2"><xsl:value-of select="'.00'"/></xsl:when>
      <xsl:when test="$secDecPlaces = 3"><xsl:value-of select="'.000'"/></xsl:when>
      <xsl:when test="$secDecPlaces = 4"><xsl:value-of select="'.0000'"/></xsl:when>
      <xsl:when test="$secDecPlaces = 5"><xsl:value-of select="'.00000'"/></xsl:when>
      <xsl:when test="$secDecPlaces = 6"><xsl:value-of select="'.000000'"/></xsl:when>
      <xsl:otherwise><xsl:value-of select="''"/></xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <xsl:variable name="degrees" select="floor($positiveDecimalDegrees)"/>
  <xsl:variable name="decimalMinutes" select="number(number($positiveDecimalDegrees - $degrees) * 60 )"/>
  <xsl:variable name="minutes" select="floor($decimalMinutes)"/>
  <xsl:variable name="seconds" select="number(number($decimalMinutes - $minutes)*60)"/>

  <xsl:variable name="partiallyNormalisedMinutes">
    <xsl:if test="number(format-number($seconds, concat('00', $decPlFmt))) = 60"><xsl:value-of select="number($minutes + 1)"/></xsl:if>
    <xsl:if test="not(number(format-number($seconds, concat('00', $decPlFmt))) = 60)"><xsl:value-of select="$minutes"/></xsl:if>
  </xsl:variable>

  <xsl:variable name="normalisedSeconds">
    <xsl:if test="number(format-number($seconds, concat('00', $decPlFmt))) = 60"><xsl:value-of select="0"/></xsl:if>
    <xsl:if test="not(number(format-number($seconds, concat('00', $decPlFmt))) = 60)"><xsl:value-of select="$seconds"/></xsl:if>
  </xsl:variable>

  <xsl:variable name="partiallyNormalisedDegrees">
    <xsl:if test="format-number($partiallyNormalisedMinutes, '0') = '60'"><xsl:value-of select="number($degrees + 1)"/></xsl:if>
    <xsl:if test="not(format-number($partiallyNormalisedMinutes, '0') = '60')"><xsl:value-of select="$degrees"/></xsl:if>
  </xsl:variable>

  <xsl:variable name="normalisedDegrees">
    <xsl:if test="format-number($partiallyNormalisedDegrees, '0') = '360'"><xsl:value-of select="0"/></xsl:if>
    <xsl:if test="not(format-number($partiallyNormalisedDegrees, '0') = '360')"><xsl:value-of select="$partiallyNormalisedDegrees"/></xsl:if>
  </xsl:variable>

  <xsl:variable name="normalisedMinutes">
    <xsl:if test="format-number($partiallyNormalisedMinutes, '00') = '60'"><xsl:value-of select="0"/></xsl:if>
    <xsl:if test="not(format-number($partiallyNormalisedMinutes, '00') = '60')"><xsl:value-of select="$partiallyNormalisedMinutes"/></xsl:if>
  </xsl:variable>

  <xsl:if test="$sign = -1">-</xsl:if>
  <xsl:value-of select="format-number($normalisedDegrees, '0')"/>
  <xsl:value-of select="$degreesSymbol"/>
  <xsl:value-of select="format-number($normalisedMinutes, '00')"/>
  <xsl:value-of select="$minutesSymbol"/>
  <xsl:choose>
    <xsl:when test="$useSymbols = 'true'">
      <xsl:value-of select="format-number($normalisedSeconds, concat('00', $decPlFmt))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="translate(format-number($normalisedSeconds, concat('00', $decPlFmt)), '.', '')"/>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:value-of select="$secondsSymbol"/>
</xsl:template>


</xsl:stylesheet>
