问题点
1、arcgis 通过 sde 服务连接数据库服务器,数据库服务器在 局域网 ip固定。
2、当更换 数据库ip后 ,通过 sde 无法链接到数据库
3、考虑用程序修正 mxd 文件 图层 datasource ,或者 让 datasource 为 localhost
代码参照如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OracleClient;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Controls;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml;
namespace mxdRepair
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//从数据库获得二进制mxd字段文件,即arcgis工程文件
private void button1_Click(object sender, EventArgs e)
{
OracleConnection connection;
string connectionString = "Data source =csdj;User ID=hebei;Password=hebei";
using (connection = new System.Data.OracleClient.OracleConnection(connectionString))
{
try
{
connection.Open();
OracleCommand cmd = connection.CreateCommand();
string sql = "select wdbh ,wj from dj_slwd_test";
cmd.CommandText = sql;
OracleDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
OracleLob tempLob = dr.GetOracleLob(1);
System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath + "\\mxdFile\\" + dr["wdbh"].ToString() + ".mxd", FileMode.Create);
int length = 1048576;
byte[] Buffer = new byte[length];
int i;
while ((i = tempLob.Read(Buffer, 0, length)) > 0)
{
fs.Write(Buffer,0,i);
}
fs.Close();
tempLob.Clone();
}
dr.Close();
cmd.Parameters.Clear();
}
catch(Exception ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
}
// 更换 sde datasource
private void button2_Click(object sender, EventArgs e)
{
//-----------------------20190326 modify by grj start
//修正原因:原入库程序保存mxd工程文件到数据库,其中工程文件打开后图层属性数据源为sde oracle
// 数据库,属性中server 项目 被写死成固定的ip ,当数据库服务器更换ip地址后,打开工程文件图层丢失
// 弥补工程文件打开sde服务器ip地址写死的问题,做了以下修正
//1、打开数据库保存的工程文件
//2、更换工程文件中sde数据源,即变更后的数据库服务器ip
//3、保存工程文件
//-----------------------
try
{
// license 初始化
IAoInitialize m_aoinitialize = new AoInitializeClass();
m_aoinitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
DirectoryInfo folder = new DirectoryInfo(Application.StartupPath + "\\mxdFile\\");
foreach (FileInfo file in folder.GetFiles("*.mxd"))
{
label4.Text = file.FullName+" 转换中......";
//获取MapDocument
IMapDocument pMapDocument = new MapDocumentClass();
pMapDocument.Open(file.FullName, "");
//创建一个MapControl
IMapControl2 pMapControl = new MapControlClass();
string sFileName = file.FullName;
pMapControl.LoadMxFile(sFileName, null, null);
//创建一个工作空间
IWorkspaceFactory pWorkFactory = new SdeWorkspaceFactoryClass();
IPropertySet pPropertySet = new PropertySetClass();
//获取链接数据库配置
string strSdeConfigFile = Application.StartupPath + "\\CheckStandard\\SdeServerConfig.xml";
XmlDocument doc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create(strSdeConfigFile, settings);
doc.Load(reader);
XmlDocument xmlDoc = doc;
if (xmlDoc == null)
{
MessageBox.Show("链接数据未找到");
}
XmlElement xmlEle = xmlDoc.DocumentElement;
if (xmlEle != null)
{
foreach (XmlNode node in xmlEle.ChildNodes)
{
pPropertySet.SetProperty(node.Name, node.InnerText);
}
}
IWorkspace pWorkspace = pWorkFactory.Open(pPropertySet, 0);
//获取工作空间的全部的dataset
IEnumDataset pEnumDataSet = pWorkspace.get_Datasets(esriDatasetType.esriDTFeatureDataset);
IDataset pDataSet = pEnumDataSet.Next();
ISpatialReference pRef = (pDataSet as IGeoDataset).SpatialReference;
string sDistrictCode = string.Empty;
string sScale = string.Empty;
if (pDataSet != null)
{
UID uid = new UIDClass();
uid.Value = "{" + typeof(IFeatureLayer).GUID.ToString() + "}";
IEnumLayer pEnumLayer = pMapControl.Map.get_Layers(uid, true);
IFeatureLayer pFealyr = pEnumLayer.Next() as IFeatureLayer;
IFeatureWorkspace pFeaClsWks = pWorkspace as IFeatureWorkspace;
while (pFealyr != null)
{
string sDsName = ((pFealyr as IDataLayer).DataSourceName as IDatasetName).Name;
if ((pWorkspace as IWorkspace2).get_NameExists(esriDatasetType.esriDTFeatureClass, sDsName))
{
pFealyr.FeatureClass = pFeaClsWks.OpenFeatureClass(sDsName);
pFealyr.Name = pFealyr.Name;
}
pFealyr = pEnumLayer.Next() as IFeatureLayer;
}
pMapControl.Map.SpatialReference = pRef;
IMxdContents pMxdC;
pMxdC = pMapControl.Map as IMxdContents;
pMapDocument.Open((pMapControl as IMapControl3).DocumentFilename, "");
pMapDocument.ReplaceContents(pMxdC);
pMapDocument.Save(true, true);
//释放资源 防止出现 0x80040228 出现资源锁定错误
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(pWorkspace);
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(pFeaClsWks);
ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(pWorkFactory);
if (pMapDocument != null)
{
pMapDocument.Close();
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
MessageBox.Show("文件夹mxd文档数据源转换完毕!");
}
// 更新数据库 blob 字段 mxd文件
private void button3_Click(object sender, EventArgs e)
{
string connectionString = "Data source =csdj;User ID=hebei;Password=hebei";
DirectoryInfo folder = new DirectoryInfo(Application.StartupPath + "\\mxdFile\\");
OracleConnection conn = new OracleConnection(connectionString);
conn.Open();
foreach (FileInfo file in folder.GetFiles("*.mxd"))
{
string Commstr = "update dj_slwd set wj =:blobMxd, remark = 'by tool update 20190328' where wdbh ='" + file.Name.Replace(".mxd","") + "'";
OracleCommand cmd = new OracleCommand(Commstr, conn);
System.IO.FileStream fs = new System.IO.FileStream(file.FullName, FileMode.Open, FileAccess.Read);
Byte[] blob = new Byte[fs.Length];
fs.Read(blob, 0, blob.Length);
fs.Close();
OracleParameter param = new OracleParameter("blobMxd", OracleType.Blob);
param.Value = blob;
//OracleParameter param = new OracleParameter("blobMxd", OracleType.Blob, blob.Length, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, blob);
cmd.Parameters.Add(param);
try
{
//OracleTransaction transaction = cmd.Connection.BeginTransaction();
//cmd.Transaction = transaction;
cmd.ExecuteNonQuery();
//transaction.Commit();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
//throw new Exception();
}
}
conn.Close();
conn.Dispose();
MessageBox.Show("数据库mxd文件更新完毕!");
}
}
}