Showing posts with label ArcGIS 10. Show all posts
Showing posts with label ArcGIS 10. Show all posts

Thursday, March 28, 2013

Support GUI Design in ArcGIS for Desktop

Please support this idea of having GUI designer in python built in with python add-ins.

It can be found here: http://ideas.arcgis.com/ideaView?id=087E00000004SmHIAU

Thanks everyone.

Friday, February 22, 2013

Creating a List with n number of entries (Python)

Normally when you create a list object in python, you cannot specify the number of items in the object by default unlike say an array object in C# or C++.  I recently ran into a situation where I was using the arcpy.da cursor objects for table that could have n number of fields.  I wanted the row to be initialized with a default value, so I used the * operator on the list to multiply a single value into a multi-value list.

Example:

# Get a list of fields that are not BLOB, OBJECTID, RASTER, GEOMETRY or GUID
fields = [field.name for field in arcpy.ListFields(service_table) \
                  if not(field.type.upper() in ['BLOB', 'OID', 'RASTER','GEOMETRY','GUID'])
# create a row list with default values
row = [""]* len(fields)

This will create a list object called row, where each value by default is an empty string ("").

Enjoy

Thursday, September 27, 2012

Using Map() or Apply_async() For Multiprocessing


With the release of this new python article on the ArcGIS blogs.  I find it increasingly harder to find concrete/simple explanations of important functions that help make life easier for processing data in ArcGIS.
Though the crux of this article is to give guidance to when or when not to use multiprocessing with ArcGIS, it does use a variation on a method of multiprocessing different than I prefer.  So I decided to investigate the differences between map() and apply_async() on the Pool object.
Pool.apply_async() is also like Python's built-in apply(), except that the call returns immediately instead of waiting for the result. An ApplyResult object is returned. You call its get() method to retrieve the result of the function call. The get() method blocks until the function is completed. Apply_async() does not preserve the order of the results meaning that the codes return results will not be a 1:1 correlation between when it was called and when it finished.  In addition, apply_async() allows coders to call multiple functions instead of a single function.
Pool.map() is like the Python's built-in map() function.  Pool.map() applies the same function to many arguments. The results are returned in an order corresponding to the order of the arguments.

When it comes right down to it, you basically need to find the right tool for the right job.

Here are some resources to help you along.

Enjoy

Friday, September 21, 2012

Uninstalling Time!

The funny things you see when upgrading versions of software:

Installers always were lousy estimators of time, but this one was way off!!!! I guess I need two cups of coffee for this one.

Enjoy

Friday, September 7, 2012

Article on 3rd Party Modules

The Esri python team wrote another good article on 3rd party modules, which is a good read for anyone who is new to python.

The article can be found here.

Enjoy

Thursday, July 12, 2012

ArcGIS Python Window Color Scheme

If you are like me, I prefer dark backgrounds and white or bright text verse the standard white on black.

The python window color scheme can be changed by doing the following:

  1. Right click on the python window 
  2. Select Format
  3. Select 'Set Black Theme'
Now your background is black


Wednesday, July 11, 2012

ArcGIS 10 SP5 Released

Service Pack 5 has been released.

Get it while it's hot from here.

List of issues fixed here.

Enjoy

Thursday, June 14, 2012

Random Number Generator (arcpy.env)

This is a tool that creates a random number based on a seed number and an algorithm selection.
Inputs are as follows:
  1. Seed—The seed is an integer value and is used to initiate the random number generator. The default value is 0.
  2. Random Generator Type—The random generator algorithm.


    • ACM599—ACM collected algorithm 599. This is the default.
    • MERSENNE_TWISTER—Mersenne Twister mt19937.
    • STANDARD_C—Standard C Rand

So to create a random number generation environmental variable you can do it two ways:

Option 1:

from arcpy import env
env.randomGenerator = "4 MERSENNE_TWISTER"


Option 2:

from arcpy import env
env.randomGenerator = arcpy.CreateRandomValueGenerator(4, "MERSENNE_TWISTER")



To produce a random number, the easiest way is to use the arcpy.CalculateValue() and get the results from that tool.
Example:

import arcpy
arcpy.env.randomGenerator = "4 MERSENNE_TWISTER"
result = arcpy.CalculateValue_management("arcgis.rand('normal 0.0 10.0')")
randomValue = float(result.getOutput(0))
print randomValue


The code should print a random number.

It should be noted that this environmental variable will effect any tool that uses random values.

Enjoy

Monday, June 11, 2012

Using SQL to Get n number of Rows

When you query spatial data in ArcMap/Catalog/Python, etc.. you cannot limit the row search by default and you can only specify the where part of the sql statement: "SELECT * from < DATASET > WHERE" and then you can specify TYPE = '1'.

Let's assume you want to just get back n number of rows.  If you are using SDE, you could use ArcSDESQLExecute's methods to perform your sql, but you could also use a sub-query. 

Take your default statement that ArcMap allows you to perform on a layer: 

     "Select * from wgs.temp where "

Since we want to just get back n number of rows, use the OBJECTID field as a reference and the 'in' function:

    "Select * from wgs.temp where OBJECT in (select OBJECTID  from wgs.temp where rownum <= 5)"

This will return 5 rows in the data set.  If you want 10, 15, of n number of rows, replace the 5 with whatever value you want.  You can apply this to update and search cursors on SDE data only.

Enjoy



Thursday, May 31, 2012

Using Tkniter in ArcToolbox

If you download this script: http://resources.arcgis.com/gallery/file/geoprocessing/details?entryID=C2594BA8-1422-2418-A048-74E477699334 from the resource center and want to call it from a toolbox, you can do the following:

  1. Open ArcCatalog
  2. Create a new toolbox (something.tbx)
  3. Create a new script
  4. Point to the file from the download
  5. Uncheck both "Show command window when executing" and "Run python script in process"
  6. Press finish
Now the GUI form will show.  

(Note, I didn't write that script, but I'm using it as an example of showing a GUI form from ArcToolbox.  If you have issues with the code, please contact the developer of the script.)

Enjoy

Friday, May 18, 2012

Uncompressing Multiple File Geodatabases

Often when I receive spatial data from individuals on a DVD or CD, it is in the form of a file geodatabase and it's compressed.  If all the data is in a single file geodatabase, it is not a big problem, but when you get multiple file geodatabases, that's when I break out my python.

Here is a helpful little script that will try to uncompress all file geodatabases in a single folder.  It should be noted that if a file geodatabase is already uncompressed, it will just be ignored.


import arcpy
from arcpy import env
if __name__ == '__main__':
    try:
        workspace = arcpy.GetParameterAsText(0)
        env.workspace = workspace
        fgdbs = arcpy.ListWorkspaces("*","FileGDB")
        for fgdb in fgdbs:
            arcpy.UncompressFileGeodatabaseData_management(fgdb)
        env.workspace = None
        arcpy.SetParameterAsText(1,True)
    except:
        arcpy.AddError(str(arcpy.GetMessages(2)))
        arcpy.SetParameterAsText(1,False)
So what I have done is list all file geodatabases in a given workspace (folder), then I just use the standard UncompressFileGeodatabaseData_management().  When I'm done processing, I set my environmental workspace variable to None just to clean up some loose ends.  I could delete the object like fgdbs, but since they are self contained within the function, those variables should not persist beyond the life of the function.

Enjoy

Tuesday, March 6, 2012

Sending Email At the End of Your Process

Here is a nice script that will allow you to send emails at the end of your python script, or where ever you want to.  Today I just posted a comment on my topic of long running scripts, and I am adding this component onto my workflow, so I know when processes finish or that they have completed.

Enjoy

import arcpy
import smtplib
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
def send_mail(send_from, send_to,
              subject, text,
              f="",server="THE SERVER URL"):
    assert type(send_to)==list
    # Provide the name of your email server below
    #
    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject
 
    msg.attach( MIMEText(text) )
    if os.path.isfile(f):
        part = MIMEBase('application', "zip")
        part.set_payload( open(f,"rb").read() )
        Encoders.encode_base64(part)
        part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
        msg.attach(part)
    smtp = smtplib.SMTP(server)
    smtp.sendmail(send_from, send_to, msg.as_string())
    smtp.quit()
def trace():
    import traceback
    import inspect
    import sys
    '''
    trace finds the line, the filename and error message and returns it
    to the user
    '''
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]
    # script name + line number
    line = tbinfo.split(", ")[1]
    filename = inspect.getfile( inspect.currentframe() )
    # Get Python syntax error
    #
    synerror = traceback.format_exc().splitlines()[-1]
    return line, filename, synerror  
def main(*argv):
    try:
        #    User Inputs
        #
        server = argv[0]
        subject = argv[1]
        message = argv[2]
        recievers = str(argv[3]).split(';')
        #    Email Function
        #
        send_mail(
              "NOTIFICATION@DONOTREPLY.COM",
              recievers,
              subject,
              message,
              "",
              server)
        arcpy.SetParameterAsText(4,True)
    except:
        arcpy.AddError(arcpy.GetMessages(2))
        arcpy.AddError(str(trace()))
        arcpy.SetParameterAsText(4,False)
if __name__ == "__main__":
    argv = tuple(arcpy.GetParameterAsText(i)
            for i in range(arcpy.GetArgumentCount()))
    main(*argv)

Thursday, March 1, 2012

Clean Up Files - A Helpful Function

I've been developing window services using python (win32api), and often I find is necessary that I need to clean up files at the end of the process.  I developed a small function that is quite helpful for cleaning up files by extension:


def cleanUpFiles(directory,extension):
    dir = directory
    files = os.listdir(dir)
    for f in files:
      if not os.path.isdir(f) and extension in f:
        os.remove(dir + os.sep + f)


Enjoy

Thursday, February 16, 2012

Unofficial ArcGIS 10 OMD for Python

Posted today in the ArcGIS forums is the unofficial ArcPy OMD.

Check it out here.

Enjoy

Friday, December 16, 2011

Support HTML Tages in Page Layout

Please support the idea of allowing HTML tags in labels:

http://ideas.arcgis.com/ideaView?id=08730000000bsT8AAI

Thanks

Monday, December 5, 2011

Fitting Text in Page Elements Based on Sentence Length

When working with Page Layout and Map Automation, sometimes you want to let the user pass some random text into a text element, but you need to format the text so it doesn't look like one big line of mush.

For this example assume you have a page layout and the maximum length a text item can be is 90 characters.  To format this correctly, you need to check if the values provided are less than 90 characters, if it is, write it, if not, start a new line.

sentence = "No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise please start a new thread in this forum instead."
lineLength = 90
count = 0
currentLine =""
lines = []
for word in str(sentence).split(" "):
    wordLength = len(word + " ")
    if (count + 1) < lineLength:
        currentLine = currentLine + word + " "
    else:
        lines.append(currentLine.strip() + "\n")
        currentLine = word + " "
        count = 0
    count += wordLength
lines.append(currentLine.strip() + "\n") 


So I took some test from a random forums I was reading and used that as my dummy text.  At the end of each sentence when I reach the 90 character limit or when the next word will push the line over the 90 character limit, I add a '\n' which will signal for a newline.
Now, put the text in a text element:


mxd = arcpy.mapping.MapDocument("CURRENT")
elem = arcpy.mapping.ListLayoutElements(mxd,"TEXT_ELEMENT","txtTestLength")[0]
elem.text = ""
for line in lines:
    elem.text += line
arcpy.RefreshActiveView()

The arcpy.RefreshActiveView() is essential to use in order to see the new text.  If there is a better way, post it in the comments.

Enjoy and Happy Mapping!

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

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.