In my application, I need the user to be able to draw a polygon and a line, but have them different colors. Upon completion of the polygon / line it will prompt the user for the type. I have each type assigned to a specific color. Once the type is chosen I need to be able to color the most recently completed polygon / line the given color.
I figured out how to do it with points, but I have not been able to get it working with polygons or lines. Does anyone have an example on how to do this?
The other issue I guess is while trying to get this to work, it now is complaining that I am trying to use customstyles and defaultstyles. So basically I need one example that says how to draw polygon / lines with custom styles only and then color them differently based on the above criteria.
Thank you in advance.
Change polygon & line colors
Hi Scott,
I created a sample which might be useful on this case:
AreaStyle areaStyle;
private void WpfMap_Loaded(object sender, RoutedEventArgs e)
{
wpfMap1.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitWmsWpfOverlay worldMapKitOverlay = new WorldMapKitWmsWpfOverlay();
wpfMap1.Overlays.Add(worldMapKitOverlay);
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@"D:\TestData\Countries02.shp");
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
areaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Blue));
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.DarkYellow);
worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(areaStyle);
LayerOverlay staticOverlay = new LayerOverlay();
staticOverlay.Layers.Add("WorldLayer", worldLayer);
staticOverlay.TileType = TileType.SingleTile;
wpfMap1.Overlays.Add(staticOverlay);
wpfMap1.CurrentExtent = new RectangleShape(-133.2515625, 89.2484375, 126.9046875, -88.290625);
wpfMap1.Refresh();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (areaStyle != null)
{
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.DarkGreen);
wpfMap1.Refresh();
}
}
In the sample, it just works on the polygon shapes but it should be similar with the line shape.
Please don’t hesitate to let us know if there is any questions.
Thanks,
Johnny
That example gets me started,. but does that allow each polygon the user draw to potentially be a different color? What to I call when they want to start drawing the polygon? Normally it’s just “wpfMap1.TrackOverlay.TrackMode = TrackMode.Polygon;”. Is that still the case?
Posted By Johnny on 09-25-2013 05:01 AM
Hi Scott,
I created a sample which might be useful on this case:
AreaStyle areaStyle;
private void WpfMap_Loaded(object sender, RoutedEventArgs e)
{
wpfMap1.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitWmsWpfOverlay worldMapKitOverlay = new WorldMapKitWmsWpfOverlay();
wpfMap1.Overlays.Add(worldMapKitOverlay);
ShapeFileFeatureLayer worldLayer = new ShapeFileFeatureLayer(@“D:\TestData\Countries02.shp”);
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
areaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Blue));
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.DarkYellow);
worldLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(areaStyle);
LayerOverlay staticOverlay = new LayerOverlay();
staticOverlay.Layers.Add(“WorldLayer”, worldLayer);
staticOverlay.TileType = TileType.SingleTile;
wpfMap1.Overlays.Add(staticOverlay);
wpfMap1.CurrentExtent = new RectangleShape(-133.2515625, 89.2484375, 126.9046875, -88.290625);
wpfMap1.Refresh();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (areaStyle != null)
{
areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.DarkGreen);
wpfMap1.Refresh();
}
}
In the sample, it just works on the polygon shapes but it should be similar with the line shape.
Please don’t hesitate to let us know if there is any questions.
Thanks,
Johnny
So it was easy to use that example to color the polygon’s all a different color than the default…I guess now I need a way to make the first one blue, second one orange, etc… the color would be determined by the type of polygon they are drawing (based on a question they area asked after they finish drawing).
Posted By Scott on 09-25-2013 09:33 AM
So it was easy to use that example to color the polygon’s all a different color than the default…I guess now I need a way to make the first one blue, second one orange, etc… the color would be determined by the type of polygon they are drawing (based on a question they area asked after they finish drawing).
I have tried customstyles, but I guess I didn’t know how to then start the drawing since the default way I mentioned above throws an error since I am trying to use defaultstyles and cusstomstyles at the same time.
For reference, here is the code I am trying to use:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Valmont.Core.ViewModel;
using ReactiveUI;
using System.Diagnostics;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WpfDesktopEdition;
using Valmont.Core.BL;
namespace Valmont.Wpf.Views
{
///
/// Interaction logic for MapView.xaml
///
public partial class MapView : UserControl, IViewFor<IMapViewModel>
{
private bool bStylesAdded = false;
private int _currentIndex;
public MapView()
{
InitializeComponent();
InitializeMap();
}
private void InitializeMap()
{
wpfMap1.MapUnit = GeographyUnit.Meter;
var tileCacheFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
GoogleMapsOverlay googleOverlay = new GoogleMapsOverlay(tileCacheFolder, Properties.Settings.Default.ThinkGeoClientID, Properties.Settings.Default.ThinkGeoPrivateKey);
wpfMap1.CurrentExtent = new RectangleShape(-5000000, 5000000, 5000000, -5000000);
ManagedProj4Projection proj = new ManagedProj4Projection(); proj.InternalProjectionParametersString = ManagedProj4Projection.GetEpsgParametersString(4326);
proj.ExternalProjectionParametersString = ManagedProj4Projection.GetGoogleMapParametersString();
proj.Open();
Vertex projectedShape = proj.ConvertToExternalProjection(-85.844993, 41.473924);
wpfMap1.CenterAt(new Feature(projectedShape)); // usa
googleOverlay.MapType = GoogleMapsMapType.Hybrid;
googleOverlay.TileType = TileType.MultipleTile;
googleOverlay.DrawingExceptionMode = DrawingExceptionMode.ThrowException;
wpfMap1.Overlays.Add(googleOverlay);
wpfMap1.ZoomLevelSet = new GoogleMapsZoomLevelSet();
InMemoryFeatureLayer pointLayer = new InMemoryFeatureLayer();
pointLayer.ZoomLevelSet = new GoogleMapsZoomLevelSet();
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
pointLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimplePointStyle(PointSymbolType.Triangle, GeoColor.SimpleColors.Black, 1);
var kmlLayer = new KmlFeatureLayer("sample.kml");
kmlLayer.ZoomLevelSet = new GoogleMapsZoomLevelSet();
kmlLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
var projection = new ManagedProj4Projection(ManagedProj4Projection.GetEpsgParametersString(4326), ManagedProj4Projection.GetGoogleMapParametersString());
kmlLayer.FeatureSource.Projection = projection;
//kmlLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Black), new GeoSolidBrush(GeoColor.SimpleColors.Yellow));
var styles = kmlLayer.ZoomLevelSet.ZoomLevel01.GetRequiredColumnNames();
kmlLayer.Open();
var featureSource = (KmlFeatureSource)kmlLayer.FeatureSource;
foreach (var style in featureSource.Styles)
{
kmlLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(style.Value);
}
LayerOverlay pointOverlay = new LayerOverlay();
pointOverlay.Layers.Add("PointLayer", pointLayer);
wpfMap1.Overlays.Add("PointOverlay", pointOverlay);
var overlay = new LayerOverlay();
overlay.Layers.Add("kmllayer", kmlLayer);
wpfMap1.Overlays.Add(overlay);
var feature = kmlLayer.FeatureSource.GetAllFeatures(new[] { "" }).First();
wpfMap1.CenterAt(feature);
var values = feature.ColumnValues;
wpfMap1.TrackOverlay.TrackEnded += new EventHandler<TrackEndedTrackInteractiveOverlayEventArgs>(TrackEnded);
}
private void TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)
{
if (!ViewModel.DrawingPaused && wpfMap1.TrackOverlay.TrackMode != TrackMode.Point)
{
ProcessStop();
ViewModel.StopButtonCommand.Execute(null);
wpfMap1.TrackOverlay.TrackMode = TrackMode.None;
}
}
private void RecordButton_Click(object sender, RoutedEventArgs e)
{
StartRecording();
}
private void StartRecording()
{
if (!ViewModel.DrawingPaused)
{
switch (wpfMap1.TrackOverlay.TrackMode)
{
case TrackMode.Polygon:
ViewModel.CurrentGeometryType = Core.GeometryType.Polygon;
break;
case TrackMode.Line:
ViewModel.CurrentGeometryType = Core.GeometryType.Line;
break;
}
}
else
{
Collection<Vertex> vertexes = null;
switch (ViewModel.CurrentGeometryType)
{
case Valmont.Core.GeometryType.Polygon:
wpfMap1.TrackOverlay.TrackMode = TrackMode.Polygon;
PolygonShape polygonShape = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].GetShape() as PolygonShape;
vertexes = (wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[0].GetShape() as PolygonShape).OuterRing.Vertices;
vertexes.RemoveAt(vertexes.Count - 1);
wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(_currentIndex);
break;
case Valmont.Core.GeometryType.Line:
ViewModel.CurrentGeometryType = Core.GeometryType.Line;
wpfMap1.TrackOverlay.TrackMode = TrackMode.Line;
if (_currentIndex >= 0)
{
vertexes = (wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].GetShape() as LineShape).Vertices;
wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.RemoveAt(_currentIndex);
}
break;
}
if (vertexes != null && vertexes.Count > 0)
{
for (int i = 0; i < vertexes.Count; i++)
{
wpfMap1.TrackOverlay.MouseDown(new InteractionArguments() { WorldX = vertexes.X, WorldY = vertexes.Y });
}
wpfMap1.TrackOverlay.MouseDown(new InteractionArguments() { WorldX = vertexes[vertexes.Count - 1].X, WorldY = vertexes[vertexes.Count - 1].Y });
}
}
ViewModel.DrawingPaused = false;
}
private void PauseOrStopRecording()
{
if (ViewModel.RemoveLastPoint)
{
_currentIndex = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count - 1;
if (_currentIndex >= 0)
{
switch (wpfMap1.TrackOverlay.TrackMode)
{
case TrackMode.Line:
ViewModel.CurrentGeometryType = Core.GeometryType.Line;
LineShape lineShape = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].GetShape() as LineShape;
if (lineShape != null)
{
lineShape.Vertices.RemoveAt(lineShape.Vertices.Count - 1);
wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].WellKnownBinary = lineShape.GetWellKnownBinary();
}
break;
case TrackMode.Polygon:
ViewModel.CurrentGeometryType = Core.GeometryType.Polygon;
PolygonShape polygonShape = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].GetShape() as PolygonShape;
if (polygonShape != null)
{
polygonShape.OuterRing.Vertices.RemoveAt(polygonShape.OuterRing.Vertices.Count - 2);
wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[_currentIndex].WellKnownBinary = polygonShape.GetWellKnownBinary();
}
break;
}
}
wpfMap1.TrackOverlay.TrackMode = TrackMode.None;
wpfMap1.Refresh();
}
}
private void PauseButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.DrawingPaused = true;
PauseOrStopRecording();
}
private void StopButton_Click(object sender, RoutedEventArgs e)
{
ViewModel.RemoveLastPoint = true;
wpfMap1.TrackOverlay.MouseDoubleClick(new InteractionArguments());
}
private void ProcessStop()
{
GeometryTypeDialogViewModel vm = new GeometryTypeDialogViewModel();
switch (wpfMap1.TrackOverlay.TrackMode)
{
case TrackMode.Line:
vm.GeometryType = Core.GeometryType.Line;
break;
case TrackMode.Polygon:
vm.GeometryType = Core.GeometryType.Polygon;
break;
case TrackMode.Point:
vm.GeometryType = Core.GeometryType.Point;
break;
default:
return;
}
ViewModel.DrawingPaused = false;
Valmont.Wpf.Pages.GeometryTypeDialog dialog = new Pages.GeometryTypeDialog(vm);
dialog.ShowDialog();
ViewModel.LastGeometryColor = ((GeometryTypeDialogViewModel)dialog.DataContext).GeometryColor;
ViewModel.GeometryValueType = ((GeometryTypeDialogViewModel)dialog.DataContext).GeometryValueType;
PauseOrStopRecording();
}
private void FlagButton_Click(object sender, RoutedEventArgs e)
{
if (wpfMap1.TrackOverlay.TrackMode != TrackMode.None)
{
ViewModel.DrawingPaused = true;
PauseOrStopRecording();
}
wpfMap1.TrackOverlay.TrackMode = TrackMode.Point;
}
private void AddMapLayers()
{
if (!bStylesAdded)
{
LayerOverlay pointOverlay = (LayerOverlay)wpfMap1.Overlays["PointOverlay"];
InMemoryFeatureLayer pointLayer = (InMemoryFeatureLayer)pointOverlay.Layers["PointLayer"];
pointLayer.FeatureSource.Open();
pointLayer.Columns.Add(new FeatureSourceColumn("POINT_TYPE"));
pointLayer.Close();
wpfMap1.TrackOverlay.TrackShapeLayer.Open();
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("POLYGON_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("LINE_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Close();
// add point styles
ValueStyle valueStyle = new ValueStyle();
if (ViewModel != null)
{
foreach (Valmont.Core.PointTypeColor pointTypeColor in ViewModel.PointTypeColors)
{
AddValueStyleItem("POINT_TYPE", ref valueStyle, pointTypeColor.PointType.ToString(), pointTypeColor.Color);
}
pointLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
pointLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
}
// TODO: add polygon styles
//areaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.LightGreen));
//areaStyle.FillSolidBrush = new GeoSolidBrush(GeoColor.SimpleColors.Transparent);
valueStyle = new ValueStyle();
foreach (Valmont.Core.PolygonTypeColor polygonTypeColor in ViewModel.PolygonTypeColors)
{
AddValueStyleItem("POLYGON_TYPE", ref valueStyle, polygonTypeColor.PolygonType.ToString(), polygonTypeColor.Color);
}
//wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
//wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = areaStyle;
//wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
//// TODO: add line styles
//valueStyle = new ValueStyle();
//foreach (Valmont.Core.LineTypeColor lineTypeColor in ViewModel.LineTypeColors)
//{
// AddValueStyleItem("LINE_TYPE", ref valueStyle, lineTypeColor.LineType.ToString(), lineTypeColor.Color);
//}
//wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
//wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
bStylesAdded = true;
}
}
private static void AddValueStyleItem(string columnName, ref ValueStyle valueStyle, string type, Valmont.Core.ColorOptions col)
{
if (col != Core.ColorOptions.Default)
{
System.Drawing.Color c = System.Drawing.Color.FromName(col.ToString());
GeoColor g = GeoColor.FromArgb(c.A, c.R, c.G, c.B);
valueStyle.ColumnName = columnName;
valueStyle.ValueItems.Add(new ValueItem(type, PointStyles.CreateSimpleCircleStyle(g, 7, g)));
}
}
private void wpfMap1_MapClick(object sender, MapClickWpfMapEventArgs e)
{
if (wpfMap1.TrackOverlay.TrackMode == TrackMode.Point)
{
ProcessStop();
LayerOverlay pointOverlay = (LayerOverlay)wpfMap1.Overlays["PointOverlay"];
InMemoryFeatureLayer pointLayer = (InMemoryFeatureLayer)pointOverlay.Layers["PointLayer"];
string pointName = ViewModel.GeometryValueType;
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("POINT_TYPE", pointName);
Feature feature = new Feature(e.WorldLocation, dictionary);
pointLayer.InternalFeatures.Add(pointName, feature);
pointOverlay.Refresh();
}
}
private void PolygonButton_Click(object sender, RoutedEventArgs e)
{
wpfMap1.TrackOverlay.TrackMode = TrackMode.Polygon;
ViewModel.RemoveLastPoint = false; // reset
ViewModel.RecordButtonCommand.Execute(null);
StartRecording();
}
private void LineButton_Click(object sender, RoutedEventArgs e)
{
wpfMap1.TrackOverlay.TrackMode = TrackMode.Line;
ViewModel.RemoveLastPoint = false; // reset
ViewModel.RecordButtonCommand.Execute(null);
StartRecording();
}
private void UpdateLocation(object msg)
{
var message = (GgaMessage)msg;
var vertex = new Vertex((double)message.Longitude, (double)message.Latitude);
var feature = new Feature(vertex);
var projection = new ManagedProj4Projection(ManagedProj4Projection.GetWgs84ParametersString(), ManagedProj4Projection.GetGoogleMapParametersString());
projection.Open();
feature = projection.ConvertToExternalProjection(feature);
projection.Close();
var overlay = (LayerOverlay)wpfMap1.Overlays["PointOverlay"];
var layer = (InMemoryFeatureLayer)overlay.Layers["PointLayer"];
if (layer.InternalFeatures.Contains("CurrentLocation"))
{
layer.InternalFeatures.Remove("CurrentLocation");
}
layer.InternalFeatures.Add("CurrentLocation", feature);
overlay.Refresh();
wpfMap1.CenterAt(feature);
}
public IMapViewModel ViewModel
{
get { return (IMapViewModel)GetValue(ViewModelProperty); }
set
{
SetValue(ViewModelProperty, value);
DataContext = ViewModel;
AddMapLayers();
}
}
object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (IMapViewModel)value; }
}
public static readonly DependencyProperty ViewModelProperty =
DependencyProperty.Register("ViewModel", typeof(IMapViewModel), typeof(MapView), new PropertyMetadata(null));
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
DataContext = ViewModel;
ViewModel.UpdateLocationCommand.Subscribe(message => UpdateLocation(message));
}
}
}
Hi Scott,
Sorry for the misunderstanding.
I checked your codes and I guess I might be find out the issue why the value style doesn’t apply to the drawn line/polygon, which you may encountered.
I noticed the TrackShapeLayer columns have added two columns (POLYGON_TYPE and LINE_TYPE) and the value style’ column name also be assigned. However, the features in TrackShapeLayer didn’t includes any feature columns. So in order to make the value style work, we can attach those columns to the features in the TrackEnded event. Some codes should be like the below:
void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e)
{
//…other stuffs
int count = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count;
Feature latestFeature = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[count - 1];
latestFeature.ColumnValues.Add("POLYGON_TYPE","the value can match with the value item value");
latestFeature.ColumnValues.Add("LINE_TYPE", "the value can match with the value item value");
}
As for the exception when use the defaultstyles and customstyles at the same time, this is not allowed in Map Suite Style system. So, we should only keep one of them.
If any more questions, don’t hesitate to let us know.
Thanks,
Johnny
Thanks. That helps. I guess I am not sure where I am using defaultstyles in that code and how to turn that off and only use customstyles.
So if I could have help in setting it up to only use CustomStyles and how to set it up so the user can draw a polygon on the map using only the CustomStyles, then I think I will be all set. Because the way it is now, when I try to draw a polygon nothing is showing up on the map…so it is not registering or something.
Hi Scott,
Actually, The TrackShapeLayer is an inmemoryFeatureLayer and owns the defaultStyles during the initialization, that’s the reason there might be a conflict when we try to apply a customeStyle to it. In order to avoid the conflict, we can set those default styles as null when init our map. So, in the codes,
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.Open();
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("POLYGON_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("LINE_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Close();
Besides, here is another way to control the TrackOverlay easily. We can define a custom TrackOverlay to inherit the TrackInteractiveOverlay:
internal class CustomTrackOverlay : TrackInteractiveOverlay
{
public CustomTrackOverlay()
: base()
{
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(…);
// other stuffs
}
}
Then assign the custom Trackoverlay to the map at the first:
wpfMap1.TrackOverlay = new CustomTrackOverlay();
Hope the two ways will help.
Thanks,
Johnny
Hi Scott,
Actually, The TrackShapeLayer is an inmemoryFeatureLayer and owns the defaultStyles during the initialization, that’s the reason there might be a conflict when we try to apply a customeStyle to it. In order to avoid the conflict, we can set those default styles as null when init our map. So, in the codes,
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = null;
wpfMap1.TrackOverlay.TrackShapeLayer.Open();
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("POLYGON_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn("LINE_TYPE"));
wpfMap1.TrackOverlay.TrackShapeLayer.Close();
Besides, here is another way to control the TrackOverlay easily. We can define a custom TrackOverlay to inherit the TrackInteractiveOverlay:
internal class CustomTrackOverlay : TrackInteractiveOverlay
{
public CustomTrackOverlay()
: base()
{
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = null;
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(…);
// other stuffs
}
}
Then assign the custom Trackoverlay to the map at the first:
wpfMap1.TrackOverlay = new CustomTrackOverlay();
Hope the two ways will help.
Thanks,
Johnny
That got rid of the error, so we are good to go there. The last issue now is that it doesn’t actually draw the polygon or line when I start tracking and then click on the map.
I got it drawing now. I was missing the line
this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(this.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.CloneDeep());
Now I just have to get it to change the color when it is done…which isn’t working yet…but you have examples in this thread about that so I’ll reference those again and see if I can get it up with those.
so i guess now i am wondering if it is staying on that default style, but adding that to the custom styles was the only way to get it to draw…it’s almost like it isn’t even using the custom style values that i added. I confirmed that the column value that i try to set it to in track_ended has been added to the custom styles.
Adding custom styles:
wpfMap1.TrackOverlay.TrackShapeLayer.Open();
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn(“POLYGON_TYPE”));
wpfMap1.TrackOverlay.TrackShapeLayer.Columns.Add(new FeatureSourceColumn(“LINE_TYPE”));
wpfMap1.TrackOverlay.TrackShapeLayer.Close();
// add polygon styles
valueStyle = new ValueStyle();
foreach (Valmont.Core.PolygonTypeColor polygonTypeColor in ViewModel.PolygonTypeColors)
{
AddValueStyleItem(“POLYGON_TYPE”, ref valueStyle, polygonTypeColor.PolygonType.ToString(), polygonTypeColor.Color);
}
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);
wpfMap1.TrackOverlay.TrackShapeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
and then this in track_ended:
int count = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures.Count;
Feature latestFeature = wpfMap1.TrackOverlay.TrackShapeLayer.InternalFeatures[count - 1];
string polygonName = ViewModel.GeometryValueType;
switch (wpfMap1.TrackOverlay.TrackMode)
{
case TrackMode.Polygon:
latestFeature.ColumnValues.Add(“POLYGON_TYPE”, polygonName);
break;
// other code…
}
wpfMap1.TrackOverlay.Refresh();
ViewModel.StopButtonCommand.Execute(null);
wpfMap1.TrackOverlay.TrackMode = TrackMode.None;
Think I got it…I had to change my AddValueStyleItem method from what I had above to the following:
private static void AddValueStyleItem(string columnName, ref ValueStyle valueStyle, string type, Valmont.Core.ColorOptions col, Valmont.Core.GeometryType gt)
{
if (col != Core.ColorOptions.Default)
{
System.Drawing.Color c = System.Drawing.Color.FromName(col.ToString());
GeoColor g = GeoColor.FromArgb(c.A, c.R, c.G, c.B);
valueStyle.ColumnName = columnName;
switch (gt)
{
case Core.GeometryType.Point:
valueStyle.ValueItems.Add(new ValueItem(type, PointStyles.CreateSimpleCircleStyle(g, 7, g)));
break;
case Core.GeometryType.Polygon:
valueStyle.ValueItems.Add(new ValueItem(type, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Transparent, g)));
break;
case Core.GeometryType.Line:
valueStyle.ValueItems.Add(new ValueItem(type, LineStyles.CreateSimpleLineStyle(g, 7, g, 7, false)));
break;
}
}
}
Yup…got it all working like I want now…thank you so much for your help!
Hi Scott,
Good to hear you have figured out.
Please feel free to let us know if any questions.
Thanks,
Johnny