Monday, November 10, 2008
Posted on Monday, November 10, 2008 3:32:36 PM (Mountain Standard Time, UTC-07:00)  Comments [4] | 
Categories: .NET | ArcGIS Devt | ArcGIS Server

So I'm getting ready to cook up a tile cache, and I want to use the ESRI ArcGIS Online tile scheme so I can use their tiles for the first 10 or so zoom levels. To do this, you need to have your map's spatial reference set to WGS84, which was not a problem when I was setting up the "Road Map", but I ran into a snag with the "Hybrid" (roads + parcels + orthos) - the Ortho images did not have any spatial reference defined - which means that ArcMap could not project them. Doh!

Now - I should point out that there is likely a neat-o way to do this with some Geoprocessing Python, but I'm a .NET guy, so I used my .NET hammer to solve this.

Ive done enough with images over the years to know that the spatial reference will be stored in the .aux.xml files that share the name of the raster. But for one set of images, there were no .aux.xml files. Solution: Open all the files in ArcMap and it will create these files. Sweet.

Next up, for one raster, I manually set the correct spatial reference in ArcCatalog. Easy, but there are several hundred files, so it's not going to work as a solution. Enter System.Xml...

I then opened up the .aux.xml file (in notepad) for the raster that I manually assigned a spatial reference to, and simply copied the projection information from the <SRS> element. I then cooked up a simple loop over all the files, opened them up in an XmlDocument, injected or updated the <SRS> element, saved the file and shazam! all done. The pertinent function is below.

 

        private void UpdateSpatialRef(string folderPath, string srs)

        {

            //Loop over all the xml files, open as xml doc, inject the SRS node, save

            string[] fileNames = Directory.GetFiles(folderPath, "*.sid.aux.xml");

            for (int i = 0; i < fileNames.Length; i++)

            {

                string fileName = fileNames[i];

                //Open the file

                XmlDocument xDoc = new XmlDocument();

                xDoc.Load(fileName);

                //find the SRS element if it's here

                XmlNodeList srsNodes = xDoc.SelectNodes("//SRS");

                XmlElement srsEl = xDoc.CreateElement("SRS");

                srsEl.InnerText = srs;

                if (srsNodes.Count > 0)

                {

                    //Already set... replace                   

                    if (xDoc.DocumentElement.FirstChild.Name == "SRS")

                    {

                        xDoc.DocumentElement.ReplaceChild(srsEl, xDoc.DocumentElement.FirstChild);

                        xDoc.Save(fileName);

                    }//if it's somewhere else in your doc, it's likely bad & you've got other problems!

                }

                else

                {

                    xDoc.DocumentElement.PrependChild(srsEl);

                    xDoc.Save(fileName);

                }

                Console.WriteLine("Fixed: " + fileName);

            }

        }

 

While more over the top than may be necessary, it was quick to write and solved my problem... now to kick off the cache creation!

Tuesday, November 11, 2008 8:05:19 AM (Mountain Standard Time, UTC-07:00)
Unless I'm missing something, there's no geoprocessing involved. It's just XML. The Python version wouldn't be much shorter.
Tuesday, November 11, 2008 9:04:58 AM (Mountain Standard Time, UTC-07:00)
This should do the same thing using Python and geoprocessing:
----------------------

import arcgisscripting

# Create Geoprocessing Object
gp = arcgisscripting.create()

#Set input workspace and projection file
gp.workspace = sys.argv[1]
prj = sys.argv[2]

#Get a list of rasters
rasters = gp.ListRasters()
raster = rasters.Next()
while raster:
gp.DefineProjection_management(raster, prj)
raster = rasters.Next()


---------------------------
I use this script a lot.
Nils
Nils Babel
Tuesday, November 11, 2008 10:06:18 AM (Mountain Standard Time, UTC-07:00)
Thanks Nils - I knew there would be a python option using some GP function! Alas I'm too far gone down the .NET path to turn back!

Thanks!

Dave
Wednesday, November 12, 2008 1:05:23 PM (Mountain Standard Time, UTC-07:00)
I'm sure your way is much faster, especially if you have many rasters.

Nils
Nils Babel
Comments are closed.