如何生成IStyleGalleryItem和ISymbol对象的预览图

ArcGIS Engine 同时被 3 个专栏收录
12 篇文章 2 订阅
18 篇文章 0 订阅
12 篇文章 0 订阅

 

先来看一下ArcMap的符号选择器:


ArcMap的符号选择器都提供了符号的预览图,另一个预览图的位置是在按钮上,比如设置MapGrid的格网交点符号和格网线符号。

本文给出生成这里的符号预览图的代码。

方法1:通过ISymbologyStyleClass的Preview方法生成预览图

        private string routin_ReadRegistry(string sKey)
        {
            Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(sKey, true);
            if (rk == null) return "";
            return (string)rk.GetValue("InstallDir");
        }


        public void LoadStyleGalleryItems()
        {
            string sInstall = routin_ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
            if (sInstall == "")
            {
                return;
            }

            ISymbologyControl pSymbologyControl = new SymbologyControlClass();
            pSymbologyControl.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
            m_pSymbologyStyleClass = pSymbologyControl.GetStyleClass(esriSymbologyStyleClass.esriStyleClassScaleBars);

            //Clean items in ImageComboBox and images in ImageCollection.
            this.imageComboBoxEdit1.Properties.Items.Clear();
            this.imageCollection1.Images.Clear();

            int nWidth, nHeight;
            nWidth = this.imageCollection1.ImageSize.Width;
            nHeight = this.imageCollection1.ImageSize.Height;

            Image pImage = null;

            //Load StyleGalleryItems into he ImageComboBox's drop down list.
            IStyleGalleryItem pStyleGalleryItem = null;
            IPictureDisp pPicture = null;
            for (int i = 0; i < m_pSymbologyStyleClass.get_ItemCount(m_pSymbologyStyleClass.StyleCategory); i++)
            {
                pStyleGalleryItem = m_pSymbologyStyleClass.GetItem(i);
                pPicture = m_pSymbologyStyleClass.PreviewItem(pStyleGalleryItem, nWidth, nHeight);
                pImage = System.Drawing.Image.FromHbitmap(new IntPtr(pPicture.Handle));
                AddItem(pStyleGalleryItem.Name, pImage, pStyleGalleryItem, i);
            }
            this.imageComboBoxEdit1.SelectedIndex = 0;
        }

        private void AddItem(string sDescription, Image pImage, IStyleGalleryItem pStyleGalleryItem, int nImageIndex)
        {
            this.imageComboBoxEdit1.Properties.Items.Add(new ImageComboBoxItem(sDescription, pStyleGalleryItem, nImageIndex));
            this.imageCollection1.Images.Add(pImage);
        }
        //其中m_pSymbologyStyleClass是ISymbologyStyleClass的实例。

        //上面的代码演示如何使用ISymbologyControl接口在下拉列表控件中加载符号集,其中包含生成预览图的代码,对于符号选择器,使用SymbologyControl,可以直接参考AE范例里的符号选择器的例子,下面是符号选择器里更为精简的代码:
        protected void PreviewImage()
        {
            ISymbologyStyleClass pSymbologyStyleClass = wndSymbologyControl.GetStyleClass(wndSymbologyControl.StyleClass);
            IPictureDisp pPicture = pSymbologyStyleClass.PreviewItem(m_StyleGalleryItem, wndPictureEdit.Width - 10, wndPictureEdit.Height - 10);
            Image pImage = Image.FromHbitmap(new IntPtr(pPicture.Handle));
            wndPictureEdit.Image = pImage;
        }

        protected void LoadStyleCalss(esriSymbologyStyleClass styleClass)
        {
            string sInstall = routin_ReadRegistry("SOFTWARE\\ESRI\\CoreRuntime");
            wndSymbologyControl.LoadStyleFile(sInstall + "\\Styles\\ESRI.ServerStyle");
            wndSymbologyControl.StyleClass = styleClass;
            m_SymbologyStyleClass = wndSymbologyControl.GetStyleClass(wndSymbologyControl.StyleClass);
            m_SymbologyStyleClass.SelectItem(0);
        }
方法2:通过IStyleGalleryClass的Preview方法获取符号的预览图
        private Image PreViewMarkerSymbol(ISymbol pSymbol, int width, int height)
        {
            IStyleGalleryClass pStyleGalleryClass = new MarkerSymbolStyleGalleryClass();
            Image img = new Bitmap(width, height);
            Graphics gc = Graphics.FromImage(img);
            IntPtr hdc = gc.GetHdc();
            tagRECT rect = new tagRECT();
            rect.left = 0;
            rect.top = 0;
            rect.right = width;
            rect.bottom = height;
            pStyleGalleryClass.Preview(pSymbol, hdc.ToInt32(), ref rect);
            gc.ReleaseHdc(hdc);
            gc.Dispose();
            return img;
        }


        private void checkEdit2_CheckedChanged(object sender, EventArgs e)
        {
            if (m_bLoading) return;
            if (mMapGrid != null)
            {
                if (checkEdit2.Checked)
                {
                    mMapGrid.LineSymbol = null;
                    ISimpleMarkerSymbol pSimpleMarkerSymbol = new SimpleMarkerSymbol();
                    pSimpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCross;
                    IMarkerSymbol pMarkerSymbol = pSimpleMarkerSymbol as IMarkerSymbol;
                    mMapGrid.TickMarkSymbol = pMarkerSymbol;
                    mMapGrid.SetLabelVisibility(true, true, true, true);
                    simpleButton1.Image = PreViewMarkerSymbol(pMarkerSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
                    if (ValueChanged != null) ValueChanged();
                }
            }
        }
使用第二种方法时,要注意ISymbol对象的类型。因为所有符号集类都实现了IStyleGalleryClass接口,如MarkerSymbolStyleGalleryClass、LineSymbolStyleGalleryClass、 ScaleBarStyleGalleryClass等。生成预览图时,各符号的预览图只能由与其对应的StyleGalleryClass来生成,也就是说NorthArrow类型的符号只能用 NorthArrowStyleGalleryClass来预览,而不能用其它类型,像下面这样是会发生异常的:
        private void checkEdit3_CheckedChanged(object sender, EventArgs e)
        {
            if (m_bLoading) return;
            if (mMapGrid != null)
            {
                if (checkEdit3.Checked)
                {
                    ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbol();
                    pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
                    ILineSymbol pLineSymbol = pSimpleLineSymbol as ILineSymbol;
                    mMapGrid.LineSymbol = pLineSymbol;
                    mMapGrid.TickMarkSymbol = null;
                    mMapGrid.SetLabelVisibility(true, true, true, true);
                    simpleButton1.Image = PreViewMarkerSymbol(pLineSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
                    if (ValueChanged != null) ValueChanged();
                }
            }
        }
这里,传入的是LineSymbol对象,在PreViewMarkerSymbol中,用MarkerSymbolStyleGalleryClass的事例来预览一个LineSymbol,程序在调用Preview时,会直接崩溃,正确的用法是:
        private Image PreViewLineSymbol(ISymbol pSymbol, int width, int height)
        {
            IStyleGalleryClass pStyleGalleryClass = new LineSymbolStyleGalleryClass();
            Image img = new Bitmap(width, height);
            Graphics gc = Graphics.FromImage(img);
            IntPtr hdc = gc.GetHdc();
            tagRECT rect = new tagRECT();
            rect.left = 0;
            rect.top = 0;
            rect.right = width;
            rect.bottom = height;
            pStyleGalleryClass.Preview(pSymbol, hdc.ToInt32(), ref rect);
            gc.ReleaseHdc(hdc);
            gc.Dispose();
            return img;
        }


        private void checkEdit3_CheckedChanged(object sender, EventArgs e)
        {
            if (m_bLoading) return;
            if (mMapGrid != null)
            {
                if (checkEdit3.Checked)
                {
                    ISimpleLineSymbol pSimpleLineSymbol = new SimpleLineSymbol();
                    pSimpleLineSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
                    ILineSymbol pLineSymbol = pSimpleLineSymbol as ILineSymbol;
                    mMapGrid.LineSymbol = pLineSymbol;
                    mMapGrid.TickMarkSymbol = null;
                    mMapGrid.SetLabelVisibility(true, true, true, true);
                    simpleButton1.Image = PreViewLineSymbol(pLineSymbol as ISymbol, simpleButton1.Height, simpleButton1.Width);
                    if (ValueChanged != null) ValueChanged();
                }
            }
        }

实际上IStyleGalleryItem的Item成员,都是ISymbol成员,因此一个ISymbol对象,除了可以直接用IStyleGalleryClass的Previe预览以外,还可以转换成IStyleGalleryItem然后使用ISymbologyStyleClass的Preview方法来预览,比如:

IStyleGalleryItem pStyleGalleryItem = new ServerStyleGalleryItemClass();
IClone pClone = pScaleBar as IClone;
pStyleGalleryItem.Item = pClone.Clone();

之后就可以使用第一种方法来生成预览图了。

下面是自制的符号选择器:


  • 0
    点赞
  • 0
    评论
  • 2
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值