C#打造一个开源webgis(四)地图客户端(中)

应用场景

做过开发的会遇到过这样一个情景:

1、写了很多代码做了一个系统;

2、后来又要做一个类似系统,也有了设计模式概念,就把第一个系统的代码抽调出来,封装成公用模块或类库,供第二个系统使用;

3、又有几个类似的系统要做,为了减少工作效率,提炼出自己的一个框架。

说起这个,就绕回到第一节提到过地图系统架构问题,在这里主要就是地图服务api的概念。可以想象一下,本来做的GIS系统只支持桌面方式,突然说要做出WebGiS,是不是要重新开发?没必要,我们只需做一个共有的地图服务接口供调用,无论是给桌面程序还是浏览器,都可以获得一致的效果,这也就是从B/S和C/S转向B/S/S和C/S/S概念,中间的S就是Application Server,我们把服务api部署在这里,基于此,我们又可以做一个DEMO。


DEMO

1、在此,借用一下WCF,创建控制台程序,构建解决方案如图,由于只是简单演示,具体细节先不做深究:
C#打造一个开源webgis(四)地图客户端(中)_第1张图片

IDomain.cs、DomainService.cs、clentaccesspolicy.xml是为了实现跨域,Site是数据库里的基站信息model,ISiteService和SiteService为模拟的地图查询服务,具体代码为:
IDomain.cs
  [ServiceContract]
    public interface IDomain
    {
        [OperationContract]
        [WebGet(UriTemplate = "ClientAccessPolicy.xml")]
        Message ProvidePolicyFile();
    }
ISiteService.cs
  [ServiceContract]
    public interface ISiteService
    {
        [OperationContract]
        List GetSites();
    }
Site.cs
  [DataContract]
    public class Site
    {
        [DataMember]
        public string GID { get; set; }

        [DataMember]
        public string SiteName { get; set; }

        [DataMember]
        public string Geom { get; set; }
    }

DomainService.cs
  public class DomainService : IDomain
    {
        public System.ServiceModel.Channels.Message ProvidePolicyFile()
        {
            MemoryStream ms = new MemoryStream();
            using (FileStream fs = File.OpenRead(@"clientaccesspolicy.xml"))
            {
                int length = (int)fs.Length;
                byte[] data = new byte[length];
                fs.Position = 0;
                fs.Read(data, 0, length);
                ms = new MemoryStream(data);
            }
            XmlReader reader = XmlReader.Create(ms);
            Message result = Message.CreateMessage(MessageVersion.None, "", reader);
            return result;
        }
    }

SiteService.cs
 public class SiteService:ISiteService
    {
        private DataSet ds = new DataSet();
        private DataTable dt = new DataTable();
        public List GetSites()
        {
            List source = new List();
            try
            {
                // PostgeSQL-style connection string        
                string connstring = String.Format("Server={0};Port={1};User Id={2};Password={3};Database={4};", "localhost", "5432", "postgres", "sa", "postgis20");
                // Making connection with Npgsql provider           
                NpgsqlConnection conn = new NpgsqlConnection(connstring);
                conn.Open();
                // quite complex sql statement                  
                // data adapter making request from our connection
                //string sql = "SELECT * from cellcover_region";
                string sql = "SELECT a.* FROM public.cellcover_region as a, site_font_point as b where b.gid=1 and ST_Within(b.geom,a.geom)";
                NpgsqlDataAdapter da = new NpgsqlDataAdapter(sql, conn);          
                ds.Reset();
                // filling DataSet with result from NpgsqlDataAdapter        
                da.Fill(ds);
                // since it C# DataSet can handle multiple tables, we will select first           
                dt = ds.Tables[0]; 
                int count = dt.Rows.Count;
                for (int i = 0; i < count; i++)
                {
                    DataRow dr = dt.Rows[i];
                    Site site = new Site
                    {
                        GID = dr[0].ToString(),
                        SiteName = dr[1].ToString(),
                        Geom = dr[2].ToString()
                    };
                    source.Add(site);
                }
                conn.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return source;
        }
    }

Program.cs
  static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(SiteService));
            ServiceHost crossDomainserviceHost = new ServiceHost(typeof(DomainService));
            host.Opened += delegate
            {
                Console.WriteLine("服务已经启动,按任意键终止...");
            };

            crossDomainserviceHost.Opened += delegate
            {
                Console.WriteLine("跨域服务已经启动,按任意键终止...");
            };
            crossDomainserviceHost.Open();
            host.Open();
            Console.ReadKey();
            host.Close();
            host.Abort();
            crossDomainserviceHost.Close();
            crossDomainserviceHost.Abort();
        }

编译运行,效果如图,表示服务正常启动:
C#打造一个开源webgis(四)地图客户端(中)_第2张图片

下面两点在后续节中再做详细补充:
2、把上节做的silverlight客户端,添加该WCF服务,在交互过程中(如点击图元)调用服务方法,完成数据展现
3、wpf做地图客户端,添加该WCF服务,在交互过程中调用服务,完成地图展现

你可能感兴趣的:(GIS,C#)