📄 mapdatacollection.cs
字号:
}
catch (System.Exception exc)
{
UpdateStatus("export to GML failed.",0);
throw new Exception("Export to GML failed :\r"+exc.Message +"\rinner exception : "+exc.InnerException.Message );
}
finally
{
// System.Delegate[] hds = StatusChange.GetInvocationList();
// Console.WriteLine("delegatesA {0}",hds.Length);
// for(int i=0;i<hds.Length;i++)
// {
// this.StatusChange-=(StatusEventHandler)hds[i];
// }
// hds=null;
UnloadDynoDomain(validateOutput);
}
}
private void UnloadDynoDomain(bool validateOutput)
{
try
{
System.AppDomain.Unload(dynoDomain);
dynoDomain=null;
}
catch (System.Exception exc)
{
throw new Exception("Unloading dynamic domain failed :\r"+exc.Message);
}
if(validateOutput) ValidateGML();
}
/// <summary>
/// Validates the output GML file.
/// The necessary schemas should be accessible, or else.
/// </summary>
private void ValidateGML()
{
XmlTextReader tr = new XmlTextReader(this.targetfile);
XmlValidatingReader vr = new XmlValidatingReader(tr);
vr.ValidationType = ValidationType.Schema;
vr.Schemas.Add(getNS("gml"),"feature.xsd");
vr.ValidationEventHandler += new ValidationEventHandler (ValidationHandler);
while(vr.Read())
{
//TODO : do something with validation result;
}
}
/// <summary>
/// Method which handles the validation process.
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public static void ValidationHandler(object sender, ValidationEventArgs args)
{
Console.WriteLine("Severity:{0}\tMessage:{1}", args.Severity,args.Message);
}
/// <summary>
/// Creates new domain for dynamic assembly.
/// </summary>
/// <param name="filename">path to the assembly file.</param>
private void ProcessAssembly(string filename)
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(filename);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = fileInfo.DirectoryName;
setup.PrivateBinPath = AppDomain.CurrentDomain.BaseDirectory;
setup.ApplicationName = "Dynomain";
setup.ShadowCopyFiles = "true";
dynoDomain = AppDomain.CreateDomain("Dynomain", null, setup);
dynoAssName = fileInfo.Name.Replace(fileInfo.Extension, "");
}
/// <summary>
/// Load assembly to dynamic domain. Invoked by dynamic domain.
/// </summary>
public void LoaderCallBack()
{
AppDomain.CurrentDomain.Load(dynoAssName);
}
/// <summary>
/// A callback method invoked from dynamic domain that prepares the serialization data.
/// </summary>
public void SerializeCallBack()
{
//if this method invoked from current app domain, it will load it's dynamic assembly into
//the current app domain, and we won't be able to unload the dynamic assembly later.
System.Reflection.Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();
object[][] members = new object[this.Count][];
for(int i=0;i<ass.Length;i++)
{
if(ass[i].GetName().Name!="dyno") continue;
System.Type factoryType = ass[i].GetType("Dyno."+"DynoFactory");
object factory=factoryType.GetConstructor(System.Type.EmptyTypes).Invoke(null);
for(int j=0;j<this.Count;j++ )
{
this[j].customType=ass[i].GetType("Dyno."+this[j].Name);
MethodInfo mi = factoryType.GetMethod("Create"+this[j].Name+"Array");
int objcount = this[j].Fields[0].Count;
members[j]=(object[])( mi.Invoke(factory,new object[]{(int)objcount,this[j].Fields}) );
}
factoryType=null;
factory=null;
break;
}
this.SerializeGML(this.targetfile, members);
members=null;
}
/// <summary>
/// Serialize this MapDataCollection to GML.
/// </summary>
/// <param name="GMLFileString">path to GML file to create.</param>
/// <param name="members">Array of gml.FeatureAssociationType of each map, as feature members of the collection</param>
private void SerializeGML(string GMLFileString, object[][] members)
{
UpdateStatus("processing feature members...",70);
wfs.FeatureCollectionType features = new wfs.FeatureCollectionType(new gml.BoundingShapeType(this.GetBoundingBox()));
features.description=this.Description;
string xsfile = System.IO.Path.GetFileNameWithoutExtension(GMLFileString)+".xsd";
string xsloc = getNS("gc")+" "+xsfile+" " + getNS("wfs")+" WFS-basic.xsd";
features.schemaLocation = xsloc;
xsloc=null;
xsfile=null;
XmlAttributes xatts = new XmlAttributes();
XmlSerializerNamespaces nsnames = createSerializerNamespaces();
string targetNS=getNS("gc");
System.Type[] customTypes = new Type[this.getActiveCount()];
int ctc = -1;
for(int i=0;i<this.Count;i++)
{
if(!this[i].isActive) continue;
ctc++;
customTypes[ctc]=this[i].customType;
features.addMembers(this[i].Fields.CreateFeatureAssociations(members[i]));
xatts.XmlElements.Add(this[i].getElementAttribute(this[i].customType,ref nsnames,targetNS));
}
XmlAttributeOverrides xovs = new XmlAttributeOverrides();
xovs.Add(typeof(gml.FeatureAssociationType),"Item",xatts);
XmlRootAttribute xra = new XmlRootAttribute(); //because root element is wfs.featurecollection
xra.Namespace = getNS("wfs");
UpdateStatus("serializing to "+GMLFileString+"...",75);
System.IO.FileStream fs = new System.IO.FileStream( GMLFileString,System.IO.FileMode.Create);
XmlSerializer ser = new XmlSerializer( typeof(wfs.FeatureCollectionType), xovs, customTypes, xra, "");
ser.Serialize(fs,features,nsnames);
fs.Close();
UpdateStatus("Done exporting to "+GMLFileString+".",100);
for(int i=0;i<this.Count;i++) this[i].customType=null;
xatts=null;
xovs=null;
xra=null;
customTypes=null;
features=null;
targetNS=null;
nsnames=null;
ser=null;
}
/// <summary>
/// Creates namespaces for gml serialization.
/// </summary>
/// <returns>the namespaces needed for serializing this mapDataCollection to gml file.</returns>
private XmlSerializerNamespaces createSerializerNamespaces()
{
XmlSerializerNamespaces nsnames = new XmlSerializerNamespaces();
nsnames.Add("",getNS("gc"));
nsnames.Add("gml",getNS("gml"));
nsnames.Add("wfs",getNS("wfs"));
nsnames.Add("xs",getNS("xs"));
nsnames.Add("xsi",getNS("xsi"));
nsnames.Add("xlink",getNS("xlink"));
return nsnames;
//layer's specific nsnames added later
}
#endregion
#region svg stuff
private int totalcount = 0;
private int currentcount = 0;
/// <summary>
/// Exports MapDataCollection to plain SVG file.
/// </summary>
/// <param name="SVGFilename">path of the SVG file to create</param>
public void ExportSVG(string SVGFilename)
{
UpdateStatus("constructing svg objects...",0);
svg.svg rootSVG = new svg.svg();
rootSVG.setDimension("0","0","100%","100%");
rootSVG.Items=new svg.group[this.getActiveCount()];
gml.BoxType box = this.GetBoundingBox();
rootSVG.viewBox = CreateViewBoxString(box);
svg.group rootGroup = new svg.group();
rootGroup.transform = "matrix(1 0 0 -1 0 " + ((double)( box.Top+box.Bottom)).ToString()+ " )";
rootGroup.Items = new svg.group[this.getActiveCount()];
float l = (float)box.Left;
float b = (float)box.Bottom;
float r = (float)box.Right;
float t = (float)box.Top;
float diagonal = (float)Math.Sqrt((r-l)*(r-l)+(t-b)*(t-b));
totalcount = 0;
for(int i=0;i<this.Count;i++)
{
if(!this[i].isActive) continue;
totalcount+= this[i].Bins.GetTotalContentsCount();
}
int gcount=0;
for(int i=this.Count-1;i>=0;i-- )
{
if(!this[i].isActive) continue;
rootGroup.Items[gcount]=CreateSvgGroup(this[i],diagonal);
gcount++;
}
rootSVG.Items=new svg.SvgElement[2]{CreateSvgStyle(diagonal),rootGroup};
XmlSerializerNamespaces nsnames = new XmlSerializerNamespaces();
nsnames.Add("",getNS("svg"));
nsnames.Add("xlink",getNS("xlink"));
XmlRootAttribute xra = new XmlRootAttribute();
xra.Namespace = getNS("svg");
UpdateStatus("serializing to "+SVGFilename+"...",85);
XmlSerializer ser = new XmlSerializer( typeof(svg.svg), null, System.Type.EmptyTypes, xra, "");
System.IO.FileStream fs = new System.IO.FileStream( SVGFilename,System.IO.FileMode.Create);
ser.Serialize(fs,rootSVG,nsnames);
fs.Close();
UpdateStatus("Done.",100);
box=null;
nsnames=null;
xra=null;
rootGroup=null;
rootSVG=null;
ser=null;
}
/// <summary>
/// Creates CSS style element for the svg output.
/// </summary>
/// <param name="diagonal">diagonal of the svg bounding box</param>
/// <returns>SVG Style object</returns>
private svg.style CreateSvgStyle(float diagonal)
{
svg.style st = new svg.style();
System.Text.StringBuilder sb=new System.Text.StringBuilder();
for(int i=0;i<this.Count;i++)
{
if(!this[i].isActive) continue;
sb.Append(this[i].Bins.GetCSSText(this[i].Name,diagonal)+"\r");
}
st.Item=sb.ToString();
sb=null;
return st;
}
/// <summary>
/// Creates svg Group for a specified map in this collection
/// </summary>
/// <param name="map">map to be enclosed in the group</param>
/// <param name="diagonal">diagonal of the svg bounding box</param>
/// <returns>svg group for the specified map</returns>
private svg.group CreateSvgGroup(MapData map, double diagonal)
{
FieldCollection fields=map.Fields;
GeometryField fgeo = map.Fields.GetGeometryField();
svg.SvgElement[] elems=new svg.SvgElement[fgeo.Count];
for(int k=0;k<map.Bins.Count;k++ )
{
Bin bin = map.Bins[k];
//scale point radius for svg document
double pr = bin.Symbol.PointRadiusMap*diagonal/100;
foreach (int ci in bin.ContentsIndex)
{
currentcount+=1;
UpdateStatus("",80*currentcount/totalcount);
if(fgeo[ci]==fgeo.NullSymbol ) continue;
gml.GeometryPropertyType gpt =(gml.GeometryPropertyType)fgeo[ci];
if(gpt.Item==null) continue;
gpt.Item.PointRadius = pr;
elems[ci] = gpt.Item.createSvgObject();
elems[ci].id = map.Name+"_f"+ci.ToString();
elems[ci].@class = "style-"+map.Name.Replace("_","-")+"-"+k.ToString();
gpt=null;
}
bin=null;
}
svg.group g = new svg.group(elems);
g.id=map.Name;
fields=null;
fgeo=null;
elems=null;
return g;
}
/// <summary>
/// Creates value for viewBox attribute of root SVG.
/// </summary>
/// <param name="box">bounding box of the root svg</param>
/// <returns>attribute value for viewBox</returns>
private static string CreateViewBoxString(gml.BoxType box)
{
string str = box.Left.ToString() +" ";
str+= box.Bottom.ToString()+" ";
str+= (box.Right-box.Left).ToString()+" ";
str+= (box.Top-box.Bottom).ToString();
return str;
}
#endregion
#region utilities
/// <summary>
/// Occurs when there's noticable change in the export progress.
/// </summary>
// public event StatusEventHandler StatusChange;
// private StatusEventArgs StatusArgs = new StatusEventArgs("",0);
private void UpdateStatus(string message, int progressvalue)
{
// if(StatusChange==null) return;
// if(progressvalue>0 && progressvalue-StatusArgs.statusValue<5) return;
// StatusArgs.setCurrentStatus(message, progressvalue);
// StatusChange(this,StatusArgs);
//Console.WriteLine("{0} status:{1}% ",message,progressvalue);
// this.StatusMessage = message;
// this.StatusValue = progressvalue;
}
// private string statmsg="";
// public string StatusMessage
// {
// get{return statmsg;}
// set{statmsg=value;}
// }
// private int statval=0;
// public int StatusValue
// {
// get{return statval;}
// set{statval=value;}
// }
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -