/// <summary> /// Draws the labels for the given features. /// </summary> /// <param name="e">MapArgs to get Graphics object from.</param> /// <param name="features">Features, whose labels get drawn.</param> private void DrawFeatures(MapArgs e, IEnumerable <IFeature> features) { // Check that exists at least one category with Expression if (Symbology.Categories.All(_ => string.IsNullOrEmpty(_.Expression))) { return; } Graphics g = e.Device ?? Graphics.FromImage(BackBuffer); Matrix origTransform = g.Transform; // Only draw features that are currently visible. var featureList = features as IList <IFeature> ?? features.ToList(); if (DrawnStates == null || !DrawnStates.ContainsKey(featureList.First())) { CreateLabels(); } Dictionary <IFeature, LabelDrawState> drawStates = DrawnStates; if (drawStates == null) { return; } // Sets the graphics objects smoothing modes g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.AntiAlias; Action <IFeature> drawFeature; switch (featureList.First().FeatureType) { case FeatureType.Polygon: drawFeature = f => DrawPolygonFeature(e, g, f, drawStates[f].Category, drawStates[f].Selected, ExistingLabels); break; case FeatureType.Line: drawFeature = f => DrawLineFeature(e, g, f, drawStates[f].Category, drawStates[f].Selected, ExistingLabels); break; case FeatureType.Point: case FeatureType.MultiPoint: drawFeature = f => DrawPointFeature(e, g, f, drawStates[f].Category, drawStates[f].Selected, ExistingLabels); break; default: return; // Can't draw something else } foreach (ILabelCategory category in Symbology.Categories) { category.UpdateExpressionColumns(FeatureSet.DataTable.Columns); var cat = category; // prevent access to unmodified closure problems List <IFeature> catFeatures = new List <IFeature>(); foreach (IFeature f in featureList) { if (drawStates.ContainsKey(f) && drawStates[f].Category == cat) { catFeatures.Add(f); } } // Now that we are restricted to a certain category, we can look at // priority if (category.Symbolizer.PriorityField != "FID") { Feature.ComparisonField = cat.Symbolizer.PriorityField; catFeatures.Sort(); // When preventing collisions, we want to do high priority first. // otherwise, do high priority last. if (cat.Symbolizer.PreventCollisions) { if (!cat.Symbolizer.PrioritizeLowValues) { catFeatures.Reverse(); } } else { if (cat.Symbolizer.PrioritizeLowValues) { catFeatures.Reverse(); } } } for (int i = 0; i < catFeatures.Count; i++) { if (!FeatureLayer.DrawnStates[i].Visible) { continue; } drawFeature(catFeatures[i]); } } if (e.Device == null) { g.Dispose(); } else { g.Transform = origTransform; } }
private void BuildPaths(MapArgs e, IEnumerable <int> indices, out Dictionary <FastDrawnState, GraphicsPath> paths, bool selected) { paths = new Dictionary <FastDrawnState, GraphicsPath>(); var indiceList = indices as IList <int> ?? indices.ToList(); FastDrawnState[] states = DrawnStatesNeeded ? DrawnStates : new FastDrawnState[0]; if (DrawnStatesNeeded && indiceList.Max() >= states.Length) { AssignFastDrawnStates(); states = DrawnStates; } if (selected && (!DrawnStatesNeeded || !DrawnStates.Any(_ => _.Selected))) { return; } if (ProgressReportingEnabled) { ProgressMeter = new ProgressMeter(ProgressHandler, "Building Paths", indiceList.Count); } FastDrawnState state = new FastDrawnState(selected, Symbology.Categories[0]); Extent drawExtents = e.GeographicExtents; Rectangle clipRect = e.ProjToPixel(e.GeographicExtents); SoutherlandHodgman shClip = new SoutherlandHodgman(clipRect); List <ShapeRange> shapes = DataSet.ShapeIndices; double[] vertices = DataSet.Vertex; foreach (int shp in indiceList) { if (ProgressReportingEnabled) { ProgressMeter.Next(); } if (shp >= shapes.Count) { return; } ShapeRange shape = shapes[shp]; if (!shape.Extent.Intersects(e.GeographicExtents)) { continue; } if (DrawnStatesNeeded) { if (!states[shp].Visible || (selected && !states[shp].Selected)) { continue; } state = new FastDrawnState(selected, states[shp].Category); } if (!paths.ContainsKey(state)) { paths.Add(state, new GraphicsPath(FillMode.Winding)); } BuildPolygon(vertices, shapes[shp], paths[state], e, drawExtents.Contains(shape.Extent) ? null : shClip); } if (ProgressReportingEnabled) { ProgressMeter.Reset(); } }
/// <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"); } }
// This draws the individual point features private void DrawFeatures(MapArgs e, IEnumerable <int> indices, bool selected) { if (selected && (!DrawnStatesNeeded || !DrawnStates.Any(_ => _.Selected))) { return; // there are no selected features } Graphics g = e.Device ?? Graphics.FromImage(BackBuffer); Matrix origTransform = g.Transform; FeatureType featureType = DataSet.FeatureType; double minX = e.MinX; double maxY = e.MaxY; double dx = e.Dx; double dy = e.Dy; // CGX if (dx < 2000000000 && dx > -2000000000 && dy < 2000000000 && dy > -2000000000) { if (!DrawnStatesNeeded) { if (Symbology == null || Symbology.Categories.Count == 0) { return; } FastDrawnState state = new FastDrawnState(false, Symbology.Categories[0]); IPointSymbolizer ps = (state.Category as IPointCategory)?.Symbolizer; if (ps == null) { return; } double[] vertices = DataSet.Vertex; foreach (int index in indices) { // CGX if (Visibility != null) { bool visi = Visibility[index].Visible; if (!visi) { continue; } } if (featureType == FeatureType.Point) { DrawPoint(vertices[index * 2], vertices[(index * 2) + 1], e, ps, g, origTransform); } else { // multi-point ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { DrawPoint(vertices[i * 2], vertices[(i * 2) + 1], e, ps, g, origTransform); } } } } else { FastDrawnState[] states = DrawnStates; var indexList = indices as IList <int> ?? indices.ToList(); if (indexList.Max() >= states.Length) { AssignFastDrawnStates(); states = DrawnStates; } double[] vertices = DataSet.Vertex; foreach (int index in indexList) { if (index >= states.Length) { break; } FastDrawnState state = states[index]; if (!state.Visible || state.Category == null) { continue; } if (selected && !state.Selected) { continue; } IPointCategory pc = state.Category as IPointCategory; if (pc == null) { continue; } IPointSymbolizer ps = selected ? pc.SelectionSymbolizer : pc.Symbolizer; if (ps == null) { continue; } if (featureType == FeatureType.Point) { DrawPoint(vertices[index * 2], vertices[(index * 2) + 1], e, ps, g, origTransform); } else { ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { DrawPoint(vertices[i * 2], vertices[(i * 2) + 1], e, ps, g, origTransform); } } } } } if (e.Device == null) { g.Dispose(); } else { g.Transform = origTransform; } }
// This draws the individual line features private void DrawFeatures(MapArgs e, IEnumerable <IFeature> features) { Graphics g = e.Device ?? Graphics.FromImage(_backBuffer); // Only draw features that are currently visible. if (DrawnStates == null || !DrawnStates.ContainsKey(features.First())) { CreateLabels(); } Dictionary <IFeature, LabelDrawState> drawStates = DrawnStates; if (drawStates == null) { return; } //Sets the graphics objects smoothing modes g.TextRenderingHint = TextRenderingHint.AntiAlias; g.SmoothingMode = SmoothingMode.AntiAlias; FeatureType type = features.First().FeatureType; foreach (ILabelCategory category in Symbology.Categories) { var cat = category; // prevent access to unmodified closure problems //List<IFeature> catFeatures = (from feature in features // where drawStates.ContainsKey(feature) && drawStates[feature].Category == cat // select feature).ToList(); List <IFeature> catFeatures = new List <IFeature>(); foreach (IFeature f in features) { if (drawStates.ContainsKey(f)) { if (drawStates[f].Category == cat) { catFeatures.Add(f); } } } // Now that we are restricted to a certain category, we can look at // priority if (category.Symbolizer.PriorityField != "FID") { Feature.ComparisonField = cat.Symbolizer.PriorityField; catFeatures.Sort(); // When preventing collisions, we want to do high priority first. // otherwise, do high priority last. if (cat.Symbolizer.PreventCollisions) { if (!cat.Symbolizer.PrioritizeLowValues) { catFeatures.Reverse(); } } else { if (cat.Symbolizer.PrioritizeLowValues) { catFeatures.Reverse(); } } } foreach (IFeature feature in catFeatures) { switch (type) { case FeatureType.Polygon: DrawPolygonFeature(e, g, feature, drawStates[feature].Category, drawStates[feature].Selected, ExistingLabels); break; case FeatureType.Line: DrawLineFeature(e, g, feature, drawStates[feature].Category, drawStates[feature].Selected, ExistingLabels); break; case FeatureType.Point: DrawPointFeature(e, g, feature, drawStates[feature].Category, drawStates[feature].Selected, ExistingLabels); break; } } } if (e.Device == null) { g.Dispose(); } }