ThinkGeo.com    |     Documentation    |     Premium Support

Get map color from shape file column?

I'm guessing this is going to be really obvious when I see the answer, but I haven't been able to find this in my testing. I'm loading a shape file that has a colors column that I would like to use to define the fill color of the shape file areas. The column contains the argb values for the color. Is there a way I can use this value directly to define my areaStyle?


Thank you in advance,


Kimberly



Kimberly, 
  
 You can implement this by creating your own AreaStyle. Here I generate a shape file with 4 columns (“A”, “R”, “G”, “B”) and render it based on those columns. Please have a look. 
  
 
// The AreaStyle I recreated for render
class ARGBAreaStyle : AreaStyle
    {
        protected override void DrawCore(System.Collections.Generic.IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
            foreach (Feature feature in features)
            {
                int a = int.Parse(feature.ColumnValues["A"]);
                int r = int.Parse(feature.ColumnValues["R"]);
                int g = int.Parse(feature.ColumnValues["G"]);
                int b = int.Parse(feature.ColumnValues["B"]);
                canvas.DrawArea(feature, this.OutlinePen, new GeoSolidBrush(GeoColor.FromArgb(a, r, g, b)), DrawingLevel.LevelOne, this.XOffsetInPixel, this.YOffsetInPixel, this.PenBrushDrawingOrder);
            }
        }
    }

// Here is how to use the style
 ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer("c:\testShp.shp");
            ARGBAreaStyle argbAreaStyle = new ARGBAreaStyle();
            argbAreaStyle.RequiredColumnNames.Add("A");
            argbAreaStyle.RequiredColumnNames.Add("R");
            argbAreaStyle.RequiredColumnNames.Add("G");
            argbAreaStyle.RequiredColumnNames.Add("B");
            layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(argbAreaStyle);
            layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            

// Here is how I generate the test data
  private static void CreateShapeFile(string filePath)
        {
            List<DbfColumn> dbfColumns = new List<DbfColumn>();
            dbfColumns.Add(new DbfColumn("A", DbfColumnType.String, 10, 0));
            dbfColumns.Add(new DbfColumn("R", DbfColumnType.String, 10, 0));
            dbfColumns.Add(new DbfColumn("G", DbfColumnType.String, 10, 0));
            dbfColumns.Add(new DbfColumn("B", DbfColumnType.String, 10, 0));
            ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Polygon, filePath, dbfColumns);

            Dictionary<string, string> columns1 = new Dictionary<string, string>();
            columns1.Add("A", "128");
            columns1.Add("R", "255");
            columns1.Add("G", "0");
            columns1.Add("B", "128");
            Feature feature1 = new Feature(new PolygonShape("Polygon((0 0,10 0,10 10,0 10,0 0))"), columns1);

            Dictionary<string, string> columns2 = new Dictionary<string, string>();
            columns2.Add("A", "128");
            columns2.Add("R", "0");
            columns2.Add("G", "255");
            columns2.Add("B", "255");
            Feature feature2 = new Feature(new PolygonShape("Polygon((0 0,5 0,5 5,0 5,0 0))"), columns2);

            ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(filePath, ShapeFileReadWriteMode.ReadWrite);
            layer.FeatureSource.Open();
            layer.FeatureSource.BeginTransaction();
            layer.FeatureSource.AddFeature(feature1);
            layer.FeatureSource.AddFeature(feature2);
            layer.FeatureSource.CommitTransaction();
            layer.FeatureSource.Close();
        }
 
 Thanks, 
  
 Ben

Ben, 
  
   I think you might have missed this a bit. :-)  I think what Kimberly means is that she has one column with an ARGB value.  I might be wrong though. 
  
 Kimberly – Can you show us the format of the ARGB value is it like ‘0,255,0,0’ or something like this?  In any event I think Ben’s sample almost what you need.  If you give us the format we can modify the sample.  That is unless you can take it from here. 
  
 David

Hi David, your message is funny.


You are right. I do have one column with the 4 values. It looks like '0,0,204,128' without the quotes. I had meant to take the code that was posted and try to modify it for my needs, but I haven't gotten to it. I apologize for leaving the thread open, I just haven't had a chance to touch it. I will try to get to it today and post a new message.


Thank you both!


Kimberly


 



Kimberly, 
  
 Here is the new ARGBStyle which supports the format as ‘0,0,204,128’. It doesn’t change a lot but makes it more practical to use.  
  
 
// The AreaStyle I recreated for render
 class ARGBAreaStyle : AreaStyle
    {
        protected override void DrawCore(System.Collections.Generic.IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
            foreach (Feature feature in features)
            {
                string[] elements = feature.ColumnValues[“ARGB”].Split(’,’);
                int a = int.Parse(elements[0]);
                int r = int.Parse(elements[1]);
                int g = int.Parse(elements[2]);
                int b = int.Parse(elements[3]);
                canvas.DrawArea(feature, this.OutlinePen, new GeoSolidBrush(GeoColor.FromArgb(a, r, g, b)), DrawingLevel.LevelOne, this.XOffsetInPixel, this.YOffsetInPixel, this.PenBrushDrawingOrder);
            }
        }
    }

// Here is how to use the style
  ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(“c:\TestData\ARGBShape.shp”);
  ARGBAreaStyle argbAreaStyle = new ARGBAreaStyle();
  argbAreaStyle.RequiredColumnNames.Add(“ARGB”);
  layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(argbAreaStyle);
  layer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

// Here is how I generate the test data
    private static void CreateShapeFile(string filePath)
        {
            List<DbfColumn> dbfColumns = new List<DbfColumn>();
            dbfColumns.Add(new DbfColumn(“ARGB”, DbfColumnType.String, 20, 0));
            ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Polygon, filePath, dbfColumns);

            Dictionary<string, string> columns1 = new Dictionary<string, string>();
            columns1.Add(“ARGB”, “128,255,0,128”);
            Feature feature1 = new Feature(new PolygonShape(“Polygon((0 0,10 0,10 10,0 10,0 0))”), columns1);

            Dictionary<string, string> columns2 = new Dictionary<string, string>();
            columns2.Add(“ARGB”, “128,0,255,255”);
            Feature feature2 = new Feature(new PolygonShape(“Polygon((0 0,5 0,5 5,0 5,0 0))”), columns2);

            ShapeFileFeatureLayer layer = new ShapeFileFeatureLayer(filePath, ShapeFileReadWriteMode.ReadWrite);
            layer.FeatureSource.Open();
            layer.FeatureSource.BeginTransaction();
            layer.FeatureSource.AddFeature(feature1);
            layer.FeatureSource.AddFeature(feature2);
            layer.FeatureSource.CommitTransaction();
            layer.FeatureSource.Close();
        }
 
 Thanks, 
  
 Ben

Ben, 
 This works for PolygonStyle. How about Line and point styles. How do i color them using above technique. I tried several ways but failed to do it. appreciate your help.

Hello rajanikanth,


What Ben did is just write a ARGBAreaStyle inherit from AreaStyle, if you want to using in the Line and Point, you can just refer his thought and finish your OwnLineStyle and PointStyle, then the way to get the ARGB from the database, you have a lot of choice.



    public class TestLineStyle : LineStyle
    {
        protected override void DrawCore(System.Collections.Generic.IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
            foreach (Feature feature in features)
            {
                int a = 0;
                int r = 0;
                int g = 0;
                int b = 0;
                canvas.DrawLine(feature, new GeoPen(GeoColor.FromArgb(a, r, g, b)), DrawingLevel.LabelLevel);
            }
        }
    }

Let me know if you have any questions.


Regards,


Gary