Microsoft SQL Geometryはそんなに優秀なのか? – 3 –



前回までの続き

3回通しての結論としてかなり使える。
特にArcObjectsのカーソルはトレースとれば分かるが、データ取得で速度が出ない。
下記結果の通り普通に使う場面ではSQL Serverが速いパターンが多い。

環境変わってSQL Serverは2012に
ArcGIS10.1 にSDE 10.1 SQL Server2012

結果はSQL Server圧勝
2501.8764 ミリ秒@ArcObjects
3018.3834 ミリ秒@ArcObjects

967.1224 ミリ秒@SQL Server
951.1214 ミリ秒@SQL Server

1902件のテーブルA(面)をテーブルB 49件件(面)で抜き出す(67件)試験
物理テーブルとしては同一。

ArcSDE管理下でも双方の手法が選べるのがよいところ?
10.2のSQLite実装にも期待?

テーブルBをユニオンして、重なるものを取得する。
SQLクエリで表現するとシンプルなのも得点が高い。

ArcGIS側コード

using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

using (ComReleaser com = new ComReleaser())
    {

        IPropertySet propSet = new PropertySetClass();
        com.ManageLifetime(propSet);

        propSet.SetProperty("SERVER", null);
        propSet.SetProperty("INSTANCE", "sde:sqlserver:localhost");
        propSet.SetProperty("DATABASE", "データベース名");
        propSet.SetProperty("USER", "gis");
        propSet.SetProperty("PASSWORD", "パスワード");
        propSet.SetProperty("VERSION", "dbo.DEFAULT");

        Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory");
        IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
        com.ManageLifetime(workspaceFactory);

        IWorkspace workspace = workspaceFactory.Open(propSet, 0);
        com.ManageLifetime(workspace);

        IFeatureWorkspace fw = (IFeatureWorkspace)workspace;
        IFeatureClass fc = fw.OpenFeatureClass("テーブルB");
        com.ManageLifetime(fc);

        IFeatureCursor cursor = fc.Search(null, true);
        com.ManageLifetime(cursor);
        IFeature feature = null;

        IGeometry geom = null;

        while ((feature = cursor.NextFeature()) != null)
        {
            if (geom == null)
            {
                geom = feature.Shape;
            }
            else
            {
                geom = ((ITopologicalOperator)feature.Shape).Union(geom);
            }
        }//end loop

        ISpatialFilter spFilter = new SpatialFilterClass();
        com.ManageLifetime(spFilter);

        IFeatureClass fc2 = fw.OpenFeatureClass("テーブルA");

        spFilter.Geometry = geom;
        spFilter.AddField(fc2.OIDFieldName);
        spFilter.GeometryField = fc2.ShapeFieldName;

        spFilter.SearchOrder = esriSearchOrder.esriSearchOrderSpatial;
        spFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;

        IFeatureCursor curosr2 = fc2.Search(spFilter, true);
        com.ManageLifetime(curosr2);

        IFeature feature2 = null;

        int cnt = 0;
        while ((feature2 = curosr2.NextFeature()) != null)
        {
            cnt++;
            Console.WriteLine(feature2.OID);
        }
        Console.WriteLine("DATACOUNT" + cnt.ToString());

    }//end com
}//end method

SQL Server側コード

using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;

DatabaseFactory.ClearDatabaseProviderFactory();
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());

Database db = DatabaseFactory.CreateDatabase("DefaultDB");
using (DbConnection con = db.CreateConnection())
{

con.Open();
DbCommand selectCmd = con.CreateCommand();
selectCmd.CommandText = @"
DECLARE @Shape GEOMETRY
SET @Shape = GEOMETRY::STGeomFromText('GEOMETRYCOLLECTION EMPTY', 4612)

SELECT
 @Shape = @Shape.STUnion(Shape)
FROM
 テーブルB

SELECT
 OBJECTID
FROM
 テーブルB
WHERE
 Shape.STIntersects(@Shape) = 1
";
selectCmd.CommandType = CommandType.Text;

DataSet ds = db.ExecuteDataSet(selectCmd);
DataTable dt = ds.Tables[0];

foreach (DataRow row in dt.Rows)
{
    Console.WriteLine(row["OBJECTID"]);
}//end loop

Console.WriteLine("DATACOUNT:" + dt.Rows.Count.ToString());
カテゴリー: 開発 タグ: , , パーマリンク