天气雷达云图绘制

如图,最近项目的需求,要求绘制一张图,叠加到地图上:

原先的实现方式是从后台拿到一张图片的地址,直接下载后通过高德的groundOverlay添加到地图上.

后来又把需求改成点阵json数据,让APP端通过接口下载一个json文件.解析这个json文件.然后在app端绘制.

根据json数据的特点:二维点阵数组,外层代表行号,内层代表列号.元素的值就是这个点的颜色.

绘制思路:创建一个宽高分别为二维数组外层count,内层count的画布.在上面绘制rect,一个rect宽高就是1,设置填充色即可.

绘制部分代码如下:

       UIGraphicsBeginImageContext(CGSizeMake(897, 721)); //在这个范围内开启一段上下文

        CGContextRef context = UIGraphicsGetCurrentContext();

        UIImage *image ;

        //    for(int i =startIndexX;i<endIndexX;i++){

        for(int i =0;i<897;i++){

            for(int j=720;j>=0;j--){

                NSArray *arr = model.mutaOffsetedData[j];//arr有255个元素

                CGRect rect = CGRectMake( i, j, 1.0f, 1.0f); //宽高 1.0只要有值就够了

                CGFloat colorValue = [arr[i]floatValue];

                UIColor *colorRect = [UIColor clearColor];

                if(colorValue>=minValue&&colorValue<=maxValue){

                    colorRect = [self getColorWithIndexValue:colorValue];

                }

                UIColor *color = ([arr[i] integerValue]!=-1)?colorRect:[UIColor clearColor];

                CGContextSetFillColorWithColor(context, [color CGColor]);//在这段上下文中获取到颜色UIColor

//                CGContextSetShouldAntialias(context, YES);

                CGContextFillRect(context, rect);//用这个颜色填充这个上下文

            }

        }

        CGContextRotateCTM(context, -M_PI*0.5);

        float  translateX = 0;

        float translateY = -721;

        CGContextTranslateCTM(context, translateX, translateY);

        image = UIGraphicsGetImageFromCurrentImageContext();//从这段上下文中获取Image属性,,,结束

        UIImage *mirroredImage = [PublicFunction fixOrientationWithImageOrientation:UIImageOrientationLeftMirrored andImage:image];

        UIImage *orientationImage = [PublicFunction image:mirroredImage rotation:UIImageOrientationLeft];

        UIGraphicsEndImageContext();

需要注意的是:绘制这部分特别耗时,最好开辟一个子线程来绘图,尽量不让用户拖动地图的时候卡顿

有一点要说的是:这个json数据本来只有225*181.所以绘制出来的图分辨率很低,地图上放大时,虚化特别严重,看起来很不好看.有两种解决办法:1.用同一色值来填充像素,即用相同的颜色来复制之前的一个rect像素.使之成为:(225*4)*(181*4)像素的图片.这样只能解决虚化严重的问题,并不能解决颗粒感严重的问题.

解决办法:2.在1的基础上,采用渐变色填充像素的方法.实现思路是:将相邻的两个元素之间填充渐变色,即前一个元素A的色值减去后一个元素B的色值,中间按等差数列塞值进去,这样就能使得从A a1 a2 a3 B的颜色是渐变的.很大程度上消除颗粒感.

这里有个麻烦的地方:相邻元素插值,不仅仅是横向相邻,纵向也需要相邻元素插值.纵向插值处理比较麻烦,所以,我们先进行横向插值,横向插值完成后,再对这个数组进行横纵向颠倒,这时候再按照之前横向插值的方法进行插值,插值完成后再把数组颠倒回来即可.

期间遇到了个奇怪的问题,之前放在主线程绘图时,必须再次手动调用CGContextRelease(context)  

否则内存一直居高不下,释放不掉,后来放到子线程绘图时,不需要手动调用了.加了这句反而报了下面的错.貌似是强制去释放一个已经不存在的对象导致的崩溃.有没有大神能解释解释一下问题的根本原因的.

libobjc.A.dylib`objc_object::release:    CGContextRelease(context)

猜你喜欢

转载自blog.csdn.net/qq_31186665/article/details/80970280
今日推荐