Formatting Coordinates with DmsFormat
If you noticed you're rewriting that coordinate formatting routine
each time you need a slightly different output, DmsFormat is for you -
next time, you'll simply use a different format string.
Introduction
In a nutshell, what
DmsFormat does is accept a coordinate value
(latitude or longitude in MapPoints internal decimal degree notation -
a double, that is) and convert it into a string, given a pattern
string that controls formatting and conversion.
Signature and parameters
The actual signature of the function is as follows:
Public Function DmsFormat(dblVal As Double, strPattern As String, _
blnIsLatitude As Boolean, _
blnForceDp As Boolean) As String
Let's have a quick look at the parameters:
- dblVal - this is the latitude or longitude value to be converted
- strPattern - the format string - will be explained in detail below
- blnIsLatitude - pass True if the coordinate is a latitude -
used to format the compass point
- blnForceDp - pass True to force a decimal point instead of
a comma. If your country settings in control panel specify a comma as
decimal separator, DmsFormat will format respect this, unless you
force it to be a period. Use this e.g. if you want to write DmsFormat
data to file in a format that is not locale-dependent.
- Return value - DmsFormat returns its result in string format, for further processing.
Source code
The source code for DmsFormat can be downloaded
here. It
is available in the form of a .BAS module that you can add to your own
projects (alternatively, just paste the routine into your code). To
download the file, right-click on the link above, and select "Save
target as ..."
The pattern string
The most important parameter is the pattern string. DmsFormat will
scan this string, replacing two-character placeholders in angular
brackets with certain values, and leaving the rest as it is.
For example, in the following pattern string:
"A latitude of <Di> degrees, <Mi> minutes and <Sd> seconds <Cp>"
<Di> will be replaced by integer degrees, <Mi> by integer minutes, and
<Sd> by decimal seconds. <Cp> will be replaced by the compass point,
i.e. S or N depending whether dblVal is negative or not. (And assuming
blnIsLatitude is passed as True)
With a dblValue of 49.00220, DmsFormat would return the following result:
"A latitude of 49 degrees, 0 minutes and 7.9 seconds N"
The following table lists the placeholders recognized by DmsFormat
(see "Format specification" below for an explanation of the "default
format" column):
Placeholder | Description | Result for dblVal = -1.23456 | Default format |
<Di> |
Integer (whole) degrees, unsigned
| 1 |
"##0" |
<Mi> |
Integer (whole) degrees, unsigned
| 14 |
"#0" |
<Si> |
Integer (whole) seconds, unsigned
| 4 |
"#0" |
<Dd> |
Decimal degrees, unsigned
| 1.23456 |
"##0.0####" |
<Md> |
Decimal minutes, unsigned
| 14.074 |
"#0.0##" |
<Sd> |
Decimal seconds, unsigned
| 4.4 |
"#0.0" |
<Cp> |
Compass point (W, E, N, or S)
| S (assuming blnIsLatitude passed as True) |
"W|E|S|N" |
Format specification
DmsFormat provides "sensible" formatting of the values that get
substituted for the two-character placeholders. In general, integer
values do not get any decimal places nor a decimal point, and the
decimal values get "enough" of them - five for Dd, three for Md, and
one for Sd.
But if you want, you can override these default formats, and provide
your own. Simply append an equals sign to the two-character
placeholder (inside the angular brackets), and add a format
specification in the form understood by the VB "
Format" function.
Example: You'd like to output integer degrees and decimal
minutes, with a compass point. The degrees should be three digits with
leading zeroes, the decimal minutes two digits (with leading zeroes)
before, and three after the decimal point. This is the pattern string
you would use:
"<Di=000> degrees and <Md=00.000> minutes <Cp>"
and this is what the result would look like, assuming dblVal = -1.23456 and blnIsLatitude set:
"001 degrees and 14.074 minutes S"
A special case: The Compass point format
All placeholders represent numerical values, except for the compass
point. It has a special format string too. Instead of the defaults
W,E,N, and S, you can provide other names for the compass strings by
listing them, separated by pipe characters, after the "Cp".
Example: to get more verbose compass points, you could use the following:
"<Cp=West|East|North|South>"
Note that which of those four names is used depends on the sign of
dblVal, as well as the blnIsLatitude flag. The names have to be in the
exact order shown above: WENS.
Default formats
Every placeholder has a default format that will be used if you do not
override it using the assignment syntax just described. The placeholder table
above has a column that lists the default format specifications for every
placeholder.
Controlling field widths
The desired width of a replacement can be specified by appending a
colon (:) and the width to the format specification. For example, to
output integer degrees without leading zeroes right-justified in a
field that is always 5 characters wide, use the following format:
"---<Di=##0:5>---"
(The dashes are used to make the alignment more visible)
The output would be the following (for dblVal = -1.23456):
"--- 1---" (Note the additional four spaces in front of the 1.)
To left-justify the value, use a negative width. For example:
"---<Di=##0:-5>---"
(The dashes are used to make the left justification more visible)
The output would be the following (for dblVal = -1.23456):
"---1 ---" (Note the additional four spaces after the 1.)
Note that the field width that you specify is always observed - if
the resulting value is too big to fit, it will be truncated.
Special escape placeholders
If you need to include the less-than (<) and greater-than (>)
characters themselves inside your pattern string, use <lt> and <gt> to represent them.
Tips, tricks, and pitfalls
- The placeholders are case-insensitive - it doesn't matter if you use <cp>, <CP>, or <Cp>.
- Undefinded placeholders (e.g. <xy>) will be replaced by 99.99
- In the format specification part, anything the VB Format function understands can be used -
for example, <Dd=General number> will work.
- If you need a signed version of the coordinates (negative for west and south, positive for east and north),
use e.g. <Cp=-|+|-|+><Dd>
- If you would like to use the default format specification, but
want to specify a width, add the equals sign immediately followed by a
colon. Example: <Dd=:8>
- If you specify a width, make sure it is large enough for the value to be displayed, otherwise, the value will be truncated.
- Avoid using thousands separators in the format specification, as they can create havoc in combination with blnForceDp
Mapping and especially GPS-related topics are a hobby - Gilles enjoys developing solutions for Microsoft MapPoint and his favorite outdoor occupation is confluence hunting.