protected void AssignFastDrawnStates() { _drawnStatesNeeded = true; _drawnStates = new FastDrawnState[DataSet.ShapeIndices.Count]; _selection = new IndexSelection(this); // update the new drawn-states; _selection.Changed += SelectedFeaturesChanged; // Fastest when no categories are used because we don't need DataTable at all List<IFeatureCategory> categories = _scheme.GetCategories().ToList(); IFeatureCategory deflt = null; if(categories.Count > 0 && categories[0].FilterExpression == null) deflt = categories[0]; for (int i = 0; i < DataSet.ShapeIndices.Count; i++) { _drawnStates[i] = new FastDrawnState(); _drawnStates[i].Category = deflt; } if(categories.Count == 1 && categories[0].FilterExpression == null) return; bool containsFID = false; DataTable table = DataSet.DataTable; foreach (var category in categories) { if (category.FilterExpression != null && category.FilterExpression.Contains("[FID]")) { containsFID = true; } } if(containsFID && table.Columns.Contains("FID") == false) { table.Columns.Add("FID"); for(int i = 0; i < table.Rows.Count; i++) { table.Rows[i]["FID"] = i; } } foreach (var category in categories) { DataRow[] result = table.Select(category.FilterExpression); foreach (DataRow row in result) { _drawnStates[table.Rows.IndexOf(row)].Category = category; } } if(containsFID)table.Columns.Remove("FID"); }
// This draws the individual line features private void DrawFeatures(MapArgs e, IEnumerable<int> indices) { Graphics g = e.Device ?? Graphics.FromImage(_backBuffer); double minX = e.MinX; double maxY = e.MaxY; double dx = e.Dx; double dy = e.Dy; if(!DrawnStatesNeeded) { if(Symbology == null || Symbology.Categories.Count == 0) return; FastDrawnState state = new FastDrawnState(false, Symbology.Categories[0]); IPointCategory pc = state.Category as IPointCategory; IPointSymbolizer ps = null; if(pc != null && pc.Symbolizer !=null) ps = pc.Symbolizer; if (ps == null) return; g.SmoothingMode = ps.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; double[] vertices = DataSet.Vertex; foreach (int index in indices) { if(!DrawnStates[index].Visible) continue; if(DataSet.FeatureType == FeatureTypes.Point) { System.Drawing.Point pt = new System.Drawing.Point(); pt.X = Convert.ToInt32((vertices[index * 2] - minX) * dx); pt.Y = Convert.ToInt32((maxY - vertices[index * 2 + 1]) * dy); double scaleSize = 1; if (ps.ScaleMode == ScaleModes.Geographic) { scaleSize = e.ImageRectangle.Width / e.GeographicExtents.Width; } Matrix old = g.Transform; Matrix shift = g.Transform; shift.Translate(pt.X, pt.Y); g.Transform = shift; ps.Draw(g, scaleSize); g.Transform = old; } else { // multi-point ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { System.Drawing.Point pt = new System.Drawing.Point(); pt.X = Convert.ToInt32((vertices[i * 2 ] - minX) * dx); pt.Y = Convert.ToInt32((maxY - vertices[i * 2 + 1]) * dy); double scaleSize = 1; if (ps.ScaleMode == ScaleModes.Geographic) { scaleSize = e.ImageRectangle.Width / e.GeographicExtents.Width; } Matrix old = g.Transform; Matrix shift = g.Transform; shift.Translate(pt.X, pt.Y); g.Transform = shift; ps.Draw(g, scaleSize); g.Transform = old; } } } } else { FastDrawnState[] states = DrawnStates; double[] vertices = DataSet.Vertex; foreach (IPointCategory category in Symbology.Categories) { if (category.Symbolizer == null) continue; double scaleSize = 1; if (category.Symbolizer.ScaleMode == ScaleModes.Geographic) { scaleSize = e.ImageRectangle.Width / e.GeographicExtents.Width; } Size2D size = category.Symbolizer.GetSize(); if (size.Width * scaleSize < 1 || size.Height * scaleSize < 1) continue; Bitmap normalSymbol = new Bitmap((int)(size.Width * scaleSize), (int)(size.Height * scaleSize)); Graphics bg = Graphics.FromImage(normalSymbol); bg.SmoothingMode = category.Symbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; Matrix trans = bg.Transform; trans.Translate((float)size.Width/2, (float)size.Height/2); bg.Transform = trans; category.Symbolizer.Draw(bg, 1); Size2D selSize = category.SelectionSymbolizer.GetSize(); if (selSize.Width * scaleSize < 1 || selSize.Height * scaleSize < 1) continue; Bitmap selectedSymbol = new Bitmap((int)(size.Width * scaleSize), (int)(size.Height * scaleSize)); Graphics sg = Graphics.FromImage(selectedSymbol); sg.SmoothingMode = category.SelectionSymbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; Matrix trans2 = bg.Transform; trans2.Translate((float)size.Width / 2, (float)size.Height / 2); sg.Transform = trans2; category.Symbolizer.Draw(sg, 1); foreach (int index in indices) { FastDrawnState state = states[index]; if (!state.Visible) continue; if (state.Category == null) continue; IPointCategory pc = state.Category as IPointCategory; if (pc == null) continue; if (pc != category) continue; Bitmap bmp = normalSymbol; if (state.Selected) { bmp = selectedSymbol; } if (DataSet.FeatureType == FeatureTypes.Point) { System.Drawing.Point pt = new System.Drawing.Point(); pt.X = Convert.ToInt32((vertices[index * 2] - minX) * dx); pt.Y = Convert.ToInt32((maxY - vertices[index * 2 + 1]) * dy); Matrix old = g.Transform; Matrix shift = g.Transform; shift.Translate(pt.X, pt.Y); g.Transform = shift; g.DrawImageUnscaled(bmp, -bmp.Width/2,-bmp.Height/2); g.Transform = old; } else { ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { System.Drawing.Point pt = new System.Drawing.Point(); pt.X = Convert.ToInt32((vertices[i*2] - minX)*dx); pt.Y = Convert.ToInt32((maxY - vertices[i*2 + 1])*dy); Matrix old = g.Transform; Matrix shift = g.Transform; shift.Translate(pt.X, pt.Y); g.Transform = shift; g.DrawImageUnscaled(bmp, -bmp.Width / 2, -bmp.Height / 2); g.Transform = old; } } } } if (e.Device == null) g.Dispose(); } }
private void BuildPaths(MapArgs e, IEnumerable<int> indices, out List<GraphicsPath> paths) { paths = new List<GraphicsPath>(); Extent drawExtents = new Extent(e.PixelToProj(_drawingBounds)); Dictionary<FastDrawnState, GraphicsPath> borders = new Dictionary<FastDrawnState, GraphicsPath>(); for (int selectState = 0; selectState < 2; selectState++) { foreach (IPolygonCategory category in Symbology.Categories) { FastDrawnState state = new FastDrawnState(selectState == 1, category); GraphicsPath border = new GraphicsPath(); borders.Add(state, border); paths.Add(border); } } List<ShapeRange> shapes = DataSet.ShapeIndices; double[] vertices = DataSet.Vertex; if(!DrawnStatesNeeded) { FastDrawnState state = new FastDrawnState(false, Symbology.Categories[0]); foreach (int shp in indices) { ShapeRange shape = shapes[shp]; if (!shape.Extent.Intersects(e.GeographicExtents)) continue; if(shp >= shapes.Count) continue; if (!borders.ContainsKey(state)) continue; if (drawExtents.Contains(shape.Extent)) { BuildPolygon(vertices, shapes[shp], borders[state], e, false); } else { BuildPolygon(vertices, shapes[shp], borders[state], e, true); } } } else { FastDrawnState[] states = DrawnStates; foreach (int shp in indices) { if (shp >= shapes.Count) continue; if (shp >= states.Length) { AssignFastDrawnStates(); states = DrawnStates; } if (states[shp].Visible == false) continue; ShapeRange shape = shapes[shp]; if (!shape.Extent.Intersects(e.GeographicExtents)) continue; if (drawExtents.Contains(shape.Extent)) { FastDrawnState state = states[shp]; if (!borders.ContainsKey(state)) continue; BuildPolygon(vertices, shapes[shp], borders[state], e, false); } else { FastDrawnState state = states[shp]; if (!borders.ContainsKey(state)) continue; BuildPolygon(vertices, shapes[shp], borders[state], e, true); } } } }