Byte配列とラスタ


MXDレイヤの派生で確認

MXDレイヤ

Byte配列をRasterとして読み込み4隅座標を与える。
・HTTP等の受取とラスタカタログ登録
・DB格納のバイナリデータ描画
・投影変換考慮の歪み描画
の際に使えるかと思いちょっと確認程度

IRasterPropsの4隅はISaveAs等で永続化する際にのみ?
TwoPointsAdjust以外手がないのか?(速度は?)
とりあえずテンポラリディレクトリ見てる限りはOnMemoryのみで処理完結なので
速度劣化の主要因であるディスク処理をスキップはできそう。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesRaster;
using ESRI.ArcGIS.Carto;

[ComVisible(true)]
[Guid("AE201ED6-8D6C-4886-8BDD-C6F83623F94C")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Custom.CustomMxdLayer2")]
public class CustomMxdLayer2 : CustomMxdLayer
{
    public CustomMxdLayer2()
        : base()
    {
    }//end method

    public CustomMxdLayer2(string mxd)
        : base(mxd)
    {
    }

    public override void Draw(esriDrawPhase DrawPhase, IDisplay Display, ITrackCancel TrackCancel)
    {
        //ベースを読み替えるのでコメント
        //base.Draw(DrawPhase, Display, TrackCancel);

        //選択と注記は無視
        if (DrawPhase != esriDrawPhase.esriDPGeography)
            return;
        using (ComReleaser com = new ComReleaser())
        {
            IDisplayTransformation diTransform = Display.DisplayTransformation;

            tagRECT rect = diTransform.get_DeviceFrame();
            int scWidth = rect.right;
            int scHeight = rect.bottom;

            IPoint leftU = diTransform.ToMapPoint(0, 0);
            com.ManageLifetime(leftU);

            IPoint rightB = diTransform.ToMapPoint(scWidth, scHeight);
            com.ManageLifetime(rightB);

            IEnvelope env = new EnvelopeClass();
            com.ManageLifetime(env);
            env.PutCoords(leftU.X, leftU.Y, rightB.X, rightB.Y);
            env.SpatialReference = Display.DisplayTransformation.SpatialReference;

            Type t = Type.GetTypeFromProgID("esriDataSourcesRaster.RasterWorkspaceFactory");

            string tmpPath = System.IO.Path.GetTempPath();
            IWorkspaceFactory wsf = (IWorkspaceFactory)Activator.CreateInstance(t);
            IRasterWorkspace3 rsw = (IRasterWorkspace3)wsf.OpenFromFile(tmpPath, 0);

            using (Bitmap img = base.getImg(env, scWidth, scHeight))
            using (System.IO.MemoryStream mem = new System.IO.MemoryStream())
            //using (Graphics gra = Graphics.FromHdc((IntPtr)Display.hDC))
            {
                //gra.DrawImageUnscaled(img, rect.top, rect.left);
                img.Save(mem, ImageFormat.Png);

                byte[] data = mem.ToArray();
                IRasterDataset rds = rsw.OpenRasterDatasetFromBytes(ref data, false);
                com.ManageLifetime(rds);

                IGeoDataset geoDataset = (IGeoDataset)rds;

                data = null;

                IRaster raster = rds.CreateDefaultRaster();
                com.ManageLifetime(raster);
                //IRasterProps rprops = (IRasterProps)((IRasterDataset2)rds).CreateFullRaster();
                ////rds.CreateDefaultRaster();
                //com.ManageLifetime(rprops);
                //rprops.Extent = env;

                IRasterLayer rasterLayer = new RasterLayerClass();
                com.ManageLifetime(rasterLayer);

                rasterLayer.Name = "TEST";
                rasterLayer.Visible = true;

                rasterLayer.CreateFromRaster(raster);

                IRasterRenderer render = rasterLayer.Renderer;
                com.ManageLifetime(render);
                render.ResamplingType = rstResamplingTypes.RSP_NearestNeighbor;
                (render as IRasterStretch).StretchType = esriRasterStretchTypesEnum.esriRasterStretch_NONE;
                (render as IRasterStretch3).UseGamma = false;

                IPointCollection fromPts = new MultipointClass();
                com.ManageLifetime(fromPts);
                object o = Type.Missing;
                fromPts.AddPoint(geoDataset.Extent.LowerLeft, ref o, ref o);
                fromPts.AddPoint(geoDataset.Extent.UpperRight, ref o, ref o); 

                IPointCollection toPts = new MultipointClass();
                com.ManageLifetime(toPts);
                toPts.AddPoint(env.LowerLeft, ref o, ref o);
                toPts.AddPoint(env.UpperRight, ref o, ref o);

                IGeoReference georef = (IGeoReference)rasterLayer;
                georef.TwoPointsAdjust(fromPts, toPts);

                rasterLayer.Draw(DrawPhase, Display, TrackCancel);

            }

        }//end com

    }//end method}//end class
カテゴリー: 開発 タグ: パーマリンク