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



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

の続きISpatialIndexを忘れていたので付加したところ、ESRIの圧勝
ちなみに誤解がないように言っておくと普通ならそんなに差は出ないはず(2万点のループ中340点程度なら)

次の記事

幾何演算は、データ依存で結果が相当違うのが恐ろしいところ。
忙しくて続きを書けなかったがふとISpatialIndexを思い出した。。
ポリゴン側にかけるだけで結果が変わりすぎるのがArcObjectsの恐ろしいところ。


_______領域が狭い場合(340点/2万)

msTime:199.0114ms
esriTime:173.0099ms
msTime:173.0099ms
esriTime:170.0097ms
msTime:174.01ms
esriTime:166.0095ms
msTime:176.0101ms
esriTime:161.0092ms
msTime:177.0102ms
esriTime:164.0093ms

_______領域が広い場合(前回までと同様)
msTime: 26,224.5ms
esriTime: 2,175.1244ms
msTime: 25,752.473ms
esriTime: 2,142.1225ms
msTime: 26,249.5014ms
esriTime: 2,243.1283ms
msTime: 25,687.4692ms
esriTime: 2,150.123ms
msTime: 26,372.5085ms
esriTime: 2,128.1217ms

public static void TEST(string gdbPath,string areaName , string ptName)
{
    using (ComReleaser lifetime = new ComReleaser())
    {
        Type t = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
        IWorkspaceFactory2 wsf = (IWorkspaceFactory2)Activator.CreateInstance(t);
        lifetime.ManageLifetime(wsf);

        IFeatureWorkspace fw = (IFeatureWorkspace)wsf.OpenFromFile(gdbPath, 0);
        lifetime.ManageLifetime(fw);

        Type geomType = Type.GetTypeFromProgID("esriGeometry.GeometryEnvironment");
        IGeometryFactory3 geomfact = (IGeometryFactory3)Activator.CreateInstance(geomType);
        lifetime.ManageLifetime(geomfact);

        IRelationalOperator areaComGeom = null;
        SqlGeometry areaGeom = null;
        IFeatureClass fcArea = fw.OpenFeatureClass(areaName);
        IFeatureCursor areaCursor = fcArea.Search(null, true);
        lifetime.ManageLifetime(areaCursor);

        IFeature areaFeature = null;
        while ((areaFeature = areaCursor.NextFeature()) != null)
        {
            areaComGeom = (IRelationalOperator)areaFeature.ShapeCopy;
            lifetime.ManageLifetime(areaGeom);

            byte[] shape = (byte[])geomfact.CreateWkbVariantFromGeometry(areaFeature.Shape);

            System.Data.SqlTypes.SqlBytes bytes = new SqlBytes(shape);
            Microsoft.SqlServer.Types.SqlGeometry geom = SqlGeometry.STGeomFromWKB(bytes, 0);
            areaGeom = geom;

            ComReleaser.ReleaseCOMObject(areaFeature);
            break;
        }

        IFeatureClass ptFc = fw.OpenFeatureClass(ptName);
        lifetime.ManageLifetime(ptFc);

        IFeature ptFeature = null;
        IFeatureCursor cursor = ptFc.Search(null, false);
        lifetime.ManageLifetime(cursor);

        List<IGeometry> topoList = new List<IGeometry>(); ;
        List<SqlGeometry> sqlGeomList = new List<SqlGeometry>();

        while ((ptFeature = cursor.NextFeature()) != null)
        {
            byte[] shape = (byte[])geomfact.CreateWkbVariantFromGeometry(ptFeature.Shape);

            System.Data.SqlTypes.SqlBytes bytes = new SqlBytes(shape);
            Microsoft.SqlServer.Types.SqlGeometry geom = SqlGeometry.STGeomFromWKB(bytes, 0);

            sqlGeomList.Add(geom);
            topoList.Add((IGeometry)ptFeature.ShapeCopy);
        }

        //+++++++++++++++++++++++++++++++++++++++++++++++++++
        ISpatialIndex spIndex = (ISpatialIndex)areaComGeom;
        spIndex.AllowIndexing = true;
        spIndex.Invalidate();
        //+++++++++++++++++++++++++++++++++++++++++++++++++++

        for (int i = 0; i < 5; i++)
        {
            DateTime dt = DateTime.Now;

            foreach (var item in topoList)
            {
                //Console.Write(
                areaComGeom.Contains(item);
                //);
            }

            TimeSpan esriTime = DateTime.Now - dt;

            dt = DateTime.Now;

            foreach (var item in sqlGeomList)
            {
                //+++++++++++++++++++++++++++++++++++++++++++++++++++
                //http://msdn.microsoft.com/ja-jp/library/microsoft.sqlserver.types.sqlgeometry_methods.aspx
                //
                //Filter::
                //Offers a fast, index-only intersection method to determine if a SqlGeometry instance intersects another SqlGeometry instance,
                //assuming an index is available.
                //+++++++++++++++++++++++++++++++++++++++++++++++++++
                // ?????? STContains == Filter ??????

                ////Console.Write(
                areaGeom.Filter(item);
                //areaGeom.STContains(item);
                ////);
            }

            TimeSpan msTime = DateTime.Now - dt;

            string msg = string.Format("msTime:{0}ms\nesriTime:{1}ms", msTime.TotalMilliseconds, esriTime.TotalMilliseconds);
            Console.WriteLine(msg);
        }

        foreach (var item in topoList)
        {
            ComReleaser.ReleaseCOMObject(item);
        }
        topoList.Clear();
        topoList = null;

    }//end com
}//end method
カテゴリー: 開発, 設計 タグ: パーマリンク