<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D04DQ3w_fip7ImA9WhBaGU4.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517</id><updated>2013-05-30T19:46:12.246+02:00</updated><category term="uDig" /><category term="Python" /><category term="node.js" /><category term="logging" /><category term="Rtree" /><category term="javascript" /><category term="roslyn" /><category term="DatagridView" /><category term="WKT" /><category term="GeometryVisualizer" /><category term="youtube" /><category term="anti-rdbms" /><category term="shell" /><category term="Jython" /><category term="projections" /><category term="MongoDb" /><category term="spatial index" /><category term="csv" /><category term="OpenLayers" /><category term="WinForms" /><category term="featureclass" /><category term="code publishing" /><category term="Cursors" /><category term="ogr" /><category term="table" /><category term="esri rest specification" /><category term="document database" /><category term="gvSIG" /><category term="PostGIS" /><category term="ArcGIS" /><category term="DragDrop" /><category term="shortest path" /><category term="syntax highlighting" /><category term="GeoJSON" /><category term="Psyco" /><category term="checked" /><category term="C#" /><category term="Python Toolbox" /><category term="PostgreSQL" /><category term="Tokyo Cabinet" /><category term="Ruby" /><category term="ArcObjects" /><category term="unchecked" /><category term="spatial filter" /><category term="Quantum GIS" /><category term="Ubuntu" /><category term="geoprocessing" /><category term="PyPy" /><category term="duplicate code" /><category term="NetworkX" /><category term="Clone Digger" /><category term="pyproj" /><category term="REPL" /><category term="similar code" /><category term=".NET" /><category term="transformations" /><title>GIS Solved</title><subtitle type="html">Solving GIS and other programming problems</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://gissolved.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/GisSolved" /><feedburner:info uri="gissolved" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEMGRnk-eSp7ImA9WhVQFUs.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-6771626229663843440</id><published>2012-04-04T21:06:00.001+02:00</published><updated>2012-04-04T21:07:07.751+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-04T21:07:07.751+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><category scheme="http://www.blogger.com/atom/ns#" term="esri rest specification" /><title>Creating a node.js GeometryService : part 3</title><content type="html">&lt;p&gt;Its been a while since I posted my &lt;a href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-1.html"&gt;first&lt;/a&gt; and &lt;a href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-2.html"&gt;second&lt;/a&gt; post on a GeometryService based on node.js and PostGIS.&lt;/p&gt;

&lt;p&gt;Today I want to announce that I open sourced my work in progress. It is in a pre-alpha state and it can be found &lt;a href="https://bitbucket.org/gissolved/node_geometryservice"&gt;here&lt;/a&gt;. The only thing it can do at the moment is convert ESRI Json geometries from one coordinate system to another. This is done by converting the geometry to WKT, creating a sql statement for the re-projection and then converting the GeoJSON result back to ESRI Json.&lt;/p&gt;
&lt;p&gt;A sample input url when you started the geometryservice is : 
&lt;a href="http://127.0.0.1:3000/rest/services/Geometry/GeometryServer/project?inSR=4326&amp;outSR=3819&amp;geometries={%22geometryType%22:%22esriGeometryPoint%22,%22geometries%22:[{%22x%22:-117,%22y%22:34},%20{%22x%22:-115,%22y%22:25}]}"&gt;http://127.0.0.1:3000/rest/services/Geometry/GeometryServer/project?inSR=4326&amp;outSR=3819&amp;geometries={%22geometryType%22:%22esriGeometryPoint%22,%22geometries%22:[{%22x%22:-117,%22y%22:34},%20{%22x%22:-115,%22y%22:25}]}&lt;/a&gt;. This returns &lt;pre&gt;{"geometries":[{"x":-115.00495449693217,"y":24.99533030379053},{"x":-117.00524224953409,"y":33.99507554185914}]}&lt;/pre&gt; as a result. The intermediate sql statement looks like this : &lt;pre&gt;SELECT st_asgeojson(st_transform(st_geomfromtext(geometries.geometry, '4326'), '3819')) g FROM  (SELECT ST_ASTEXT('POINT(-117 34)') geometry UNION SELECT ST_ASTEXT('POINT(-115 25)')) geometries&lt;/pre&gt;.
&lt;/p&gt;

&lt;p&gt;Most of the logic of the code happens in geometryService.js. The conversion from and to ESRI Json happens in datatransformer.js. As stated in my previous post I also created some tests for the functions in the datatransformer.js. There is still a lot to do, especially everything related to error handling and logging and off course the implementation of the other geometry operations.&lt;/p&gt;

&lt;p&gt;The main dependency is a runnning instance of PostgreSQL with PostGIS. As the connection string is not configurable yet you'll have to change it in the executeSQL function in geometryService.js.&lt;/p&gt;

&lt;p&gt;The code can be found on following url &lt;a href="https://bitbucket.org/gissolved/node_geometryservice"&gt;https://bitbucket.org/gissolved/node_geometryservice&lt;/a&gt; and it is licensed under the MIT license.&lt;/p&gt;

&lt;p&gt;If you like this then consider &lt;a href="http://www.amazon.com/gp/registry/wishlist/2FADRJ331LHIZ?reveal=unpurchased&amp;filter=all&amp;sort=universal-title"&gt;buying me a book&lt;/a&gt; or a license for &lt;a href="http://www.sublimetext.com/2"&gt;Sublime Text 2&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/0l2U5k30HgQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/6771626229663843440/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2012/04/creating-nodejs-geometryservice-part-3.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6771626229663843440?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6771626229663843440?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/0l2U5k30HgQ/creating-nodejs-geometryservice-part-3.html" title="Creating a node.js GeometryService : part 3" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2012/04/creating-nodejs-geometryservice-part-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYCQH89eSp7ImA9WhRaEEU.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1375211270263989426</id><published>2012-02-12T13:54:00.001+01:00</published><updated>2012-02-12T23:36:01.161+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-12T23:36:01.161+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Timing functions in Python</title><content type="html">&lt;div&gt;&lt;p&gt;Recently I saw a &lt;a href="http://gisstudio.wordpress.com/2012/01/27/tracking-time-in-a-script-how-i-do-it/"&gt;blogpost&lt;/a&gt; on tracking time in Python. This is inspired me to share how I track time in my python scripts. First I put the following python &lt;a href="http://wiki.python.org/moin/PythonDecorators"&gt;decorator&lt;/a&gt; function in my code or preferably import it from a common module.&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #008000; font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #0e84b5; font-weight: bold"&gt;time&lt;/span&gt;                                                

&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #0060B0; font-weight: bold"&gt;timeit&lt;/span&gt;(method):

    &lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #0060B0; font-weight: bold"&gt;timed&lt;/span&gt;(&lt;span style="color: #303030"&gt;*&lt;/span&gt;args, &lt;span style="color: #303030"&gt;**&lt;/span&gt;kw):
        ts &lt;span style="color: #303030"&gt;=&lt;/span&gt; time&lt;span style="color: #303030"&gt;.&lt;/span&gt;time()
        result &lt;span style="color: #303030"&gt;=&lt;/span&gt; method(&lt;span style="color: #303030"&gt;*&lt;/span&gt;args, &lt;span style="color: #303030"&gt;**&lt;/span&gt;kw)
        te &lt;span style="color: #303030"&gt;=&lt;/span&gt; time&lt;span style="color: #303030"&gt;.&lt;/span&gt;time()

        &lt;span style="color: #008000; font-weight: bold"&gt;print&lt;/span&gt;(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;&lt;/span&gt;&lt;span style="background-color: #e0e0e0"&gt;%r&lt;/span&gt;&lt;span style="background-color: #fff0f0"&gt; (&lt;/span&gt;&lt;span style="background-color: #e0e0e0"&gt;%r&lt;/span&gt;&lt;span style="background-color: #fff0f0"&gt;, &lt;/span&gt;&lt;span style="background-color: #e0e0e0"&gt;%r&lt;/span&gt;&lt;span style="background-color: #fff0f0"&gt;) &lt;/span&gt;&lt;span style="background-color: #e0e0e0"&gt;%2.2f&lt;/span&gt;&lt;span style="background-color: #fff0f0"&gt; sec&amp;#39;&lt;/span&gt; &lt;span style="color: #303030"&gt;%&lt;/span&gt; (method&lt;span style="color: #303030"&gt;.&lt;/span&gt;__name__, args, kw, te&lt;span style="color: #303030"&gt;-&lt;/span&gt;ts))
        &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; result

    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; timed
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use the timeit function like this:&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #505050; font-weight: bold"&gt;@timeit&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #0060B0; font-weight: bold"&gt;longRunningOperation&lt;/span&gt;(dummyArg, optionalDummyArg&lt;span style="color: #303030"&gt;=&lt;/span&gt;&lt;span style="color: #007020"&gt;None&lt;/span&gt;):
    time&lt;span style="color: #303030"&gt;.&lt;/span&gt;sleep(&lt;span style="color: #0000D0; font-weight: bold"&gt;3&lt;/span&gt;)
    
longRunningOperation(&lt;span style="background-color: #fff0f0"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;, &lt;span style="background-color: #fff0f0"&gt;&amp;quot;optional test&amp;quot;&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The output of the timeit decorator function looks like this:&lt;/p&gt;
&lt;pre&gt;'longRunningOperation' (('test', 'optional test'), {}) 3.00 sec&lt;/pre&gt;

&lt;p&gt;As you can see, the timit function reports the function name, the passed arguments and the elapsed time&lt;/p&gt;

&lt;p&gt;If you want to learn more about decorator functions I would suggest to read the python.org wiki article on &lt;a href="http://wiki.python.org/moin/PythonDecorators"&gt;decorators&lt;/a&gt;. On the same site there is also an &lt;a href="http://wiki.python.org/moin/PythonDecoratorLibrary"&gt;article&lt;/a&gt; with useful decorator functions for things like caching, properties, pre- and post conditions, memoization and many more.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/JNV5HJ2l5Ao" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1375211270263989426/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2012/02/timing-functions-in-python.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1375211270263989426?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1375211270263989426?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/JNV5HJ2l5Ao/timing-functions-in-python.html" title="Timing functions in Python" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2012/02/timing-functions-in-python.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMMQ3g6eip7ImA9WhRbFEs.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1283288864082843768</id><published>2012-02-05T20:01:00.000+01:00</published><updated>2012-02-05T20:01:22.612+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-05T20:01:22.612+01:00</app:edited><title>Roundup January 2012</title><content type="html">&lt;p&gt;This post is a roundup post for the month january.&lt;/p&gt;

&lt;h3&gt;Blogging&lt;/h3&gt;

&lt;p&gt;Just before the end of the year I created a &lt;a href="http://dailyw.tumblr.com/"&gt;tumblr blog&lt;/a&gt; where I shared some inspiring or interesting quotes.&lt;/p&gt;

&lt;p&gt;On this blog I wrote 2 posts. The first post of january was my second post on developing a &lt;a href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-2.html"&gt;GeometryService in node.js&lt;/a&gt;. Some things I talked about where &lt;a href="https://github.com/cenanozen/nodemonw"&gt;nodemonw&lt;/a&gt; for monitoring your files for changes and restarting node.js, &lt;a href="https://github.com/dannycoates/node-inspector"&gt;node-inspector&lt;/a&gt; for debugging and &lt;a href="http://vowsjs.org/"&gt;vowsjs&lt;/a&gt; for writing tests. The &lt;a href="http://gissolved.blogspot.com/2012/01/visualizing-geometries.html"&gt;second post&lt;/a&gt; of this month elaborated on the &lt;a href="http://gissolved.blogspot.com/p/geometry-visualizer.html"&gt;Geometry Visualizer&lt;/a&gt; that I created this month. The Geometry Visualizer uses the &lt;a href="http://help.arcgis.com/en/webapi/javascript/arcgis/"&gt;ArcGIS JavaScript API&lt;/a&gt; and &lt;a href="http://openlayers.org"&gt;openlayers&lt;/a&gt; to provide a .&lt;/p&gt;

&lt;h3&gt;GIS/Geography&lt;/h3&gt;
&lt;p&gt;
 &lt;ul&gt;
  &lt;li&gt;List of &lt;a href="http://freegisdata.rtwilson.com/"&gt;free GIS datasets&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://lists.osgeo.org/pipermail/gdal-dev/2012-January/031450.html"&gt;GDAL/OGR 1.9&lt;/a&gt; with support for lots of new drivers like DWG, CouchDB, ESRI FileGDB, SVG, Google Fusion Tables and many more new goodies.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://mapbox.com/blog/designing-minimalist-openstreetmap-baselayer/"&gt;Designing a Minimalist OpenStreetMap Baselayer for MapBox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://mapbox.com/tilemill/"&gt;Tilemill&lt;/a&gt; now also available for windows&lt;/li&gt;
 &lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;Programming&lt;/h3&gt;
&lt;p&gt;
 &lt;ul&gt;
  &lt;li&gt;&lt;a href="http://wf.codeplex.com/wikipage?title=Clean%20Project%20overview"&gt;Clean Project&lt;/a&gt;: a simple tool for e-mailing Visual Studio solutions.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://sqldiffframework.codeplex.com/"&gt;SqlDiffFramework&lt;/a&gt;: a visual differencing engine for dissimilar data source.&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://github.com/schambers/fluentmigrator/"&gt;FluentMigrator&lt;/a&gt;: a migration framework for .net much like Ruby Migrations.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://blogs.msdn.com/b/kirillosenkov/archive/2012/01/10/datetime-utcnow-is-generally-preferable-to-datetime-now.aspx"&gt;Use DateTime.UtcNow&lt;/a&gt;, it's faster and you never have problems with daylight saving time 1 hour jumps (&lt;a href="http://www.hanselman.com/blog/BackToBasicsDaylightSavingsTimeBugsStrikeAgainWithSetLastModified.aspx"&gt;Scott Hanselmann got bitten by this one&lt;/a&gt;).&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://michaelcrump.net/11-things-every-software-developer-should-be-doing-in-2012"&gt;11 Things every Software Developer should be doing in 2012 : &lt;/a&gt;Twitter, StackOverflow, blog, get out there, have a modern phone, embrace mobile, learn a design pattern, set a reachable goal, learn a programming language, boost your confidence and read programming blogs,/books/magazines.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.yellosoft.us/evilgenius/"&gt;Haskell for the Evil Genius&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;Teaching/learning&lt;/h3&gt;
&lt;p&gt;
 &lt;ul&gt;
  &lt;li&gt;
   &lt;a href="http://www.npr.org/2012/01/01/144550920/physicists-seek-to-lose-the-lecture-as-teaching-tool"&gt;Physicists Seek To Lose The Lecture As Teaching Tool&lt;/a&gt;
  &lt;/li&gt;&lt;li&gt;
   &lt;a href="http://learnjquery.tutsplus.com/"&gt;Learn jQuery in 30 days&lt;/a&gt;
  &lt;/li&gt;&lt;li&gt;
   &lt;a href="http://codeyear.com/"&gt;Learn JavaScript programming this year&lt;/a&gt; thanks to &lt;a href="http://www.codecademy.com/#!/exercises/0"&gt;Codecademy&lt;/a&gt; (Ruby and Python are in the making).
  &lt;/li&gt;&lt;li&gt;
   &lt;a href="http://learnjquery.tutsplus.com/"&gt;Learn jQuery in 30 days&lt;/a&gt; with tuts+.
  &lt;/li&gt;&lt;li&gt;
   &lt;a href="http://www.algo-class.org/"&gt;Follow a Stanford course online&lt;/a&gt;, see at the bottom for more courses.
  &lt;/li&gt;&lt;li&gt;
   I'm reading &lt;a href="http://www.amazon.com/Real-World-Functional-Programming-Examples/dp/1933988924/ref?tag=gissolved-20"&gt;Real World Functional Programming&lt;/a&gt; and &lt;a href="http://queue.acm.org/detail.cfm?id=2038036"&gt;here&lt;/a&gt; is why you should pick up a functional programming language.
  &lt;/li&gt;
 &lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;Other&lt;/h3&gt;
&lt;p&gt;
&lt;ul&gt;
 &lt;li&gt;Facebook, Google, ... &lt;a href="http://www.voyce.com/index.php/2012/01/06/tax-avoidance-2-0/"&gt;Tax avoidance 2.0&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://blog.priceonomics.com/post/15403657245/minimum-viable-seo"&gt;Minimum viable SEO&lt;/a&gt; (long tail vs head tail, use bread crumb navigation and use page titles.&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://unspace.ca/blog/duck-programming/"&gt;Duck programming&lt;/a&gt;, the pitfalls of building a system around rules engines, programmable workflow or domain-specific language and how to avoid them.&lt;/li&gt;
 &lt;li&gt;Your time is $1000/hour, and you need to act accordingly: &lt;a href="http://blog.asmartbear.com/value-time.html"&gt;How should a startup founder value her time?&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://spin.atomicobject.com/2012/01/11/small-teams-are-dramatically-more-efficient-than-large-teams/"&gt;Small teams are dramatically more efficient than large teams&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://zenhabits.net/bah/"&gt;The Case Against Buying Christmas Presents&lt;/a&gt; by Leo Babauta.&lt;/li&gt;
 &lt;li&gt;Awesome answers on the question "&lt;a href="http://bicycles.stackexchange.com/questions/7858/how-accurate-are-the-power-numbers-from-a-tacx-flow"&gt;How accurate are the power numbers from a Tacx Flow?&lt;/a&gt;" at &lt;a href="http://bicycles.stackexchange.com/"&gt;bicycles.stackexchange.com&lt;/a&gt;. Yet another reason to &lt;a href="http://www.joefrielsblog.com/2012/01/why-you-need-a-power-meter.html"&gt;buy a power meter&lt;/a&gt;. Although not everyone &lt;a href="http://www.training4cyclists.com/power-meters-are-not-compulsory/"&gt;agrees&lt;/a&gt;.&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://www.kalzumeus.com/2012/01/23/salary-negotiation/"&gt;Salary Negotiation&lt;/a&gt;: Make More Money, Be More Valued.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;Entertainment&lt;/h3&gt;
&lt;p&gt;
 &lt;ul&gt;
  &lt;li&gt;Youtube: &lt;a href="http://www.youtube.com/watch?v=Ci0-cdLi3sQ"&gt;"Video Game Math is The New Reading"&lt;/a&gt; and &lt;a href="http://www.youtube.com/watch?v=I_3kHURyv4I"&gt;"Shopping Math is The New Free&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Funky music: &lt;a href="http://www.youtube.com/watch?v=Cjwoit91SxU"&gt;Goldfish - Get Busy Living&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://i.imgur.com/pAy4z.png"&gt;Amazing C book review on Amazon&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Fascinating: &lt;a href="http://www.youtube.com/results?search_query=smart+crow"&gt;Smart crows and ravens&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/p&gt;

&lt;h3&gt;New blogs to follow&lt;/h3&gt;
&lt;p&gt;
 &lt;ul&gt;
 &lt;li&gt;&lt;a href="http://blog.cwa.me.uk/"&gt;The Morning Brew&lt;/a&gt;: daily .NET software development link blog.&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://viperchill.com"&gt;ViperChill&lt;/a&gt;: a blog about viral marketing, the best post I read was &lt;a href="http://www.viperchill.com/productivity/"&gt;The Post on Productivity I Wish Someone Else Had Written&lt;/a&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/0fcBieKrlos" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1283288864082843768/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2012/02/roundup-january-2012.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1283288864082843768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1283288864082843768?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/0fcBieKrlos/roundup-january-2012.html" title="Roundup January 2012" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2012/02/roundup-january-2012.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHRX07fCp7ImA9WhVRGEs.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-4266732842447580212</id><published>2012-01-25T20:35:00.000+01:00</published><updated>2012-03-27T16:57:14.304+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-27T16:57:14.304+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="OpenLayers" /><category scheme="http://www.blogger.com/atom/ns#" term="WKT" /><category scheme="http://www.blogger.com/atom/ns#" term="GeoJSON" /><category scheme="http://www.blogger.com/atom/ns#" term="GeometryVisualizer" /><category scheme="http://www.blogger.com/atom/ns#" term="esri rest specification" /><title>Visualizing Geometries</title><content type="html">&lt;p&gt;In this post I'm going to give some more information about the &lt;a href="http://gissolved.blogspot.com/p/geometry-visualizer.html"&gt;GeometryVisualizer&lt;/a&gt; that I created recently.&lt;/p&gt;

&lt;p&gt;The goal of the GeometryVisualizer is to be able to quickly visualize a GeoJson, WKT or ESRI JSON geometry. I created this to be able to quickly see how some ESRI JSON and WKT geometries looked like and visually verify some geometry conversion code I'm writing for my &lt;a href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-1.html"&gt;GeometryService in node.js&lt;/a&gt;. You can also use this to visualize the WKT or GeoJSON output of a PostGIS geometry query.&lt;/p&gt;

&lt;p&gt;The ESRI JSON geometries are rendered with the &lt;a href="http://help.arcgis.com/en/webapi/javascript/arcgis/"&gt;ArcGIS JavaScript API&lt;/a&gt;. The WKT and GeoJSON geometries are rendered with &lt;a href="http://openlayers.org"&gt;OpenLayers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;
&lt;h3&gt;Some code&lt;/h3&gt;
In this section I'll show some parts of the code that made this web application possible and compare the ArcGIS JavaScript API with the OpenLayers API. First we'll take a look at the initialization of the map. The most notable facts about the initialization are that we need to add a layer before we are able to add graphics and that disabling the zoomwheel is less straight forward with the OpenLayers API.&lt;/p&gt;

&lt;p&gt;ESRI JavaScript API map initialization:&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; map &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.Map(&lt;span style="background-color: #fff0f0"&gt;&amp;quot;esriJsonMap&amp;quot;&lt;/span&gt;);
map.disableScrollWheelZoom();

&lt;span style="color: #808080"&gt;// add a layer and directly hide it because otherwise we can&amp;#39;t create graphics&lt;/span&gt;
&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; basemapURL&lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer&amp;quot;&lt;/span&gt;

&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; basemap &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.layers.ArcGISDynamicMapServiceLayer(basemapURL);
map.addLayer(basemap);
basemap.visible &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;false&lt;/span&gt;;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;OpenLayers map initialization:&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;var options &lt;span style="color: #303030"&gt;=&lt;/span&gt; {
  maxExtent: new OpenLayers&lt;span style="color: #303030"&gt;.&lt;/span&gt;Bounds(&lt;span style="color: #303030"&gt;-&lt;/span&gt;&lt;span style="color: #0000D0; font-weight: bold"&gt;1000000000&lt;/span&gt;, &lt;span style="color: #303030"&gt;-&lt;/span&gt;&lt;span style="color: #0000D0; font-weight: bold"&gt;1000000000&lt;/span&gt;, &lt;span style="color: #0000D0; font-weight: bold"&gt;1000000000&lt;/span&gt;, &lt;span style="color: #0000D0; font-weight: bold"&gt;1000000000&lt;/span&gt;),
}
var &lt;span style="color: #007020"&gt;map&lt;/span&gt; &lt;span style="color: #303030"&gt;=&lt;/span&gt; new OpenLayers&lt;span style="color: #303030"&gt;.&lt;/span&gt;Map(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;openLayersMap&amp;#39;&lt;/span&gt;, options);

&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; controls &lt;span style="color: #303030"&gt;=&lt;/span&gt; map.getControlsByClass(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;OpenLayers.Control.Navigation&amp;#39;&lt;/span&gt;); 
&lt;span style="color: #008000; font-weight: bold"&gt;for&lt;/span&gt;(&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; i &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #0000D0; font-weight: bold"&gt;0&lt;/span&gt;; i&lt;span style="color: #303030"&gt;&amp;lt;&lt;/span&gt;controls.length; &lt;span style="color: #303030"&gt;++&lt;/span&gt;i){ 
    controls[i].disableZoomWheel(); 
}

&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; layer &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; OpenLayers.Layer.ArcGIS93Rest( &lt;span style="background-color: #fff0f0"&gt;&amp;quot;ArcGIS World Street Map&amp;quot;&lt;/span&gt;, 
                &lt;span style="background-color: #fff0f0"&gt;&amp;quot;http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer&amp;quot;&lt;/span&gt;,
                {layers&lt;span style="color: #303030"&gt;:&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;} );
map.addLayer(layer);
layer.setVisibility(&lt;span style="color: #008000; font-weight: bold"&gt;false&lt;/span&gt;);
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;
To be able to render an ESRI JSON geometry string with the ArcGIS JavaScript API you have to do some specific steps :
&lt;ul&gt;
&lt;li&gt;Clear the graphics&lt;/li&gt;
&lt;li&gt;Parse the geometry string representation&lt;/li&gt;
&lt;li&gt;Create a graphic and set its symbol according to the geometry type.&lt;/li&gt;
&lt;li&gt;Update the extent of the map&lt;/li&gt;
&lt;/ul&gt; 
Not that for updating the extent, I had to access an undocumented property of the graphics object and for point graphics the extent had to be enlarged. 
&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt; addGeometry(geometryText) {
    
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(map.graphics &lt;span style="color: #303030"&gt;===&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;null&lt;/span&gt;) &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt;; &lt;span style="color: #808080"&gt;// map not loaded yet or something else is wrong&lt;/span&gt;
            
    map.graphics.clear();

    &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; geometryJson &lt;span style="color: #303030"&gt;=&lt;/span&gt; JSON.parse(geometryText);
    &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; graphic &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.Graphic(geometryJson);

    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt; (&lt;span style="color: #303030"&gt;!&lt;/span&gt;graphic.symbol){
      &lt;span style="color: #008000; font-weight: bold"&gt;switch&lt;/span&gt;(graphic.geometry.type){
        &lt;span style="color: #008000; font-weight: bold"&gt;case&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;point&amp;quot;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;
        &lt;span style="color: #008000; font-weight: bold"&gt;case&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;multipoint&amp;quot;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;
          graphic.setSymbol(&lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.symbol.SimpleMarkerSymbol());
          &lt;span style="color: #008000; font-weight: bold"&gt;break&lt;/span&gt;;
        &lt;span style="color: #008000; font-weight: bold"&gt;case&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;polyline&amp;quot;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;
          graphic.setSymbol(&lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.symbol.SimpleLineSymbol());
          &lt;span style="color: #008000; font-weight: bold"&gt;break&lt;/span&gt;;
        &lt;span style="color: #008000; font-weight: bold"&gt;default&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;
          graphic.setSymbol(&lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; esri.symbol.SimpleFillSymbol());
          &lt;span style="color: #008000; font-weight: bold"&gt;break&lt;/span&gt;;
      }
    }

    map.graphics.add(graphic);
    &lt;span style="color: #808080"&gt;// use undocumented object&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; ext &lt;span style="color: #303030"&gt;=&lt;/span&gt; graphic._extent;
    &lt;span style="color: #808080"&gt;// if point expand the extent&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(ext.getWidth() &lt;span style="color: #303030"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #6000E0; font-weight: bold"&gt;0.00000001&lt;/span&gt; &lt;span style="color: #303030"&gt;||&lt;/span&gt; ext.getHeight() &lt;span style="color: #303030"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color: #6000E0; font-weight: bold"&gt;0.00000001&lt;/span&gt;){
      &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; factor &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #0000D0; font-weight: bold"&gt;1&lt;/span&gt;;
      ext.update(ext.xmin &lt;span style="color: #303030"&gt;-&lt;/span&gt; factor, ext.ymin &lt;span style="color: #303030"&gt;-&lt;/span&gt; factor, ext.xmax &lt;span style="color: #303030"&gt;+&lt;/span&gt; factor, ext.ymax &lt;span style="color: #303030"&gt;+&lt;/span&gt; factor, ext.spatialReference);
    }

    map.setExtent(ext.expand(&lt;span style="color: #0000D0; font-weight: bold"&gt;2&lt;/span&gt;));
}
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The process of adding WKT and GeoJSON geometries was very similar.
&lt;ul&gt;
&lt;li&gt;Remove all features&lt;/li&gt;
&lt;li&gt;Parse the geometry string representation with a predefined formatter (OpenLayers.Format.WKT or OpenLayers.Format.GeoJSON)&lt;/li&gt;
&lt;li&gt;Update the extent of the map.&lt;/li&gt;
&lt;/ul&gt;
Note that I didn't had to specify the symbology and zooming to the extent of the feature was easier. 
The WKT parsing was very straight forward. For the GeoJSON parsing I had to add two things. First I had to ensure that the parsed JSON had a property "type" with as value "Feature" and the parsed object returned a feature collection with one feature instead of directly returning the feature.
&lt;/p&gt;

&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt; addGeometry(geometryInput, parser, type){
  vectorLayer.removeAllFeatures();
  &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; feature &lt;span style="color: #303030"&gt;=&lt;/span&gt; parser.read(geometryInput);
  vectorLayer.addFeatures(feature);
  &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(dojo.isArray(feature)){
    feature &lt;span style="color: #303030"&gt;=&lt;/span&gt; feature[&lt;span style="color: #0000D0; font-weight: bold"&gt;0&lt;/span&gt;];
  }
  &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; bounds &lt;span style="color: #303030"&gt;=&lt;/span&gt; feature.geometry.getBounds();
  bounds = bounds.scale(1.1);
  map.zoomToExtent(bounds);  
}

&lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt; addWkt(geometryText) {
  &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; wktFormat &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; OpenLayers.Format.WKT();
  addGeometry(geometryText, wktFormat);
}

&lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt; addGeoJson(geometryText) {
  &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; geoJsonFormat &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;new&lt;/span&gt; OpenLayers.Format.GeoJSON();
  &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; geometry &lt;span style="color: #303030"&gt;=&lt;/span&gt; JSON.parse(geometryText);
  geometry[&lt;span style="background-color: #fff0f0"&gt;&amp;quot;type&amp;quot;&lt;/span&gt;] &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;Feature&amp;quot;&lt;/span&gt;;
  addGeometry(geometry, geoJsonFormat);
}
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This are the most interesting parts of the code. The full source code is in the &lt;a href="http://gissolved.blogspot.com/p/geometry-visualizer.html"&gt;GeometryVisualizer&lt;/a&gt;.
&lt;p&gt;Any questions/remarks/improvements ? Let me know !&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/apD-WTveMjg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/4266732842447580212/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2012/01/visualizing-geometries.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/4266732842447580212?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/4266732842447580212?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/apD-WTveMjg/visualizing-geometries.html" title="Visualizing Geometries" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2012/01/visualizing-geometries.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMGRHw5eyp7ImA9WhVUGEU.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1358890831265359342</id><published>2011-12-15T21:38:00.016+01:00</published><updated>2012-05-24T21:07:05.223+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-24T21:07:05.223+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><category scheme="http://www.blogger.com/atom/ns#" term="esri rest specification" /><title>Creating a node.js GeometryService : part 2</title><content type="html">&lt;div&gt;&lt;p&gt;This is my second post on what I learned from creating an implementation of the  geometryservice specification in node.js. The first post can be found &lt;a href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-1.html"&gt;here&lt;/a&gt;.  &lt;p&gt;By default node.js doesn't reload your files when they have changed but while developing this can be very handy. The most easy to use tool for node.js on windows that monitors your files for changes, with an easy way to set the node.js debugging flag, is nodemonw. You can download nodemonw at &lt;a href="https://github.com/cenanozen/nodemonw"&gt;https://github.com/cenanozen/nodemonw&lt;/a&gt;. Once you've downloaded the executable I suggest to copy it to your %Appdata%\npm directory or another directory thats in your path. To start nodemonw I now run the following command &lt;code&gt;nodemonw --debug index.js&lt;/code&gt;. In the next section it will become clear why I added the --debug flag. &lt;/p&gt;&lt;p&gt;To be able to debug my node.js application I installed &lt;a href="https://github.com/dannycoates/node-inspector"&gt;node-inspector&lt;/a&gt; (&lt;code&gt;npm install -g node-inspector&lt;/code&gt;). As you can read in the readme of node-inspector it is really easy to get started with node-inspector. You just have to start node-inspector and then open &lt;a href="http://127.0.0.1:8080/debug?port=5858"&gt;http://127.0.0.1:8080/debug?port=5858&lt;/a&gt; in your favorite WebKit based browser. On Wikipedia I found this list of &lt;a href="http://en.wikipedia.org/wiki/List_of_web_browsers#WebKit-based"&gt;WebKit based browsers&lt;/a&gt;. The most well known ones for Windows are &lt;a href="https://www.google.com/chrome/?brand=ECSB&amp;installdataindex=no-apps-no-promo"&gt;Google Chrome&lt;/a&gt; and &lt;a href="http://www.apple.com/safari/download/"&gt;Safari&lt;/a&gt;. A screencast on node-inspector can be found &lt;a href="http://howtonode.org/debugging-with-node-inspector"&gt;here&lt;/a&gt;. There is also a &lt;a href="http://www.youtube.com/view_play_list?p=A5216AC29A41EFA8"&gt;node-inspector playlist&lt;/a&gt; on YouTube. &lt;/p&gt;&lt;p&gt;To be able to test parts of my GeometryService I used vows (&lt;code&gt;npm install -g vows&lt;/code&gt;). Vows is an asynchronous behavior driven development framework. More info about it can be found on &lt;a href="http://vowsjs.org/"&gt;http://vowsjs.org/&lt;/a&gt;. I am now going to show a small part of the code from my GeometryService and some tests I wrote for this code. My directory structure for the code I'll show looks like this: &lt;code&gt; lib/&lt;br /&gt;
-- datatransformer.js&lt;br /&gt;
test/&lt;br /&gt;
-- datatransformers.test.js&lt;br /&gt;
&lt;/code&gt; In datatransformer.js I started a function to convert an ESRI geometry JSON object to wkt based on its geometry type.&lt;/p&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;exports.esriGeoJsonToWKT &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt; esriGeoJsonToWKT (geometryType, geometry) {
  &lt;span style="color: #008000; font-weight: bold"&gt;if&lt;/span&gt;(geometryType &lt;span style="color: #303030"&gt;===&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;esriGeometryPoint&amp;quot;&lt;/span&gt;) {
    &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;POINT(&amp;quot;&lt;/span&gt; &lt;span style="color: #303030"&gt;+&lt;/span&gt; geometry.x &lt;span style="color: #303030"&gt;+&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span style="color: #303030"&gt;+&lt;/span&gt; geometry.y &lt;span style="color: #303030"&gt;+&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;;
  }
}
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And the content of datatransformer.test.js is:&lt;/p&gt;&lt;!-- HTML generated using hilite.me --&gt;&lt;div style="background: #ffffff; overflow:auto;width:auto;color:black;background:white;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;"&gt;&lt;pre style="margin: 0; line-height: 125%"&gt;&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; dt &lt;span style="color: #303030"&gt;=&lt;/span&gt; require(&lt;span style="background-color: #fff0f0"&gt;&amp;quot;../lib/datatransformer&amp;quot;&lt;/span&gt;);
&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; vows &lt;span style="color: #303030"&gt;=&lt;/span&gt; require(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;vows&amp;#39;&lt;/span&gt;);
&lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; assert &lt;span style="color: #303030"&gt;=&lt;/span&gt; require(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;assert&amp;#39;&lt;/span&gt;);

vows.describe(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;Esri geometry JSON to WKT&amp;#39;&lt;/span&gt;).addBatch({
  &lt;span style="background-color: #fff0f0"&gt;&amp;#39;when converting esriGeometryPoint {&amp;quot;x&amp;quot;:-117,&amp;quot;y&amp;quot;:34}&amp;#39;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;{
    topic&lt;span style="color: #303030"&gt;:&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt;(){ 
      &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; geomType &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;#39;esriGeometryPoint&amp;#39;&lt;/span&gt;;
      &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; p &lt;span style="color: #303030"&gt;=&lt;/span&gt; JSON.parse(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;{&amp;quot;x&amp;quot;:-117,&amp;quot;y&amp;quot;:34}&amp;#39;&lt;/span&gt;);
      &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; dt.esriGeoJsonToWKT(geomType, p);
    },
    &lt;span style="background-color: #fff0f0"&gt;&amp;#39;we get &amp;quot;POINT(-117 34)&amp;quot;&amp;#39;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt;(topic){
      assert.equal(topic, &lt;span style="background-color: #fff0f0"&gt;&amp;quot;POINT(-117 34)&amp;quot;&lt;/span&gt;);
    }
  },
  &lt;span style="background-color: #fff0f0"&gt;&amp;#39;but when converting esriGeometryPoint {&amp;quot;x&amp;quot;:-117.01,&amp;quot;y&amp;quot;:34.02}&amp;#39;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt;{
    topic&lt;span style="color: #303030"&gt;:&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt;(){ 
      &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; geomType &lt;span style="color: #303030"&gt;=&lt;/span&gt; &lt;span style="background-color: #fff0f0"&gt;&amp;#39;esriGeometryPoint&amp;#39;&lt;/span&gt;;
      &lt;span style="color: #008000; font-weight: bold"&gt;var&lt;/span&gt; p &lt;span style="color: #303030"&gt;=&lt;/span&gt; JSON.parse(&lt;span style="background-color: #fff0f0"&gt;&amp;#39;{&amp;quot;x&amp;quot;:-117.01,&amp;quot;y&amp;quot;:34.02}&amp;#39;&lt;/span&gt;);
      &lt;span style="color: #008000; font-weight: bold"&gt;return&lt;/span&gt; dt.esriGeoJsonToWKT(geomType, p);
    },
    &lt;span style="background-color: #fff0f0"&gt;&amp;#39;we get &amp;quot;POINT(-117.01 34.02)&amp;quot;&amp;#39;&lt;/span&gt;&lt;span style="color: #303030"&gt;:&lt;/span&gt; &lt;span style="color: #008000; font-weight: bold"&gt;function&lt;/span&gt;(topic){
      assert.equal(topic, &lt;span style="background-color: #fff0f0"&gt;&amp;quot;POINT(-117.01 34.02)&amp;quot;&lt;/span&gt;);
    }
  }
}).exportTo(module);
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see I created two tests for converting point geometries from ESRI JSON to wkt. One for integer coordinates and one for decimal coordinates. The easiest way to run this tests with vows on windows was opening a commandline in the root directory of my node.js project and type &lt;code&gt;vows --spec&lt;/code&gt;. This will run the tests it finds in the test and spec directories of your project. My output looks like this :&lt;/p&gt;&lt;code&gt;  ? Esri geometry JSON to WKT&lt;br /&gt;
&lt;br /&gt;
when converting esriGeometryPoint {"x":-117,"y":34}&lt;br /&gt;
V we get "POINT(-117 "4)"&lt;br /&gt;
but when converting esriGeometryPoint {"x":-117.01,"y":34.02}&lt;br /&gt;
V we get "POINT(-117.01 34.02)"&lt;br /&gt;
&lt;br /&gt;
V OK » 2 honored (0.007s)&lt;br /&gt;
&lt;/code&gt;  &lt;p&gt;On a side note if you ever encounter that node can't find any of your globally installed packages then it might help to add a new User Variable called NODE_PATH with as value %AppData%\npm\node_modules. That was it for this post more posts on this project will follow.&lt;/p&gt;

&lt;p&gt;As I announced in this &lt;a href="http://gissolved.blogspot.com/2012/04/creating-nodejs-geometryservice-part-3.html"&gt;post&lt;/a&gt;, I open sourced the code of this project. It can be found in this &lt;a href="https://bitbucket.org/gissolved/node_geometryservice"&gt;bitbucket repository&lt;/a&gt;.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/3GPGwWk2WY0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1358890831265359342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-2.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1358890831265359342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1358890831265359342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/3GPGwWk2WY0/creating-nodejs-geometryservice-part-2.html" title="Creating a node.js GeometryService : part 2" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEMSXY7cCp7ImA9WhVQFUs.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-8155082192735650069</id><published>2011-12-15T21:00:00.000+01:00</published><updated>2012-04-04T21:11:28.808+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-04T21:11:28.808+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><category scheme="http://www.blogger.com/atom/ns#" term="esri rest specification" /><title>Creating a node.js GeometryService : part 1</title><content type="html">&lt;p&gt;Ever since I encountered the &lt;a href="http://www.esri.com/library/whitepapers/pdfs/geoservices-rest-spec.pdf"&gt;geoservices-rest-specification (pdf)&lt;/a&gt; I've been thinking about creating my own implementation. I also wanted wanted to try out &lt;a href="http://nodejs.org/"&gt;node.js&lt;/a&gt; so I combined both ideas and started implementing a GeometryService in node.js. If you've never heard of node.js, this is the short introduction from the homepage of node.js:&lt;br /&gt;&lt;q&gt;Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.&lt;/q&gt; The GeometryService is a web service that contains GIS related utility methods like project, intersect, buffer,... A sample server can be found here &lt;a href="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"&gt;http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I first downloaded and installed the windows installer of node.js version 0.65. After a reboot all locations where added to my path so that I can now start a new cmd window and type node. Note that when you install packages globally with the node package manager called npm (&lt;code&gt;npm install &amp;lt;package&amp;gt; -g&lt;/code&gt;) npm (the node package manager) then the packages are installed in Windows 7 under %AppData%\npm (C:\Users\&amp;lt;username&amp;gt;\AppData\Roaming\npm). The full list of packages is located here &lt;a href="http://search.npmjs.org/"&gt;search.npmjs.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get started learning node I first read the node.js tutorial at &lt;a href="http://www.nodebeginner.org/"&gt;nodebeginner.com&lt;/a&gt;. By following this tutorial I got a great insight in how to create your own webserver. At this moment I'm continuing to build my webservice based on this code but I plan to use some framework like &lt;a href="http://expressjs.com/"&gt;express&lt;/a&gt; or &lt;a href="https://github.com/cloudhead/journey/"&gt;journey&lt;/a&gt; in a later stage. This is not very urgent because I'll first focus on the JSON output of the GeometryService and thus won't need to output any html.&lt;/p&gt;

&lt;p&gt;For my first version of the GeometryService I decided to use &lt;a href="http://postgis.refractions.net/"&gt;PostGIS&lt;/a&gt; as my geometry processor. I know this introduces an extra overhead. But I think this is the easiest way to get something up and running in a short period of time. If you don't want to bother with installing PostgreSQL and PostGIS I suggest you to &lt;a href="http://opengeo.org/technology/suite/download/"&gt;download&lt;/a&gt; the Community edition of the &lt;a href="http://opengeo.org/"&gt;Open Geo Suite&lt;/a&gt;. To be able to connect to the database I installed &lt;a href="https://github.com/brianc/node-postgres"&gt;node-postgres&lt;/a&gt; with following command line: &lt;code&gt;npm install pg -g&lt;/code&gt;. If you're on windows and get build errors you might try to add a file called true.cmd to the directory where node.exe resides (e.g. C:\Program Files (x86)\nodejs) with as content &lt;code&gt;exit 0&lt;/code&gt;. Below is a short snippet on how I connect to the database. Make sure to replace all placeholders in the connection string.&lt;br /&gt;

&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; pg &lt;span style='color:#808030; '&gt;=&lt;/span&gt; require&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;pg&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;

&lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; executeSQL&lt;span style='color:#808030; '&gt;(&lt;/span&gt;sql&lt;span style='color:#808030; '&gt;,&lt;/span&gt; parameters&lt;span style='color:#808030; '&gt;,&lt;/span&gt; resultCallback&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;{&lt;/span&gt;
  &lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; connectionString &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;pg://username:password@host:port/databasename&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
  pg&lt;span style='color:#808030; '&gt;.&lt;/span&gt;connect&lt;span style='color:#808030; '&gt;(&lt;/span&gt;connectionString&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;err&lt;span style='color:#808030; '&gt;,&lt;/span&gt; client&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
    client&lt;span style='color:#808030; '&gt;.&lt;/span&gt;query&lt;span style='color:#808030; '&gt;(&lt;/span&gt;sql&lt;span style='color:#808030; '&gt;,&lt;/span&gt;parameters&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;err&lt;span style='color:#808030; '&gt;,&lt;/span&gt; result&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
      &lt;span style='color:#696969; '&gt;// TODO add error handling&lt;/span&gt;
      console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;log&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;result&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
      resultCallback&lt;span style='color:#808030; '&gt;(&lt;/span&gt;result&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
&lt;span style='color:#800080; '&gt;}&lt;/span&gt;
&lt;/pre&gt;

&lt;/p&gt;

&lt;p&gt;That was it for today. In the next part of the series I'll write about debugging node.js and about my progress on the GeometryService.&lt;/p&gt;

&lt;p&gt;As I announced in this &lt;a href="http://gissolved.blogspot.com/2012/04/creating-nodejs-geometryservice-part-3.html"&gt;post&lt;/a&gt;, I open sourced the code of this project. It and can be found in this &lt;a href="https://bitbucket.org/gissolved/node_geometryservice"&gt;bitbucket repository&lt;/a&gt;.&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/_yKhQhW6P9E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/8155082192735650069/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-1.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/8155082192735650069?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/8155082192735650069?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/_yKhQhW6P9E/creating-nodejs-geometryservice-part-1.html" title="Creating a node.js GeometryService : part 1" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2011/12/creating-nodejs-geometryservice-part-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUADRn47eSp7ImA9WhRRGU0.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-2031030966136785562</id><published>2011-12-03T06:07:00.004+01:00</published><updated>2011-12-03T10:16:17.001+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-03T10:16:17.001+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="REPL" /><category scheme="http://www.blogger.com/atom/ns#" term="roslyn" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><title>C# REPL</title><content type="html">&lt;p&gt;Until recently when you wanted to test small snippets of C# code you had to create a small console application or use the immediate window while debugging or use something like LinqPad.&lt;/p&gt;

&lt;p&gt;But a few weeks ago Microsoft finally announced a solution for this called Roslyn. The goal of Roslyn is to provide an API for the compiler. This is still just a CTP but it is very promising. One of the features of Roslyn is an interactive window for C# also called a REPL (read eval print loop). Note that some C# features like Linq query expressions, events and the dynamic and async keywords have not been implemented yet. More information on the Roslyn CTP can be found here 
&lt;a href="http://blogs.msdn.com/b/visualstudio/archive/2011/10/19/introducing-the-microsoft-roslyn-ctp.aspx"&gt;Introducing the Roslyn CTP&lt;/a&gt; and here &lt;a href="http://msdn.com/roslyn"&gt;http://msdn.com/roslyn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tip of the day:&lt;br /&gt;
When you want to reevaluate or edit a previous entry then use ALT+Up and ALT+Down.&lt;/p&gt;
&lt;p&gt;Bonus tip:&lt;br /&gt;
You might also wanna try out &lt;a href="http://billyreisinger.com/jash/"&gt;Jash&lt;/a&gt;. This is a javascript shell that can be opened on any website with a bookmarklet. It  features some code completion and is very practical for trying out things you`re unsure about.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/CEXo0b5HXQc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/2031030966136785562/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2011/12/c-repl.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2031030966136785562?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2031030966136785562?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/CEXo0b5HXQc/c-repl.html" title="C# REPL" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2011/12/c-repl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4MSX45fyp7ImA9WhRRGU0.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-964099810531455907</id><published>2011-11-07T22:16:00.006+01:00</published><updated>2011-12-03T10:36:28.027+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-03T10:36:28.027+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="C#" /><category scheme="http://www.blogger.com/atom/ns#" term="unchecked" /><category scheme="http://www.blogger.com/atom/ns#" term="checked" /><title>Performance of Checked vs Unchecked</title><content type="html">&lt;p&gt;If you're ever in doubt on using the checked keyword in C# or the /checked compiler directive because it might hurt your performance then don't worry anymore.&lt;/p&gt;
&lt;p&gt;I did some integer additions on my portable in a checked and unchecked context and the performance decrease was only about &lt;b&gt;3-5%&lt;/b&gt; on operations of about 5 seconds. Don't forget that checked and unchecked only have an effect on integers. Float and double never check for overflows and the decimal always does. More info on this feature can be found on &lt;a href="http://msdn.microsoft.com/en-us/library/khy08726(v=vs.80).aspx"&gt;msdn&lt;/a&gt; and in this &lt;a href="http://www.codeproject.com/KB/cs/overflow_checking.aspx"&gt;Code Project article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the code I used to benchmark the performance of a checked vs unchecked context. I also tested subtraction, multiplication and division with similar results. Pay great attention when using the checked context. Only inline operations are checked/unchecked, code in function calls and anonymous functions isn't.&lt;/p&gt;

&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
&lt;span style='color:#800000; font-weight:bold; '&gt;using&lt;/span&gt; System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Diagnostics&lt;span style='color:#800080; '&gt;;&lt;/span&gt;

&lt;span style='color:#800000; font-weight:bold; '&gt;namespace&lt;/span&gt; GISSolved&lt;span style='color:#808030; '&gt;.&lt;/span&gt;TestConsole
&lt;span style='color:#800080; '&gt;{&lt;/span&gt;
    &lt;span style='color:#800000; font-weight:bold; '&gt;class&lt;/span&gt; Program
    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
        &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; Main&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;string&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; args&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
        &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
            GC&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Collect&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;3&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; GCCollectionMode&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Forced&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            var checkedResult &lt;span style='color:#808030; '&gt;=&lt;/span&gt; TimeIt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;true&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Checked : {0}&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; checkedResult&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            GC&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Collect&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;3&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; GCCollectionMode&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Forced&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            var uncheckedResult &lt;span style='color:#808030; '&gt;=&lt;/span&gt; TimeIt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Unchecked : {0}&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; uncheckedResult&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Difference : {0:0}%&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;1&lt;/span&gt; &lt;span style='color:#808030; '&gt;-&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;double&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;checkedResult &lt;span style='color:#808030; '&gt;/&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;double&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;uncheckedResult&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#008c00; '&gt;100&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ReadLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
        
        &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;long&lt;/span&gt; TimeIt&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;bool&lt;/span&gt; isCheckedCalculation&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
        &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
            var s &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Stopwatch&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            s&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Start&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;

            Int32 a &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;123&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; b &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;123&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;isCheckedCalculation&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
            &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                &lt;span style='color:#800000; font-weight:bold; '&gt;checked&lt;/span&gt;
                &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                    &lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt; i &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i &lt;span style='color:#808030; '&gt;&amp;lt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;900000000&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                        a &lt;span style='color:#808030; '&gt;=&lt;/span&gt; i &lt;span style='color:#808030; '&gt;+&lt;/span&gt; b &lt;span style='color:#808030; '&gt;+&lt;/span&gt; a&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                        a &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;125&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
                    &lt;span style='color:#696969; '&gt;// extra check to make sure that overflow exceptions are thrown&lt;/span&gt;
                    &lt;span style='color:#800000; font-weight:bold; '&gt;try&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;   
                        Int32 x &lt;span style='color:#808030; '&gt;=&lt;/span&gt; a &lt;span style='color:#808030; '&gt;+&lt;/span&gt; Int32&lt;span style='color:#808030; '&gt;.&lt;/span&gt;MaxValue&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
                    &lt;span style='color:#800000; font-weight:bold; '&gt;catch&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;OverflowException&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                        Console&lt;span style='color:#808030; '&gt;.&lt;/span&gt;WriteLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;Int32 Overflow&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
                &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
            &lt;span style='color:#800000; font-weight:bold; '&gt;else&lt;/span&gt; 
            &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                &lt;span style='color:#800000; font-weight:bold; '&gt;unchecked&lt;/span&gt;
                &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                    &lt;span style='color:#800000; font-weight:bold; '&gt;for&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;int&lt;/span&gt; i &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i &lt;span style='color:#808030; '&gt;&amp;lt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;900000000&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; i&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;
                        a &lt;span style='color:#808030; '&gt;=&lt;/span&gt; i &lt;span style='color:#808030; '&gt;+&lt;/span&gt; b &lt;span style='color:#808030; '&gt;+&lt;/span&gt; a&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                        a &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;125&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
                    Int32 x &lt;span style='color:#808030; '&gt;=&lt;/span&gt; a &lt;span style='color:#808030; '&gt;+&lt;/span&gt; Int32&lt;span style='color:#808030; '&gt;.&lt;/span&gt;MaxValue&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
                &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
            s&lt;span style='color:#808030; '&gt;.&lt;/span&gt;Stop&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
            &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; s&lt;span style='color:#808030; '&gt;.&lt;/span&gt;ElapsedMilliseconds&lt;span style='color:#800080; '&gt;;&lt;/span&gt;
        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;
&lt;span style='color:#800080; '&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/aehrqrhpYQE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/964099810531455907/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2011/11/checked-vs-unchecked-in-c.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/964099810531455907?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/964099810531455907?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/aehrqrhpYQE/checked-vs-unchecked-in-c.html" title="Performance of Checked vs Unchecked" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2011/11/checked-vs-unchecked-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMEQno9fCp7ImA9WhRXFk8.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1230325856045734193</id><published>2010-06-16T12:51:00.003+02:00</published><updated>2011-12-23T07:06:43.464+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-23T07:06:43.464+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spatial index" /><category scheme="http://www.blogger.com/atom/ns#" term="MongoDb" /><title>MongoDB : Geospatial Indexing</title><content type="html">&lt;p&gt;Just a short note to let you know that &lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt; this post&lt;/a&gt; has become outdated because MongoDB supports native two dimensional geospatial indexing. More information can be found &lt;a href="http://www.mongodb.org/display/DOCS/Geospatial+Indexing"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/mp9YCyC5H2o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1230325856045734193/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2010/06/mongodb-geospatial-indexing.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1230325856045734193?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1230325856045734193?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/mp9YCyC5H2o/mongodb-geospatial-indexing.html" title="MongoDB : Geospatial Indexing" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2010/06/mongodb-geospatial-indexing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QCQ3Yyfyp7ImA9WxFWGU8.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-3959823362329284584</id><published>2010-06-01T08:33:00.008+02:00</published><updated>2010-06-07T16:36:02.897+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-07T16:36:02.897+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NetworkX" /><category scheme="http://www.blogger.com/atom/ns#" term="PyPy" /><category scheme="http://www.blogger.com/atom/ns#" term="Psyco" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="shortest path" /><title>2 Possible Ways To Speed Up NetworkX (and Python)</title><content type="html">&lt;p&gt;I'm in the process of looking for a way to run the shortest path algorithms of &lt;a href="http://networkx.lanl.gov/"&gt;NetworkX&lt;/a&gt; in a faster way. At this moment I tried &lt;a href="http://psyco.sourceforge.net/"&gt;psyco&lt;/a&gt; and &lt;a href="http://pypy.org/"&gt;PyPy&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;Psyco&lt;/h4&gt;

&lt;p&gt;Using &lt;a href="http://psyco.sourceforge.net/"&gt;psyco&lt;/a&gt; is really easy. After installing it you only have to write the following two lines.&lt;/p&gt;
&lt;q&gt;import psyco&lt;/q&gt;
&lt;q&gt;psyco.full()&lt;/q&gt;

&lt;p&gt;Psyco didn't speedup my shortest path calculations.&lt;/p&gt;

&lt;p&gt;If you want to know more about psyco I suggest you to read &lt;a href="http://psyco.sourceforge.net/psycoguide/index.html"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;PyPy&lt;/h4&gt;

&lt;p&gt;In order to test &lt;a href="http://pypy.org/"&gt;PyPy&lt;/a&gt; I downloaded the latest windows binary and ran my code against PyPy instead of CPython by invoking my script on the command line with pypy.exe.&lt;/p&gt; 

&lt;p&gt;The startup time is a lot longer for PyPy but if you don't take this startup cost into account then the speedup on my machine is in the range of 10-20% for shortest path routing with NetworkX.&lt;/p&gt;

&lt;p&gt;So far my tests. Any suggestions ?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/HpxdQIfUr8Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/3959823362329284584/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2010/06/speed-up-python.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3959823362329284584?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3959823362329284584?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/HpxdQIfUr8Y/speed-up-python.html" title="2 Possible Ways To Speed Up NetworkX (and Python)" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2010/06/speed-up-python.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcFQnc-eyp7ImA9WxFWE0o.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-3665682487335768038</id><published>2010-05-31T21:56:00.004+02:00</published><updated>2010-06-01T09:23:33.953+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-01T09:23:33.953+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="NetworkX" /><category scheme="http://www.blogger.com/atom/ns#" term="Jython" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="shortest path" /><title>Using NetworkX with Jython</title><content type="html">&lt;p&gt;Just a quick note to let you know that the Python graph library &lt;a href="http://networkx.lanl.gov/"&gt;NetworkX&lt;/a&gt; (version 1.1), which by the way is really good, can be ported to Jython with some minor modifications. Sadly enough you loose some performance in the process.&lt;/p&gt;&lt;p&gt;The two changes I made to get it running where :&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Because numpy doesn't exist for Jython you can't use the current_flow_closeness_centrality function in current_flow_closeness.py. I moved the &lt;q&gt;import numpy as np&lt;/q&gt; statement at the top to the _compute_C function at the bottom.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;In the __init__.py file under generators I commented &lt;q&gt;from atlas import *&lt;/q&gt; out.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;In the following weeks I will try to port a small subset off NetworkX to Java or Scala. Hopefully I'll be able to outperform the Jython and CPython version.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/qrk_Kz9UuOo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/3665682487335768038/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2010/05/using-networkx-with-jython.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3665682487335768038?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3665682487335768038?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/qrk_Kz9UuOo/using-networkx-with-jython.html" title="Using NetworkX with Jython" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2010/05/using-networkx-with-jython.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcAQX8_fSp7ImA9WxFWE0o.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-9046988078175261918</id><published>2010-05-27T21:36:00.001+02:00</published><updated>2010-06-01T09:24:00.145+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-01T09:24:00.145+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="youtube" /><title>Arithmetic, Population, and Energy.</title><content type="html">&lt;p&gt;Just watched Dr. Albert A. Bartlett's presentation on "Arithmetic, Population, and Energy." on youtube. It's really good and entertaining. It's in 8 parts and I encourage you to watch them all.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;The url of part 1 is : &lt;a href="http://www.youtube.com/watch?v=F-QA2rkpBSY"&gt;http://www.youtube.com/watch?v=F-QA2rkpBSY&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/nGzQdYMJGso" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/9046988078175261918/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2010/05/arithmetic-population-and-energy.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/9046988078175261918?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/9046988078175261918?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/nGzQdYMJGso/arithmetic-population-and-energy.html" title="Arithmetic, Population, and Energy." /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2010/05/arithmetic-population-and-energy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUERnk_cCp7ImA9WxNVGEk.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-4466918726169092553</id><published>2009-10-29T21:26:00.003+01:00</published><updated>2009-10-29T21:30:07.748+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T21:30:07.748+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="featureclass" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Cursors" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcObjects" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Using yield to create an iterator</title><content type="html">&lt;p&gt;Not so long ago I blogged about &lt;a href="http://gissolved.blogspot.com/2009/09/using-foreach-with-icursor.html"&gt;using the foreach statement with an ICursor&lt;/a&gt;. I achieved this by inheriting from IEnumerator&lt;IRow&gt; and IEnumerable&lt;IRow&gt;.&lt;/p&gt;

&lt;p&gt;But by using the yield statement we can achieve a similar effect with much less code. The generator function looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFeatureCursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IFeature&lt;/span&gt; &lt;span class="n"&gt;feat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;feat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextFeature&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;feat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use this method like below.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;IFeatureClass&lt;/span&gt; &lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;// initialize feature class&lt;/span&gt;
&lt;span class="n"&gt;IQueryFilter&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QueryFilterClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhereClause&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;clause&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;your&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you're running .NET 3.0 or more you can create the following extension method in an extension class. This method adds the SearchIter method to the IFeatureClass interface which replaces the Search method.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Extensions&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SearchIter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IFeatureClass&lt;/span&gt; &lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IQueryFilter&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;IFeatureCursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;IFeature&lt;/span&gt; &lt;span class="n"&gt;feat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;feat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextFeature&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;feat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The usage of the extension method is similar to the usage of the Iter method but you can replace&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;with this&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IFeature&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;featureClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SearchIter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recycling&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So this was it. I hope you learned something and feel free to leave a comment.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a hef="http://gissolved.blogspot.com/2009/10/editing-with-arcobjects.html"&gt;Disposable Editing&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html"&gt;Drag Drop from ArcCatalog&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html"&gt;Inserting Features and Rows&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/BEXByRMlHYM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/4466918726169092553/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/10/using-yield-to-create-iterator.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/4466918726169092553?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/4466918726169092553?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/BEXByRMlHYM/using-yield-to-create-iterator.html" title="Using yield to create an iterator" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/10/using-yield-to-create-iterator.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEFSHg7eSp7ImA9WxNbFU4.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-466070987894016672</id><published>2009-10-29T20:42:00.005+01:00</published><updated>2009-11-18T10:30:19.601+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-18T10:30:19.601+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="geoprocessing" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Looping over a Workspace</title><content type="html">&lt;p&gt;Ever wanted to execute a function on all the tables and/or featureclasses in a workspace then the following code is something for you.
What it basically does is first loop over all the featureclasses that are in featuredatasets. Then loop over all the other featureclasses and finally loop over all the tables in the provided workspace.&lt;/p&gt;

&lt;p&gt;To achieve this and still be able to retrieve the result of each function execution on the tables and featureclasses I created a generator function. I did this by using the yield statement. In order to avoid duplicate code I also created a nested function for looping over the featureclasses.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;executeiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;featclassfunction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tablefunction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
    
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;loopfcs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;fcs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listfeatureclasses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;fc&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fcs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;featclassfunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    
    &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;featclassfunction&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listdatasets&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;datasetworkspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datasetworkspace&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;loopfcs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
                &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

        &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;loopfcs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
            
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tablefunction&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;tables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listtables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tables&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;tablefunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you don't need the result of the function you can call the following function. It takes the same arguments as the executeiter function but its a regular function instead of a generator.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;featclassfunction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tablefunction&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;executeiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;featclassfunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tablefunction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To demonstrate the usage of my code I first initialized a geoprocessing object and a workspace variable. Then I used the executeiter method to make it return the uppercase version of the name of the tables and featureclasses in my workspace. I could also have passed for example the describe or the listfields method of the geoprocessing object or a custom function. When you want to pass a function that doesn't return a result like the deleterows or deletefeatures function its more convenient to call the execute function.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;arcgisscripting&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;string&lt;/span&gt;

&lt;span class="n"&gt;gp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arcgisscripting&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;r&amp;#39;D:\temp\temp.gdb&amp;#39;&lt;/span&gt; &lt;span class="c"&gt;# path to your workspace&lt;/span&gt;

&lt;span class="c"&gt;# print the uppercase names of all the tables and featureclasses&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;uppername&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;executeiter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upper&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;uppername&lt;/span&gt;

&lt;span class="c"&gt;# delete all rows of all the tables and featureclasses&lt;/span&gt;
&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deletefeatures&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deleterows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I've come to the end of this post. Did I miss something ? Know a Python idiom I really should start using ? Feel free to comment.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html"&gt;Inserting features and rows&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/04/table-to-csv.html"&gt;Export a table to a csv&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/Xcti_wrmPJE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/466070987894016672/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/10/looping-over-workspace.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/466070987894016672?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/466070987894016672?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/Xcti_wrmPJE/looping-over-workspace.html" title="Looping over a Workspace" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/10/looping-over-workspace.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYFQXw5eCp7ImA9WxNWFEs.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1760387821837706403</id><published>2009-10-13T21:24:00.003+02:00</published><updated>2009-10-13T21:28:30.220+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-13T21:28:30.220+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcObjects" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Editing with ArcObjects</title><content type="html">&lt;p&gt;Recently I found myself rewriting a lot of code which started and stopped edit sessions to decorate it with try ... finally blocks to make sure that every started edit session closes even when an error occurs. The code I wrote looked like below.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;saveEdits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StartEditing&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;featureclass&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;saveEdits&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;StopEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;saveEdits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I thought that there had to be a cleaner way to achieve the same functionality. Here comes the &lt;a href="http://msdn.microsoft.com/en-us/library/yh598w02.aspx"&gt;using statement&lt;/a&gt; to the rescue. To be able to use the using statement with a class it has to implement the &lt;a href="http://msdn.microsoft.com/en-us/library/system.idisposable.aspx"&gt;IDisposable&lt;/a&gt; interface. So I wrote the following wrapper class for starting and stopping edit sessions.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EditSession&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IWorkspaceEdit&lt;/span&gt; &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IWorkspaceEdit&lt;/span&gt; &lt;span class="n"&gt;WorkspaceEdit&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="k"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;{&lt;/span&gt; &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;EditSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IWorkspace&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IWorkspaceEdit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EditSession&lt;/span&gt; &lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IWorkspace&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;EditSession&lt;/span&gt; &lt;span class="n"&gt;editSession&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;EditSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;editSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;editSession&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsBeingEdited&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartEditOperation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SaveAndStop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsBeingEdited&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StopEditOperation&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StopEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="cp"&gt;#region IDisposable Members&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_workspaceEdit&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_workspaceEdit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsBeingEdited&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;

    &lt;span class="cp"&gt;#endregion&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use the EditSession class like this.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EditSession&lt;/span&gt; &lt;span class="n"&gt;editSession&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EditSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;featureclass&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;editSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SaveAndStop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you're using .NET 3.0 or a later version you can use the following class which creates an &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension method&lt;/a&gt; for the IWorkspace.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Extensions&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;EditSession&lt;/span&gt; &lt;span class="nf"&gt;StartEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IWorkspace&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;EditSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withUndoRedo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With the extension method you can directly call StartEditing on a workspace.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EditSession&lt;/span&gt; &lt;span class="n"&gt;editSession&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartEditing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;edit&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;featureclass&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;editSession&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SaveAndStop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html"&gt;Drag Drop from ArcCatalog&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/using-foreach-with-icursor.html"&gt;Using foreach with ICursor&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html"&gt;Inserting Features and Rows&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/WgcXNwaMlgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1760387821837706403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/10/editing-with-arcobjects.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1760387821837706403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1760387821837706403?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/WgcXNwaMlgM/editing-with-arcobjects.html" title="Editing with ArcObjects" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/10/editing-with-arcobjects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEFRH0zcCp7ImA9WxNXEEg.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1275139815917820748</id><published>2009-09-27T11:59:00.006+02:00</published><updated>2009-09-27T13:23:35.388+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T13:23:35.388+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="featureclass" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcObjects" /><category scheme="http://www.blogger.com/atom/ns#" term="table" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Inserting Features and Rows</title><content type="html">&lt;p&gt;Recently I was inserting features in a feature class but my code was rather slow so I looked around for another method and the following is what I found.&lt;/p&gt;
&lt;p&gt;First you need to start an edit session and then you can use the code below. This is just a short body of code to give you an idea on how to use the different objects.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;IFeatureCursor&lt;/span&gt; &lt;span class="n"&gt;insertFeatCursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;outputFeatClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;featureToInsert&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;featuresToInsert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IFeatureBuffer&lt;/span&gt; &lt;span class="n"&gt;outputFeatBuffer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;outputFeatClass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateFeatureBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c"&gt;// set the shape&lt;/span&gt;
    &lt;span class="n"&gt;outputFeatBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="c"&gt;// set the different values&lt;/span&gt;
    &lt;span class="n"&gt;outputFeatBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c"&gt;// insert the feature buffer&lt;/span&gt;
    &lt;span class="n"&gt;insertFeatCursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertFeature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputFeatBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;insertFeatCursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you now save and close your edit session the features are inserted. The code for inserting rows in a table is very similar.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ITable&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ICursor&lt;/span&gt; &lt;span class="n"&gt;insertCursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;IRowBuffer&lt;/span&gt; &lt;span class="n"&gt;rowBuffer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateRowBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;rowBuffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_Value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fieldIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insertCursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertRow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rowBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;insertCursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you have any comments or questions, let me know !!!&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/using-foreach-with-icursor.html"&gt;Using foreach with the ICursor&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html"&gt;Drag Drop from ArcCatalog&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt;Pythonnet (call .NET from Python)&lt;/a&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/NpOaWmJmJWo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1275139815917820748/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1275139815917820748?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1275139815917820748?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/NpOaWmJmJWo/inserting-features-and-rows.html" title="Inserting Features and Rows" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQESHo8cCp7ImA9WxNQE0s.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-6116249359442830593</id><published>2009-09-19T14:02:00.005+02:00</published><updated>2009-09-19T14:11:49.478+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-19T14:11:49.478+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gvSIG" /><category scheme="http://www.blogger.com/atom/ns#" term="uDig" /><category scheme="http://www.blogger.com/atom/ns#" term="Quantum GIS" /><category scheme="http://www.blogger.com/atom/ns#" term="geoprocessing" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Geoprocessing 1 : Intersect</title><content type="html">&lt;p&gt;The intersect operation is one of the many overlay operations. When intersecting layer A with a layer B the result will include all those parts that occur in both A and B. In this post I'm going to compare the results of the ArcGIS Intersect tool with the corresponding operation in 3 other GIS packages. The reason why did this was that I noticed that the output from ArcGIS contains more features then I expected when dealing with overlapping geometries. This is usually not a problem but it becomes one when you have lots of overlapping geometries.&lt;/p&gt;

&lt;p&gt;The GIS tools I used to compare the result of ArcGIS with were : &lt;a href="http://udig.refractions.net/"&gt;uDig&lt;/a&gt;, &lt;a href="http://www.qgis.org/"&gt;Quantum GIS&lt;/a&gt; and  &lt;a href="http://www.gvsig.gva.es/"&gt;gvSIG&lt;/a&gt;. All these and some more can be found on &lt;a href="http://www.archaeogeek.com/download.php"&gt;Portable GIS&lt;/a&gt;. Portable GIS brings open source GIS to your usb.&lt;/p&gt;

&lt;p&gt;To test the code I prepared 2 shapefiles. One with a long small polygon and the other one with 3 overlapping rectangles (see image below).&lt;/p&gt;

&lt;a target="_blank" href="http://h.imagehost.org/view/0599/intersect_situation"&gt;&lt;img src="http://h.imagehost.org/0599/intersect_situation.jpg" border="0" width="369" height="286" alt="ImageHost.org" /&gt;&lt;/a&gt;

&lt;p&gt;When intersecting with ArcGIS (version 9.2 and 9.3 tested) the output looks like below. As you can see in the attribute table the result contains 9 polygons.&lt;/p&gt;

&lt;a target="_blank" href="http://h.imagehost.org/view/0713/intersect_1_2_ArcMap"&gt;&lt;img src="http://h.imagehost.org/0713/intersect_1_2_ArcMap.jpg" border="0" width="552" height="253" alt="ImageHost.org" /&gt;&lt;/a&gt;

&lt;p&gt;To be able to do the intersect operation with uDig I had to install the &lt;a href="http://www.axios.es/"&gt;Axios&lt;/a&gt; Spatial Operations Extension. You can install this extension by clicking Help -&gt; Find and install from the menubar. With Quantum GIS I needed to enable the &lt;a href="http://www.ftools.ca/"&gt;ftools&lt;/a&gt; plugin to enable the geoprocessing functionality. The results of the 3 used open source GIS packages where the same. Only 3 features where created in the output shapefile. For completeness I added the screenshots of the results.&lt;/p&gt;

&lt;p&gt;uDig :&lt;/p&gt;
&lt;a target="_blank" href="http://h.imagehost.org/view/0292/intersect_1_2_uDig"&gt;&lt;img src="http://h.imagehost.org/t/0292/intersect_1_2_uDig.jpg" border="0" width="122" height="150" alt="intersect_1_2_uDig.jpg (28 KB)" /&gt;&lt;/a&gt;
&lt;p&gt;Quantum GIS :&lt;/p&gt;
&lt;a target="_blank" href="http://h.imagehost.org/view/0402/intersect_1_2_QGIS"&gt;&lt;img src="http://h.imagehost.org/t/0402/intersect_1_2_QGIS.jpg" border="0" width="150" height="146" alt="intersect_1_2_QGIS.jpg (41 KB)" /&gt;&lt;/a&gt;
&lt;p&gt;gvSIG :&lt;/p&gt;
&lt;a target="_blank" href="http://h.imagehost.org/view/0499/intersect_1_2_gvSIG"&gt;&lt;img src="http://h.imagehost.org/t/0499/intersect_1_2_gvSIG.jpg" border="0" width="150" height="123" alt="intersect_1_2_gvSIG.jpg (19 KB)" /&gt;&lt;/a&gt;

&lt;p&gt;Have any comments or questions ? Let me know !&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/04/table-to-csv.html"&gt;Exporting an ArcGIS table to a text file&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/04/projections-and-transformations-with.html"&gt;Projections and Transformations with pe.dll&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt;Accessing a .NET dll from within Python&lt;/a&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/SKTLmBo7Xpo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/6116249359442830593/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/09/geoprocessing-1-intersect.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6116249359442830593?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6116249359442830593?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/SKTLmBo7Xpo/geoprocessing-1-intersect.html" title="Geoprocessing 1 : Intersect" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/09/geoprocessing-1-intersect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HQHg5cCp7ImA9WxNXEEk.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-2007000677903054748</id><published>2009-09-08T21:47:00.004+02:00</published><updated>2009-09-27T12:05:31.628+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T12:05:31.628+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="Cursors" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcObjects" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Using foreach with the ICursor</title><content type="html">&lt;p&gt;My &lt;a href="http://gissolved.blogspot.com/2009/04/using-for-loops-for-cursors.html"&gt;first post&lt;/a&gt; on this blog was about how to loop over an ESRI cursor in Python with the for statement instead of the while statement. The same problem exists in .NET when using the various cursor objects like ICursor and IFeatureCursor. Normally you would code something like this :&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ICursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;IRow&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextRow&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// some code&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ICursor&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;IRow&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// some code&lt;/span&gt;
    &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And I want to replace it with the following.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;ITable&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;// get table from somewhere&lt;/span&gt;
&lt;span class="n"&gt;IQueryFilter&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;// create QueryFilter or leave it null&lt;/span&gt;
&lt;span class="n"&gt;CursorGS&lt;/span&gt; &lt;span class="n"&gt;cursorGS&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;CursorGS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IRow&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cursorGS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// ... insert your code here&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To make a class usable in a foreach statement you need to implement the IEnumerable and IEnumerator interfaces. I found a good introduction to making class usable in a foreach statement in this &lt;a href="http://support.microsoft.com/kb/322022"&gt;Microsoft article&lt;/a&gt;. So what I did was creating a class that inherited from IEnumerator&amp;lt;IRow&amp;gt; and IEnumerable&amp;lt;IRow&amp;gt; and implement all the needed properties and methods. For IEnumerator these where Current, MoveNext, Reset and Dispose and for IEnumerable only the method GetEnumerator was needed. The biggest problem was the Reset method because an ICursor doesn't have a reset method. I decided to set the cursor null and the recreated at the moment that MoveNext is called. This also makes sure the ICursor is only created when we really need it. Below you can find my full class&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ESRI.ArcGIS.Geodatabase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;GisSolved.GeoDiff.Esri&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CursorGS&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ITable&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;IQueryFilter&lt;/span&gt; &lt;span class="n"&gt;_queryFilter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;ESRI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArcGIS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ADF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComReleaser&lt;/span&gt; &lt;span class="n"&gt;_comReleaser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;IRow&lt;/span&gt; &lt;span class="n"&gt;_currentRow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ICursor&lt;/span&gt; &lt;span class="n"&gt;_cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CursorGS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ITable&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IQueryFilter&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_table&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_queryFilter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queryFilter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;_comReleaser&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ESRI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArcGIS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ADF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ComReleaser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#region IEnumerator&amp;lt;IRow&amp;gt; Members&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IRow&lt;/span&gt; &lt;span class="n"&gt;Current&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="k"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_currentRow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#endregion&lt;/span&gt;

        &lt;span class="cp"&gt;#region IEnumerator Members&lt;/span&gt;

        &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="k"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_currentRow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_cursor&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// initialize the cursor&lt;/span&gt;
            &lt;span class="k"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_queryFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;_comReleaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ManageLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_cursor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;_currentRow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_currentRow&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_cursor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#endregion&lt;/span&gt;

        &lt;span class="cp"&gt;#region IEnumerable&amp;lt;IRow&amp;gt; Members&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IRow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#endregion&lt;/span&gt;

        &lt;span class="cp"&gt;#region IEnumerable Members&lt;/span&gt;

        &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#endregion&lt;/span&gt;

        &lt;span class="cp"&gt;#region IDisposable Members&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_comReleaser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;

        &lt;span class="cp"&gt;#endregion&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see I used the ESRI &lt;a href="http://edndoc.esri.com/arcobjects/9.2/NET/fe9f7423-2100-4c70-8bd6-f4f16d5ce8c0.htm"&gt;ComReleaser object&lt;/a&gt; to make sure that the ICursor references get released properly.&lt;/p&gt;

&lt;p&gt;So now you know how to create a wrapper around the ICursor you can start creating other wrappers for often used cursors like the IFeatureCursor, IFields, ... and I can go to my bed. Success and feel free to post any comments or your implementation !!!&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/09/inserting-features-and-rows.html"&gt;Inserting Features and Rows&lt;/a&gt;
&lt;a href="http://gissolved.blogspot.com/2009/04/using-for-loops-for-cursors.html"&gt;Using for-loops for cursors (Python)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html"&gt;Drag Drop from ArcCatalog&lt;/a&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/abxCL65CUvo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/2007000677903054748/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/09/using-foreach-with-icursor.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2007000677903054748?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2007000677903054748?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/abxCL65CUvo/using-foreach-with-icursor.html" title="Using foreach with the ICursor" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/09/using-foreach-with-icursor.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEBQn4zeyp7ImA9WxJaE08.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-2956304473643772384</id><published>2009-08-03T21:13:00.005+02:00</published><updated>2009-08-03T21:27:33.083+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-03T21:27:33.083+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="DatagridView" /><category scheme="http://www.blogger.com/atom/ns#" term="WinForms" /><title>DatagridView Tricks</title><content type="html">&lt;p&gt;This post will entirely be about the .NET DatagridView control. I will show you how to synchronize the scrolling of two Datagridviews, disable column sorting, disable cell selection and focus cues.&lt;/p&gt;

&lt;p&gt;To synchronize the scrolling of two DatagridViews you should subscribe to the Scroll event of the two Datagridviews and add the following code. What it does is equalizing the first row index and the scrolled horizontal offset. I did set the FirstDisplayedScrollingRowIndex because the VerticalScrollingOffset is a readonly property.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dataGridViewA_Scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrollEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dataGridViewB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstDisplayedScrollingRowIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataGridViewA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstDisplayedScrollingRowIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;dataGridViewB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HorizontalScrollingOffset&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataGridViewA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HorizontalScrollingOffset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dataGridViewB_Scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScrollEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;dataGridViewA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstDisplayedScrollingRowIndex&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataGridViewB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstDisplayedScrollingRowIndex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;dataGridViewA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HorizontalScrollingOffset&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataGridViewB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HorizontalScrollingOffset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For the following tricks I created a custom control called DatagridViewGS that derives from the DatagridView control.&lt;p&gt;

&lt;p&gt;Disabling column sorting for all columns is done by setting the SortMode to NotSortable for every column of the DatagridView. In order to do that I subscribed the DataBindingComplete event and added the following code to it&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DatagridViewGS_DataBindingComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataGridViewBindingCompleteEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DataGridViewColumn&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortMode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataGridViewColumnSortMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotSortable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Cell selection is disabled by subscribing to the CellStateChanged event and setting the Selected property of the cell whose state changed to false. I've also set the SelectionMode of the DataGridView to DataGridViewSelectionMode.CellSelect and the MultiSelect property to false.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DatagridViewGS_CellStateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataGridViewCellStateChangedEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StateChanged&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DataGridViewElementStates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Selected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After disabling cell selection there where still focus cues. These are the small dotted lines around the selected elements. To hide these I needed to override ShowFocusCues property of the DataGridView and make it always return false.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;ShowFocusCues&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;get&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The full code of my custom DatagridView looked like this :&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Windows.Forms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Drawing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;GisSolved.GUI&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatagridViewGS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;DataGridView&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DatagridViewGS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;MultiSelect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;SelectionMode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataGridViewSelectionMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CellSelect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;CellStateChanged&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataGridViewCellStateChangedEventHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DatagridViewGS_CellStateChanged&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            
            &lt;span class="n"&gt;DataBindingComplete&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataGridViewBindingCompleteEventHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DatagridViewGS_DataBindingComplete&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
        
        &lt;span class="c"&gt;// Disable column sorting&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DatagridViewGS_DataBindingComplete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataGridViewBindingCompleteEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DataGridViewColumn&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SortMode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataGridViewColumnSortMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotSortable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;// Disable cell selection&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DatagridViewGS_CellStateChanged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DataGridViewCellStateChangedEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StateChanged&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DataGridViewElementStates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Selected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Selected&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="c"&gt;// Disable focus cues&lt;/span&gt;
        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;ShowFocusCues&lt;/span&gt;
        &lt;span class="k"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt;
            &lt;span class="k"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Do you know other useful tricks with DatagridViews or other .NET controls ? Feel free to write them down in the comments section !&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html"&gt;Drag and drop from ArcCatalog to a .NET form.&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt; Calling .NET code from Python&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/nUmUTozqJEA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/2956304473643772384/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/08/datagridview-tricks.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2956304473643772384?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2956304473643772384?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/nUmUTozqJEA/datagridview-tricks.html" title="DatagridView Tricks" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/08/datagridview-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4MQHo9eSp7ImA9WxJbF08.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-1887239811920309482</id><published>2009-07-27T20:53:00.000+02:00</published><updated>2009-07-27T20:56:21.461+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T20:56:21.461+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rtree" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><title>Building and Installing Spatial Index on Ubuntu</title><content type="html">&lt;p&gt;This is a short post about installing Spatial Index on Ubuntu. First download the &lt;a href="http://trac.gispython.org/spatialindex/wiki/Releases"&gt;latest release&lt;/a&gt;. At the moment it's version 3.2 and cd to the location of your download. Then issue the following commands :&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;tar xzvf spatialindex-1.3.2.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;spatialindex-1.3.2
./configure
sudo make install
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you want to configure your install you should take a look at the installation notes. You can find more information about Spatial Index at the projects &lt;a href="http://trac.gispython.org/spatialindex/"&gt;trac&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related Posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/07/installating-tokyo-cabinet-and-ruby-on.html"&gt;Installing Tokyo Cabinet and Ruby on Ubuntu&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;Rtree and MongoDB&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/5EQW4OComPI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/1887239811920309482/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/07/building-and-installing-spatial-index.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1887239811920309482?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/1887239811920309482?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/5EQW4OComPI/building-and-installing-spatial-index.html" title="Building and Installing Spatial Index on Ubuntu" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/07/building-and-installing-spatial-index.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMBRHg5eip7ImA9WxJbEUw.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-8032790868644847596</id><published>2009-07-16T21:48:00.006+02:00</published><updated>2009-07-20T21:00:55.622+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-20T21:00:55.622+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tokyo Cabinet" /><category scheme="http://www.blogger.com/atom/ns#" term="anti-rdbms" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="ogr" /><title>Tokyo Cabinet 2 : Loading and querying point data</title><content type="html">&lt;p&gt;After &lt;a href="http://gissolved.blogspot.com/2009/07/installating-tokyo-cabinet-and-ruby-on.html"&gt;setting up Tokyo Cabinet and Ruby&lt;/a&gt; its time to use it. As with my post about MongoDB I'm going to load 500.000 POIs in a database and query them with a bounding box query. I will use the table database from Tokyo Cabinet because it supports the most querying facilities. With a table database you can query numbers with full matched and range queries and for strings you can do full matching, forward matching, regular expression matching,...&lt;/p&gt;

&lt;p&gt;To load the data in my database I will need to read my shapefile with POIs with Ruby and write the attributes to a new database. First we create the database with the following code.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;tokyocabinet&amp;#39;&lt;/span&gt;
&lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;TokyoCabinet&lt;/span&gt;

&lt;span class="c1"&gt;# create the object&lt;/span&gt;
&lt;span class="n"&gt;tdb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TDB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kp"&gt;new&lt;/span&gt;

&lt;span class="c1"&gt;# open or create  the database&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;poi_db.tct&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OWRITER&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;TDB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;OCREAT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;open error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errmsg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ecode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To read the features in my shapefile I am going to use the Ruby bindings for GDAL/OGR. Because I installed Tokyo Cabinet on &lt;a href="http://www.gisvm.com/"&gt;GISVM&lt;/a&gt; I already had &lt;a href="http://fwtools.maptools.org/"&gt;FWTools&lt;/a&gt; installed but I still needed to install the Ruby bindings for it. I did this with the following command.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;sudo apt-get install libgdal-ruby
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we are going to read a shapefile with 500.000 point features and write the records to the database. First we open the shapefile and get the layer. Then we loop over the features, create a new record and fill the record with the x,y information and the other fields when they aren't empty. The values need to be converted to strings otherwise the record can't be saved. Then we put the record in the database.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;gdal/ogr&amp;#39;&lt;/span&gt;

&lt;span class="c1"&gt;# open my shapefile&lt;/span&gt;
&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Gdal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Ogr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;poi_500000.shp&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;layer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="n"&gt;feature_defn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_layer_defn&lt;/span&gt;

&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_feature_count&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="c1"&gt;# create new record&lt;/span&gt;
    &lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_feature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;geom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_geometry_ref&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_x&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;geom&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_y&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;pkey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;genuid&lt;/span&gt; &lt;span class="c1"&gt;# init primary key&lt;/span&gt;
 &lt;span class="n"&gt;feature_defn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_field_count&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;field_defn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feature_defn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_field_defn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;fieldname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;field_defn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_name_ref&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_field_as_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;field_defn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_name_ref&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;pkey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
   &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fieldname&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
 &lt;span class="c1"&gt;# store the record in Tokyo Cabinet&lt;/span&gt;
 &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To add indexes on the x and y field we call the following code. This creates two supplementary files called poi_db.tct.idx.x.dec and poi_db.tct.idx.y.dec.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;# add index on x and y&lt;/span&gt;
&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setindex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ITDECIMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setindex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ITDECIMAL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To query the POIs in the database I created a function to query the POIs for a given bounding box and then I benchmarked it. I used the same bounding box as in my previous posts about &lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;MongoDB&lt;/a&gt;, &lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;Rtree&lt;/a&gt;, &lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt;Pythonnet&lt;/a&gt; and &lt;a href="http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html"&gt;PostGIS&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;# query POIs by bounding box&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;miny&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="kp"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addcond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QCNUMGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addcond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QCNUMLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addcond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QCNUMGE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;miny&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addcond&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;y&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QCNUMLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
 &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setorder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;TDBQRY&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;QONUMASC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

 &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;qry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;
 &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="c1"&gt;# number of results found&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;benchmark&amp;#39;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;measure&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The query returned 98000 POIs. I ran the benchmark 12 times and this where the results :&lt;/p&gt;
&lt;div&gt;&lt;pre&gt;  1.620000   0.190000   1.810000 (  1.866339)
  1.570000   0.030000   1.600000 (  1.625303)
  1.640000   0.030000   1.670000 (  1.668573)
  1.650000   0.000000   1.650000 (  1.664806)
  1.650000   0.020000   1.670000 (  1.708228)
  1.730000   0.010000   1.740000 (  1.744645)
  1.410000   0.310000   1.720000 (  1.749268)
  1.620000   0.050000   1.670000 (  1.724199)
  1.610000   0.010000   1.620000 (  1.657794)
  1.660000   0.020000   1.680000 (  1.680383)
  1.710000   0.020000   1.730000 (  1.767141)
  1.720000   0.010000   1.730000 (  1.809114)&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;According to the Ruby documentation the benchmark outputs the user CPU time, the system CPU time, the sum of the user and system CPU times, and the elapsed real time. So this means that the query took between 1.65 and 1.87 seconds to get a list of 98000 POIs within the given bounding box. This is a nice indication of the speed of Tokyo Cabinet.&lt;/p&gt;

&lt;p&gt;To demonstrate how you can access the attribute I created the following code. It loops over the first 100 found POIs and prints the ID and the x- and y-coordinate.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;51&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# print the first hundred found POIs&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;rkey&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
 &lt;span class="n"&gt;rcols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rkey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;rcols&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rcols&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rcols&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
 &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt;
 &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we are ready to close the database. I hope you enjoyed this post and as always I welcome any comments.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c1"&gt;# close the database&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;
 &lt;span class="n"&gt;ecode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ecode&lt;/span&gt;
 &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;close error: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tdb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errmsg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ecode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Related Posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/07/installating-tokyo-cabinet-and-ruby-on.html"&gt;Installing Tokyo Cabinet and Ruby on Ubuntu&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;Populating a MongoDb with POIs&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;Spatial indexing a MongoDb with Rtree&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html"&gt;PostGIS : Loading and querying data&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/p0E82Gt0yC0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/8032790868644847596/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/07/tokyo-cabinet-2-loading-and-querying.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/8032790868644847596?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/8032790868644847596?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/p0E82Gt0yC0/tokyo-cabinet-2-loading-and-querying.html" title="Tokyo Cabinet 2 : Loading and querying point data" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/07/tokyo-cabinet-2-loading-and-querying.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4NSXo_fip7ImA9WxJbF08.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-3471997680361475944</id><published>2009-07-07T20:45:00.005+02:00</published><updated>2009-07-27T20:56:38.446+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-27T20:56:38.446+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tokyo Cabinet" /><category scheme="http://www.blogger.com/atom/ns#" term="anti-rdbms" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu" /><title>Installing Tokyo Cabinet and Ruby on Ubuntu</title><content type="html">&lt;p&gt;After &lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;MongoDB&lt;/a&gt; its time for another alternative to relational databases called Tokyo Cabinet. Tokyo Cabinet is a library of routines for managing a file based key-value store. It's a high performing database and it can be accessed over a network with Tokyo Tyrant. In this post I install Tokyo Cabinet, Ruby and the Ruby bindings for Tokyo Cabinet. But there will be a follow up post where I load and query POIs like I did with &lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;MongoDB&lt;/a&gt; and &lt;a href="http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html"&gt;PostgreSQL/PostGIS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tokyo Cabinet only works on Linux so I installed it in on an Ubuntu virtual machine. It took me some time to figure everything out but if I can do it you can too. First you need to download the latest version of Tokyo Cabinet from the &lt;a href="http://tokyocabinet.sourceforge.net/"&gt;project site&lt;/a&gt;. Once downloaded you open a terminal window, navigate to the download location and issue the following commands.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;tar xzvf tokyocabinet-1.4.20.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;tokyo-cabinet/
&lt;span class="c"&gt;# install dependencies&lt;/span&gt;
sudo apt-get install checkinstall build-essential libbz2-dev
&lt;span class="c"&gt;# now compile&lt;/span&gt;
./configure --prefix&lt;span class="o"&gt;=&lt;/span&gt;/usr
make clean
make
&lt;span class="c"&gt;# creates and installs a Debian package&lt;/span&gt;
sudo checkinstall -D 
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I decided to use the Ruby bindings so if you don't have it you can install it with the below command. This installs Ruby, an interactive shell, an interactive reference, the Ruby documentation and the dev part of the Ruby Standard Library. We will need the ruby-dev package for building the Ruby bindings of Tokyo Cabinet.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;sudo apt-get install ruby irb ri rdoc ruby1.8-dev
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After downloading the Ruby bindings for Tokyo Cabinet from the &lt;a href="http://tokyocabinet.sourceforge.net/"&gt;project site&lt;/a&gt;, I installed them with the following commands.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;tar xzvf tokyocabinet-ruby-1.26.tar.gz
&lt;span class="nb"&gt;cd &lt;/span&gt;tokyocabinet-ruby-1.26
ruby extconf.rb
make
sudo make install
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the &lt;a href="http://tokyocabinet.sourceforge.net/spex-en.html"&gt;specifications document&lt;/a&gt; you can find a lot of information about Tokyo Cabinet and the underlying concepts. As you can read there are four types of databases : a hash database, a B+ tree database, a fixed-length database and a table database. In the examples directory of the Ruby bindings you will find some samples that create and use these four database. There is also a sample that uses the abstract database API with which you can communicate to the four database types. For more info on the Ruby bindings you can read the &lt;a href="http://tokyocabinet.sourceforge.net/rubydoc/"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Problems with the installation ? Here are the sources that helped me with the installation process or post a comment and maybe I can help out.&lt;br /&gt;
&lt;a href="http://openwferu.rubyforge.org/tokyo.html"&gt;http://openwferu.rubyforge.org/tokyo.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://oui.com.br/blog/nando-en/post/installing-tokyo-cabinet"&gt;http://oui.com.br/blog/nando-en/post/installing-tokyo-cabinet&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.ubuntugeek.com/how-to-install-ruby-on-rails-ror-in-ubuntu.html"&gt;http://www.ubuntugeek.com/how-to-install-ruby-on-rails-ror-in-ubuntu.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.law.harvard.edu/hoanga/2006/10/27/fixing-mkmf-load-error-ruby-in-ubuntu/"&gt;http://blogs.law.harvard.edu/hoanga/2006/10/27/fixing-mkmf-load-error-ruby-in-ubuntu/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/07/tokyo-cabinet-2-loading-and-querying.html"&gt;Tokyo Cabinet 2 : Loading and querying points&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;Populating a MongoDb with POIs&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;Spatial indexing a MongoDb with Rtree&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html"&gt;PostGIS : Loading and querying data&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/n5_AllmLJ70" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/3471997680361475944/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/07/installating-tokyo-cabinet-and-ruby-on.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3471997680361475944?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/3471997680361475944?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/n5_AllmLJ70/installating-tokyo-cabinet-and-ruby-on.html" title="Installing Tokyo Cabinet and Ruby on Ubuntu" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/07/installating-tokyo-cabinet-and-ruby-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04DR348eSp7ImA9WxNXEEk.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-6130247787353159763</id><published>2009-06-30T21:25:00.011+02:00</published><updated>2009-09-27T12:06:16.071+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-27T12:06:16.071+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="featureclass" /><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="DragDrop" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcObjects" /><category scheme="http://www.blogger.com/atom/ns#" term="table" /><category scheme="http://www.blogger.com/atom/ns#" term="ArcGIS" /><title>Drag Drop from ArcCatalog</title><content type="html">&lt;p&gt;As you probably already noticed you can drag drop items within ArcGIS. For example you can drag a feature class from ArcCatalog to ArcMap or from ArcMap or ArcCatalog to a geoprocessing form. In this post I'm going to show you what has to be done to enable drag drop behavior from ArcCatalog and Windows Explorer to a textbox.&lt;/p&gt;

&lt;p&gt;To enable drag drop on a textbox I added event handlers for DragEnter, DragOver and DragDrop for my textbox called textBoxPath. In the DragEnter and DragOver handlers I check whether the dragged object is valid. If this is the case the drag drop effect is set to &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.dragdropeffects.aspx"&gt;All&lt;/a&gt;. This is a combination of the &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.dragdropeffects.aspx"&gt;Copy, Move, and Scroll&lt;/a&gt; effect. But its in the DragDrop event handler and more precisely in the helper function GetPaths that the most import stuff happens. As you can see the Data property of the DragEventArgs is processed by the GetPaths method and if any paths to feature classes or tables are found the first path is shown. After that I added a small hack to put the cursor at the end of the text in the textbox.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TextBoxPath_DragEnter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DragEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EsriDragDrop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;DragDropEffects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DragDropEffects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TextBoxPath_DragOver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DragEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EsriDragDrop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;DragDropEffects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;All&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DragDropEffects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TextBoxPath_DragDrop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DragEventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
 &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EsriDragDrop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetPaths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="n"&gt;TextBox&lt;/span&gt; &lt;span class="n"&gt;txtBoxPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TextBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="k"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;// set value of textbox to the first found path&lt;/span&gt;
  &lt;span class="n"&gt;txtBoxPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;esriDragDrop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Paths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="c"&gt;// place cursor at the end of the textbox&lt;/span&gt;
  &lt;span class="n"&gt;txtBoxPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectionStart&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;txtBoxPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TextLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the below EsriDragDrop class I placed the IsValid and GetPaths methods. The IsValid method checks whether the IDataObject coming from the drag event contains any valid objects. The GetPaths method retrieves those valid objects and returns the paths to the found feature classes and tables. It uses the IDataObjectHelper interface and its GetNames and GetFiles methods to access the objects in the IDataObject. Note that only feature classes and tables will be returned by my code but this constraint can easily be removed by not checking the Type of the datasetName. I didn't add any functionality to check whether the file path dragged from a Windows Explorer to the textbox was valid but you can implement this by using the &lt;a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=Geoprocessor_object"&gt;Geoprocessor object&lt;/a&gt; and its &lt;a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=Exists_method"&gt;Exists&lt;/a&gt; and &lt;a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=Describe_method"&gt;Describe&lt;/a&gt; methods or by &lt;a href="http://forums.esri.com/Thread.asp?c=93&amp;f=1170&amp;t=203270#609558"&gt;trying to open the table or feature class&lt;/a&gt;.&lt;/p&gt;


&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Windows.Forms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ESRI.ArcGIS.esriSystem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ESRI.ArcGIS.Geodatabase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;ESRI.ArcGIS.SystemUI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;GisSolved.DragDrop&lt;/span&gt;
&lt;span class="k"&gt;{&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EsriDragDrop&lt;/span&gt;
 &lt;span class="k"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DATAOBJECT_ESRINAMES&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ESRI Names&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDataObject&lt;/span&gt; &lt;span class="n"&gt;dataObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dataObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDataPresent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATAOBJECT_ESRINAMES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt;
    &lt;span class="n"&gt;dataObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDataPresent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Windows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Forms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFormats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileDrop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetPaths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDataObject&lt;/span&gt; &lt;span class="n"&gt;dataObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;foundPaths&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
   &lt;span class="n"&gt;IDataObjectHelper&lt;/span&gt; &lt;span class="n"&gt;dataObjectHelper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataObjectHelperClass&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="n"&gt;dataObjectHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InternalObject&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;dataObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataObjectHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanGetNames&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IEnumName&lt;/span&gt; &lt;span class="n"&gt;enumNames&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataObjectHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetNames&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;IName&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enumNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IDatasetName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="k"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;IDatasetName&lt;/span&gt; &lt;span class="n"&gt;datasetName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IDatasetName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c"&gt;// only accept feature classes and tables&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datasetName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;esriDatasetType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esriDTFeatureClass&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt;
       &lt;span class="n"&gt;datasetName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;esriDatasetType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;esriDTTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;{&lt;/span&gt;
       &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;datasetName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WorkspaceName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PathName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;datasetName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="n"&gt;foundPaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;}&lt;/span&gt;
     &lt;span class="k"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataObjectHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CanGetFiles&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="k"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;&lt;span class="n"&gt;dataObjectHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;{&lt;/span&gt;
     &lt;span class="c"&gt;// TODO : Add code here to check if the file path is a valid path&lt;/span&gt;
     &lt;span class="n"&gt;foundPaths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;foundPaths&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;}&lt;/span&gt;
 &lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is all you need to implement drag drop behavior from ArcCatalog or Windows Explorer to your textbox. If you want to implement drag drop from ArcMap to your form I suggest you to read &lt;a href="http://mrrichie.spaces.live.com/blog/cns!DD16C3F34F4D913E!599.entry"&gt;this&lt;/a&gt; and &lt;a href="http://mrrichie.spaces.live.com/blog/cns!DD16C3F34F4D913E!1741.entry"&gt;this&lt;/a&gt;. Any comments or suggestions ? Let me know.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/08/datagridview-tricks.html"&gt;DatagridView Tricks&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt; Calling .NET from Python to execute spatial queries&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/04/projections-and-transformations-with.html"&gt;Projecting coordinates with Python and the ArcGIS Projection Engine&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/JLrzNx0zL70" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/6130247787353159763/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6130247787353159763?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/6130247787353159763?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/JLrzNx0zL70/drag-drop-from-arccatalog.html" title="Drag Drop from ArcCatalog" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/06/drag-drop-from-arccatalog.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04ESHo8eSp7ImA9WxJVE0U.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-2784385595857794455</id><published>2009-06-25T20:35:00.006+02:00</published><updated>2009-06-30T21:25:09.471+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-30T21:25:09.471+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="similar code" /><category scheme="http://www.blogger.com/atom/ns#" term="Clone Digger" /><category scheme="http://www.blogger.com/atom/ns#" term="Python Toolbox" /><category scheme="http://www.blogger.com/atom/ns#" term="duplicate code" /><category scheme="http://www.blogger.com/atom/ns#" term="Python" /><title>Python Toolbox 4 : Clone Digger</title><content type="html">&lt;p&gt;Looking for duplicate code or opportunities to refactor, let me introduce you to a great Python tool called &lt;a href="http://clonedigger.sourceforge.net/"&gt;Clone Digger&lt;/a&gt;. As the &lt;a href="http://clonedigger.sourceforge.net/"&gt;projects page&lt;/a&gt; says
&lt;blockquote&gt;Clone Digger aimed to detect similar code in Python and Java programs. The synonyms for the term "similar code" are "clone" and "duplicate code".&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;Once &lt;a href="http://clonedigger.sourceforge.net/download.html"&gt;installed&lt;/a&gt; you call the clonedigger.py file with as arguments the path for the output html and the path to a folder or code file to analyze. If you call it with the parameter -h it outputs the different commandline options. To show the power of Clone Digger I used the following extract from actual code.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;arcgisscripting&lt;/span&gt;

&lt;span class="n"&gt;gp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arcgisscripting&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createobject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Point&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;createPolygon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xMax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMax&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;polygon&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createobject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;array&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;##Add the first point&lt;/span&gt;
    &lt;span class="n"&gt;newPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;polygon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;##Add the second point&lt;/span&gt;
    &lt;span class="n"&gt;newPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;polygon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;##Add the third point&lt;/span&gt;
    &lt;span class="n"&gt;newPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;polygon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;##Add the fourth point&lt;/span&gt;
    &lt;span class="n"&gt;newPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;polygon&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;##Close the polygon&lt;/span&gt;
    &lt;span class="n"&gt;newPoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;createPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xMin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;yMin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;#polygon.Add(newPoint)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;polygon&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To run Clone Digger on this file all you have to is issue the below command. Make sure that your shell finds the file clonedigger.py by adding to your path variables or by navigating to its folder.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;python clonedigger.py -o D:\output.html D:\CodeTest.py
&lt;/pre&gt;&lt;/div&gt;&lt;br/&gt;

&lt;p&gt;The output first shows some summary values from the code analysis. Then it shows the different code blocks where duplicate or similar code where found. This is how the output looks like for my short Python code.&lt;/p&gt;

&lt;div class="highlight"&gt;
    &lt;P&gt;Source files: 1&lt;/P&gt;
 &lt;P&gt;Clones detected: 2&lt;/P&gt;
 &lt;P&gt;9 of 17 lines are duplicates (52.94%) &lt;/P&gt;
&lt;P&gt;
&lt;B&gt;Parameters&lt;BR&gt; &lt;/B&gt;

clustering_threshold = 10&lt;BR&gt;
distance_threshold = 5&lt;BR&gt;
size_threshold = 5&lt;BR&gt;
hashing_depth = 1&lt;BR&gt;
clusterize_using_hash = False&lt;BR&gt;
clusterize_using_dcup = False&lt;BR&gt;
&lt;/P&gt; 
 
    &lt;B&gt;Time elapsed&lt;/B&gt;&lt;BR&gt;Construction of AST : 0.00 seconds&lt;BR&gt;
Building statement hash : 0.00 seconds&lt;BR&gt;

Building patterns : 0.00 seconds&lt;BR&gt;
Marking similar statements : 0.02 seconds&lt;BR&gt;
Finding similar sequences of statements : 0.00 seconds&lt;BR&gt;
Refining candidates : 0.02 seconds&lt;BR&gt;
 Total time: 0.03&lt;BR&gt;
 Started at: Wed Jun 24 21:05:15 2009&lt;BR&gt;
 Finished at: Wed Jun 24 21:05:15 2009
    &lt;P&gt;&lt;B&gt;Clone # 1&lt;/B&gt;&lt;BR&gt;Distance between two fragments = 4 &lt;BR&gt;Clone size = 7&lt;TABLE NOWRAP WIDTH=100% BORDER=1&gt;&lt;TD&gt;Source file "D:\CodeToTest.py"&lt;BR&gt;The first line is 16&lt;/TD&gt;&lt;TD&gt;&lt;/TD&gt;&lt;TD&gt;Source file "D:\CodeToTest.py"&lt;BR&gt;The first line is 13&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;

&lt;TD&gt;
newPoint = createPoint(xMin, &lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;
newPoint = createPoint(xMin, &lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=AQUA&gt; &lt;/TD&gt;&lt;TD&gt;

polygon.Add(newPoint)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;, yMax)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMin&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;)&lt;/TD&gt;

&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=AQUA&gt; &lt;/TD&gt;&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
newPoint = createPoint(xMax, &lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;

newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=AQUA&gt; &lt;/TD&gt;&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;

&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMin&lt;/span&gt;, yMin)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt; &lt;/P&gt; &lt;HR&gt;&lt;BR&gt;

&lt;P&gt;&lt;B&gt;Clone # 2&lt;/B&gt;&lt;BR&gt;Distance between two fragments = 4 &lt;BR&gt;Clone size = 5&lt;TABLE NOWRAP WIDTH=100% BORDER=1&gt;&lt;TD&gt;Source file "D:\CodeToTest.py"&lt;BR&gt;The first line is 19&lt;/TD&gt;&lt;TD&gt;&lt;/TD&gt;&lt;TD&gt;Source file "D:\CodeToTest.py"&lt;BR&gt;The first line is 13&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;
&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;&lt;/span&gt;)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;

newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;xMin&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=AQUA&gt; &lt;/TD&gt;&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;

&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;&lt;/span&gt;)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;xMin&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;

&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=AQUA&gt; &lt;/TD&gt;&lt;TD&gt;
polygon.Add(newPoint)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR&gt;
&lt;TD&gt;
newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;xMin&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;yMin&lt;/span&gt;)&lt;/TD&gt;
&lt;TD style="width: 10px;" BGCOLOR=RED&gt; &lt;/TD&gt;&lt;TD&gt;

newPoint = createPoint(&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;xMax&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;, &lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;yMax&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TABLE&gt; &lt;/P&gt; &lt;HR&gt;
    
    
    &lt;HR&gt;
    Clone Digger is aimed to find software clones in Python and Java programs. It is provided under the GPL license and can be downloaded from the site &lt;a href="http://clonedigger.sourceforge.net"&gt;http://clonedigger.sourceforge.net&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;I would not try remove all the duplicates or similarities found by Clone Digger. But I think it's a great tool to find code that can be improved. The degree to which you refactor depends greatly on the goal of your code and your time restrictions. Clone Digger is also be useful when working with multiple people on a project or when having to improve some legacy code.&lt;br /&gt;
Have any comments ? Any tools you can't live without ? Any suggestions for me ? Feel free to let me know.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt;Pythonnet (call .NET from Python)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/05/python-toolbox-2-pygments.html"&gt;Pygments (syntax highlighter)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/05/python-toolbox-1-logging.html"&gt;Logging&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/aIQi4c3z_jM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/2784385595857794455/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/06/python-toolbox-4-clone-digger.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2784385595857794455?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/2784385595857794455?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/aIQi4c3z_jM/python-toolbox-4-clone-digger.html" title="Python Toolbox 4 : Clone Digger" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/06/python-toolbox-4-clone-digger.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IFRX85fSp7ImA9WxJWGEk.&quot;"><id>tag:blogger.com,1999:blog-4113082053753185517.post-7970578413082183301</id><published>2009-06-21T22:11:00.004+02:00</published><updated>2009-06-24T15:18:34.125+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-24T15:18:34.125+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PostGIS" /><category scheme="http://www.blogger.com/atom/ns#" term="PostgreSQL" /><category scheme="http://www.blogger.com/atom/ns#" term="spatial filter" /><title>PostGIS : Loading and querying data</title><content type="html">&lt;p&gt;Today I'm going to load some POIs (points of interest) in a PostGIS database and query them back. 
To do this you'll first need an installed version of PostgreSQL with PostGIS. I suggest to first &lt;a href="http://www.postgresql.org/download/"&gt;download&lt;/a&gt; and  &lt;a href="http://www.postgresql.org/docs/8.3/interactive/admin.html"&gt;install PostgreSQL&lt;/a&gt; and then &lt;a href="http://postgis.refractions.net/documentation/manual-1.3/ch02.html"&gt;install PostGIS&lt;/a&gt; with the &lt;a href="http://postgis.refractions.net/download/"&gt;latest version&lt;/a&gt;. Then you should &lt;a href="http://postgis.refractions.net/documentation/manual-1.3/ch02.html#templatepostgis"&gt;create a spatially enabled database&lt;/a&gt;. I called mine pois_db.&lt;/p&gt;

&lt;p&gt;Now we are ready to import the POIs. I first extracted 500.000 POIs from a file geodatabase into a shapefile with the ArcGIS Select tool. Then I used the PostGIS shp2pgsql tool which is located in your bin folder of your PostgreSQL installation to create a text file. This file can then be used to import the data in your database with the PostgreSQL psql tool.
My commandline looked like below.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;rem -s : srid (spatial reference id)&lt;/span&gt;
&lt;span class="c"&gt;rem -c : creates a new table and populates it&lt;/span&gt;
&lt;span class="c"&gt;rem -D : use PostgreSQL dump format&lt;/span&gt;
&lt;span class="c"&gt;rem -i create a GiST index on the geometry column&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;C:\Program Files\PostgreSQL\8.3\bin\shp2pgsql.exe&amp;quot;&lt;/span&gt; -s &lt;span class="m"&gt;4326&lt;/span&gt; -c -D -i poi_&lt;span class="m"&gt;500000&lt;/span&gt;.shp pois_db &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pois&lt;/span&gt;.sql
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;More information about the usage of shp2pgsql can be found &lt;a href="http://postgis.refractions.net/documentation/manual-1.3/ch04.html#id2571948"&gt;here&lt;/a&gt;. Note that I set the srid to 4326 which stands for WGS84. On &lt;a href="http://spatialreference.org/"&gt;spatialreference.org&lt;/a&gt; you can find a list of spatial reference ids or you can take a look at the &lt;a href="http://postgis.refractions.net/documentation/manual-1.3/ch04.html#id2571306"&gt;spatial_ref_sys table&lt;/a&gt; in your database.&lt;br /&gt;
Next thing we are going to is load the pois.sql in the pois_db with the following command line.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="s2"&gt;&amp;quot;C:\Program Files\PostgreSQL\8.3\bin\psql&amp;quot;&lt;/span&gt; -d pois_db -f pois.sql
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To query the POIs we issue the following sql command. 
This query checks whether the bounding box of the point intersects with the bounding box of a &lt;a href="http://en.wikipedia.org/wiki/Well-known_text"&gt;created rectangle polygon&lt;/a&gt;.
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;pois&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;the_geom&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;GeomFromText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;POLYGON((4.5 50.5, 5.0 50.5, 5.0 51.0, 4.5 51.0, 4.5 50.5))&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4326&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This query takes in pgAdmin III with a gist index on the geometry column only 515 ms for more then 4000 found POIs. If I only ask the ids the query is down to 67 ms which is slightly slower then &lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;with Rtree&lt;/a&gt; but faster then with &lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;MongoDb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've come to the end of this post. I hope you liked it and leave a comment if you want to.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Related Posts&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/python-toolbox-3-pythonnet.html"&gt;Pythonnet&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/05/populating-mongodb-with-pois.html"&gt;MongoDB&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://gissolved.blogspot.com/2009/06/spatial-indexing-mongodb-with-rtree.html"&gt;Rtree&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/GisSolved/~4/VE33zMytaew" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gissolved.blogspot.com/feeds/7970578413082183301/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/7970578413082183301?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4113082053753185517/posts/default/7970578413082183301?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/GisSolved/~3/VE33zMytaew/postgis-loading-and-querying-data.html" title="PostGIS : Loading and querying data" /><author><name>Samuel Bosch</name><uri>https://plus.google.com/100255729904270940832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/--D6YquRdq8c/AAAAAAAAAAI/AAAAAAAABLI/U6H8Mgzs1FI/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gissolved.blogspot.com/2009/06/postgis-loading-and-querying-data.html</feedburner:origLink></entry></feed>
