ThinkGeo.com    |     Documentation    |     Premium Support

Muliple DotDensityStyles on one layer?

 Howdy good people,


Does anyone know whether it is possible to put more than one DotDensityStyle on a single layer. I have a suburbs layer which needs to display more than one dot density on different fields.


Currently i'm using cloneDeep to duplicate the layer and then create a new DotDensityStyle on the cloned layer, not so sure whether this is the best route. Could anyone tell me?


Thanks


Eugene


 



 


Hi, Eugene
Why don’t construct one new DotDesityStyle and add it to the CustomStyles collection of FeatureLayer directly? There is no need to construct one additional FeatureLayer. Please refer to the codes below:
                ShapeFileFeatureLayer statesLayer = new ShapeFileFeatureLayer(Server.MapPath("~/SampleData/USA/states.shp"));                
                statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
               
                DotDensityStyle dotDensityStyle = new DotDensityStyle();
                dotDensityStyle.ColumnName = "POP1990";
                dotDensityStyle.PointToValueRatio = 0.00002;
                dotDensityStyle.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.OrangeRed)), 4);
                statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle);
 
                DotDensityStyle dotDensityStyle1 = new DotDensityStyle();
                dotDensityStyle1.ColumnName = "POP1990";
                dotDensityStyle1.PointToValueRatio = 0.0000002;
                dotDensityStyle1.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Black)), 4);
                statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle1);
 
Thanks,
Khalil

 Hi Khalil,


Thank you for your speedy reply!


The problem that occurs when you load them all on the same featurelayer is that they get loaded above each other.


In this image there are multiple featurelayers and each style is scattered according to the it's own amount.



In this one, i used a single feature layer and the result is that it doesn't scatter each dot according to their own column name, but rather seem to put them on top of one another. The effect is that it blends the colours where 2 dots are right above each other (eg the purple dots). When zoomed right in it becomes more obvious as some colours never display.




Here is the code i used for the single feature layer 
  
 '### thematics
            Dim suburbs As New MsSql2008FeatureLayer(connSpatial, “VW_SUBURB_IMS_DD”, “mi_prinx”)
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(New AreaStyle(New GeoPen(GeoColor.FromHtml("#000000")), New GeoSolidBrush(GeoColor.SimpleColors.Transparent)))
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(TextStyles.Urban1(“Suburb”))
            suburbs.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
            suburbs.DrawingMarginPercentage = 1

            Dim ddOther As DotDensityStyle = New DotDensityStyle
            ddOther.ColumnName = “ALL_OTHER_PRIVATE”
            ddOther.PointToValueRatio = 1
            ddOther.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Red)), 8)
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddOther)

            Dim ddMP As DotDensityStyle = New DotDensityStyle
            ddMP.ColumnName = “MEDICAL_PRACTITIONERS”
            ddMP.PointToValueRatio = 1
            ddMP.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Blue)), 8)
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddMP)

            Dim ddPH As DotDensityStyle = New DotDensityStyle
            ddPH.ColumnName = “PRIVATE_HOSPITALS_AND_CLINICS”
            ddPH.PointToValueRatio = 1
            ddPH.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Green)), 8)
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPH)

            Dim ddPR As DotDensityStyle = New DotDensityStyle
            ddPR.ColumnName = “PRIVATE_RETAIL_PHARMACIES”
            ddPR.PointToValueRatio = 1
            ddPR.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Orange)), 8)
            suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPR)

              dynamicOverlay.Layers.Add(“suburbs”, suburbs) 


I don't think that what you are describing is occuring more in one case than in the other. The dots are placed randomly on the polygon, so whether you use one FeatureLayer with two DotDensityStyles or two FeatureLayers with one DotDensityStyles, the behavior is going to be the same. I think that in your screenshots, it was just coincidence that one case the dots appear more on top of each others than in the other case. To illustrate my point, I use the sample data USStates shapefile and use the columns "AGE_18_64" with one DotDensityStyle and "AGE_65_UP" for the other one. (The PointToValueRatio is 0.00001 or 1 dot represents 100,000 inhabitants (1 / 100000) = 0.00001 ). In one case, I use one FeatureLayer, in the second case, I use two FeatureSources. You can see in the screenshots that there is no more overlapping in one case than in the other. The dots are placed ramdomly within the polygon they belong to.


Case 1: One Featurelayer with two DotDensityStyles



 


Case 2: Two Featurelayers with one DotDensityStyle each




For purpose of completeness, I add the code I used for my explanation:


 



    //Case 1: One FeatureLayer with two DotDensityStyles
    winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
    winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

    ShapeFileFeatureLayer statesLayer = new ShapeFileFeatureLayer(@"../../data/USStates.shp");
    statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

    statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.StandardColors.Black,1),new GeoSolidBrush(GeoColor.StandardColors.LightGray)));

    DotDensityStyle dotDensityStyle = new DotDensityStyle();
    dotDensityStyle.ColumnName = "AGE_18_64";
    dotDensityStyle.PointToValueRatio = 0.00001; // (1 / 100,000) = 0.00001
    dotDensityStyle.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.OrangeRed)), 6);
    statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle);

    DotDensityStyle dotDensityStyle1 = new DotDensityStyle();
    dotDensityStyle1.ColumnName = "AGE_65_UP";
    dotDensityStyle1.PointToValueRatio = 0.00001; // (1 / 100,000) = 0.00001
    dotDensityStyle1.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Green)), 6);
    statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle1);

    LayerOverlay layerOverlay = new LayerOverlay();
    layerOverlay.Layers.Add("States",statesLayer);
    winformsMap1.Overlays.Add("Overlay",layerOverlay);

    statesLayer.Open();
    winformsMap1.CurrentExtent = statesLayer.GetBoundingBox();
    statesLayer.Close();

    winformsMap1.Refresh();
 

    //Case 2: Two FeatureLayers with one DotDensityStyle each
    winformsMap1.MapUnit = GeographyUnit.DecimalDegree;
    winformsMap1.BackgroundOverlay.BackgroundBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);

    ShapeFileFeatureLayer statesLayer = new ShapeFileFeatureLayer(@"../../data/USStates.shp");
    statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;

    statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new AreaStyle(new GeoPen(GeoColor.StandardColors.Black, 1), new GeoSolidBrush(GeoColor.StandardColors.LightGray)));

    DotDensityStyle dotDensityStyle = new DotDensityStyle();
    dotDensityStyle.ColumnName = "AGE_18_64";
    dotDensityStyle.PointToValueRatio = 0.00001; // (1 / 100,000) = 0.00001
    dotDensityStyle.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.OrangeRed)), 6);
    statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle);


    ShapeFileFeatureLayer statesLayer1 = (ShapeFileFeatureLayer)statesLayer.CloneDeep();

    DotDensityStyle dotDensityStyle1 = new DotDensityStyle();
    dotDensityStyle1.ColumnName = "AGE_65_UP";
    dotDensityStyle1.PointToValueRatio = 0.00001; // (1 / 100,000) = 0.00001
    dotDensityStyle1.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Green)), 6);
    statesLayer1.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(dotDensityStyle1);

    LayerOverlay layerOverlay = new LayerOverlay();
    layerOverlay.Layers.Add("States", statesLayer);
    layerOverlay.Layers.Add("States1", statesLayer1);
    winformsMap1.Overlays.Add("Overlay", layerOverlay);

    statesLayer.Open();
    winformsMap1.CurrentExtent = statesLayer.GetBoundingBox();
    statesLayer.Close();

    winformsMap1.Refresh();


 Again, thank you very very much for the reply.


I'm not sure what i'm doing wrong, but i'll illustrate the effect with this suburb (stuarts hill) as an example


This link goes opens the map with multiple layers and , as you can see, irrespective of how many times you refresh, it always shows 3 dots:


test.lightstone.co.za/mapsui...8074703813


 


This one, uses the single layer and always only shows 2 dots as it merges 2 of the dots together:


test.lightstone.co.za/mapsui...p;single=1


I'll publish the code right after this


 



I have put both the single and multilayer in the same function differentiated using the querystring parameter “single” 
 Please let me know whether you can find the problem. 
 Kindest Regards 
  
 Eugene 
  
 
Dim googleBounds As String = Request(“b”)
Dim bounds As New RectangleShape(clsFunctions.RertunPolyGonStringFromGoogleBounds(googleBounds))
Map1.CurrentExtent = bounds

’### thematics
Dim suburbs As New MsSql2008FeatureLayer(connSpatial, “VW_SUBURB_IMS_DD”, “mi_prinx”)
suburbs.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20
suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(AreaStyles.Country2)
suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(TextStyles.Urban1(“Suburb”))

Dim suburbs2 As FeatureLayer
Dim suburbs3 As FeatureLayer
Dim suburbs4 As FeatureLayer

If Request(“single”) = Nothing Then
    suburbs2 = suburbs.CloneDeep
    suburbs3 = suburbs.CloneDeep
    suburbs4 = suburbs.CloneDeep
End If


Dim ddOther As DotDensityStyle = New DotDensityStyle
ddOther.ColumnName = "ALL_OTHER_PRIVATE"
ddOther.PointToValueRatio = 1
ddOther.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Red)), 8)

suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddOther)

Dim ddMP As DotDensityStyle = New DotDensityStyle
ddMP.ColumnName = "MEDICAL_PRACTITIONERS"
ddMP.PointToValueRatio = 1
ddMP.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Blue)), 8)


If Request(“single”) = Nothing Then
    suburbs2.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddMP)
Else
    suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddMP)
End If

Dim ddPH As DotDensityStyle = New DotDensityStyle
ddPH.ColumnName = "PRIVATE_HOSPITALS_AND_CLINICS"
ddPH.PointToValueRatio = 1
ddPH.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Green)), 8)

If Request(“single”) = Nothing Then
    suburbs3.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPH)
Else
    suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPH)
End If

Dim ddPR As DotDensityStyle = New DotDensityStyle
ddPR.ColumnName = "PRIVATE_RETAIL_PHARMACIES"
ddPR.PointToValueRatio = 1
ddPR.CustomPointStyle = New PointStyle(PointSymbolType.Circle, New GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.StandardColors.Orange)), 8)

If Request(“single”) = Nothing Then
    suburbs4.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPR)
Else
    suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(ddPR)
End If

dynamicOverlay.Layers.Add(“suburbs”, suburbs)
If Request(“single”) = Nothing Then
    dynamicOverlay.Layers.Add(“suburbs2”, suburbs2)
    dynamicOverlay.Layers.Add(“suburbs3”, suburbs3)
    dynamicOverlay.Layers.Add(“suburbs4”, suburbs4)
End If


dynamicOverlay.TileType = TileType.SingleTile

Map1.CustomOverlays.Add(dynamicOverlay)

 


I did some tests using 1 as a value for the property PointToValueRatio meaning that there should be as many dots as the count in the column. I found some unconsistent behavior. I contacted the development team and they should respond to us soon to tell us if this is a bug. Thank you for your cooperation.

Hi Val,  
 Just want to say that you guys ROCK! 
  
 We have migrated all our codefrom MapXtreme, on whose forum i must have posted upwards of 30 problems without getting a single reply. 
  
 I just want to congratulate you on awesome support.

Eugene, 


I have created a sample to try to reproduce this problem, as my result, I think it’s not a bug. Two cases results are the same. I also attached my sample code you can try it as well.



Thanks


James



MultipleDotDensityStyles.zip (103 KB)

Hi James,  
  
 Thanks for the reply. 
  
 I checked your code, and compared it to mine, but can’t for the life of me figure out where mine is going wrong. 
 If you check the 2 url’s posted above, you will see that the dots are stacked on top of each other every single time the page with single layer and multiple styles is executed, whereas it never ever happens when multiple layers are used.  
  
 Obviously the mutliple layer approach is causing a huge performance hit as it executes the sql query 4 times - once for every style. Having a single layer is literally 4 times faster. Unfortunately, as my example shows, i can’t use a single layer as dots are disappearing. Any ideas. Could it possibly have something to to with it being a sql2008 feature layer? 
  
 Cheers 
  
 Eugene

Eugene, 
  
 We have fixed a bug for DotDensityStyle, I think it related with your problem. Please get the lastest version of MapSuiteCore.DLL from custom portal. 
  
 Let me know if it still has problem. 
 Thanks 
 James

HI James, 
  
 Again, thank you very much for your reply. You guys truely do rock. 
  
 It seems slightly better on the single layer as it will now split the dots once very 6 or 7 refreshes ( 
 test.lightstone.co.za/mapsuite/pharma_disp.aspx?w=646&h=400&b=((-34.078569753846295,%2018.843437591905534),%20(-34.07146035730077,%2018.8572992480945))&exp=1&r=0.16037208074703813&single=1 
 ) but unfortunately still not the same result as having multiple feature layers. 
  
 Thanks anyway 
  
 Eugene 


Eugene,


The problem is that your AreaStyle brush is not transparent, and you have multi layers, so the second layer will cover the first layer's dots, the third layer will cover the second layer. that's the reason you see the less dots than you expect.


So I think it's not a bug, for this case, if you want to use multi layers, you may set the transparent brush for each layer.


Please let me know if you have good idea to solve your problem.


Thanks


James


 



Hi James,  
  
 It didn’t make any difference changing the brush to: 
 suburbs.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(New AreaStyle(New GeoPen(GeoColor.SimpleColors.DarkBlue), New GeoSolidBrush(GeoColor.SimpleColors.Transparent))) 
  
 What i did find, however, is that i don’t need 4 featurelayers. Using the above examples urls i updated the code for the multilayer to create only one clonedeep of the featurelayer and then to create 2 DotDensityStyles per featurelayer. This seems to work perfectly. 
 Effectively i have cut down the overhead 100%. Unfortunately it still doesn’t work to use 4 different DotDensityStyles on a single featurelayer (test.lightstone.co.za/mapsuite/pharma_disp.aspx?w=646&h=400&b=((-34.078569753846295,%2018.843437591905534),%20(-34.07146035730077,%2018.8572992480945))&exp=1&r=0.16037208074703813&single=1). 
  
 Thanks again for the reply. 
  
 Eugene

Eugene,


Could you provide your sample code which still have problem even you set brush to transparent?


It works at my machine, the first screen-shot is LightGray colro, the second one is transparent.




Thanks


James