I am trying to draw radar data on top of a map using CoreGraphics. Before, I was trying to draw each data point individually by making a path around each individual data point and then filling the appropriate color. So for this method I had to have 4 location points and a data value for each data point. Doing it this way turned out to be way too costly, as there are between 30,000 and 80,000 data points for each image.
The radar data is stored in a radial format (360 radials, each containing 230 data points). So instead of looping through every data point, I only loop through the radials. And instead of a path around each data point, I have a path around each radial. I then create and draw a linear gradient (CGGradientCreateWithColors) using the array of colors for that particular gradient.
This method is drawing a lot faster than before, but it is still not fast enough. Another issue with it is the "smoothness" of the data when I zoom in. The gradient blends between every data point in the radial so you cannot see the individual pixels. I do not want it to do this. I think this is where my biggest performance hit is coming from (computing the gradient between each data point). I would rather each data point be drawn as a discrete color. This would look better开发者_如何学编程 and it should perform better.
Is there a way to provide an array of colors to a path (similar to what I did with the gradient) that will draw them discretely. I need to be able to draw this without having to go back to drawing the individual data points.
Thank you in advance, Ross
EDIT
The first picture is the original way I was doing the drawing (by drawing each data point individually). This is how I want it to look in the end.
The second picture is the gradient, which is more efficient than before (not efficient enough though), but does not look right.
I'm having trouble picturing quite what you're trying to draw (it's hard to imagine drawing 80,000 of anything on an iPhone screen and have each thing be bigger than a pixel....) but here are some thoughts along your way.
First, if you have a consistent thing to draw repeatedly, put it on a CGLayer
. Not a CALayer
, a CGLayer
. This is a hardware-optimized object for "stamping" the same thing repeatedly. If you need to change colors or even apply a gradient, you can apply these using a mask or by compositing a CGImage
(the latter is generally faster if you can then reuse the resulting image and not have to scale anything).
As much as possible, pre-compute your gradients and store them in data structures. Trying to compute them in drawRect:
is often a major performance hit. Similarly, pre-compute your paths so that you don't have to build them every time you draw.
If you can avoid scaling your layers, you can set their shouldRasterize
to YES
, which will generally improve performance when you have complex layers. On the other hand, if you need to do scaling or other transforms, then drawing on a CALayer
and applying the needed transform can be very fast. You can also apply transforms to the whole UIView
, but if you need lots of separate things transformed, then that's what CALayer
is all about. (To the earlier point, you can of course draw a CGLayer
onto a CALayer
.)
I don't understand what you mean by drawing a path "discretely." A path is a continuous line defined by control points.
EDIT: Based on your edits, what I recommend experimenting with is an indexed colorspace (CGColorSpaceCreateIndexed()
). This way your gradient shouldn't be able to include intermediate colors, and calculations should be faster on the entire drawing.
You should also look at CGShading
. (I believe it's available for iOS and not just Mac.) It may be closer to what you want than CGGradient
.
精彩评论