zoukankan      html  css  js  c++  java
  • 使用wcf编写坐标字符串生成shapefile文件,在iis发布供前端调用

    项目有一需求,需要由坐标字符串(格式:x,y,点名)生成shapefile,由于在前台开发类似功能比较麻烦而且也不适用,最终决定使用WCF来实现,不借助现有GIS软件,基于GDAL实现。

    实现过程如下:

    编写坐标对生成shapefile的坐标,并使用zipHelper将shapefile压缩成zip文件,返回前端下载,整个代码如下:

    (1)编写坐标转换服务代码

        [Description("坐标服务接口")]
        [ServiceContract]
        public interface ICoord2Shapefile
        {
            //[WebGet(UriTemplate = "{points}", ResponseFormat = WebMessageFormat.Json)]
            [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json,UriTemplate="/")]
            [Description("将坐标生成shapefile,并压缩打包")]
            [OperationContract]
            
            string point2zip(string points);
    
        }
    
        [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
        [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
        public class Coord2ShapefileService : ICoord2Shapefile
        {
            public string point2zip(string points)
            {
                LogHelper.Info(points);
                string zip = "";
                //List<Location> locs = JsonHelper.DeserializeJsonToList<Location>(points);
    
                try
                {
                    List<Location> locs = new List<Location>();
                    string[] pps = points.Split(';');
                    for (int i = 0; i < pps.Length; i++)
                    {
                        string[] pp = pps[i].Split(',');
                        double x = Convert.ToDouble(pp[0]);
                        double y = Convert.ToDouble(pp[1]);
                        Location loc = new Location() { X = x, Y = y, Name = pp[2] };
                        locs.Add(loc);
                    }
    
                    if (locs != null && locs.Count > 0)
                    {
                        LogHelper.Info(string.Format("{0} 个点",locs.Count));
    
                        string shpfile = Path.GetTempFileName();
                        shpfile = shpfile.Substring(0, shpfile.Length - 3) + "shp";
    
                        LogHelper.Info(shpfile);
    
                        //shpfile = "e:\aa.shp";
    
                        WriteVectorFileShp(shpfile, locs);
    
                        if (File.Exists(shpfile))
                        {
                            FileInfo fileinfo = new FileInfo(shpfile);
                            DirectoryInfo dirInfo = fileinfo.Directory;
    
                            string shpName = Path.GetFileNameWithoutExtension(shpfile);
    
                            List<string> files = new List<string>();
                            files.Add(shpfile);
                            files.Add(Path.Combine(dirInfo.FullName, shpName + ".prj"));
                            files.Add(Path.Combine(dirInfo.FullName, shpName + ".dbf"));
                            files.Add(Path.Combine(dirInfo.FullName, shpName + ".shx"));
    
                            //string zipFile = "d:\point.zip";
                            string id = Guid.NewGuid().ToString();
                            string zipFile = string.Format("d:\update\temp\{0}{1}{2}{3}{4}{5}{6}.zip", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
                            //string zipFile = string.Format("d:\{0}{1}{2}{3}{4}{5}{6}.zip", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond);
                            //string zipFile = "www.simplemap.com.cn/update/temp";
                            int ret = ZipHelper.ZipFiles(zipFile, files.ToArray(), "data");
                            if (ret > 0)
                            {
                                foreach (var file in files)
                                {
                                    try
                                    {
                                        File.Delete(file);
                                    }
                                    catch (Exception)
                                    {
                                    }
                                }
                                if (File.Exists(zipFile))
                                {
                                    FileInfo ff = new FileInfo(zipFile);zip = "http://localhost/temp" + ff.Name;
                                }
                            }
                        }
                        else
                        {
                            LogHelper.Info(string.Format("{0} 不存在!", shpfile));
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error(ex.Message, ex);
                }
    
                return zip;
            }
    
            static void WriteVectorFileShp(String shapefile_path, List<Location> locs)  //创建算法生产的边界矢量图
            {
                // 为了支持中文路径,请添加下面这句代码
                OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
                // 为了使属性表字段支持中文,请添加下面这句
                OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "");
                // 注册所有的驱动
                Ogr.RegisterAll();
    
                LogHelper.Info("注册GDAL成功");
                //创建数据,创建ESRI的shp文件
                string strDriverName = "ESRI Shapefile";
                Driver oDriver = Ogr.GetDriverByName(strDriverName);
                if (oDriver == null)
                {
                    Debug.WriteLine("%s 驱动不可用!
    ", shapefile_path);
                    return;
                }
    
                // 步骤1、创建数据源
                DataSource oDS = oDriver.CreateDataSource(shapefile_path, null);
                if (oDS == null)
                {
                    Debug.WriteLine("创建矢量文件【%s】失败!", shapefile_path);
                    return;
                }
                LogHelper.Info("创建矢量文件成功");
                //步骤2、创建空间坐标系
                OSGeo.OSR.SpatialReference oSRS = new OSGeo.OSR.SpatialReference("");
                oSRS.SetWellKnownGeogCS("WGS84");
                //步骤3、创建图层,并添加坐标系,创建一个多边形图层(wkbGeometryType.wkbUnknown,存放任意几何特征)
                Layer oLayer = oDS.CreateLayer("地名", oSRS, wkbGeometryType.wkbPoint, null);
                if (oLayer == null)
                {
                    Debug.WriteLine("图层创建失败!");
                    return;
                }
    
                // 步骤4、下面创建属性表
                FieldDefn oFieldPlotArea = new FieldDefn("Name", FieldType.OFTString);          // 先创建一个叫PlotArea的属性
                oFieldPlotArea.SetWidth(100);
                // 步骤5、将创建的属性表添加到图层中
                oLayer.CreateField(oFieldPlotArea, 1);
                //步骤6、定义一个特征要素oFeature(特征要素包含两个方面1.属性特征2.几何特征)
                foreach (var loc in locs)
                {
                    FeatureDefn oDefn = oLayer.GetLayerDefn();
                    Feature oFeature = new Feature(oDefn);    //建立了一个特征要素并将指向图层oLayer的属性表
                    //步骤7、设置属性特征的值
                    oFeature.SetField(0, loc.Name);
                    OSGeo.OGR.Geometry pt = new Geometry(wkbGeometryType.wkbPoint);
                    pt.AddPoint(loc.X, loc.Y, 0);
                    oFeature.SetGeometry(pt);
                    //OSGeo.OGR.Geometry geomTriangle = OSGeo.OGR.Geometry.CreateFromWkt(wkt);//创建一个几何特征
                    //步骤8、设置几何特征
                    //oFeature.SetGeometry(geomTriangle);
                    //步骤9、将特征要素添加到图层中
                    oLayer.CreateFeature(oFeature);
                }
                oDS.Dispose();
                LogHelper.Info("数据集创建完成!");
                //Debug.WriteLine("数据集创建完成!");
            }
    
        }
    
        public class Location
        {
            public double X { get; set; }
            public double Y { get; set; }
            public string Name { get; set; }
        }

    (2)由于GDAL只能在x86下使用,将目标平台编译成x86。

    (3)创建一个空网站,添加Service.svc服务文件,内容如下:

    <%@ ServiceHost Language="C#" Debug="true" Service="CoordService.Coord2ShapefileService" %>

    (4)设置web.config的配置文件

    <configuration>
      <configSections>
        <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/>
      </configSections>
      <log4net>
        <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
          <file type="log4net.Util.PatternString" value="%logger\%date{yyyy-MM-dd}log.txt"/>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date %-5level %message%newline"/>
          </layout>
        </appender>
        <root>
          <appender-ref ref="LogFileAppender"/>
        </root>
        <logger name="Logger" additivity="false">
          <level value="All"/>
          <appender-ref ref="LogFileAppender"/>
        </logger>
      </log4net>
    
      <system.web>
          <compilation debug="true" targetFramework="4.0" />
        </system.web>
    
      <system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
          multipleSiteBindingsEnabled="true">
        </serviceHostingEnvironment>
        <services>
          <!--behaviorConfiguration属性开通服务的元数据发布服务,无此属性,服务的元数据发布无法使用,但服务中的功能可以调用-->
          <service name="CoordService.Coord2ShapefileService" behaviorConfiguration="metadataExchange">
            <!--终结点不加behaviorConfiguration属性,无法调用服务中的功能,会出现“由于 AddressFilter 在 EndpointDispatcher 不匹配”的错误-->
            <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBinding_Default" contract="CoordService.ICoord2Shapefile" behaviorConfiguration="webHttp"/>
          </service>
        </services>
        <bindings>
          <webHttpBinding>
            <binding name="webHttpBinding_Default" maxReceivedMessageSize="2147483647" />
          </webHttpBinding>
        </bindings>
        <behaviors>
          <!--开通服务的元数据发布-->
          <serviceBehaviors>
            <behavior name="metadataExchange">
              <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
          <endpointBehaviors>
            <behavior name="webHttp">
              <webHttp helpEnabled="True"/>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    View Code

    (5)创建IIS宿主服务

           a.创建应用程序池,目标平台.net4.0,应用32位应用程序=True,这个很重要,因为服务是32位的。

           b.在默认网站下,添加应用程序目标,指向网站目录。

    (6)测试

           a.由于坐标字符串生成shapefile文件时,前台给生成传入的字符串比较多,只能使用POST请求,而且还需要在配置文件中添加如下配置信息:

          <webHttpBinding>
            <binding name="webHttpBinding_Default" maxReceivedMessageSize="2147483647" />
          </webHttpBinding>

            b.使用fiddler测试,选择Composer页,见下图:

  • 相关阅读:
    set
    皮肤病药物
    C 批量保存图片进 mysql 利用MYSQL_BIND插入longblob
    eclipse行号显示
    dynamic_cast使用
    list添加删除操作
    VS2008 对齐代码
    c++ mysql二进制存取,blob存取
    Select Window关键字——模拟打开了多个页面窗口时,在不同的窗口之间,进行窗口切换
    Click Image关键字——模拟单击某一个图片 其余:Click Button / Click Link
  • 原文地址:https://www.cnblogs.com/SimpleGIS/p/6796287.html
Copyright © 2011-2022 走看看