Wednesday, November 30, 2011

Convert Decimal Degree to Degrees Minutes Seconds Using Python

Here is a function that will convert decimal degree values to degrees, minutes, and seconds.  It's nice to show DMS notation as labels for points at times, so here is a script I made to do this:


def decimalDegrees2DMS(value,type):
    """
        Converts a Decimal Degree Value into
        Degrees Minute Seconds Notation.
        
        Pass value as double
        type = {Latitude or Longitude} as string
        
        returns a string as D:M:S:Direction
        created by: anothergisblog.blogspot.com 
    """
    degrees = int(value)
    submin = abs( (value - int(value) ) * 60)
    minutes = int(submin)
    subseconds = abs((submin-int(submin)) * 60)
    direction = ""
    if type == "Longitude":
        if degrees < 0:
            direction = "W"
        elif degrees > 0:
            direction = "E"
        else:
            direction = ""
    elif type == "Latitude":
        if degrees < 0:
            direction = "S"
        elif degrees > 0:
            direction = "N"
        else:
            direction = "" 
    notation = str(degrees) + ":" + str(minutes) + ":" +\
               str(subseconds)[0:5] + "" + direction
    return notation


It's a very simple function, but very useful.  Feel free to use it, but give my blog some love and cite me.
Enjoy

Friday, November 25, 2011

Get Selected Layer From TOC (ArcObjects)

Getting the selected layer a user is using can be an easy way to have the user interact with ArcMap without having them mull through some form.  This is be achieved in a couple of line of code:

IContentsView contentsView = mapDocument.CurrentContentsView;
object selectedItem = contentsView.SelectedItem;
if (!(selectedItem is ILayer))
{
   return;
}


First the code assumes you know how to get the current map document's reference and second it not only gets the selected item, I provided a simple check that ensures it's a layer object.

Enjoy

Wednesday, November 23, 2011

Clearing a selection from select by location

After performing a select layer by location function, sometimes you need to clear it, but the select by location function does not have a "CLEAR" option, so what to do?..?  Well no fear, you can use the following:


arcpy.SelectLayerByAttribute_management(layer, "CLEAR_SELECTION")

and magically your rows will no longer be selected.

Enjoy

Tuesday, November 22, 2011

Boxplots using matplotlib

If you ever need to graph anything using python, I recommend matplotlib. Here is an example of a boxplot below. The link will take you to the help documentation in matplotlib. It's pretty good compared to many other python modules.


from pylab import *

# fake up some data
spread= rand(50) * 100
center = ones(25) * 50
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
data =concatenate((spread, center, flier_high, flier_low), 0)

# basic plot
boxplot(data)
#savefig('box1')

# notched plot
figure()
boxplot(data,1)
#savefig('box2')

# change outlier point symbols
figure()
boxplot(data,0,'gD')
#savefig('box3')

# don't show outlier points
figure()
boxplot(data,0,'')
#savefig('box4')

# horizontal boxes
figure()
boxplot(data,0,'rs',0)
#savefig('box5')

# change whisker length
figure()
boxplot(data,0,'rs',0,0.75)
#savefig('box6')

# fake up some more data
spread= rand(50) * 100
center = ones(25) * 40
flier_high = rand(10) * 100 + 100
flier_low = rand(10) * -100
d2 = concatenate( (spread, center, flier_high, flier_low), 0 )
data.shape = (-1, 1)
d2.shape = (-1, 1)
#data = concatenate( (data, d2), 1 )
# Making a 2-D array only works if all the columns are the
# same length. If they are not, then use a list instead.
# This is actually more efficient because boxplot converts
# a 2-D array into a list of vectors internally anyway.
data = [data, d2, d2[::2,0]]
# multiple box plots on one figure
figure()
boxplot(data)
#savefig('box7')

show()


This will produce the following:
Pretty sweet.  Maybe you could use this to graph the elevation profile?  (Hint: you can)

Enjoy

Friday, November 18, 2011

Getting the Extent is Easy as Describe() - ArcPy

Early in my blog, I posted methods on obtaining the extent, and creating an extent polygon using the Array and Poylgon objects.  Here is the short cut for creating extent polygons for a whole feature class:

import arcpy
dataset = r"c:\temp\myfeatures.shp"
desc = arcpy.Describe(dataset)
extent = desc.extent
arcpy.CopyFeatures_management(extent, "c:/TEMP/extent.shp")

Very cool, and very easy.

High Resolution Moon Maps

NASA's Lunar Reconnaissance Orbiter has completed it's mission of taking high resolution images of the moon, and now you can take advantage of them as well.  According to NASA over 69K worth of photos were geo-referenced and stitched together to create raster imagery with a cell size of 328 ft by 328 ft.  They note that the polar coverage is limited due to the lack of light the moon receives there and a different orbiter is mapping the poles using lasers.

You can get the imagery here: http://wms.lroc.asu.edu/lroc

Happy Space

Wednesday, November 16, 2011

Using Sqlite3 to store Blob data

Sqlite3 is the python module that creates a self contained, server less, zero-configuration, and transactional SQL database.  SQLite is an embedded SQL database engine. Unlike most other SQL databases, SQLite does not have a separate server process. SQLite reads and writes directly to ordinary disk files. A complete SQL database with multiple tables, indices, triggers, and views, is contained in a single disk file. The database file format is cross-platform - you can freely copy a database between 32-bit and 64-bit systems.  More can be found out about the database here
In python, you can quickly access or create a SQLite database by using the Sqlite3 module as mentioned above:

db_filename = r"C:\TEMP\sqllist\myDB.db"
db_is_new = not os.path.exists(db_filename)
conn = sqlite3.connect(db_filename)
cursor = conn.cursor()
if db_is_new:
    print 'Need to create schema'
    tableCreation = """create table data (
                    id integer primary key autoincrement not null,
                    File blob,
                    Type text,
                    FileName text);"""
    conn.execute(tableCreation)
else:
    print 'Database exists, assume schema does, too.'

Let's assume we want to store a zip file inside the database.  To do this, open the reference to the file and save it as binary data.  The data will be stored in the field called 'File' as created above.

zipFile = r"C:\TEMP\sqllist\extent.zip"

with open(zipFile, "rb") as input_file:
    ablob = input_file.read()
    cursor.execute("INSERT INTO data (File,Type,FileName) VALUES(?,'zip','" + zipFile + "')", [sqlite3.Binary(ablob)])
    conn.commit()

Here we open the zip file and using an INSERT command put the data into the data table.
Next, perform a simple SELECT statement to show that the row exists in the table:

cursor.execute("select * from data")
for row in cursor:
    print row
del row

This will yield something like this:

>>> (1, , u'zip', u'C:\\TEMP\\sqllist\\extent.zip')

To get the Blob data out of the database, use the SELECT SQL statement and the open() to create a new zip file:

with open(r"c:\temp\sqllist\Output.zip", "wb") as output_file:
    cursor.execute("SELECT file FROM data WHERE id = 1")
    ablob = cursor.fetchone()
    output_file.write(ablob[0])
    cursor.close()
conn.close()

The code above creates a new file called 'output.zip' and writes the information from the blob field to the file. Then the script closes the database connection and cursor connection.

Easy as Π

Friday, November 11, 2011

Speak Up For Geography

Support Geography!  Go to here: http://speakupforgeography.rallycongress.com/

Write your congressional leadership and let them know you want them to support the "Geography is Fundamental (TGIF) Act". Please do it by November 18, 2011.

Join the cause and help students improve their geography knowledge.

Thanks everyone!

Monday, November 7, 2011

Vote November 8th - General Elections (USA)

Please remember to vote this year (and every year).  Elections have consequences, especially if you do not make your voice heard. If you don't vote you might get something you really don't want.

Friday, November 4, 2011

Parallel Python with GIS

I've begun to dive into Parallel Python to see if I can reduce processing times on long running tasks by dividing the workload among a cluster of computers. 

I've already run into some problems:
  • Spatial data is not serializable
  • Lack of good documentation from Parallel Python
  • No upload data/download results function if you use files.
  • Servers time out
  • Tasks randomly restart
You'll have to have arcpy installed on all the machines you are performing the cluster computing with.
Now that you know that, you can get started easy as this:

ppservers = ('xx.xxx.xx.xx:8080',)
job_server = pp.Server(ppservers=ppservers,ncpus=0)

You set ncpus = 0 inorder prevent processes from being used locally. To submit a job:

libs = ("arcpy",)

job_server.submit(function,# function to perform
                 (variables,), # function variable
                 (),# call back function
                 libs # modules used by function
)
job_server.wait() # waits for the job to complete
job_server.print_stats() # print some stats about the server and task
del job_server


It's that simple to run the task.

Enjoy

Thursday, November 3, 2011

Vote for HTML Tag Support in Page Layouts

Please vote for my idea on the ArcGIS Idea Page. 

Thanks
~A

pyshp - the big update

Over at GeospatialPython.com, there is an interesting blog post here that talks about .shx files as they relate to the whole shapefile make up (shp,dbf,shx,etc..) and why they are important or unimportant.  pyshp now supports the creation of .shx files to provide the complete shapefile spec. 

I think that is great, and I'm glad the community has taken to the open shapefile specification so well, but I think it's time we all move onto the file geodatabase.  You can find the API here.  As of right now, there is no python module to handle the file geodatabase spec, but I'm sure one will float up soon.