MapGuide应用开发系列(六)---- MapGuide Studio中Load Procedures分析
使用MapGuide Studio为MapGuide准备地理资源数据,我们可以使用Load Procedures,也可以使用FDO connection。今天我们先介绍一下Load Procedures。MapGuide Studio中的加载过程Load Procedure是拥有文件型GIS数据的,比如SDF、SHP、DWG、DWF等等。它其实是把上述几种GIS地图格式首先进行必要的格式转换,然后打包成mgp文件,然后Load到MapGuide站点服务器的过程。
使用MapGuide Studio为MapGuide准备地理资源数据,我们可以使用Load Procedures,也可以使用FDO connection。今天我们先介绍一下Load Procedures。MapGuide Studio中的加载过程Load Procedure是拥有文件型GIS数据的,比如SDF、SHP、DWG、DWF等等。它其实是把上述几种GIS地图格式首先进行必要的格式转换,然后打包成mgp文件(关于mgp请参考MapGuide应用开发系列(三)—-MapGuide 数据包管理及Maestro亮点功能介绍),然后Load到MapGuide站点服务器的过程。
SHP、SDF等数据在通过Load Procedure加载到MapGuide站点服务器后,由MapGuide服务器管理,称为Managed Resource,对应的文件存储到MapGuide Server内,缺省位置是C:\Program Files\OSGeo\MapGuide\Server\Repositories\Library\
如果你仔细看一下,你就会发现原先的shp文件已经被转换成了sdf文件。那么Load Procedure的内部机理到底是怎么样的么?我们可以用reflector分析一下他的主要的几个assembly :Autodesk.MapGuide.Studio.Load.dll 和 Autodesk.MapGuide.Studio.Site.dll。
代码比语言更有说服力,还是看看代码吧。下面是我以前分析的一部分反编译的代码:
LoadProcedure的Execute方法:
////通过siteConnection直接上传到指定的mapGuide Server
public void Execute(SiteConnection connection)
{
if (connection == null)
{
throw new NullReferenceException();
}
FileInfo info = null;
Stream stream = null;
try
{
info = new FileInfo(Path.GetTempFileName()); //生成一个临时的mpg文件
this.Execute(info.FullName, connection); ///调用生成mpg文件,然后上传到mapguide server
stream = info.OpenRead();
connection.ApplyPackage(stream);
}
finally
{
if (stream != null)
{
stream.Close();
}
if ((info != null) && info.Exists)
{
info.Delete();
}
}
}
//////真正上传的过程
public virtual void Execute(string packageFilePath, SiteConnection connection)
{
PackageWriter package = null;
this.usedBaseNames.Clear();
try
{
string str = string.Format(“Created by {0}.Execute().”, base.GetType().Name);
package = new PackageWriter(packageFilePath, str);
if (this.SourceFiles.Count > 0)
{
foreach (string str2 in this.sourceFiles)
{
FileInfo info = new FileInfo(str2);
if (!info.Exists)
{
throw new FileNotFoundException(null, str2);
}
}
this.ResourceIds.Clear();
foreach (string str3 in this.sourceFiles)
{
this.ProcessSourceFile(package, str3, connection); //真正上传的过程
}
}
}
finally
{
if (package != null)
{
package.Close();
}
}
}
在基类LoadProcedure中的ProcessSourceFile是一个抽象方法,具体实现在他的派生子类中定义
protected abstract void ProcessSourceFile(PackageWriter package, string filePath, SiteConnection connection);
下面看一个加载sdf的procedure ----SdfLoadProcedure的ProcessSourceFile
protected override void ProcessSourceFile(PackageWriter package, string filePath, SiteConnection connection)
{
///…………这里省略的部分代码
///…………………………………………………….
bool flag = GetSdfVersion(destFileName) < 3;
///…………这里省略的部分代码
///…………………………………………………….
if (flag) //如果sdf文件的版本不是sdf3,则把它转换成sdf3格式
{
string dst = Path.Combine(path, “converted_” + Path.GetFileName(destFileName));
if (this.SdfKeyTreatment == SdfKeyTreatment.AutogenerateAll)
{
SdfConverter.Convert(destFileName, dst, wkt, false);
}
else
{
SdfConverter.Convert(destFileName, dst, wkt, true, this.SdfKeyTreatment == SdfKeyTreatment.MergeDuplicates);
}
destFileName = dst;
}
////////////////////////////////////
/// 后面就是上传过程了,
///
// Stream stream = FeatureSource.CreateDocumentForSDF(Path.GetFileName(destFileName), connection, extensions);
// package.AddSdfFeatureSource(str12, stream, null, destFileName);
if (base.ShouldCreateLayer(connection, layerFullName)) //如果要同时创建图层的话
{
MdfVersion version = null;
if ((connection != null) && base.IsConnectedToPre2008Server(connection))
{
int nMajorNumber = 1;
int nMinorNumber = 0;
int nRevisionNumber = 0;
version = new MdfVersion(nMajorNumber, nMinorNumber, nRevisionNumber);
}
//创建图层的featureSouce
base.CreateFeatureSourceLayer(package, resourceId, schemaFilePath, layerFullName, version);
}
}
finally
{
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
}
}
//////////////////////////////////////
/// 下面是sdf版本转换类的方法列表
public class SdfConverter
{
// Methods
public SdfConverter();
public static void Convert(string src, string dst, string wkt, [MarshalAs(UnmanagedType.U1)] bool useKey);
public static void Convert(string src, string dst, string wkt, [MarshalAs(UnmanagedType.U1)] bool useKey, [MarshalAs(UnmanagedType.U1)] bool mergeDuplicates);
public static int GetSdfFileBounds(string path, ref double xMin, ref double yMin, ref double xMax, ref double yMax);
public static int GetSdfFileVersion(string path);
}
就是这样,大概的一个MapGuide Studio的加载过程。