ThinkGeo.com    |     Documentation    |     Premium Support

Custom Styles

I am using a custom point style to draw rotated and scaled point symbols based on database values.  I have successfully implemented this code.  I found that I couldn't use DefaultLineStyle if I have added a CustomStyle, so I am trying to implement a custom line style as well.  This will work out well for my project, but I have run into an problem.  The DrawCore override in the custom line style trys to draw point symbols as well.   Code is as follows:


 



using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.DesktopEdition;

class MyLineStyle : LineStyle
{
    private LineStyle lineStyle;

    public MyLineStyle()
        : this(new LineStyle())
    { }

    public MyLineStyle(LineStyle lineStyle)
    {
        this.lineStyle = lineStyle;
    }

    protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
    {
        foreach (Feature feature in features)
        {
            float Width = Convert.ToSingle(feature.ColumnValues["Width"]);
            GeoColor Color = new GeoColor(0, 0, 0);
            if (MyProject.UseLayers)
            {
                Color = GeoColor.FromWin32(DataInterface.GetLayerColor(Convert.ToInt32(feature.ColumnValues["Layer"])));
            }
            else
            {
                Color = GeoColor.FromWin32(Convert.ToInt32(feature.ColumnValues["Color"]));
            }
            canvas.DrawLine(feature, new GeoPen(Color, Width), DrawingLevel.LevelFour, 0, 0);
        }

        //base.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers);
    }
    
    protected override Collection<string> GetRequiredColumnNamesCore()
    {
        Collection<string> columns = new Collection<string>();
        columns = lineStyle.GetRequiredColumnNames();
        if (!columns.Contains("FeatureText"))
        {
            columns.Add("FeatureText");
        }
        if (!columns.Contains("TextJust"))
        {
            columns.Add("TextJust");
        }
        if (!columns.Contains("Angle"))
        {
            columns.Add("Angle");
        }
        if (!columns.Contains("RScale"))
        {
            columns.Add("RScale");
        }
        if (!columns.Contains("SymbolImage"))
        {
            columns.Add("SymbolImage");
        }
        if (!columns.Contains("Width"))
        {
            columns.Add("Width");
        }
        if (!columns.Contains("Color"))
        {
            columns.Add("Color");
        }
        if (!columns.Contains("Layer"))
        {
            columns.Add("Layer");
        }
        return columns;
    }

}
 

 


The error occurs at canvas.DrawLine.  When I check Feature.GetWellKnownText I get "POINT(582429.33 266601.63)".  I could check this but it seems a waste of processing time since point features shouldn't go through LineStyle.DrawCore.  What am I doing wrong?  Do all features go through DrawCore for all styles?  Is there an easier way to check the feature type?   



Charles, 
  
   I think I can help you on your questions.  The first this is the use of the CustomStyles collection with DefaultLineStyle.  The reason we did this was people were confused by the drawing order or always wanted a different one ie CutomsStyles before default styles or vice versa.  What we decided to do was to say if you want to use a custom style then you need to use the collection, take full control and leave the default properties behind.  It is easy to create a LineStyle and place it in the CustomStyle.  Just some background on this.  The default styles are there to really just fill the case where you want some simple rendering, once you move to something complex then the CustomStyles collection is the place you want to be. 
  
 The Style system is pretty flexible and we don’t limit one type of shape per style.  Since LineStyle inherits from Style we really don’t know it is a line style per say.  Many people have designed styles that handle multiple shape types.  We recommend that people try and keep it to one style type per shape type for sanity sakes but we don’t impose that limitation.  In our default implementation of LineStyle we do check the type but that got replaced when you overrode DrawCore.  In our previous Map Suite Versions where we just handled shape file things were like this however with the advent of spatial databases and other formats it is possible to get points  or areas mixed in with all kinds of other shape types.  Not to worry as what we typically do is inside of the DrawCore inside the features loop we do a feature.GetWellKnownType(), an enumeration, and check it.  This will pass back the well known type like point, polygon etc.  It is pretty efficient because it just indexes into a fixed location in the byte array that stores the well known binary.  Every feature is just a structure shell around an array of well known binary that holds the shape  itself.  We tried to make this very efficient. 
  
 David

David, 
  
 Thanks for the quick reply.  I thought it might be something like that, and I event thought about creating one style to handle everything but I think I will stick to two (text is just a point with text data rather than symbol data). 
  
 Charles

Charles, 
  
   It was my pleasure.  Styles are cheap and easy to build so I say build them to optimize your specific case.  As a shameless plug for my video…  If you haven’t watched the 45 minute video on building styles then I highly recommend it.  It is full of helpful advise on building all kinds of powerfull styles. 
  
 You can find the video as a link here: 
 gis.thinkgeo.com/Support/DiscussionForums/tabid/143/aff/16/aft/5418/afv/topic/Default.aspx 
  
 David