ThinkGeo.com    |     Documentation    |     Premium Support

Drawing Wind barbs

Hello,


I need to draw wind barbs on the map every 1 degree.

I initially was thinking to use ESRI Weather font and was able to draw wind barbs for Northern hemisphere.

For Southern hemisphere, wind barbs need to be flipped and I didn’t find any good option to flip a font.


fonts2u.com/esri-weather.font


Could you please suggest what is a best way to flip the font or maybe there is a different way to draw wind barbs?


Thank you,

Inna



Why not use a Marker, an image, and rotate transform.  You would have to have an icon for every wind speed, but you should be able to find them on the net.  Then select the file based on windspeed an rotate it using myAngle below…


Dim myAngle As Integer = 44 'vary this by whatever degrees you need
Dim As New BitmapImage(New Uri(“iconfile”))
Dim TempImage As TransformedBitmap = New TransformedBitmap()
TempImage.BeginInit()
TempImage.Source = b
Dim flipTrans As ScaleTransform = New ScaleTransform()
flipTrans.ScaleY = -1
Dim rotTransform As New RotateTransform(myAngle)
Dim tranGrp As New TransformGroup
tranGrp.Children.Add(flipTrans)
tranGrp.Children.Add(rotTransform)
TempImage.Transform = tranGrp
TempImage.EndInit()
Dim As New Marker
m.ImageSource = TempImage






Updated when I realized you wanted to flip as well… so added transform group and ScaleTransform(set to -1 to flip about Y)

Hi Inna, 
  
 I think Michael’s suggestion is pretty well for use marker instead of font, you can easier to control its position. 
  
 Here I have another solution, you can try to set DefaultTextStyle.RotationAngle = 180 for Southern hemisphere, but for that, you have to split Northern hemisphere and Southern hemisphere in different layer. 
  
 You can also write a custom textstyle and put your logic in it, that’s a little more complex. 
  
 Regards, 
  
 Don

Hi Michael and Don,


Michael – your approach is too heavy for displaying 1x1 gridded data for entire earth. 

Don – RotationAngle=180 doesn’t help me in my case, I need to apply “mirror” effect for any angle in southern hemisphere.


I also tried to use custom style and images, similar to what Michael suggested but it is also heavy and unusable for 1x1 data.

Here is my code. Any ideas how to improve this?



protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
       {
           foreach (Feature feature in features)
           {
               float angle =  float.Parse(feature.ColumnValues["val"]);
               PointShape centerPoint = feature.GetBoundingBox().GetCenterPoint();
 
               //PointStyle p = new PointStyle();
               //p.CharacterIndex = 233;
               //p.CharacterFont = new GeoFont("ESRI Weather", 25, DrawingFontStyles.Bold);
               //p.PointType = PointType.Character;
               //p.CharacterSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.LightGreen);
               //p.Draw(new Collection<Feature>() { feature }, canvas, labelsInThisLayer, labelsInAllLayers);
 
               GeoImage geoImg = new GeoImage("Wind_S_0.png");
               canvas.DrawWorldImageWithoutScaling(geoImg, centerPoint.X, centerPoint.Y, DrawingLevel.LabelLevel, 0, 0, angle);
           }
       }

Inna


Ok… guess I am not quite sure what you are doing and why you would show that many windbarbs when zoomed out, but in my app I have plotted over 50,000 windbarbs of ASCAT and OSCAT data in a similar way.  I do cache the images so when I first create the bitmap I see if it already exists (filename something like windbarb_25_141.png for winbarb_windspeed_angle.png.  If it does not exist, then I create and save then use.

Inna, 
  
 It looks your barbs will be with different angle in each grid. 
  
 But why it’s heavy? When you are in decimal degree, the max number of windbarbs should only about 64800, and you won’t need render them under any extent. 
  
 If it’s really slow, could you please let me know how you write your custom style? A simple sample should be better. 
  
 If the code you paste is come from your custom text style which inherited from text style, please don’t loop all features but just loop the feature with current extent. 
  
 You can try to add this code in your DrawCore function: Collection<Feature> candidateFeatures = FilterFeatures(features, canvas); 
  
 And just loop candidateFeatures. 
  
 Wish that’s help. 
  
 Regards, 
  
 Don

Hi,


With caching the performance is reasonable, but not as fast as using fonts.

I guess I don’t have any choice but using images and rotate them.


Don – I tested your suggestion about FilterFeatures, but it returns me the same number of features as in features object.


Thank you all for your help.

Inna



Not sure how you are using the font, and I’ve never tried it before, but could you use RotateTransform or LayoutTransform with however you are containing the font?

Inna, 
  
 In fact I have same question about how to use font in your scenario. 
  
 About the performance, I think you should want to make sure where takes most time, if  
 canvas.DrawWorldImageWithoutScaling(geoImg, centerPoint.X, centerPoint.Y, DrawingLevel.LabelLevel, 0, 0, angle);  
 takes most time, I think you can improve it. 
  
 Regards, 
  
 Don

Hi,


Here is how I wanted to use a ESRI Weather font, but without mirroring effect it’s no use for me.



public class WindFontStyle: TextStyle
    {
        public WindFontStyle()
            base()
        {
            
 
        }
 
        protected override Collection<string> GetRequiredColumnNamesCore()
        {
           
            var results = new Collection<string>(){"val""spd"};
            return results;
        }
 
        
        
        protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
             
            foreach (Feature feature in features)
            {
                float angle = float.Parse(feature.ColumnValues["val"]);
 
                bool isSouth = false;
                PointShape pointDegrees = (PointShape)Singleton.DefaultProjection.ConvertToInternalProjection(feature.GetBoundingBox().GetCenterPoint());
                if (pointDegrees.Y < 0)
                    isSouth = true;
                
                PointStyle p = new PointStyle();
                p.CharacterFont = new GeoFont("ESRI Weather", 25, DrawingFontStyles.Bold);
                p.PointType = PointType.Character;
                p.CharacterSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.LightGreen);
                p.RotationAngle = angle;
                p.CharacterIndex = 233;
                p.Draw(new Collection<Feature> { feature }, canvas, labelsInThisLayer, labelsInAllLayers); 
 
            }
        }
         
    }

Because I’m also implementing “progressive disclosure” part, looping for 360x180 features and deciding what to display takes time.

Attached is my implementation of progressive disclosure. Maybe it could be improved…

    

I am also really interesting to know how can I improve DrawWorldImageWithoutScaling performance.


Inna



WindStyle.txt (4.74 KB)

Hi Inna, 
  
 It looks you have implemented it but it’s still slow without cache? Are you sure that caused by DrawWorldImageWithoutScaling function? 
  
 Maybe you want to write your own FilterFeatures function to reduce unnecessary draw image. 
  
 Regards, 
  
 Don

Hi Don,


Yes. It is still slow with the wind symbol caching.

I already wrote my own FilterFeatures function (see WindStyle.txt from previous post), it helped, but not enough.


Inna



Hi Inna, 
  
 Sorry I haven’t notice you have override FilterFeaturesCore.  
  
 In fact we have an IconStyle which is similar with your WindFontStyle, I compare the code and found you optimize the code best. So for now, if you want to go on enhancement it, I think maybe you want to use some helper utility like Profiler, for make sure where takes most memory and CPU, for now DrawWorldImageWithoutScaling is not easy to improve. 
  
 Regards, 
  
 Don