PYTHON CODE TO CHANGE DASH VALUES TO DEGREE MINUTE SECOND

2156
10
Jump to solution
01-02-2014 04:19 PM
SaniTakwim
New Contributor
I'm a novice in programming and would appreciate if somebody can provide me with a Python code that can convert the values in my cogo "Direction" field in the "180-0-0" format to the degree minute second format so that I can used the labels when printing out my traverse map. TQ.

Sani
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
T__WayneWhitley
Frequent Contributor
Sounds to me you are almost there - your statement that the seconds character returned a '?' simply means this Unicode character didn't get resolved.  Are you working with a shapefile?...if so, Unicode support is weak -- work with a file gdb if you can.

Also, if running test successive calculations, make sure you set the text you're converting back to what the function is expecting (xx-xx-xx).

Note that you can also mimic the minutes (prime) and seconds (double prime) characters with single quote and double quote -- labeling with this calculation result at a small scale will work fine, so again, check your initial field values and use the Python calc function - I think this will work okay with the quote characters for min and sec:
def calc(val):     val = val.split('-')     return u'%s\u00B0 %s\' %s"' % tuple(val)


Hope that helps - note that behavior via the field calculator is not guaranteed...the following is the testing of output via IDLE, notice the subtle difference in the symbols - this likely makes no aesthetic difference in labeling for you:
>>> Delta = '12-54-45' >>>  >>> def calc(val):  val = val.split('-')  return u'%s\u00B0 %s\' %s"' % tuple(val)   >>> calc(Delta) '12\xb0 54\' 45"' >>>  >>> print _ 12° 54' 45" >>>  >>> def calcUC(val):  val = val.split('-')  return u'%s\u00B0 %s\u2032 %s\u2033' % tuple(val)   >>> calcUC(Delta) u'12\xb0 54\u2032 45\u2033' >>> >>> print _ 12° 54??? 45??? >>>  >>> # (side-by-side comparison) >>> print calc(Delta) 12° 54' 45" >>> print calcUC(Delta) 12° 54??? 45??? >>>

View solution in original post

0 Kudos
10 Replies
T__WayneWhitley
Frequent Contributor
Try this:
def FindLabel ( [DegMinSec] ):
   deg, min, sec = [DegMinSec].split('-')
   S = u"str({0}) + '\u00B0 ' + str({1}) + '\u2032' + str({2}) + '\u2033'".format(deg, min, sec)
   return S


(Change DegMinSec to your particular field name containing your text string deg-min-sec)


EDIT:  I didn't test this, so some modifications may be required...for instance, not sure if this:

[DegMinSec].split('-')


...should instead be this:

([DegMinSec]).split('-')
0 Kudos
T__WayneWhitley
Frequent Contributor
My apologies, the behavior is not the same as with the CalculateField tool - the corrected label expression is below (substitute your field name for YourField):
def FindLabel ( [YourField] ):
  deg, min, sec = [YourField].split('-')
  S = u"{0}\u00B0 {1}\u2032 {2}\u2033".format(deg, min, sec)
  return S


Also, this doesn't accommodate neg lat/long vals.  Also the parens on [YourField] in the applied py split is not necessary.

Enjoy,
Wayne
0 Kudos
SaniTakwim
New Contributor
Dear Wayne,

The code fails to work. I am using ArcGIS 10. I am sending you a screenshot of the file and attribute which I am working on. I either want to replace the values in the Direction or Delta field(s) to Degree Minute Seconds. In the field calculator, I ticked Python and String to run the code. For the [Myfield] I replaced it with [Delta] when working with the Direction field.

Can you help out? TQ.
0 Kudos
T__WayneWhitley
Frequent Contributor
That should work in the label expression.
For the field calculation, you can use the expression from gis.stackexchange, tested at 10.0:
http://gis.stackexchange.com/questions/30754/field-calculate-degree-minute-second-in-different-forma...
def calc(val):
    val = val.split('-')
    return u'%s\u00B0 %s\u2032 %s\u2033' % tuple(val)


...at 10.2, the seconds Unicode character (\u2033) doesn't resolve properly - strange, \u2032 works.  Maybe this is fixed with the service pack.  Meanwhile, you can use the double-quote character in the line above:

return u'%s\u00B0 %s\u2032 %s"' % tuple(val)

-Wayne
0 Kudos
SaniTakwim
New Contributor
Dear Wayne,

I've tried the code in the field calculator ticking Python and string but it failed to work. Perhaps you need to teach me step by step on how to use both so that it can be done correctly ;  the label expression and the field calculator. Perhaps I am not a novice but worse than that in using ArcGIS 10 and programming.
i) How I field calculate  - Add theme> open attribute table> right hand click on the Delta field (refer to the screenshot file which I sent last time) to select field calculator > For Parser, I select Python> For type, I select string> For the expression box, Delta = def calc(val):
    val = val.split('-')
    return u'%s\u00B0 %s\u2032 %s\u2033' % tuple(val)
>OK
A message pops up "There was a failure during processing, check the Geoprocessing result window for details.

ii) Label expression  - Add theme>right hand click to select Properties> Layer Properties, I select Labels> Label field, I select Delta>Click on Expression> In Label Expression, I paste your code
def FindLabel ( [YourField] 😞
  deg, min, sec = [YourField].split('-')
  S = u"{0}\u00B0 {1}\u2032 {2}\u2033".format(deg, min, sec)
  return S
(I changed [YourField] with [Delta]
>OK
A message pop up "Carriage return are not allowed in simple expressions".

Please enlighten me on this. Sorry if I sound stupid or silly but please forgive this middle age man. TQ
0 Kudos
T__WayneWhitley
Frequent Contributor
Don't worry too much about it -- I spend too much time forgetting things I should know and handing out unsolicited advice on stuff I hardly know well enough......
hmmm, well let's start with something simple 1st.  The last part of your post you were trying out the labeling - and if you don't mind I'm not going to logon to my other machine where ArcGIS is installed and try this by rote?  I'm sorry, I forgot the Python parser is not supported at 10.0... so let's go with, VBScript -- hold on for a bit, and I'll put together some VBScript for you to run.

So we're going to try the simplest scenario - labeling, ok??  The message you got, "...not allowed in simple expressions", simply means you forgot to click on the 'advanced' option (or whatever it is called) so that you can enter a multi-line function -- otherwise ArcMap is expecting a single line of code.  I think that checkbox is to the upper right of where you enter the code.  If you do this right, a 'stub' is produce -- meaning the basic form of the code (without any function entered) is entered for you.

Let me get back to you in a few minutes with the equivalent VBScript...meanwhile, if you have questions about the general procedure entering advanced expressions, see this:

Building label expressions
http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//00s800000027000000.htm


-Wayne

EDIT - or use the field calculator:  Python is accommodated at 10.0 in the field calculator ---- so it may be quicker for you to use the Python function I gave you at post #4.  See the picture of the Field Calculator on this web page:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Calculate_Field_examples/005s0000002m0...

1- Click on the Python parser as shown in the picture (near the top left).
2- Click 'show Codeblock', also as shown in the picture (middle left).
3- copy/paste the code at post #4, as-is above (don't change a thing).
4- Since you want to calculate your delta field, enter the following in the bottom box (the very bottom)
calc(!Delta!)


Then, of course, hit OK...

Let me know if you have further questions.
0 Kudos
T__WayneWhitley
Frequent Contributor
Okay, now back to the VBScript for the label expression (if you haven't tried the field calculation), which doesn't change your fields but labels based on the current xx-xx-xx field values.

I think this expression (I haven't tested it) will work...just not sure if I passed in the unicode symbols appropriately:
Function FindLabel ( [Delta] )
  Dim MyStrArray
  MyStrArray = Split([Delta], "-", -1, 1)
  FindLabel = MyStrArray(0) & "\u00B0 " & MyStrArray(1) & "\u2032 " & MyStrArray(2) & "\u2033"
End Function


To be clearer - the code posted here (post #7) is for the label expression (does not change your field values in the attribute table).  The field calculator code I refer to (post #6) is for use in the field calculator - this code changes the values in your attribute table.

Wayne

EDIT- I think you'll have to change the FindLabel line for VBScript to interpret the unicode degree, prime, and double prime characters.  Try this substitution:
FindLabel = MyStrArray(0) & Chrw(176) & MyStrArray(1) & Chrw(&H2032) & MyStrArray(2) & Chrw(&H2033)


...or, this alternative substitution:
FindLabel = MyStrArray(0) & Chrw(176) & MyStrArray(1) & Chrw(8242) & MyStrArray(2) & Chrw(8243)
0 Kudos
SaniTakwim
New Contributor
Dear Wayne,

Thanks for your trouble and I really appreciate it. I have yet to try Post#7 but since you say that a new field won't be created but it will only label on the map(right?) I can wait for further solution.

Your post #6 almost worked but the "seconds" symbology becomes "?"(Question mark). I also tried substituting with what you suggest in Post #4 (return u'%s\u00B0 %s\u2032 %s"' % tuple(val)) and by Mike Toews but failure messages appear. Any further remedy to this?
0 Kudos
T__WayneWhitley
Frequent Contributor
Sounds to me you are almost there - your statement that the seconds character returned a '?' simply means this Unicode character didn't get resolved.  Are you working with a shapefile?...if so, Unicode support is weak -- work with a file gdb if you can.

Also, if running test successive calculations, make sure you set the text you're converting back to what the function is expecting (xx-xx-xx).

Note that you can also mimic the minutes (prime) and seconds (double prime) characters with single quote and double quote -- labeling with this calculation result at a small scale will work fine, so again, check your initial field values and use the Python calc function - I think this will work okay with the quote characters for min and sec:
def calc(val):     val = val.split('-')     return u'%s\u00B0 %s\' %s"' % tuple(val)


Hope that helps - note that behavior via the field calculator is not guaranteed...the following is the testing of output via IDLE, notice the subtle difference in the symbols - this likely makes no aesthetic difference in labeling for you:
>>> Delta = '12-54-45' >>>  >>> def calc(val):  val = val.split('-')  return u'%s\u00B0 %s\' %s"' % tuple(val)   >>> calc(Delta) '12\xb0 54\' 45"' >>>  >>> print _ 12° 54' 45" >>>  >>> def calcUC(val):  val = val.split('-')  return u'%s\u00B0 %s\u2032 %s\u2033' % tuple(val)   >>> calcUC(Delta) u'12\xb0 54\u2032 45\u2033' >>> >>> print _ 12° 54??? 45??? >>>  >>> # (side-by-side comparison) >>> print calc(Delta) 12° 54' 45" >>> print calcUC(Delta) 12° 54??? 45??? >>>
0 Kudos