ThinkGeo.com    |     Documentation    |     Premium Support

Z-index in a FeatureLayer

Hello,


I've a CustomFeatureLayer (inherited from FeatureLayer).

The GetFeaturesInsideBoundingBoxCore() method sends a lis of features with Points, Lines and Area.


The style of this layer is the following :


            var style = new ClassBreakStyle("TypeName");

            style.ClassBreaks.Add(new ClassBreak(double.MinValue, KubaGisStyles.DefaultLine));

            style.ClassBreaks.Add(new ClassBreak((int)TypeNames.KantonGrenzen, KubaGisStyles.Kanton));

            style.ClassBreaks.Add(new ClassBreak((int)TypeNames.GemeindeGrenzen, KubaGisStyles.Gemeinden));

            style.ClassBreaks.Add(new ClassBreak((int)TypeNames.GebietseinheitenGrenzen, KubaGisStyles.Gebietseinheiten));

            style.ClassBreaks.Add(new ClassBreak((int)TypeNames.RbbsNationalAxis, KubaGisStyles.RbbsLine));

            style.ClassBreaks.Add(new ClassBreak((int)TypeNames.RbbsNationalReferencePoints, KubaGisStyles.ReferencePoint));

            wfsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(style);

            wfsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;


When the map is drawn, the point features are always drawn under the line features. I would like to have the point over the line.


Is there a way to specify some kind of z-index on the feature in such a layer, in order to say that point must always be drawn over lines ?


Thanks,

Guillaume.



I also had this problem. The point shape was added after the line shape, even though, the points stood bellow the lines. 
 I had to add the points to another overlay in order to show them on top.

Hi Gustavo, 
  
 Thank you for your trick, but adding a new layer really means many modifications in my current code. If there isn’t any other solution I’ll probably do that, but for now I’ll wait to see if there is a more simple solution. 
  
 Guillaume.

Gustavo & Guillaume,


Thanks for your guys input and ideas, I appreciate it very much.
 
I think we can definitely solve this issue if we pay some attention to 2 issues.
1)Line Style Issue
Just plays around with the following test code with two kinds of LineStyles are used. In this small sample you can the great difference when using between LineStyle1 and LineStyle2. So when compound OutPen & InnerPen(Or and CenterPen) used LineStyle, it will make the point is drawn below.
 


 
 

winformsMap1.MapUnit = GeographyUnit.DecimalDegree;

winformsMap1.CurrentExtent = new RectangleShape(0, 100, 100, 0);
winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.StandardColors.White);

LineShape lineShape = (LineShape)BaseShape.CreateShapeFromWellKnownData("LINESTRING(60 60, 70 70,75 60, 80 70, 85 60,95 80)");
InMemoryFeatureLayer inMemoryLayer = new InMemoryFeatureLayer();

inMemoryLayer.InternalFeatures.Add("Line", new Feature(lineShape));
foreach (Vertex vertex in lineShape.Vertices)
{
     Feature pointFeature = new Feature(vertex.X, vertex.Y);
     inMemoryLayer.InternalFeatures.Add(pointFeature);
}

PointStyle pointStyle = new PointStyle( PointSymbolType.Circle,new GeoSolidBrush(GeoColor.FromArgb(255, GeoColor.StandardColors.Green)),20);
LineStyle lineStyle1 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20));
LineStyle lineStyle2 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20), new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Blue), 12));

inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = lineStyle1;
//inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = lineStyle2;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = pointStyle;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

LayerOverlay staticOverlay = new LayerOverlay();
staticOverlay.Layers.Add("InMemoryFeatureLayer", inMemoryLayer);
winformsMap1.Overlays.Add("InMemoryOverlay", staticOverlay);

winformsMap1.Refresh();

 
To solve this issue, I suggest we use the custom styles instead, following style give the same result when using lineStyle2 while keep point was drawn above.
 

PointStyle pointStyle = new PointStyle( PointSymbolType.Circle,new GeoSolidBrush(GeoColor.FromArgb(255, GeoColor.StandardColors.Green)),20);
LineStyle subStyle1 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20));
LineStyle subStyle2 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Blue), 12));
inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(subStyle1);
inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(subStyle2);            inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(pointStyle);

 
2) Add feature sequence issue.
 
The adding features sequence will also make some different even though we only use the OutPen for the LineStyle. In this case, it will draw the features as its adding sequence.
 


winformsMap1.MapUnit = GeographyUnit.DecimalDegree;

winformsMap1.CurrentExtent = new RectangleShape(0, 100, 100, 0);
winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.StandardColors.White);

LineShape lineShape = (LineShape)BaseShape.CreateShapeFromWellKnownData("LINESTRING(60 60, 70 70,75 60, 80 70, 85 60,95 80)");
InMemoryFeatureLayer inMemoryLayer = new InMemoryFeatureLayer();

foreach (Vertex vertex in lineShape.Vertices)
{
     Feature pointFeature = new Feature(vertex.X, vertex.Y);
     inMemoryLayer.InternalFeatures.Add(pointFeature);
}
inMemoryLayer.InternalFeatures.Add("Line", new Feature(lineShape));

PointStyle pointStyle = new PointStyle( PointSymbolType.Circle,new GeoSolidBrush(GeoColor.FromArgb(255, GeoColor.StandardColors.Green)),20);
LineStyle lineStyle1 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20));
LineStyle lineStyle2 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20), new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Blue), 12));

inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = lineStyle1;
//inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = lineStyle2;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = pointStyle;
inMemoryLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

LayerOverlay staticOverlay = new LayerOverlay();
staticOverlay.Layers.Add("InMemoryFeatureLayer", inMemoryLayer);
winformsMap1.Overlays.Add("InMemoryOverlay", staticOverlay);

winformsMap1.Refresh();

 
In order to solve this problem, we may need to reorder the feature sequence at the beginning or before the DrawCore in your customized feature layer.
 
Any more questions just feel free to let me know.
 
Thanks.
 
Yale

Guys, 
  
   I would try the CustomStyles collection and add whatever style you want to draw first the first one in the collection.  The way to get the most control would be to create you own style and then in the style you can choose what drawing level each features gets drawn on.  There are is a video and samples on how to create your own style at the link below.  I would only go this route if the custom styles collection doesn’t do what you need but I think it will.  Let us know your results. 
  
 Extending Map Suite: Creating Custom Styles 
 gis.thinkgeo.com/Products/GISComponentsforNETDevelopers/MapSuiteDesktopEdition/Videos/tabid/679/Default.aspx 
  
 David

Hello, 
  
 It has been almost 4 months, but I finally tried this solution (the first one), and it worked very well. 
  
 Thanks ! 
 Guillaume.

Hi Yale, 
  
  When you add more than one CustomStyle to the CustomStyles collection as in: 
  
 
PointStyle pointStyle = new PointStyle( PointSymbolType.Circle,new GeoSolidBrush(GeoColor.FromArgb(255, GeoColor.StandardColors.Green)),20);
LineStyle subStyle1 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Red), 20));
LineStyle subStyle2 = new LineStyle(new GeoPen(GeoColor.FromArgb(200, GeoColor.StandardColors.Blue), 12));
inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(subStyle1);
inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(subStyle2);            inMemoryLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(pointStyle);
 
 
  
  How does the Feature know which one to use? It wouldn’t be just posible to set the SubStyle custom style to de DefaultStyle property?

Carlos, 
  
 If you add more than one style into CustomStyles, it will loop all custom styles, use each one to draw feature on the canvas. For example, you have two lineStyles, you can not set DefaultLineStyle for both, but you can add them to CustomStyles collection, and then you can see the result for both. 
 Your first pen is semi-transparent red, your second pen is semi-transparent blue, so the result will be mixed two colors but more like blue. 
  
 Thanks 
 James


    So all the CustomStyles are applied to all of the Features, right? so it would be possible to do the same with just one custom style by writting the proper DrawCore code, isn’t it?

Carlos, 
  
 Yes for both. We have some style can do the same as many styles do, such as ValueStyle, ClassBreakStyle, and also we provide many simple samples to demostrate how to use styles at HowDoI sample. 
  
 Thanks 
 James

Ok, seems that the more powerful way to take control over the rendering is by using a CustomStyle and add all the functionality within it. 
  
  Thanks a lot James. 
  
 Carlos. 


Carlos, 
  
 Yes, you are right. Our MapSuite is designed for progressive framework, so that the beginners can quickly start to use it, and the senior users also can do very complex thing by use it. 
  
 No problem, just fell free to ask questions. 
 James

That’s nice. The only thing is that It takes time until a beginner realizes what can be done with each technique and what cannot be done, or what’s more eficient. For instance I start creating one layer per feature so it was possible to configure a unique style for each one (as for fulfill one of my project requirements), it was working but the performance was very very bad. 
  
     Now I found this customstyles approach, and I have full control on the rendering, so is easy to give an unique style for every single object depending on it’s type, state, etc, all of them on the same layer and the same overlay, so the performance is good again. 
  
     Once you have a CustomStyle, you can do almost anything as in the lots of CustomStyles examples they are (AdjustedScalingImageStyle, ClusterPointStyle, CachedValueStyle, SizedPointStyle, TimeBasedPointStyle, etc) or even better, to combine them to create a really stunning effect.

Now I found this customstyles approach, and I have full control on the rendering, so is easy to give an unique style for every single object depending on it’s type, state, etc, all of them on the same layer and the same overlay, so the performance is good again.   
  
 Carlos, out of curiosity, how are you arranging your layers and overlays as it sounds like you have a lot of layers.  Do you allow the user to be able to turn off some layers? 
  


Hi Klaus, 
  
  I tested with one layer per object before discovering the customstyles, now I plot all the “assets” on two layers, so I don’t have that much. My constant questions on performance is because the software is going to be used to track fleets of 200-2700 assets reporting up to once every hour, and I tracks might contain a couple of months of info, what it’s a lot. In addition, every asset has it’s own style (different icon, icon color, track line size, and other icon addons depending on it’s status) 
  
  The development is pretty alpha now, I’m just learning and testing in order to get all the building blocks I will need, but by know I have: 
  
 >BackgroundOverlay (WpfMap property)- SolidBrush 
 >WorldMapOverlay (LayerOverlay) 
 -->BackgroundLayer (BackgroundLayer)- SolidBrush 
 -->KMLLayerZEE (KmlFeatureLayer) - ZEE zones as a poligons from a kml file 
 -->WorldCountriesLayer (ShapeFileFeatureLayer) - Countries02 shape file from MapSuite 
  
 >AdornmentOverlay (WpfMap property) 
 -->Graticule (GraticuleAdornmentLayer) - CustomGraticuleAdornment that works beyond 180º boundary 
 -->ScaleBarLayer (CustomUnitScaleBarLayer) - Custom ScaleBar 
 -->GraphicLogoAdornment (GraphicLogoAdornmentLayer) 
  
 >PopupOverlay 
 >LayersOverlay (LayersOverlay) 
 -->VesselGPS (InMemoryFeatureLayer) - With a moving icon for the vessel GPS position 
  
 >TracksOverlay (LayerOverlay) 
 -->TrackPointsFeatureLayer (InMemoryFeatureLayer) - With CustomTrackStyle for the track of the individual position reports within the line tracks 
 -->TracksFeatureLayer (InMemoryFeatureLayer) - With CustomTrackStyle for the track lines as LineShapes 
 -->TrackIconsFeatureLayer (InMemoryFeatureLayer) - With CustomTrackStyle for the icons as PointShapes (with all shorts of customizations) 
  
 CustomTrackStyle is a single class that handles the Style based on a ColumnAttribute of the element called “IconStyle”, that contains a serialized XML with an object defining specific properties such as configured icon, if the icon is rotated with the heading direction or not, track color and width, etc. Is the same for all the TracksOverlay Layers, but DrawCore takes care of the kind of Feature being rendered. 
  
   It will be a “Track” overlay (as in HowDoI samples) for user elements like a ruler, waypoints, etc (Probably I will rename my TracksOverlay in order to avoid confusion, it’s because it’s an asset tracking application and I used to call “tracks” to the asset tracks)

I’m realizing this is a bit of offtopic, I should answered you in the Layers and Overlays Summary thread ;)

Carlos, 
  
 I agree with you, let us talk about it in the Layers and Overlays Summary thread. 
  
 Thanks 
 James