⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapdatacollection.cs

📁 实现SHP
💻 CS
📖 第 1 页 / 共 2 页
字号:
///GeoCon, free tool to create gml & svg from gis files. 
///Copyright(C) 2005 Amri Rosyada 
///Distributed under GNU-LGPL, see a copy of the license in root directory

using System;
using System.Collections;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Globalization;
using System.Drawing;

using GeoCon.Classification;

namespace GeoCon.Data
{
	/// <summary>
	/// Collection of MapData.
	/// </summary>
	[Serializable]
	public class MapDataCollection : CollectionBase
	{

		/// <summary>
		/// Constructs empty collection.
		/// </summary>
		public MapDataCollection()
		{
			initNamespaces();
		}


		#region private fields
		private System.Collections.Hashtable _ns=new Hashtable();  //XmlNamespaceManager can't cross appdomain boundary
		private System.AppDomain dynoDomain; //domain where the dynamic assembly loaded
		private string dynoAssName;	//name of the dynamic assembly
		private string targetfile; //export target file name
		#endregion

		#region basic props & methods

		/// <summary>
		/// Gets MapData at specified index.
		/// </summary>
		public MapData this[int index]
		{
			get{return (MapData)List[index];}
		}

		/// <summary>
		/// Adds new MapData into the collection
		/// </summary>
		/// <param name="map">MapData to add</param>
		/// <returns>index of the newly added mapdata</returns>
		public int Add(MapData map)
		{
			//add default prefix:namespacename
			map.NamespacePrefix ="gc";
			map.NamespaceName = getNS(map.NamespacePrefix);
			return this.List.Add(map);
		}

		/// <summary>
		/// do some minor clean up. currently unused
		/// </summary>
		public void CleanUp()
		{
			dynoAssName=null;
			targetfile=null;
		}

		private string desc="description for FeatureCollection.";
		/// <summary>
		/// Gets or sets description about this MapDataCollection.
		/// </summary>
		public string Description
		{
			get{return desc;}
			set{desc=value;}
		}

		/// <summary>
		/// Gets the number of active MapData in this collection
		/// </summary>
		/// <returns>number of active MapData in this collection</returns>
		private int getActiveCount()
		{
			int count=0;
			for(int i=0;i<this.Count;i++)
			{
				if(this[i].isActive) count++;
			}
			return count;
		}

		/// <summary>
		/// Changes the item position in this collection.
		/// </summary>
		/// <param name="idxfrom">Index of the item to move</param>
		/// <param name="idxto">Index to where the item should be moved.</param>
		public void MoveItem(int idxfrom,int idxto)
		{
			MapData temp = this[idxfrom];
			this.List.RemoveAt(idxfrom);
			this.List.Insert(idxto,temp);
			temp=null;
		}


		/// <summary>
		/// Initializes namespaces for SVG and GML
		/// </summary>
		private void initNamespaces()
		{
			_ns.Add("", "http://www.mycgiserver.com/~amri/percobaan"); 
			_ns.Add("gc", "http://www.mycgiserver.com/~amri/percobaan");
			_ns.Add("gml", "http://www.opengis.net/gml"); 
			_ns.Add("wfs", "http://www.opengis.net/wfs");
			_ns.Add("xs", "http://www.w3.org/2001/XMLSchema");
			_ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
			_ns.Add("xlink", "http://www.w3.org/1999/xlink");
			_ns.Add("svg", "http://www.w3.org/2000/svg");
		}


		/// <summary>
		/// Gets a namespace name
		/// </summary>
		/// <param name="prefix">prefix of the namespace</param>
		/// <returns>Namespace name corresponds to the prefix</returns>
		private string getNS(string prefix)
		{
			return _ns[prefix].ToString();
		}

		/// <summary>
		/// Gets the Bounding Box which is the union of all Bounding Box of each map.
		/// </summary>
		/// <returns></returns>
		public gml.BoxType GetBoundingBox()
		{
			//TODO : check if map contain valid bound, else return box null
			gml.BoxType box = new gml.BoxType(double.MaxValue,double.MinValue,double.MinValue,double.MaxValue);
			for(int i=0;i<this.Count;i++) box.UnionWith(this[i].BoundingBox);
			return box;
		}
		#endregion

		#region codebuilder stuff
		/// <summary>
		/// Compiles the dynamic code for this MapDataCollection.
		/// </summary>
		/// <returns>File path to the new assembly.</returns>
		public string CompileCode()
		{
			CompilerResults crs = GetCompilerResult();
			if(crs.Errors.Count>0)
			{
				System.Text.StringBuilder sb=new System.Text.StringBuilder();
				sb.Append("ERRORs in compiling dynamic assembly :\n"); 
				for(int k=0;k<crs.Errors.Count;k++  )	
				{
					sb.Append(crs.Errors[k].ToString() + "\t");
				}
				throw new Exception(sb.ToString());
			}
			return crs.PathToAssembly;
		}

		/// <summary>
		/// Creates a compile unit and compile the code compile unit.
		/// </summary>
		/// <returns>results of the compilation</returns>
		private CompilerResults GetCompilerResult()
		{
			CodeCompileUnit ccu = new CodeCompileUnit(); 
			ccu.Namespaces.Add(CreateCodeNamespace());

			CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider(); 
			string basedir=System.AppDomain.CurrentDomain.BaseDirectory; 
			string savedir=basedir;
			if(!System.IO.Directory.Exists(savedir)) System.IO.Directory.CreateDirectory(savedir);

			ICodeCompiler comp = provider.CreateCompiler();
			CompilerParameters options = new CompilerParameters();
			options.ReferencedAssemblies.AddRange(referCurrentAssemblies()); 

			options.OutputAssembly = savedir+"\\dyno.dll";

			options.GenerateInMemory=false;
			options.TreatWarningsAsErrors=true;
			options.GenerateExecutable=false;
			options.TempFiles = new TempFileCollection(savedir,false);
			options.Evidence = System.AppDomain.CurrentDomain.Evidence;

			return comp.CompileAssemblyFromDom(options,ccu);
		}
		/// <summary>
		/// Gets references to assemblies needed for compilation.
		/// </summary>
		/// <returns>array of paths to the assembly files</returns>
		private static string[] referCurrentAssemblies()
		{
			Assembly[] ass = System.AppDomain.CurrentDomain.GetAssemblies();
			string[] ss = new string[ass.Length];
			for (int i = 0; i<ass.Length;i++)
			{
				if(ass[i].GetName().Name=="GeoLib" || ass[i].GetName().Name=="System.Xml")
				{
					ss[i]=ass[i].Location;		//break;
				}
			}
			ass=null;
			return ss;
		}

		/// <summary>
		/// Creates code namespace for the dynamic code
		/// </summary>
		/// <returns>codenamespace for this MapDataCollection</returns>
		private CodeNamespace CreateCodeNamespace()
		{
			string CLRNamespace="Dyno";
			CodeNamespace cns=new CodeNamespace(CLRNamespace);
			cns.Imports.Add(new CodeNamespaceImport("System"));  
			cns.Imports.Add(new CodeNamespaceImport("System.Xml.Serialization"));  
			cns.Imports.Add(new CodeNamespaceImport("GeoCon.Data"));  

			//add each MapData codetypedeclaration into this codenamespace
			for(int i=0;i<Count;i++)
			{
				if(!this[i].isActive) continue;
				cns.Types.Add(this[i].getCodeType());
			}

			//add factory class
			cns.Types.Add(CreateFactoryCodeType());

			return cns;
		}

		/// <summary>
		/// Creates dynamic code declaration for this MapDataCollection.
		/// </summary>
		/// <returns>new CodeTypeDeclaration</returns>
		private CodeTypeDeclaration CreateFactoryCodeType()
		{
			//create new factory class
			CodeTypeDeclaration ctDecl = new CodeTypeDeclaration("DynoFactory");

			//add default constructor
			CodeConstructor defcon = new CodeConstructor();
			defcon.Attributes = MemberAttributes.Public; 
			ctDecl.Members.Add(defcon);

			//add factory method for each mapdata
			for(int i=0;i<this.Count;i++)
			{
				if(!this[i].isActive) continue;
				System.Text.StringBuilder snip = new System.Text.StringBuilder();
				snip.Append("public object[] Create"+this[i].Name+"Array(int count, FieldCollection fs)\r");
				snip.Append("{\r"); 
				snip.Append("object[] objs=new object[count];\r");
					snip.Append("for(int i=0;i<count;i++)\r");
					snip.Append("{\r"); 
					snip.Append(""+this[i].Name+" obj=new "+this[i].Name+"();\r");
					snip.Append("obj.fid = \"" + this[i].Name + "\"+\"_\"" + "+i.ToString()"+";\r");
				for(int j=0;j<this[i].Fields.Count;j++)
				{
					if(!this[i].Fields[j].isActive) continue;
					snip.Append("if( fs["+j.ToString()+"][i] != fs["+j.ToString()+"].NullSymbol )"+"obj."+this[i].Fields[j].Name+"=("+ this[i].Fields[j].Type.ToString()+")fs["+j.ToString()+"][i];\r" );
				}
					snip.Append("objs[i]=obj;\r");
					snip.Append("}\r");

				snip.Append("return objs;\r");
				snip.Append("}\r"); 
				ctDecl.Members.Add(new CodeSnippetTypeMember(snip.ToString()));
				snip=null;
			}
			return ctDecl;
		}

		#endregion

		#region schema stuff
		/// <summary>
		/// Write application schema associated with this MapDataCollection.
		/// </summary>
		/// <param name="SchemaFileString">path to schema file to create</param>
		/// <param name="CompileSchema">value indicating whether to compile schema</param>
		public void writeApplicationSchema(string SchemaFileString, bool CompileSchema)
		{
			UpdateStatus("writing application schema...",0);

			XmlSchema xs = new XmlSchema();
			xs.TargetNamespace=getNS("gc");

			xs.Version="1.0";
			xs.ElementFormDefault = XmlSchemaForm.Qualified; 
			xs.AttributeFormDefault = XmlSchemaForm.Unqualified; 

			xs.Namespaces.Add("gc", getNS("gc"));
			xs.Namespaces.Add("gml", getNS("gml"));
			xs.Namespaces.Add("xs", getNS("xs"));

			System.Xml.Schema.XmlSchemaImport ximport = new XmlSchemaImport();
			ximport.Namespace = getNS("gml");
			ximport.SchemaLocation = "feature.xsd";
			xs.Includes.Add(ximport);
			
			XmlQualifiedName thebase = new XmlQualifiedName("AbstractFeatureType", getNS("gml"));
			XmlQualifiedName thesub  = new XmlQualifiedName("_Feature", getNS("gml"));
			for(int i=0;i<this.Count;i++)
			{
				if(!this[i].isActive) continue;
				this[i].createSchemaType(ref xs,thebase,thesub);
			}
			if(CompileSchema) xs.Compile(new ValidationEventHandler(XSCompileCallback));

			System.IO.FileStream fs = new System.IO.FileStream(SchemaFileString,System.IO.FileMode.Create);
			xs.Write(fs);
			fs.Close();

			xs=null;
			thebase=null;
			thesub=null;
		}
		/// <summary>
		/// Callback method for schema compilation.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		public static void XSCompileCallback(object sender, ValidationEventArgs args)
		{
			System.Diagnostics.Debug.WriteLine(args.Message);
		}
		#endregion

		#region gml stuff
		/// <summary>
		/// Export this MapDataCollection to GML document.
		/// </summary>
		/// <param name="gmlfilename">path to GML file to create</param>
		/// <param name="validateOutput">value indicating whether the output should be validated</param>
		public void ExportGML(string gmlfilename, bool validateOutput)
		{
			this.targetfile=gmlfilename;
			//create and save dynamic assembly code
			UpdateStatus("processing dynamic assembly...",10);
			string asspath = this.CompileCode();
			try
			{
				//create new appdomain
				ProcessAssembly(asspath);	
				//load dynamic assembly into the new appdomain; execute callback
				dynoDomain.DoCallBack(new CrossAppDomainDelegate(LoaderCallBack));
				//serialize the dynamic class
				UpdateStatus("constructing feature members...",30);
				dynoDomain.DoCallBack(new CrossAppDomainDelegate(SerializeCallBack));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -