Friday, June 26, 2009

Using a ToolValidator to create a Value List

New at 9.3, ESRI has introduced the ToolValidator. To many this is old news, because we are on 9.3.1, but to some, it's new due to the fact that it's not talked about much. The toolvalidator allows for more control of the GUI without messing around with ArcObjects or .NET.

More information on ToolValidators can be found here.

Moving on let's get to an example. Say you want to populate a string field with a predefined list of object or what is known as a value list to the GP world. Simply right click your script and click on the Validation Tab. Next click on edit, and you are ready to begin.

By default, IDLE should open, unless you customized your system to use pythonwin. You should see something like this:

Since you want the value like to show up when the GUI is fired, use the initializeParameters(self) method.

Now just create a simple search cursor, and append in the values from the table you want to force the user to choose like such:

def initializeParameters(self):
"""Refine the properties of a tool's parameters. This method is
called when the tool is opened."""
import os, sys, arcgisscripting as ARC
self.GP = ARC.create(9.3)
self.rows = self.GP.searchcursor(r"\CountryCodes.dbf")
self.row =
self.holder = []
while self.row:
self.row =
self.params[1].Filter.List = self.holder

Now you have a drop down menu from which a user is forced to select from. The best thing is that it's dynamic, so when the table changes so does the selection.


Wednesday, June 24, 2009

Create an Extent Polygon using Python

If you are like me, sometimes you want to give the user options on how they can select data. So I came up with this little number. I use this if the user does not draw a polygon, polyline, or point. If that condition is met, then the script will generate a full extent polygon and use that as it's selecting bounding box.

The function CreatePolygonExtent takes two objects: the first is the gp object, and the second is the input feature. It exports a geometry object that contains the polygon shape. The next function, InsertGeom() just is a simple insert cursor function. It takes a multiple number of inputs, and they are: gp, polyGeom, feat, ws. The gp object is the geoprocessing reference, polyGeom is the value from the CreatePolygonExtent(), feat is the name of the output feature, and ws is the saved workspace.

Outside of the two functions, the script generates a file geodatabase in the scratch workspace. This is where the temporary results will be saved.


Here is the code:

import arcgisscripting, os, sys

def CreatePolygonExtent(gp, in_Feat):
desc = gp.describe(in_Feat)
extent = desc.extent
# Create an Array object.
ary = gp.createobject("Array")
# List of coordinates.
coordList = [str(extent.xmin)+";"+str(extent.ymin),str(extent.xmin)+";"+str(extent.ymax),str(extent.xmax)+";"+str(extent.ymax),str(extent.xmax)+";"+str(extent.ymin)]
# For each coordinate set, create a point object and add the x- and
# y-coordinates to the point object, then add the point object
# to the array object.
for coordPair in coordList:
pnt = gp.createobject("Point")
x, y = coordPair.split(";")
pnt.x = x
pnt.y = y
# Create a polygon geometry object using the array object
# created from the coordinate list above.
polyGeom = gp.createobject("geometry", "polygon", ary)
return polyGeom

def InsertGeom(gp, polyGeom, feat, ws):
out_feat_class = "ExtentFeature"
gp.CreateFeatureclass(ws, feat, "POLYGON")
rows = gp.insertcursor(ws + os.sep + feat)
row = rows.newrow()
row.Shape = polyGeom
del rows, row
return feat

gp = arcgisscripting.create(9.3)
gp.scratchworkspace = r"c:\temp"
in_Feat = gp.getparameter(0)
polyGeom = CreatePolygonExtent(gp, in_Feat)
out_feat_class = "ExtentFeature"
gp.CreateFileGDB(gp.scratchworkspace, "BBoxHolder.gdb")
ws = gp.scratchworkspace + "\\BBoxHolder.gdb"
out_feat_class = "ExtentFeature"
returnFeat = InsertGeom(gp, polyGeom, out_feat_class, ws)

gp.setparameterastext(1, str(ws + os.sep + out_feat_class))

Thursday, June 18, 2009

PythonWin and Windows XP

When I reformatted my hard drive the other day, I didn't think installing pythonwin would be such a hassle, but it was.

Apparently Microsoft has deprecated some libraries in later versions of its dot NET framework. In order to solve the missing dll problem that you might encounter, go here:
and download the dlls posted on this site. Place them in the ..\windows\system32 directory.

Pythonwin should now work.

Monday, June 15, 2009

Custom GP Task Parameter in C#

I'm current writing a custom GP tool that maps out all the input parameters for a given mxd file, and I have been having trouble with the input parameter of type file. After much searching, I realized that the input parameter needs to be of type DEFileTypeClass. This will allow a user to select any file type. So in my case, a user can select the .mxd file.

Here is a snippet on how to create that input:
param = new GPParameterClass();
param.DataType = new DEFileTypeClass();
param.Name = "MXD_FILE";
param.Value = new DEFileTypeClass().CreateValue( "" );
param.DisplayName = "MXD_FILE";
param.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
param.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
param.Enabled = true;

Wednesday, June 10, 2009

Embed Silverlight Map

I navigated over to, I found a nice silverlight example for the sdk, but I wanted to embed a map into the blogger posts. Here is how I did it. I used the iframe tag to hold the silverlight reference as such.

iframe style="WIDTH: 400px; HEIGHT: 300px" src="" frameborder="0" scrolling="no"

ESRI Silverlight Map Control Example

Make sure you close the iframe tag, or it won't work.


Using SDE commands through python

I have a problem, and it has to do with SDE. The ArcToolbox Make Table View does not make a permanent table. For this I need to use the SDE commands that come with ArcSDE.

sdetable -o create_view -T view_name -t table1,table2...tablen
-c table_col1,table_col2...table_coln
[-a view_col1,view_col2...view_coln] [-w "where_clause"]
[-i service] [-s server_name] [-D database]
-u db_user_name [-p db_user_password] [-N] [-q]

The command abode will allow a person to create a temporary or permanent table view within the SDE database. In ArcCatalog, you can see the view as a table, which makes it helpful to query. To make this command work in python, you need to create a script that will call the sdetable.exe file and pass in all the parameters.

The general concept of this is quite simple:

# Run the command
stdout_handle = os.popen(commandStr, "r")
# Read the commands output into a variable from the standard output handle
text =

Here you use the os.popoen(<.exe file>, "r") which returns acknowledgement message once the script completes sucessfully or not.


Monday, June 8, 2009

Update Cursor & Example

In python, the update cursor either updates or deletes a row in a specific table. This is very helpful when you need to modify an attribute.

import arcgisscriptinggp = arcgisscripting.create(9.3)
# Create update cursor for feature class
rows = gp.UpdateCursor("D:/St_Johns/data.mdb/roads")
row = rows.Next()
# Update the field used in buffer so the distance is based on the
# type. Road type is either 1, 2, 3 or 4. Distance is in
while row:
row.buffer_distance = row.road_type *
row = rows.Next()
# Delete cursor and row objects to remove locks on
the data
del row
del rows


Friday, June 5, 2009

What's to come

So what's to come on this site:
- A update/insert cursor examples
- An abstract class that will make custom C# geoprocessing tools simple and easy.

So more to come

Tuesday, June 2, 2009

Following Penguins via Poop and GIS

This is funny and interesting. GIS can be used everywhere, even used to track the poop of penguins. Here is the whole article from the Ap Science Writer.

WASHINGTON – Scientists looking for lost penguins stumbled upon an effective method: Follow their poop from space.

In remote Antarctica, about one-and-a-half times bigger than the United States, researchers have been unable to figure out just where colonies of emperor penguins live and if their population is in peril.

It's harder still because emperor penguins, featured in the film "March of the Penguins," breed on sea ice, which scientists say will shrink significantly in the future because of global warming. Because the large penguins stay on the same ice for months, their poop stains make them stand out from space.

Scientists at the British Antarctic Survey found this out by accident when they were looking at satellite images of their bases. A reddish-brown streak on the colorless ice was right where they knew a colony was, said survey mapping scientist Peter Fretwell.

The stain was penguin poo — particularly smelly stuff — and it gave researchers an idea to search for brown stains to find penguins. They found the same telltale trail, usually dark enough to spot from space, all over the continent, said Fretwell by telephone from England.

Using satellite data, the scientists found 10 new colonies of penguins, six colonies that had moved from previously mapped positions to new spots and another six that seemed to have disappeared. Overall, 38 colonies were spotted from above, according to Fretwell's paper, "Penguins From Space" in the journal Global Ecology and Biogeography.

"It's a very important result scientifically, even though it's a lighthearted method," Fretwell said Monday.

Even though Antarctic sea ice hasn't melted so far, scientists predict it to shrink by one-third by the end of the century, potentially threatening the birds, Fretwell said.

The research is "incredibly useful," because the only time to see emperors are during breeding in winter when weather makes it nearly impossible to get to the colonies, said longtime penguin researcher William Fraser, who wasn't involved in the study. Fraser noted that salty penguin guano "over time will corrode your boots," adding that he has lost nearly a dozen pairs to poop in 35 years of penguin research.

Finding Unique Values in Python

Here is a nice script example of how to find a unique value.

def UniqueValueList(value, vallist):
found = False
for listItem in vallist:
if listItem == value:
found = True
if found == False:
return vallist

This returns a list of values. The inputs are the value you want to see if it's unique and the array list you are storing your values in.

To declare the python array all you need to do is the following:
ValueList = []

So the proper call of this function would be
ValueList = UniqueValueList(value, ValueList)