/// <summary> /// If UseChunks is true, this uses the index value combined with the chunk size /// to calculate the chunk, and also sets the category to the [0] category and the /// selection state to unselected. This can be overridden in sub-classes to come up /// with a different default state. /// </summary> /// <param name="index">The integer index to get the default state of</param> /// <returns>An IDrawnState</returns> public virtual IDrawnState GetDefaultState(int index) { if (_useChunks) { return(new DrawnState(_scheme.GetCategories().First(), false, index / _chunkSize, true)); } return(new DrawnState(_scheme.GetCategories().First(), false, 0, true)); }
/// <summary> /// Zooms so that the minimum is the minimum of the lowest category or else the /// minimum of the extents, and the maximum is the maximum of the largest category /// or else the maximum of the statistics. /// </summary> public void ZoomToCategoryRange() { if (_graph == null) { return; } Statistics stats; double? min; double? max; if (_isRaster) { if (_raster == null) { return; } stats = _rasterSymbolizer.Scheme.Statistics; min = _rasterSymbolizer.Scheme.Categories[0].Minimum; max = _rasterSymbolizer.Scheme.Categories[_rasterSymbolizer.Scheme.Categories.Count - 1].Maximum; } else { if (_scheme == null) { return; } stats = _scheme.Statistics; IEnumerable <IFeatureCategory> cats = _scheme.GetCategories(); min = cats.First().Minimum; max = cats.Last().Maximum; } _graph.Minimum = (min == null || min.Value < stats.Minimum) ? stats.Minimum : min.Value; _graph.Maximum = (max == null || max.Value > stats.Maximum) ? stats.Maximum : max.Value; FillBins(); UpdateBreaks(); Invalidate(); }
/// <summary> /// This method cycles through all the Categories in the scheme and creates a new /// category. /// </summary> /// <param name="scheme"> /// The scheme to apply /// </param> protected virtual void OnApplyScheme(IFeatureScheme scheme) { // _drawingFilter.ApplyScheme(scheme); if (_editMode) { _drawingFilter.ApplyScheme(scheme); } else { List<IFeatureCategory> categories = scheme.GetCategories().ToList(); if (_drawnStatesNeeded || (_selection != null && _selection.Count > 0) || categories.Count > 1) { AssignFastDrawnStates(); } else if (categories.Count == 1) { if (categories[0].FilterExpression != null) { AssignFastDrawnStates(); } } } _categoryExtents.Clear(); OnSchemeApplied(); OnItemChanged(this); }
/// <summary> /// This will use the filter expressions on the categories to change the categories for those members. /// This means that an item will be classified as the last filter that it qualifies for. /// </summary> /// <param name="scheme">The scheme of categories to apply to the drawing states</param> public void ApplyScheme(IFeatureScheme scheme) { _scheme = scheme; if (_isInitialized == false) { DoInitialize(); } var fc = _scheme.GetCategories().ToList(); // Short cut the rest of this (and prevent loading features) in the case where we know everything is in the default category if (fc.Count == 1 && string.IsNullOrEmpty(fc[0].FilterExpression)) { // Replace SchemeCategory in _drawnStates foreach (var drawnState in _drawnStates) { drawnState.Value.SchemeCategory = fc[0]; } return; } var tables = new List <DataTable>(); // just in case there is more than one Table somehow var allRows = new List <DataRow>(); var tempList = new List <DataTable>(); var containsFID = fc.Any(category => category.FilterExpression != null && category.FilterExpression.Contains("[FID]")); foreach (var f in _featureList) { if (f.DataRow == null) { f.ParentFeatureSet.FillAttributes(); } if (f.DataRow != null) { DataTable t = f.DataRow.Table; if (tables.Contains(t) == false) { tables.Add(t); if (containsFID && t.Columns.Contains("FID") == false) { f.ParentFeatureSet.AddFid(); tempList.Add(t); } } allRows.Add(f.DataRow); } if (_drawnStates.ContainsKey(f)) { _drawnStates[f].SchemeCategory = null; } } foreach (IFeatureCategory cat in fc) { foreach (DataTable dt in tables) { DataRow[] rows = dt.Select(cat.FilterExpression); foreach (DataRow dr in rows) { int index = allRows.IndexOf(dr); if (index != -1) { _drawnStates[_featureList[index]].SchemeCategory = cat; } } } } foreach (DataTable table in tempList) { table.Columns.Remove("FID"); } }
/// <summary> /// Given a scheme, this will build the break list to match approximately. This does not /// force the interval method to build a new scheme. /// </summary> public void UpdateBreaks() { if (_isRaster) { UpdateRasterBreaks(); return; } if (_scheme == null) { return; } IFeatureCategory selectedCat = null; if (_selectedSlider != null) { selectedCat = _selectedSlider.Category as IFeatureCategory; } Breaks.Clear(); Statistics stats = _scheme.Statistics; Rectangle gb = _graph.GetGraphBounds(); _graph.ColorRanges.Clear(); foreach (IFeatureCategory category in _scheme.GetCategories()) { ColorRange cr = new ColorRange(category.GetColor(), category.Range); _graph.ColorRanges.Add(cr); BreakSlider bs = new BreakSlider(gb, _graph.Minimum, _graph.Maximum, cr) { Color = _breakColor, SelectColor = _selectedBreakColor }; if (selectedCat != null && category == selectedCat) { bs.Selected = true; _selectedSlider = bs; _graph.SelectedRange = cr; } bs.Value = category.Maximum != null?double.Parse(category.Maximum.ToString()) : stats.Maximum; bs.Category = category; Breaks.Add(bs); } Breaks.Sort(); // Moving a break generally affects both a maximum and a minimum. // Point to the next category to actuate that. for (int i = 0; i < Breaks.Count - 1; i++) { Breaks[i].NextCategory = Breaks[i + 1].Category; // We use the maximums to set up breaks. Minimums should simply // be set to work with the maximums of the previous category. Breaks[i + 1].Category.Minimum = Breaks[i].Value; } if (Breaks.Count == 0) { return; } int breakIndex = 0; BreakSlider nextSlider = Breaks[breakIndex]; int count = 0; if (_graph?.Bins == null) { return; } foreach (double value in _values) { if (value < nextSlider.Value) { count++; continue; } nextSlider.Count = count; while (value > nextSlider.Value) { breakIndex++; if (breakIndex >= Breaks.Count) { break; } nextSlider = Breaks[breakIndex]; } count = 0; } }
/// <summary> /// This will use the filter expressions on the categories to change the categories for those members. /// This means that an item will be classified as the last filter that it qualifies for. /// </summary> /// <param name="scheme">The scheme of categories to apply to the drawing states</param> public void ApplyScheme(IFeatureScheme scheme) { _scheme = scheme; if (_isInitialized == false) DoInitialize(); List<IFeatureCategory> fc = _scheme.GetCategories().ToList(); // Short cut the rest of this (and prevent loading features) in the case where we know everything is in the default category if (fc.Count == 1 && string.IsNullOrEmpty(fc[0].FilterExpression)) return; List<DataTable> tables = new List<DataTable>(); // just in case there is more than one Table somehow List<DataRow> allRows = new List<DataRow>(); List<DataTable> tempList = new List<DataTable>(); bool containsFID = false; IEnumerable<IFeatureCategory> categories = _scheme.GetCategories(); foreach (var category in categories) { if (category.FilterExpression != null && category.FilterExpression.Contains("[FID]")) { containsFID = true; } } foreach (IFeature f in _featureList) { if (f.DataRow == null) { f.ParentFeatureSet.FillAttributes(); } if (f.DataRow != null) { DataTable t = f.DataRow.Table; if (tables.Contains(t) == false) { tables.Add(t); if (containsFID && t.Columns.Contains("FID") == false) { f.ParentFeatureSet.AddFid(); tempList.Add(t); } } allRows.Add(f.DataRow); } if (_drawnStates.ContainsKey(f)) _drawnStates[f].SchemeCategory = null; } foreach (IFeatureCategory cat in categories) { foreach (DataTable dt in tables) { DataRow[] rows = dt.Select(cat.FilterExpression); foreach (DataRow dr in rows) { int index = allRows.IndexOf(dr); if (index != -1) { _drawnStates[_featureList[index]].SchemeCategory = cat; } } } } foreach (DataTable table in tempList) { table.Columns.Remove("FID"); } }
/// <summary> /// This will use the filter expressions on the categories to change the categories for those members. /// This means that an item will be classified as the last filter that it qualifies for. /// </summary> /// <param name="scheme">The scheme of categories to apply to the drawing states</param> public void ApplyScheme(IFeatureScheme scheme) { _scheme = scheme; if (_isInitialized == false) { DoInitialize(); } var fc = _scheme.GetCategories().ToList(); // Short cut the rest of this (and prevent loading features) in the case where we know everything is in the default category if (fc.Count == 1 && string.IsNullOrEmpty(fc[0].FilterExpression)) { // Replace SchemeCategory in _drawnStates foreach (var drawnState in DrawnStates) { drawnState.Value.SchemeCategory = fc[0]; } return; } var tables = new List <IDataTable>(); // just in case there is more than one Table somehow var allRows = new Dictionary <IDataRow, int>(); var tempList = new List <IDataTable>(); var containsFid = fc.Any(category => category.FilterExpression != null && category.FilterExpression.Contains("[FID]")); var featureIndex = 0; foreach (var f in FeatureList) { if (f.DataRow == null) { f.ParentFeatureSet.FillAttributes(); } if (f.DataRow != null) { IDataTable t = f.DataRow.Table; if (tables.Contains(t) == false) { tables.Add(t); if (containsFid && t.Columns.Contains("FID") == false) { f.ParentFeatureSet.AddFid(); tempList.Add(t); } } allRows.Add(f.DataRow, featureIndex); } if (DrawnStates.ContainsKey(f)) { DrawnStates[f].SchemeCategory = null; } featureIndex++; } foreach (IFeatureCategory cat in fc) { foreach (IDataTable dt in tables) { // CGX TRY CATCH try { IDataRow[] rows = dt.Select(cat.FilterExpression); foreach (IDataRow dr in rows) { foreach (var key in allRows.Keys) { if (key.Equals(dr)) { DrawnStates[FeatureList[allRows[key]]].SchemeCategory = cat; } } /*int index; * if (allRows.TryGetValue(dr, out index)) * { * DrawnStates[FeatureList[index]].SchemeCategory = cat; * }*/ } } catch (Exception) { } } } foreach (IDataTable table in tempList) { table.Columns.Remove("FID"); } }