static void Main(string[] args) { bool showHelp = false; bool gzip = false; bool overwrite = false; bool verbose = false; string destination = "."; int[] levels = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; HashSet <string> fields = null; int threadCount = System.Environment.ProcessorCount; OptionSet p = new OptionSet() { { "d|dir=", "destination directory (defaults to current directory)", d => destination = d }, { "l|levels=", "list of scale levels [0-19], separated by commas", l => levels = l.Split(new char[] { ',' }).Select(s => Convert.ToInt32(s)).ToArray() }, { "f|fields=", "list of field names to include in UTFGrid data", f => fields = new HashSet <string>(f.Split(new char[] { ',' })) }, { "t|threads=", "number of threads to use (defaults to number of processors)", t => threadCount = Convert.ToInt32(t) }, { "z|zip", "zip the json files using gzip compression before saving", z => gzip = z != null }, { "o|overwrite", "overwrite existing files", o => overwrite = o != null }, { "v|verbose", "verbose output", v => verbose = v != null }, { "h|help", "show this message and exit", h => showHelp = h != null } }; List <string> extra; try { extra = p.Parse(args); } catch (OptionException e) { Console.Write("utfgrid"); Console.WriteLine(e.Message); Console.WriteLine("Try `utfgrid --help' for more information."); return; } if (showHelp) { Console.WriteLine("Usage: utfgrid [OPTIONS]+ mxd_document"); Console.WriteLine("Generate UTFGrid files from the given map document"); Console.WriteLine(); Console.WriteLine("Options:"); p.WriteOptionDescriptions(Console.Out); return; } else if (extra.Count < 1) { Console.WriteLine("utfgrid: no map document specified"); Console.WriteLine("Try `utfgrid --help' for more information."); return; } RuntimeManager.BindLicense(ProductCode.EngineOrDesktop); IMap map = null; try { IMapDocument mapDocument = new MapDocumentClass(); mapDocument.Open(extra[0], null); map = mapDocument.ActiveView as IMap; if (map == null) { map = mapDocument.get_Map(0); } mapDocument.Close(); } catch (Exception) { } if (map == null) { Console.WriteLine("Unable to open map at " + extra[0]); return; } if ((map.SpatialReference.FactoryCode != 102113) && (map.SpatialReference.FactoryCode != 102100) && (map.SpatialReference.FactoryCode != 3785)) { Console.WriteLine("Spatial reference of map must be Web Mercator (is " + map.SpatialReference.FactoryCode + ")"); return; } IActiveView activeView = map as IActiveView; // get the extent from the active view IEnvelope fullExtent = activeView.FullExtent; Console.WriteLine("starting utfgrid generator with " + threadCount + " threads"); UTFGridGeneratorConfig config = new UTFGridGeneratorConfig(extra[0], DescribeTiles(levels, activeView.FullExtent)); config.GZip = gzip; config.Overwrite = overwrite; config.Verbose = verbose; config.Destination = destination; Thread[] workerThreads = new Thread[threadCount]; for (int i = 0; i < threadCount; i++) { workerThreads[i] = new Thread(new ParameterizedThreadStart(UTFGridGenerator.Execute)); workerThreads[i].SetApartmentState(ApartmentState.STA); workerThreads[i].IsBackground = true; workerThreads[i].Priority = ThreadPriority.BelowNormal; workerThreads[i].Name = "UTFGridGenerator " + (i + 1).ToString(); workerThreads[i].Start(config); } foreach (Thread t in workerThreads) { t.Join(); } workerThreads = null; }
public static void Execute(object threadData) { UTFGridGeneratorConfig config = threadData as UTFGridGeneratorConfig; try { config.WorkerStart(); IMap map = null; try { IMapDocument mapDocument = new MapDocumentClass(); mapDocument.Open(config.MapPath, null); map = mapDocument.ActiveView as IMap; if (map == null) { map = mapDocument.get_Map(0); } mapDocument.Close(); } catch (Exception) { } if (map == null) { throw new Exception("Unable to open map at " + config.MapPath); } if ((map.SpatialReference.FactoryCode != 102113) && (map.SpatialReference.FactoryCode != 102100) && (map.SpatialReference.FactoryCode != 3785)) { throw new Exception("Spatial reference of map must be Web Mercator (is " + map.SpatialReference.FactoryCode + ")"); } while (true) { TileDescription tile = config.NextTile(); if (tile == null) { return; } string folder = String.Format("{0}\\{1}\\{2}", config.Destination, tile.Level, tile.Col); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } string file = String.Format("{0}\\{1}.grid.json", folder, tile.Row); if (config.GZip) { file += ".gz"; } if ((!File.Exists(file)) || config.Overwrite) { if (config.Verbose) { Console.WriteLine(Thread.CurrentThread.Name + " generating tile " + tile.Level + ", " + tile.Row + ", " + tile.Col); } Dictionary <string, object> data = CollectData(map, tile.Extent, config.Fields); if (data != null) { if (config.Verbose) { Console.WriteLine(Thread.CurrentThread.Name + " saving to " + file); } Stream fOut = new System.IO.FileStream(file, FileMode.Create); if (config.GZip) { fOut = new GZipStream(fOut, CompressionMode.Compress, CompressionLevel.BestCompression); } using (fOut) { string json = JsonConvert.SerializeObject(data, Formatting.Indented); Encoding utf8 = new UTF8Encoding(false, true); byte[] encodedJson = utf8.GetBytes(json); fOut.Write(encodedJson, 0, encodedJson.Length); } } } } } finally { config.WorkerEnd(); } }