📄 mapdatacollection.cs
字号:
///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 + -