Ahh, my first (documented) project. Again, going a bit from memory here, as this was fresh out of the military “GIS” school at the time…
My first GIS shop was using ArcGIS 9.2 and Military Analyst for a lot of their work. Before ESRI had mosaic datasets, before they had the visibility tool, before a lot of conveniences one of our common goals was to convert coordinates from one set to another (e.g., MGRS to Decimal Degrees, DMS to MGRS, etc.). That is we have points, sometimes thousands, with various coordinates. If we were lucky they were in ten digit MGRS (1 meter accuracy). If we were unlucky they had BAD coordinates. Yep, pretty common to see that some poor Lance Corporal (low level military employee) was probably hand jamming those suckers in one at a time for several days straight with the plethora of fat-fingering that comes with it. Simple enough though, right? I mean how hard could it be for the largest GIS software package to handle this simple task. Turns out, either I had bad mentors or there is not a perfect tool for this.. or Military Analyst.
So simply calculating things was already a hassle. I can imagine this would be similar to changing your paint tool to a pencil tool in Photoshop as an 8 step process. Are you kidding me?!
Now my next step was two fold. How do I set this up to be calculated on the current set of points and how do I make it possible to calculate several coordinates at once. This turned out to be the more interesting part to me and quite doable with a little learning. Since Python was clearly out of the question I looked towards Model Builder. It had almost everything I needed. Take the 8 steps here line them out, 8 steps there, line them out. Eventually I had a tool with 5 different paths, each more convoluted than the last, but they were all there. Now how do I create check boxes for everything. Turns out the answer was, “booleans.” Inserting a boolean from model builder and creating a parameter will create a check box in your tool. Perfect. Setup my booleans for all my paths and label them with their respective calculations.
My next issue was to get the information back into the original dataset. Some calculations didn’t require this extra step, but some created a new dataset. In order to get the newly created dataset coordinates back into the original I had to do some joining. I can’t assume any dataset can be pre-processed or have a unique identifier, so I have to work with FID and OIDs. This was originally the first problem I ran into and one of the hard limitations to Model Builder. At the time (and currently I believe) there is no if/then tool for Model Builder. You have to build one with Python. Even then, it often fails as any slightly advanced process will error out on one end. Model Builder wants to evaluate a model before running and since only one path will be valid, the other will be invalid and Model Builder won’t like that, causing it to throw an error. No skips or ignoring for Model Builder, it just refused to run a “bad” model.. bummer.
Solutions that may have worked were Python with multiple nested models. At this point you’re getting so advanced, just go learn Python. However, I needed something quicker for my shop that was still feasible. The solution that worked was to simply make a Feature Class version and a Shapefile version. I know, ugh.. it was a while ago. In order to transfer coordinates, I needed to calculate a new field in the original dataset, calculate it to the OID/FID, and use it as the joining factor in the Join Field tool. Now the results have coordinates, and I can simply join the coordinates to the original set. First I had to set every potential coordinate set with a separately calculated ID field which I named appropriate to the type, such as IdMGRS, IdDMS, etc. Since I am potentially joining multiple coordinate sets, I can’t use the same field name without causing errors. Here is what the Join Field tools ended up looking like:
Here I have my InputFeature (the original dataset parameter) with its FID being prepared to join with the IdDMS duplicate and transferring over a Latitude and Longitude coordinate. Later in the model, I would delete the extra ID field as part of cleanup. Multiple paths could now be joined without interrupting each other each with their own goofy process. The end result was the same file with calculations based on the actual point calculations and several could be created at once. All an analyst had to do was select their file and choose a few check boxes to calculate. Now that was simple! Here is the end product for my first project:
Like I said, an easy tool and worked on all licenses of ArcGIS without the need for any extensions. I estimated it could calculate and join all fields by thousands of points per second. Now that’s not to say it didn’t have draw backs. Namely, I had to separate between Feature Class and Shapefile. I also didn’t have any ability to change field names if they already existed. If the field MGRS already existed that leg of the model would fail and the user would be left with a worthless IdMGRS field (since that leg of the model threw an error and didn’t continue). Also, all legs that were not checked would produce a warning message. This didn’t stop any processing, but it is always annoying to get “warnings” about your tool working correctly.
A good bit of documentation and cleaning up tool pieces and I had my first tool ready to disseminate to the rest of the team! Great success. Later on after we upgraded to 10.x, I ended up turning everything into Convert Coordinate Notation tool. This was MUCH cleaner and could be used in all paths and based on the actual points location and still worked on a Basic license. This model still helped with multiple calculations and keeping the original dataset, but I’m not sure if Coordinate Notation would be available for version below 10.x. Below is the model with a download for my purposes, or anyone else who would care to check it out.
Next step is to work with proper if/then statements and much cleaner Python code, but that was ahead of me at the time and a different post for a different date.