採用三層式 WCF 架構:
IGetData,含圖片路徑、圖層樣式 XML、地圖資料源等操作。MsSqlProvider),回傳序列化後的資料集 (DataSet) 或位元組陣列。ServiceHost,透過 basicHttpBinding 發佈端點。[ServiceContract]
public interface IGetData {
[OperationContract] string GetPICAddress();
[OperationContract] byte[] GetVStyleAddress(string DataBase, ref int VLayerCount);
[OperationContract] byte[] GetLStyleAddress(string DataBase, ref int LLayerCount);
[OperationContract] byte[] ReadXML(string DataBase, string XMLName);
[OperationContract] byte[] MapDataBase(string address);
[OperationContract] byte[] GetMapDataSource(GetVDataSource VDataSource); // 取得 Provider 實體
}
public class GetData : IGetData {
Create create = new Create(); // 封裝資料存取邏輯
public string GetPICAddress() => "https://www.cnblogs.com/Config/Style/pic/";
public byte[] GetVStyleAddress(string DataBase, ref int VLayerCount) {
return Compression.SerializeData(create.GetLayers("https://.../Style/" + DataBase + "/VectorLayerXML.xml", ref VLayerCount));
}
// ... 其他方法類似,均回傳壓縮序列化後的 byte[]
public byte[] GetMapDataSource(GetVDataSource VDataSource) {
// 動態建立 Provider 並序列化傳遞 (注意:Provider 需標記 [Serializable] 或使用 DTO)
IProvider data = new MsSql(VDataSource.ConnStr, VDataSource.TableName, VDataSource.GeometryColumnName, VDataSource.OID_ColumnName);
return Compression.SerializeData(data);
}
}
static void Main(string[] args) {
using (ServiceHost host = new ServiceHost(typeof(GetData))) {
host.Opened += delegate { Console.WriteLine("Service listening at: " + host.BaseAddresses[0]); };
host.Open();
Console.Read();
}
}
<system.serviceModel>
<services>
<service name="SharpMap.WCFService.Service.GetData" behaviorConfiguration="GetDataBehavior">
<host>
<baseAddresses><add baseAddress="https://127.0.0.1:8888/GetData" /></baseAddresses>
</host>
<endpoint address="" binding="basicHttpBinding" contract="SharpMap.WCFService.Contract.IGetData" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="GetDataBehavior"><serviceMetadata httpGetEnabled="true" /></behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
public class WCFClient : ClientBase<IGetData>, IGetData {
// 透明轉發 Channel 呼叫
public string GetPICAddress() => Channel.GetPICAddress();
public byte[] GetVStyleAddress(string DataBase, ref int VLayerCount) => Channel.GetVStyleAddress(DataBase, ref VLayerCount);
// ...
// 反序列化輔助方法
public DataSet GetVStyle(string DataBase, ref int VLayerCount) {
return (DataSet)Compression.DeserializeData(GetVStyleAddress(DataBase, ref VLayerCount));
}
// ...
}
<system.serviceModel>
<client>
<endpoint address="https://127.0.0.1:8888/GetData" binding="basicHttpBinding" contract="SharpMap.WCFService.Contract.IGetData" />
</client>
</system.serviceModel>
Compression.SerializeData/DeserializeData 減少網路傳輸量 (地圖資料通常龐大)。IProvider 實例直接序列化傳給客戶端,需注意 MsSqlProvider 等類別需支援序列化 (標記 [Serializable] 或實作 ISerializable),且連線字串安全性需考量。此方案將 SharpMap 資料存取邏輯移至伺服器端,客戶端僅透過 WCF 取得渲染所需資料 (樣式、幾何)、圖片資源,適合 B/S 架構 GIS 應用。後續可優化:改用 netTcpBinding 提升效能、引入資料分頁/空間索引查詢、加強序列化安全性。