ThinkGeo.com    |     Documentation    |     Premium Support

Having a problem with PointShape.ScaleTo()

I am adding PointShapes to an InMemoryFeatureLayer (Map Suite Desktop Edition Evaluation Edition 6.0), and the unscaled points show up exactly as expected.  When I add a call to ScaleTo() with different values (in the range 1.0 to 9.0) on the PointShape, nothing changes and the points are all shown at the unscaled size. 


I've attached a txt file with a few lines of code.  The map looks the same with or without the call to ScaleTo().


Am I doing something wrong? Or does ScaleTo() have no effect here?


 



source.txt (469 Bytes)

Hi Dave,  
  
 Points do not have an area value so using the ScaleTo() method is sort of like multiplying zero by some integer value, the product is always zero. 
 I am not 100% clear what your end goal is by scaling up these points? 
 Do you want to create circles areas that use your current points as the center of the circle? 
 Or do you want scale the size of the PointStyle that is representing each point as you zoom in and out on the map?

I am trying to implement a sized-point map that I can update dynamically.  I'm adding the points to an InMemoryLayer.  I want to use the standard point shapes (circle, star, cross, triangle, diamond, etc.), but have the size of the point scaled proportional to a user-selected value associated with the point (so, compared to a "base" value provided by the user, a point with a value twice as large would appear twice as big. A point with a value 7 times as large wants to appear 7 times as large). When the user selects different data, I will remove the original point and add a new one scaled to match the newly-selected data.


I was quite excited when I saw the documentation shows ScaleTo() as a member function in PointShape (implemented in BaseShape).  Apparently my excitement was premature. :-)


To accomplish my task, do I need to draw each point as a polygon?



Perhaps an example will help you understand what I am trying to do.  I import a bunch of data from different sources to create an in-memory data table.  For example, I might end up with a table that has data for locations of stores of different brands (Safeway, Walmart, etc.).  Walmarts might be shown as green diamonds, Safeway as red circles, etc.  And the resulting table might have columns of numeric data associated with each store (such as "number of brands of diapers sold", "Hours open per week", "Hotels within 10 miles", etc. - any weird data they might have imported into my in-memory table).  The user can select any of the numeric columns for comparison, and I want to instantly have the points on the map  redrawn with the size of each point scaled to reflect the associated values in the selected data column.  When the user selects a different column, I want the map to instantly reflect the relative values in the newly-selected column.



Hi Dave,


Thanks for the explanation. The ScaleTo() is really used more for Area/Polygons to increase their size.

There is an important distinction that needs to be made between the actual PointShape that is just defined by a long/lat value and the PointStyle that defines the visible representation of the PointShape.


Thus the PointShape has parameters like GeoSolidBrush, GeoPen and SymbolSize.

Edit:  Thus the PointStyle has parameters like GeoSolidBrush, GeoPen and SymbolSize.



To change the size of point's symbol you will simply need to modify the SymbolSize parameter of the PointStyle that you apply to your InMemoryTable.


Starting out I would probably seperate your data into seperate tables/layers for each StoreName. Then you could setup a ClassBreakStyle to apply to each Table. The ClassBreak would then allow you to setup classes that contained very similar PointStyles. The only differences in each of the ClassBreaks is that the SymbolSize would change based on the value of the ClassBreakStyle.ColumnValue.


Below is some code that might help you get started: 
string userSelectedColumnName = "Column that your user selects";

//Place holders for whatever type of layer you create using your Table.
InMemoryFeatureLayer layerWalmart;
InMemoryFeatureLayer layerKmart;
InMemoryFeatureLayer layerTarget;
InMemoryFeatureLayer layerSafeway;

ClassBreakStyle classbreakWalmart = new ClassBreakStyle(userSelectedColumnName);
PointSymbolType pointSymbolTypeWalmart = PointSymbolType.Circle;
GeoSolidBrush geoSolidBrushWalmart = new GeoSolidBrush(GeoColor.SimpleColors.Blue);

classbreakWalmart.ClassBreaks.Add(new ClassBreak(double.MinValue,new PointStyle(pointSymbolTypeWalmart,geoSolidBrushWalmart,1)));
classbreakWalmart.ClassBreaks.Add(new ClassBreak(50,new PointStyle(pointSymbolTypeWalmart,geoSolidBrushWalmart,3)));
classbreakWalmart.ClassBreaks.Add(new ClassBreak(100,new PointStyle(pointSymbolTypeWalmart,geoSolidBrushWalmart,5)));
classbreakWalmart.ClassBreaks.Add(new ClassBreak(200,new PointStyle(pointSymbolTypeWalmart,geoSolidBrushWalmart,7)));
classbreakWalmart.ClassBreaks.Add(new ClassBreak(double.MaxValue,new PointStyle(pointSymbolTypeWalmart,geoSolidBrushWalmart,9)));
layerWalmart.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;



Thanks for the suggestion. Unfortunately, the table which contains the data is outside of (and unavailable to) Map Suite.  I’m adding mapping to an existing data application.  I need to create a sized PointShape (or eqivalent) on the fly from an arbitrary data value (arbitrary from Map Suite’s point of view).  The FeatureLayer has a default symbol size, and the symbol that shows up on the map is proportional to that value (So Map Suite clearly can generate different sized PointShapes).  I’m looking for a way to override the default symbol size for a given PointShape in the FeatureLayer.  It seems like it should be possible… and it seemed like PointShape.ScaleTo() was exactly what I was looking for. Why does PointShape expose ScaleTo() if PointShape is unwilling to resize itself?  Do you have a suggestion for sizing a point shape (or equivalent) on the fly?  I’m working on a prototype that I was supposed to demonstrate this week… this is the last mapping feature I need to include in the prototype… and my evaluation license (which has been extended twice) expires Nov 20th.  Any suggestion would be appreciated.

It looks like ElipseShape can solve my problem for scaling points with circles.  I’ll see if I can get the prototype feature working with circles, and then (assuming it does what it looks like it does) I’ll worry about the other shapes later.

Hi Dave,


.ScaleTo() is a method off of the BaseShape class and as PointShape inherits from BaseShape the .ScaleTo() method is available.


As for scaling the 'PointShape' on-the-fly' you might want to review my first reply again as I explain that the PointStyle is where you would want to make the size changes. I edited my original response so it makes a bit more sense. :) You could potentially poll your datasource and pass in a SymbolSize directly to the PointShape.SymbolSize, or setup some special logic to poll the same data from your datasource and create your own scalefactor to provide to the SymbolSize property.


To modify the styles displayed on the map based when your user changes Columns, you would simply need to Clear all the styles from the Layer's ZoomLevelSet and then re-apply the Styles to the Layer.ZoomLevelSet with the newly chosen ColumnValue referenced in the Styles.


If you are set on using the ScaleTo() Method then you would need to create Ellipses and then scale them based on your desired values.