private void BuildPaths(MapArgs e, IEnumerable<IFeature> features, out List<GraphicsPath> borderPaths) { borderPaths = new List<GraphicsPath>(); IEnvelope drawExtents = e.PixelToProj(_drawingBounds); for (int selectState = 0; selectState < 2; selectState++) { foreach (IPolygonCategory category in Symbology.Categories) { // Determine the subset of the specified features that are visible and match the category IPolygonCategory polygonCategory = category; int i = selectState; Func<IDrawnState, bool> isMember = state => state.SchemeCategory == polygonCategory && state.IsVisible && state.IsSelected == (i == 1); var drawnFeatures = from feature in features where isMember(DrawingFilter[feature]) select feature; GraphicsPath borderPath = new GraphicsPath(); foreach (IFeature f in drawnFeatures) { if (drawExtents.Contains(f.Envelope)) { // This optimization only works if we are zoomed out far enough // that the whole linestring fits in the short integer // drawing window. Otherwise, we need to crop the line. // FastBuildLine(graphPath, f, minX, maxY, dx, dy); BuildPolygon(DataSet.Vertex, f.ShapeIndex, borderPath, e, false); } else { BuildPolygon(DataSet.Vertex, f.ShapeIndex, borderPath, e, true); } } borderPaths.Add(borderPath); } } }
// This draws the individual line features private void DrawFeatures(MapArgs e, IEnumerable<IFeature> features) { Graphics g; if (e.Device != null) { g = e.Device; // A device on the MapArgs is optional, but overrides the normal buffering behaviors. } else { g = Graphics.FromImage(_backBuffer); } // Only draw features that are currently visible. IEnvelope drawExtents = e.PixelToProj(_drawingBounds); double minX = e.MinX; double maxY = e.MaxY; double dx = e.Dx; double dy = e.Dy; for (int selectState = 0; selectState < 2; selectState++) { foreach (ILineCategory category in Symbology.Categories) { // Define the symbology based on the category and selection state ILineSymbolizer ls = category.Symbolizer; if (selectState == SELECTED) ls = category.SelectionSymbolizer; if (ls.Smoothing) { g.SmoothingMode = SmoothingMode.AntiAlias; } else { g.SmoothingMode = SmoothingMode.None; } // Determine the subset of the specified features that are visible and match the category ILineCategory lineCategory = category; int i = selectState; Func<IDrawnState, bool> isMember = state => state.SchemeCategory == lineCategory && state.IsVisible && state.IsSelected == (i == 1); var drawnFeatures = from feature in features where isMember(DrawingFilter[feature]) select feature; GraphicsPath graphPath = new GraphicsPath(); foreach (IFeature f in drawnFeatures) { if (drawExtents.Contains(f.Envelope)) { // This optimization only works if we are zoomed out far enough // that the whole linestring fits in the short integer // drawing window. Otherwise, we need to crop the line. FastBuildLine(graphPath, DataSet.Vertex, f.ShapeIndex, minX, maxY, dx, dy); } else { for (int iPart = 0; iPart < f.NumGeometries; iPart++) { IBasicGeometry geom = f.GetBasicGeometryN(iPart); if (drawExtents.Contains(f.Envelope) == false) { geom = e.GeographicExtents.Intersection(geom); } // Cropped geometries can be either linestrings or multi-linestrings IBasicLineString bls = geom as IBasicLineString; if (bls != null) { // the result is definitely in the linestring category BuildLineString(graphPath, bls, minX, maxY, dx, dy); } else { IMultiLineString intersect = geom as MultiLineString; if (intersect == null) continue; for (int iLine = 0; iLine < intersect.NumGeometries; iLine++) { BuildLineString(graphPath, intersect.GetBasicGeometryN(iLine) as IBasicLineString, minX, maxY, dx, dy); } } } } } double scale = 1; if (ls.ScaleMode == ScaleModes.Geographic) { scale = e.ImageRectangle.Width / e.GeographicExtents.Width; } foreach (IStroke stroke in ls.Strokes) { stroke.DrawPath(g, graphPath, scale); } graphPath.Dispose(); } } 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); } } } }