0
点赞
收藏
分享

微信扫一扫

Arcgis10.2+pgsql14开发(非SDE版本)

起因:最初采用SDE和pgsql11开发,后因数据库升级到pgsql14,sde因和pgsql版本不般配,无法导入要素数据和显示数据,数据库升级又是必然,所以只能另外找解决方案。

参考资料:Spatial Database for Postgres and ArcGis users: how to choose

附加:zigGis, GDAL。传说中的zigGis相当牛,能直接将postgis中的GIS类型显示到ArcGis的控件中,但是版本又比较复杂,也有可能会设计到版本不般配问题,后期我再看看这方面的知识体系。

Pgsql+postgis使用:PostgreSQL+PostGIS的使用(转载) - 无痕客 - 博客园

PostGIS教程一:PostGIS介绍 - 知乎

实现步骤:

在postgis中提供很多函数将wkb转成它的geometry类型,同样也有将geometry转成binary的函数。当然更兴奋的是ArcGis中有针对标准wkb的转换,这样一来,可想而知,这个方案是行的通的。

第一步:从postgreSQL中通过postgis读取GIS数据显示在AxMapControl中

1. C# 连接数据库pg

注意点: 要注意的是因为ArcEngine中对wkb的支持是byte[]之间的转换,所以在进行数据库取数据时用postgis的这个函数将GIS数据转成byte[],这样写 asbinary(the_geom)

2. 将得到的byte[](也就是wkb数据)通过ArcEngine的接口得到IGeometry,如下所示:

 IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
 factory.CreateGeometryFromWkbVariant(wkb, out geom, out countin);

3. 将 IGeometry 显示在AxMapControl中。

第二步:将上一步从pg中显示出来的GIS数据进行相应的修改后保存回pg中

1. 修改指定的要素后通过 geometry得到wkb

要对修改操作进行保存,就需要将指定的要素中的geometry再次转回wkb然后通过sql语句修改pg中的指定记录即可,思路很简单,问题在于拼接SQL字符串上面,因为arcengine通过geometry得到的仍然是一个byte[],这个东西是没办法拼到sql语句中的。

2. 用到的ArcEngine接口如下:

IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
byte[] geoBytes = factory.CreateWkbVariantFromGeometry(geometry) as byte[];

3. 拼接SQL时要将上面的byte[]数组转码

    其实postgis处理存到pg中的是一长串的16进制字符串,相信大家打开数据库能看到,要想拼接好SQL串就得这样来一下:geomfromwkb(decode('" + geoByteStr + "', 'hex'))其中的geoByteStr是byte[]转成16进制的字串

上面两步已走通,是完全可以实现的,这样做的话,数据表我们也能自行定义,操作GIS数据,属性等,更灵活。

资料

读取pgsql数据库

namespace WHUGIS.Classes
{
    class DAO
    {

        private static string connectionString = "User ID=postgres;Password=admin;Server=localhost;Port=5432;Database=GIS_engine;";
        public DAO()
        {

        }
        public static Byte[] executeRouteQuery(string sqlstr)
        {
            NpgsqlConnection sqlConn = new NpgsqlConnection(connectionString);
            try
            {
                sqlConn.Open();
                NpgsqlCommand objCommand = new NpgsqlCommand(sqlstr, sqlConn);
                Byte[] routeWKB = (byte[])objCommand.ExecuteScalar();
                return routeWKB;
            }
            catch(Exception ee)
            {
                MessageBox.Show(ee.Message);
                return null;
            }
            finally
            {
                sqlConn.Close();
            }
            
        }

    }
}

ArcgisEngine Igeometry和WKB转换

using System;
using System.Collections.Generic;
using System.Text;
using GisSharpBlog.NetTopologySuite.IO;
using ESRI.ArcGIS.Geometry;

namespace Utils
{
    /// <summary>
    /// This class is used to convert a GeoAPI Geometry to ESRI and vice-versa.
    /// It can also convert a ESRI Geometry to WKB/WKT and vice-versa.
    /// </summary>
    public static class Converters
    {

        public static byte[] ConvertGeometryToWKB(IGeometry geometry)
        {
            IWkb wkb = geometry as IWkb;
            ITopologicalOperator oper = geometry as ITopologicalOperator;
            oper.Simplify();

            IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
            byte[] b = factory.CreateWkbVariantFromGeometry(geometry) as byte[];
            return b;
        }


        public static byte[] ConvertWKTToWKB(string wkt)
        {
            WKBWriter writer = new WKBWriter();
            WKTReader reader = new WKTReader();
            return writer.Write(reader.Read(wkt));
        }

        public static string ConvertWKBToWKT(byte[] wkb)
        {
            WKTWriter writer = new WKTWriter();
            WKBReader reader = new WKBReader();
            return writer.Write(reader.Read(wkb));
        }

        public static string ConvertGeometryToWKT(IGeometry geometry)
        {
            byte[] b = ConvertGeometryToWKB(geometry);
            WKBReader reader = new WKBReader();
            GeoAPI.Geometries.IGeometry g = reader.Read(b);
            WKTWriter writer = new WKTWriter();
            return writer.Write(g);
        }

        public static IGeometry ConvertWKTToGeometry(string wkt)
        {
            byte[] wkb = ConvertWKTToWKB(wkt);
            return ConvertWKBToGeometry(wkb);
        }

        public static IGeometry ConvertWKBToGeometry(byte[] wkb)
        {
            IGeometry geom;
            int countin = wkb.GetLength(0);
            IGeometryFactory3 factory = new GeometryEnvironment() as IGeometryFactory3;
            factory.CreateGeometryFromWkbVariant(wkb, out geom, out countin);
            return geom;
        }


        public static IGeometry ConvertGeoAPIToESRI(GeoAPI.Geometries.IGeometry geometry)
        {
            WKBWriter writer = new WKBWriter();
            byte[] bytes = writer.Write(geometry);
            return ConvertWKBToGeometry(bytes);
        }

        public static GeoAPI.Geometries.IGeometry ConvertESRIToGeoAPI(IGeometry geometry)
        {
            byte[] wkb = ConvertGeometryToWKB(geometry);
            WKBReader reader = new WKBReader();
            return reader.Read(wkb);
        }
    }
}
举报

相关推荐

0 条评论