1

I am working in a tabular set (.dbf) In ArcGIS 10.1 with an odd DMS format.The format is as follows:

Lat: 45585400 Long: 89560600

I believe this is a strange notation for 45°58'54" and -89°56'06". My problem is I can't figure out how to parse the Degrees, Minutes and Seconds out into individual fields in the .dbf. Once I get that far I can easily convert the value to decimal degrees and create point data out of it.

If anyone can help me with this I would really appreciate it.

  • 3
    The answer depends on whether the field type is character or numeric: which is it? Many examples of this kind of calculation have been posted: consider searching our site for inspiration. – whuber Jul 16 '13 at 19:14
  • You wouldn't really need to create temporary fields to store DMS (thought it might be easier if you don't have much experience with manipulating a string of numbers). – Paul Jul 16 '13 at 21:02
1

This should work, assuming that the input is a double, long, or string. If the input is a string, you can remove the line that casts the value to a string.

exp = """
def convert(value,latlong):
    num = str(int(value))
    i = 0 if len(num) == 8 else 1
    val = int(num[0:2+i]) + int(num[2+i:4+i])/60.0 + int(num[4+i:])/360000.0
    if latlong.lower() in ["longitude", "long", "lambda"]: val = -val    
    return val"""

arcpy.CalculateField_management("<DBF FILE>", "<new lat field>", 
                                'convert(!LAT!,"")', "PYTHON_9.3", exp)

With built in exp, it's difficult to maintain exact spacing and newline characters.

arcpy.CalculateField_management("<DBF FILE>", "<new lat field>", 
                                'convert(!LAT!,"")', "PYTHON_9.3",
                                """def convert(value,latlong):\n    num = str(int(value))\n    i = 0 if len(num) == 8 else 1\n    val = int(num[0:2+i]) + int(num[2+i:4+i])/60.0 + int(num[4+i:])/360000.0\n    if latlong.lower() in ["longitude", "long", "lambda"]: val = -val\n    return val""")
  • Did you also consider including your code as a code block of the CalculateField to make it a one liner? Am just curious - not saying it is better/worse to do so. – PolyGeo Jul 16 '13 at 22:14
  • 1
    (1) Don't forget the negate the longitude. (2) Bad things happen with these formulas if the longitude exceeds 100 in absolute value. It's probably safer to use numeric operations (int and mod) rather than picking out substrings. – whuber Jul 16 '13 at 23:02
  • Hmm, that's true. I'd have to check the length of the string to determine how many numbers to extract for the degrees portion. I'm curious as to how to use mod though... – Paul Jul 16 '13 at 23:07
  • I was meaning to have everything in the one line that is the CalculateField line i.e. use Copy Python Snippet from the Geoprocessing | Results window after you've created and run Calculate Field with a Code Block (which at that point can be multiline). – PolyGeo Jul 16 '13 at 23:18
  • 1
    OK, that looks better (+1). Mod works by extracting the last few digits of any number. For instance, 45585400 mod 10000 gives 5400. When you divide the original value by 10000 and truncate you will get 4558. Thus, you have split the original number into two pieces. Now repeat: 4558 mod 100 gives 58; dividing by 100 and truncating yields 45. In this way all three parts have been extracted as numbers. This works even for values like 123456700 or 1234500 (where your string-manipulation code still fails). For input that might be negative (not the case here), work with the absolute values. – whuber Jul 17 '13 at 13:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.