爱气象,爱气象家园! 

气象家园

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

搜索
查看: 2745|回复: 8

求助)关于投影模式下的地图图片显示

[复制链接]

新浪微博达人勋

发表于 2015-10-30 14:41:54 来自手机 | 显示全部楼层 |阅读模式

登录后查看更多精彩内容~

您需要 登录 才可以下载或查看,没有帐号?立即注册 新浪微博登陆

x
王老师好,最近在摸索利用meteoinfo(c#)版二次开发,目前加载map文件夹下地形地图图片,只能在经纬度模式下显示,如果改为兰伯特投影则不行,翻阅了论坛历史帖,说是imagelayer不支持投影。
不知道采用rasterlayer的形式是否可以实现?具体思路为将图片各像素点颜色读出,生成颜色索引值的GridData,将相关的颜色生成legendscheme,然后利用这两个量生成raster加载入map view。但是在实现是老是会出错,说对象未实例化。
通过做理想试验,当数据简单,颜色个数较少时,可以成功。但是颜色较多时,却出现错误。
现有如下疑问:
1 这种思路不知道是否可行?
2 出错的原因是不是颜色个数太多?我的legendscheme有236700多种颜色。

还请老师不吝赐教
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2015-10-30 14:52:33 | 显示全部楼层
思路应该是可行的,不过怎么会有这么多中颜色,没有重复的吗?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2015-10-30 23:03:15 | 显示全部楼层
这是我的代码,王老师
           MeteoInfoC.Data.GridData grdd = new MeteoInfoC.Data.GridData();
            MeteoInfoC.Legend.LegendScheme aLs = new LegendScheme(MeteoInfoC.Shape.ShapeTypes.Image);
            MeteoInfoC.Layer.RasterLayer rslyr = new MeteoInfoC.Layer.RasterLayer();


            string imgFname = ".\\Map\\GLOBALeb3colshade.jpg";
            Bitmap curBitmap = (Bitmap)Bitmap.FromFile(imgFname);


            //read image
            if (curBitmap != null)
            {
                int width = curBitmap.Width;
                int height = curBitmap.Height;
                BitmapData data = curBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                System.IntPtr Scan0 = data.Scan0;
                int stride = data.Stride;               
                int length = height * 3 * width;
                byte[] RGB = new byte[length];
                int[,] R = new int[height, width];
                int[,] G = new int[height, width];
                int[,] B = new int[height, width];
                 int[, ,] tempColorarray = new int[256, 256, 256];
                System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);

                grdd = new MeteoInfoC.Data.GridData(0, 360 / width, width, -90, 180 / height, height);//set grdd by image size

                unsafe
                {
                    byte* p = (byte*)Scan0;
                    //int offset = stride - width * 3;
                    int iPoint = 0;
                    for (int i = 0; i < height; i++)
                    {
                        for (int j = 0; j < width; j++)
                        {
                            B[i, j] = Convert.ToInt32(RGB[iPoint++]);
                            G[i, j] = Convert.ToInt32(RGB[iPoint++]);
                            R[i, j] = Convert.ToInt32(RGB[iPoint++]);
                            tempColorarray[R[i,j],G[i,j],B[i,j]]=R[i,j]+G[i,j]*256+B[i,j]*256*256;
                            grdd.Data[i,j]=tempColorarray[R[i,j],G[i,j],B[i,j]];
                        }
                       
                    }
                }
                curBitmap.UnlockBits(data);


                 // get differect colors
                List<MeteoInfoC.Legend.ColorBreak> lstColorB = new List<ColorBreak>();
           int tempR, tempG, tempB;
            for (int i = 0; i < 256; i++)
            {
                for (int j = 0; j < 256; j++)
                {
                    for (int k = 0; k < 256; k++)
                    {
                        if (tempColorarray[i,j,k]!=0)
                        {
                            tempB = tempColorarray[i, j, k] / 256 / 256;
                            tempG = (tempColorarray[i, j, k] - tempB * 256 * 256) / 256;
                            tempR = (tempColorarray[i, j, k] - tempB * 256 * 256 - tempG * 256);

                            ColorBreak cb = new ColorBreak();
                            if (lstColorB.Count==0)
                            {
                                cb.StartValue = 0;
                            }
                            else
                            {
                                cb.StartValue = lstColorB[lstColorB.Count - 1].EndValue;
                            }
                            cb.EndValue = lstColorB.Count + 1;                           
                            cb.Color = Color.FromArgb(tempR, tempG, tempB);
                            lstColorB.Add(cb);
                           
                        }
                    }
                }
               
            }
                aLs.LegendBreaks=lstColorB;
                List<Color> lstC=aLs.GetColors();
                var tmp = new HashSet<Color>();
                List<int> iC = new List<int>();
                for (int i = 0; i < lstC.Count; i++)
                {
                    iC.Add( (int)lstC.R + (int)(lstC.G) * 256 + (int)(lstC.B) * 256 * 256);
                }
                // set grdd.Data value
                DateTime dt = DateTime.Now;
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    int value=Convert.ToInt32(grdd.Data[i, j]);
                    grdd.Data[i, j] = Convert.ToDouble(iC.IndexOf(value)+1);//这一步很耗时,需要后续优化
                }

            }
            TimeSpan ts = DateTime.Now - dt;

            rslyr = MeteoInfoC.Data.MeteoData.DrawMeteoData.CreateRasterLayer(grdd, "myMap", aLs);

            G_LayerLegend.ActiveMapFrame.AddLayer(rslyr);
            G_LayerLegend.ActiveMapFrame.MapView.PaintLayers();
            }同时,检查了一下,从图片中读取出的颜色有380823种,不知道为何有这么多?如果真有这么多,那么想这样现实地图图片是不是不可行呀?
在执行到这一行rslyr = MeteoInfoC.Data.MeteoData.DrawMeteoData.CreateRasterLayer(grdd, "myMap", aLs);时出错了
错误信息为:
未处理System.NullReferenceException
  Message=未将对象引用设置到对象的实例。
  Source=MeteoInfoC
  StackTrace:
       在 MeteoInfoC.Layer.ImageLayer.SetPalette(List`1 colors)
       在 MeteoInfoC.Layer.RasterLayer.SetPaletteByLegend()
       在 MeteoInfoC.Layer.RasterLayer.set_LegendScheme(LegendScheme value)
       在 MeteoInfoC.Data.MeteoData.DrawMeteoData.CreateRasterLayer(GridData GridData, String LName, LegendScheme aLS)
       在 WindowsFormsApplication1.Form1.button1_Click(Object sender, EventArgs e) 位置 d:\lzf\project\WeatherDislay\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行号 155
       在 System.Windows.Forms.Control.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       在 System.Windows.Forms.Control.WndProc(Message& m)
       在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
       在 System.Windows.Forms.Button.WndProc(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.Run(Form mainForm)
       在 WindowsFormsApplication1.Program.Main() 位置 d:\lzf\project\WeatherDislay\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:行号 18
       在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       在 System.Threading.ThreadHelper.ThreadStart()
  InnerException:
不知道何故?

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2015-10-30 23:38:19 | 显示全部楼层
zfvv 发表于 2015-10-30 23:03
这是我的代码,王老师
           MeteoInfoC.Data.GridData grdd = new MeteoInfoC.Data.GridData();
   ...

width和height都是整数(应该比较大),创建GridData的参数中360/width和180/height会都是0,这样会有问题,改为360.0/width和180.0/height试试。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2015-10-31 11:39:22 | 显示全部楼层
这么晚,王老师还回复了。由于数据读取耗时,回复晚了。
谢谢您指出了griddata定义中的错误,修改过后还是同样的问题,不知何故?我将als数据和grdd数据输出为文件上传上来,如果王老师有空帮看看。
附:
数据输出程序:
           aLs.ExportToXMLFile("als.xml");
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter("sdata.txt"))
            {
                string tempstr = "";
                for (int i = 0; i < grdd.XNum; i++)
                {
                    tempstr = string.Empty;
                    for (int j = 0; j < grdd.YNum; j++)
                    {
                        tempstr = tempstr + "," + grdd.Data[j, i].ToString();
                    }
                    sw.WriteLine(tempstr);
                }
            }

数据读取程序
            MeteoInfoC.Data.GridData grdd = new MeteoInfoC.Data.GridData();
            MeteoInfoC.Legend.LegendScheme aLs = new LegendScheme(MeteoInfoC.Shape.ShapeTypes.Image);
            MeteoInfoC.Layer.RasterLayer rslyr = new MeteoInfoC.Layer.RasterLayer();
            int width = 7200;// curBitmap.Width;
            int height = 3600;// curBitmap.Height;
             grdd = new MeteoInfoC.Data.GridData(0, 360.0 / width, width, -90, 180.0 / height, height);//

             aLs.ImportFromXMLFile("als.xml");

             using (System.IO.StreamReader sw = new System.IO.StreamReader("sdata.txt"))
             {
                 string tempstr = "";
                 string[] tsss;
                 int ii = 0;
                 while (true)
                 {
                     tempstr = sw.ReadLine();
                     if (tempstr != null)
                     {
                         tsss = tempstr.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);
                         for (int j = 0; j < height; j++)
                         {
                             grdd.Data[j, ii] = double.Parse(tsss[j]);
                         }
                     }
                     else
                     {
                         break;  
                     }
                     ii++;

                 }               


             }
             rslyr = MeteoInfoC.Data.MeteoData.DrawMeteoData.CreateRasterLayer(grdd, "myMap", aLs);

             G_LayerLegend.ActiveMapFrame.AddLayer(rslyr);
             G_LayerLegend.ActiveMapFrame.MapView.PaintLayers();

错误信息:

未处理System.NullReferenceException
  Message=未将对象引用设置到对象的实例。
  Source=MeteoInfoC
  StackTrace:
       在 MeteoInfoC.Layer.ImageLayer.SetPalette(List`1 colors)
       在 MeteoInfoC.Layer.RasterLayer.SetPaletteByLegend()
       在 MeteoInfoC.Layer.RasterLayer.set_LegendScheme(LegendScheme value)
       在 MeteoInfoC.Data.MeteoData.DrawMeteoData.CreateRasterLayer(GridData GridData, String LName, LegendScheme aLS)
       在 WindowsFormsApplication1.Form1.button2_Click(Object sender, EventArgs e) 位置 d:\lzf\project\WeatherDislay\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:行号 219
       在 System.Windows.Forms.Control.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnClick(EventArgs e)
       在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       在 System.Windows.Forms.Control.WndProc(Message& m)
       在 System.Windows.Forms.ButtonBase.WndProc(Message& m)
       在 System.Windows.Forms.Button.WndProc(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       在 System.Windows.Forms.Application.Run(Form mainForm)
       在 WindowsFormsApplication1.Program.Main() 位置 d:\lzf\project\WeatherDislay\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:行号 18
       在 System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       在 System.Threading.ThreadHelper.ThreadStart()
  InnerException:


data.rar

36.67 MB, 下载次数: 0, 下载积分: 金钱 -5

als和grdd

密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2015-10-31 16:10:16 | 显示全部楼层
zfvv 发表于 2015-10-31 11:39
这么晚,王老师还回复了。由于数据读取耗时,回复晚了。
谢谢您指出了griddata定义中的错误,修改过后还是 ...

看来目前对RasterLayer的设计不适合载入较复杂的图像(主要是效率问题不好解决),加入对ImageLayer的投影功能也许是解决之道。不过最近很难抽出时间做这个。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2015-10-31 16:55:46 | 显示全部楼层
MeteoInfo 发表于 2015-10-31 16:10
看来目前对RasterLayer的设计不适合载入较复杂的图像(主要是效率问题不好解决),加入对ImageLayer的投 ...

感谢老师您的答复,您能在业余时间编出如此牛3的软件,已经很伟大了,每次使用您的软件都有一种高山仰止的感觉。
密码修改失败请联系微信:mofangbao

新浪微博达人勋

发表于 2015-10-31 19:13:08 | 显示全部楼层
zfvv 发表于 2015-10-31 16:55
感谢老师您的答复,您能在业余时间编出如此牛3的软件,已经很伟大了,每次使用您的软件都有一种高山仰止 ...

其实也都是站在别人的肩膀上,用了众多开源软件的代码和思路,也借鉴了一些商业软件的设计。越来越觉得还有很多需要完善的地方,只是个人精力实在有限,看来开源迫在眉睫了。不过也不知道开源能不能吸引更多人参与MeteoInfo的开发?
密码修改失败请联系微信:mofangbao

新浪微博达人勋

 楼主| 发表于 2015-11-1 06:27:49 | 显示全部楼层
开源后的效果不知道能不能达到预期,不过私以为坛子可能会冷清了
密码修改失败请联系微信:mofangbao
您需要登录后才可以回帖 登录 | 立即注册 新浪微博登陆

本版积分规则

Copyright ©2011-2014 bbs.06climate.com All Rights Reserved.  Powered by Discuz! (京ICP-10201084)

本站信息均由会员发表,不代表气象家园立场,禁止在本站发表与国家法律相抵触言论

快速回复 返回顶部 返回列表