/// <summary> /// Equality based on the Boolean and category settings. /// </summary> /// <param name="obj">The fast drawn state to compare with</param> /// <returns>True, if both items are equal.</returns> public override bool Equals(object obj) { FastDrawnState item = obj as FastDrawnState; if (item == null) { return(false); } return(item.Selected == Selected && item.Category == Category && Visible == item.Visible); }
/// <summary> /// Assigns the fast drawn states /// </summary> public void AssignFastDrawnStates() { _drawnStatesNeeded = true; _drawnStates = new FastDrawnState[DataSet.ShapeIndices.Count]; _selection.Changed -= SelectedFeaturesChanged; _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 { Category = deflt }; } if (categories.Count == 1 && categories[0].FilterExpression == null) { return; } bool containsFid = false; if (!DataSet.AttributesPopulated) { // We don't want to read the table multiple times for each category. Just // read a block and then do all the categories we can for that block. List<string> names = new List<string>(); foreach (var category in categories) { var current = DistinctFieldsInExpression(category.FilterExpression); foreach (string name in current.Where(name => !names.Contains(name))) { names.Add(name); } } if (names.Count() == 0) { for (int i = 0; i < DataSet.NumRows(); i++) { _drawnStates[i].Category = categories[categories.Count - 1]; } return; } int rowCount = DataSet.NumRows(); const int size = 50000; int numPages = (int)Math.Ceiling((double)rowCount / size); for (int page = 0; page < numPages; page++) { int count = (page == numPages - 1) ? rowCount - page * size : size; DataTable expressionTable = DataSet.GetAttributes(page * size, count, names); foreach (var category in categories) { DataRow[] res = expressionTable.Select(category.FilterExpression); foreach (DataRow r in res) { _drawnStates[(int)r["FID"]].Category = category; } } } } else { 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"); } } }
private void BuildPaths(MapArgs e, IEnumerable<int> indices, out List<GraphicsPath> paths) { paths = new List<GraphicsPath>(); Extent drawExtents = e.GeographicExtents; Rectangle clipRect = e.ProjToPixel(e.GeographicExtents); SoutherlandHodgman shClip = new SoutherlandHodgman(clipRect); List<GraphicsPath> graphPaths = new List<GraphicsPath>(); 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); graphPaths.Add(border); } } paths.AddRange(graphPaths); List<ShapeRange> shapes = DataSet.ShapeIndices; double[] vertices = DataSet.Vertex; if (ProgressReportingEnabled) { ProgressMeter = new ProgressMeter(ProgressHandler, "Building Paths", indices.Count()); } if (!DrawnStatesNeeded) { FastDrawnState state = new FastDrawnState(false, Symbology.Categories[0]); foreach (int shp in indices) { if (ProgressReportingEnabled) ProgressMeter.Next(); ShapeRange shape = shapes[shp]; if (!shape.Extent.Intersects(e.GeographicExtents)) return; if (shp >= shapes.Count) return; if (!borders.ContainsKey(state)) return; BuildPolygon(vertices, shapes[shp], borders[state], e, drawExtents.Contains(shape.Extent) ? null : shClip); } } else { FastDrawnState[] states = DrawnStates; foreach (GraphicsPath borderPath in borders.Values) { if (borderPath != null) { borderPath.FillMode = FillMode.Winding; } } foreach (int shp in indices) { if (ProgressReportingEnabled) ProgressMeter.Next(); if (shp >= shapes.Count) return; 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, null); } else { FastDrawnState state = states[shp]; if (!borders.ContainsKey(state)) continue; BuildPolygon(vertices, shapes[shp], borders[state], e, shClip); } } } if (ProgressReportingEnabled) ProgressMeter.Reset(); }
// This draws the individual point features private void DrawFeatures(MapArgs e, IEnumerable<int> indices) { Graphics g = e.Device ?? Graphics.FromImage(BackBuffer); Matrix origTransform = g.Transform; FeatureType featureType = DataSet.FeatureType; if (!DrawnStatesNeeded) { if (Symbology == null || Symbology.Categories.Count == 0) return; FastDrawnState state = new FastDrawnState(false, Symbology.Categories[0]); IPointCategory pc = state.Category as IPointCategory; if (pc == null) return; IPointSymbolizer ps = pc.Symbolizer; if (ps == null) return; double[] vertices = DataSet.Vertex; foreach (int index in indices) { if (DrawnStates != null && DrawnStates.Length > index && !DrawnStates[index].Visible) 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; double[] vertices = DataSet.Vertex; foreach (int index in indices) { if (index >= states.Length) break; FastDrawnState state = states[index]; if (!state.Visible || state.Category == null) continue; IPointCategory pc = state.Category as IPointCategory; if (pc == null) continue; IPointSymbolizer ps = state.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 point features private void DrawFeatures(MapArgs e, IEnumerable<int> indices) { 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; 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 != null && DrawnStates.Length > index) { if (!DrawnStates[index].Visible) continue; } if (featureType == FeatureType.Point) { Point pt = new 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 == ScaleMode.Geographic) { scaleSize = e.ImageRectangle.Width / e.GeographicExtents.Width; } Matrix shift = origTransform.Clone(); shift.Translate(pt.X, pt.Y); g.Transform = shift; ps.Draw(g, scaleSize); } else { // multi-point ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { Point pt = new 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 == ScaleMode.Geographic) { scaleSize = e.ImageRectangle.Width / e.GeographicExtents.Width; } Matrix shift = origTransform.Clone(); shift.Translate(pt.X, pt.Y); g.Transform = shift; ps.Draw(g, scaleSize); } } } } 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 == ScaleMode.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) + 1, (int)(size.Height * scaleSize) + 1); Graphics bg = Graphics.FromImage(normalSymbol); bg.SmoothingMode = category.Symbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; Matrix trans = bg.Transform; // keenedge: // added ' * scaleSize ' to fix a problme when ploted using ScaleMode=Geographic. however, it still // appeared to be shifted up and left by 1 pixel so I also added the one pixel shift to the NW. // trans.Translate((float)size.Width / 2, (float)size.Height / 2); trans.Translate(((float)(size.Width * scaleSize) / 2 - 1), (float)(size.Height * scaleSize) / 2 - 1); 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)(selSize.Width * scaleSize + 1), (int)(selSize.Height * scaleSize + 1)); Graphics sg = Graphics.FromImage(selectedSymbol); sg.SmoothingMode = category.SelectionSymbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; Matrix trans2 = sg.Transform; trans2.Translate((float)selSize.Width / 2, (float)selSize.Height / 2); sg.Transform = trans2; category.SelectionSymbolizer.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 (featureType == FeatureType.Point) { Point pt = new Point(); pt.X = Convert.ToInt32((vertices[index * 2] - minX) * dx); pt.Y = Convert.ToInt32((maxY - vertices[index * 2 + 1]) * dy); Matrix shift = origTransform.Clone(); shift.Translate(pt.X, pt.Y); g.Transform = shift; g.DrawImageUnscaled(bmp, -bmp.Width / 2, -bmp.Height / 2); } else { ShapeRange range = DataSet.ShapeIndices[index]; for (int i = range.StartIndex; i <= range.EndIndex(); i++) { Point pt = new Point(); pt.X = Convert.ToInt32((vertices[i * 2] - minX) * dx); pt.Y = Convert.ToInt32((maxY - vertices[i * 2 + 1]) * dy); Matrix shift = origTransform.Clone(); shift.Translate(pt.X, pt.Y); g.Transform = shift; g.DrawImageUnscaled(bmp, -bmp.Width / 2, -bmp.Height / 2); } } } } } if (e.Device == null) g.Dispose(); else g.Transform = origTransform; }
private void BuildPaths(MapArgs e, IEnumerable<int> indices, out List<GraphicsPath> paths) { paths = new List<GraphicsPath>(); var clipRect = ComputeClippingRectangle(e); var drawExtents = e.PixelToProj(clipRect); var shClip = new SoutherlandHodgman(clipRect); var graphPaths = new List<GraphicsPath>(); var borders = new Dictionary<FastDrawnState, GraphicsPath>(); for (var selectState = 0; selectState < 2; selectState++) { foreach (var category in Symbology.Categories) { var state = new FastDrawnState(selectState == 1, category); var border = new GraphicsPath {FillMode = FillMode.Winding}; borders.Add(state, border); graphPaths.Add(border); } } paths.AddRange(graphPaths); var states = DrawnStates; foreach (var shp in indices) { var state = states[shp]; if (!state.Visible) continue; if (!borders.ContainsKey(state)) continue; var shape = DataSet.GetShape(shp, false); if (!shape.Range.Extent.Intersects(e.GeographicExtents)) continue; BuildPolygon(shape.Range, borders[state], e, drawExtents.Contains(shape.Range.Extent) ? null : shClip); } }