/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> /// <param name="selected">If this is true, nothing is painted, because selected labels get painted together with not selected labels.</param> public void DrawRegions(MapArgs args, List <Extent> regions, bool selected) { if (FeatureSet == null || selected) { return; } #if DEBUG var sw = new Stopwatch(); sw.Start(); #endif if (FeatureSet.IndexMode) { // First determine the number of features we are talking about based on region. List <int> drawIndices = new List <int>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. Figure a region that is larger. Extent sur = region.Copy(); sur.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawIndices = drawIndices.Union(FeatureSet.SelectIndices(sur)).ToList(); } } List <Rectangle> clips = args.ProjToPixel(regions); DrawFeatures(args, drawIndices, clips, true); } else { // First determine the number of features we are talking about based on region. List <IFeature> drawList = new List <IFeature>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. Figure a region that is larger. Extent r = region.Copy(); r.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawList = drawList.Union(FeatureSet.Select(r)).ToList(); } } List <Rectangle> clipRects = args.ProjToPixel(regions); DrawFeatures(args, drawList, clipRects, true); } #if DEBUG sw.Stop(); Debug.WriteLine("MapLabelLayer {0} DrawRegions: {1} ms", FeatureSet.Name, sw.ElapsedMilliseconds); #endif }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space.</param> /// <param name="regions">The geographic regions to draw.</param> /// <param name="selected">Indicates whether to draw the normal colored features or the selection colored features.</param> public virtual void DrawRegions(MapArgs args, List <Extent> regions, bool selected) { List <Rectangle> clipRects = args.ProjToPixel(regions); if (EditMode) { List <IFeature> drawList = new List <IFeature>(); drawList = regions.Where(region => region != null).Aggregate(drawList, (current, region) => current.Union(DataSet.Select(region)).ToList()); DrawFeatures(args, drawList, clipRects, true, selected); } else { List <int> drawList = new List <int>(); List <ShapeRange> shapes = DataSet.ShapeIndices; for (int shp = 0; shp < shapes.Count; shp++) { foreach (Extent region in regions) { if (!shapes[shp].Extent.Intersects(region)) { continue; } drawList.Add(shp); break; } } DrawFeatures(args, drawList, clipRects, true, selected); } }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List <Extent> regions) { if (FeatureSet == null) { return; } if (FeatureSet.IndexMode) { // First determine the number of features we are talking about based on region. List <int> drawIndices = new List <int>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. figure a region // that is larger. Extent sur = region.Copy(); sur.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawIndices = drawIndices.Union(FeatureSet.SelectIndices(sur)).ToList(); } } List <Rectangle> clips = args.ProjToPixel(regions); DrawFeatures(args, drawIndices, clips, true); } else { // First determine the number of features we are talking about based on region. List <IFeature> drawList = new List <IFeature>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. figure a region // that is larger. Extent r = region.Copy(); r.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawList = drawList.Union(FeatureSet.Select(r)).ToList(); } } List <Rectangle> clipRects = args.ProjToPixel(regions); DrawFeatures(args, drawList, clipRects, true); } }
private static Rectangle ComputeClippingRectangle(MapArgs args, ILineSymbolizer ls) { // Compute a clipping rectangle that accounts for symbology int maxLineWidth = 2 * (int)Math.Ceiling(ls.GetWidth()); Rectangle clipRect = args.ProjToPixel(args.GeographicExtents); //use GeographicExtent for clipping because ImageRect clips to much clipRect.Inflate(maxLineWidth, maxLineWidth); return(clipRect); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public virtual void DrawRegions(MapArgs args, List <Extent> regions) { // First determine the number of features we are talking about based on region. List <Rectangle> clipRects = args.ProjToPixel(regions); if (EditMode) { List <IFeature> drawList = new List <IFeature>(); foreach (Extent region in regions) { if (region != null) { // Use union to prevent duplicates. No sense in drawing more than we have to. drawList = drawList.Union(DataSet.Select(region)).ToList(); } } DrawFeatures(args, drawList, clipRects, true); } else { List <int> drawList = new List <int>(); double[] verts = DataSet.Vertex; if (DataSet.FeatureType == FeatureType.Point) { for (int shp = 0; shp < verts.Length / 2; shp++) { foreach (Extent extent in regions) { if (extent.Intersects(verts[shp * 2], verts[(shp * 2) + 1])) { drawList.Add(shp); } } } } else { List <ShapeRange> shapes = DataSet.ShapeIndices; for (int shp = 0; shp < shapes.Count; shp++) { foreach (Extent region in regions) { if (!shapes[shp].Extent.Intersects(region)) { continue; } drawList.Add(shp); break; } } } DrawFeatures(args, drawList, clipRects, true); } }
/* * private static Extent FromBruTileExtent(BruTile.Extent extent) * { * return new Extent(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY); * } */ /// <summary> /// This draws content from the specified geographic regions onto the specified graphics /// object specified by MapArgs. /// </summary> public void DrawRegions(MapArgs args, List <Extent> regions) { BruTile.Extent extent = ToBrutileExtent(args.GeographicExtents); double pixelSize = extent.Width / args.ImageRectangle.Width; int level = Utilities.GetNearestLevel(TileSource.Schema.Resolutions, pixelSize); IList <TileInfo> tiles = TileSource.Schema.GetTilesInView(extent, level); IList <WaitHandle> waitHandles = new List <WaitHandle>(); foreach (TileInfo info in tiles) { if (TileCache.Find(info.Index) != null) { continue; } AutoResetEvent waitHandle = new AutoResetEvent(false); waitHandles.Add(waitHandle); ThreadPool.QueueUserWorkItem(GetTileOnThread, new object[] { TileSource.Provider, info, TileCache, waitHandle }); } foreach (WaitHandle handle in waitHandles) { handle.WaitOne(); } foreach (TileInfo info in tiles) { using (Image bitmap = Image.FromStream(new MemoryStream(TileCache.Find(info.Index)))) { PointF min = args.ProjToPixel(new Coordinate(info.Extent.MinX, info.Extent.MinY)); PointF max = args.ProjToPixel(new Coordinate(info.Extent.MaxX, info.Extent.MaxY)); min = new PointF((float)Math.Round(min.X), (float)Math.Round(min.Y)); max = new PointF((float)Math.Round(max.X), (float)Math.Round(max.Y)); args.Device.DrawImage(bitmap, new Rectangle((int)min.X, (int)max.Y, (int)(max.X - min.X), (int)(min.Y - max.Y)), 0, 0, TileSource.Schema.Width, TileSource.Schema.Height, GraphicsUnit.Pixel); } } }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> /// <param name="selected">Indicates whether to draw the normal colored features or the selection colored features. Because rasters can't be selected they won't be drawn if selected is true.</param> public void DrawRegions(MapArgs args, List <Extent> regions, bool selected) { if (selected) { return; } List <Rectangle> clipRects = args.ProjToPixel(regions); DrawWindows(args, regions, clipRects); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List <Extent> regions) { List <Rectangle> clipRects = args.ProjToPixel(regions); for (int i = clipRects.Count - 1; i >= 0; i--) { if (clipRects[i].Width != 0 && clipRects[i].Height != 0) { continue; } regions.RemoveAt(i); clipRects.RemoveAt(i); } DrawWindows(args, regions, clipRects); }
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> /// Instructs the map frame to draw content from the specified regions to the buffer.. /// </summary> /// <param name="regions">The regions to initialize.</param> public virtual void Initialize(List<Extent> regions) { bool setView = false; if (_backBuffer == null) { _backBuffer = CreateBuffer(); //set the view setView = true; } Graphics bufferDevice = Graphics.FromImage(_backBuffer); MapArgs args = new MapArgs(ClientRectangle, ViewExtents, bufferDevice); GraphicsPath gp = new GraphicsPath(); foreach (Extent region in regions) { if (region == null) continue; Rectangle rect = args.ProjToPixel(region); gp.StartFigure(); gp.AddRectangle(rect); } bufferDevice.Clip = new Region(gp); // Draw the background color if (null != _parent) bufferDevice.Clear(_parent.BackColor); else bufferDevice.Clear(Color.White); // First draw all the vector content foreach (IMapLayer layer in Layers) { if (layer.VisibleAtExtent(ViewExtents)) layer.DrawRegions(args, regions); } // Then MapLabelLayer.ExistingLabels = new List<RectangleF>(); foreach (IMapLayer layer in Layers) { InitializeLabels(regions, args, layer); } // First draw all the vector content foreach (IMapLayer layer in DrawingLayers) { if (layer.VisibleAtExtent(ViewExtents)) layer.DrawRegions(args, regions); } if (_buffer != null && _buffer != _backBuffer) _buffer.Dispose(); _buffer = _backBuffer; if(setView) _view = _backView; bufferDevice.Clip = new Region(ImageRectangle); gp.Dispose(); List<Rectangle> rects = args.ProjToPixel(regions); OnBufferChanged(this, new ClipArgs(rects)); }
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(); } }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List <Extent> regions) { List <Rectangle> clipRects = args.ProjToPixel(regions); DrawWindows(args, regions, clipRects); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List<Extent> regions) { List<Rectangle> clipRects = args.ProjToPixel(regions); for (int i = clipRects.Count - 1; i >= 0; i--) { if (clipRects[i].Width != 0 && clipRects[i].Height != 0) continue; regions.RemoveAt(i); clipRects.RemoveAt(i); } DrawWindows(args, regions, clipRects); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public virtual void DrawRegions(MapArgs args, List<Extent> regions) { List<Rectangle> clipRects = args.ProjToPixel(regions); if (EditMode) { List<IFeature> drawList = new List<IFeature>(); drawList = regions.Where(region => region != null).Aggregate(drawList, (current, region) => current.Union(DataSet.Select(region)).ToList()); DrawFeatures(args, drawList, clipRects, true); } else { List<int> drawList = new List<int>(); List<ShapeRange> shapes = DataSet.ShapeIndices; for (int shp = 0; shp < shapes.Count; shp++) { foreach (Extent region in regions) { if (!shapes[shp].Extent.Intersects(region)) continue; drawList.Add(shp); break; } } DrawFeatures(args, drawList, clipRects, true); } }
/* private static Extent FromBruTileExtent(BruTile.Extent extent) { return new Extent(extent.MinX, extent.MinY, extent.MaxX, extent.MaxY); } */ /// <summary> /// This draws content from the specified geographic regions onto the specified graphics /// object specified by MapArgs. /// </summary> public void DrawRegions(MapArgs args, List<Extent> regions) { System.Windows.Threading.Dispatcher dispatcher = System.Windows.Application.Current.Dispatcher; BruTile.Extent extent = ToBrutileExtent(args.GeographicExtents); double pixelSize = extent.Width / args.ImageRectangle.Width; int level = Utilities.GetNearestLevel(TileSource.Schema.Resolutions, pixelSize); IList<TileInfo> tiles = TileSource.Schema.GetTilesInView(extent, level); IList<WaitHandle> waitHandles = new List<WaitHandle>(); foreach (TileInfo info in tiles) { if (TileCache.Find(info.Index) != null) continue; AutoResetEvent waitHandle = new AutoResetEvent(false); waitHandles.Add(waitHandle); ThreadPool.QueueUserWorkItem(GetTileOnThread, new object[] { TileSource.Provider, info, TileCache, waitHandle }); } foreach (WaitHandle handle in waitHandles) handle.WaitOne(); foreach (TileInfo info in tiles) { using (Image bitmap = Image.FromStream(new MemoryStream(TileCache.Find(info.Index)))) { PointF min = args.ProjToPixel(new Coordinate(info.Extent.MinX, info.Extent.MinY)); PointF max = args.ProjToPixel(new Coordinate(info.Extent.MaxX, info.Extent.MaxY)); min = new PointF((float)Math.Round(min.X), (float)Math.Round(min.Y)); max = new PointF((float)Math.Round(max.X), (float)Math.Round(max.Y)); args.Device.DrawImage(bitmap, new Rectangle((int)min.X, (int)max.Y, (int)(max.X - min.X), (int)(min.Y - max.Y)), 0, 0, TileSource.Schema.Width, TileSource.Schema.Height, GraphicsUnit.Pixel); } } }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List<Extent> regions) { List<Rectangle> clipRects = args.ProjToPixel(regions); DrawWindows(args, regions, clipRects); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public virtual void DrawRegions(MapArgs args, List<Extent> regions) { // First determine the number of features we are talking about based on region. var clipRects = args.ProjToPixel(regions); var drawList = new List<int>(); for (var shp = 0; shp < DataSet.Count; shp++) { var pointExtent = DataSet.GetFeatureExtent(shp); if (regions.Any(pointExtent.Intersects)) { drawList.Add(shp); } } DrawFeatures(args, drawList, clipRects, true); }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public void DrawRegions(MapArgs args, List<Extent> regions) { if (FeatureSet == null) return; if (FeatureSet.IndexMode) { // First determine the number of features we are talking about based on region. List<int> drawIndices = new List<int>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. figure a region // that is larger. Extent sur = region.Copy(); sur.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawIndices = drawIndices.Union(FeatureSet.SelectIndices(sur)).ToList(); } } List<Rectangle> clips = args.ProjToPixel(regions); DrawFeatures(args, drawIndices, clips, true); } else { // First determine the number of features we are talking about based on region. List<IFeature> drawList = new List<IFeature>(); foreach (Extent region in regions) { if (region != null) { // We need to consider labels that go off the screen. figure a region // that is larger. Extent r = region.Copy(); r.ExpandBy(region.Width, region.Height); // Use union to prevent duplicates. No sense in drawing more than we have to. drawList = drawList.Union(FeatureSet.Select(r)).ToList(); } } List<Rectangle> clipRects = args.ProjToPixel(regions); DrawFeatures(args, drawList, clipRects, true); } }
/// <summary> /// This will draw any features that intersect this region. To specify the features /// directly, use OnDrawFeatures. This will not clear existing buffer content. /// For that call Initialize instead. /// </summary> /// <param name="args">A GeoArgs clarifying the transformation from geographic to image space</param> /// <param name="regions">The geographic regions to draw</param> public virtual void DrawRegions(MapArgs args, List<Extent> regions) { // First determine the number of features we are talking about based on region. List<Rectangle> clipRects = args.ProjToPixel(regions); if (EditMode) { List<IFeature> drawList = new List<IFeature>(); foreach (Extent region in regions) { if (region != null) { // Use union to prevent duplicates. No sense in drawing more than we have to. drawList = drawList.Union(DataSet.Select(region)).ToList(); } } DrawFeatures(args, drawList, clipRects, true); } else { List<int> drawList = new List<int>(); List<ShapeRange> shapes = DataSet.ShapeIndices; for (int shp = 0; shp < shapes.Count; shp++) { foreach (Extent region in regions) { if (!shapes[shp].Extent.Intersects(region)) continue; drawList.Add(shp); break; } } DrawFeatures(args, drawList, clipRects, true); } }
private void DrawFeatures(MapArgs e, IEnumerable <int> indices, bool selected) { if (selected && !DrawnStatesNeeded) { return; } Graphics g = e.Device ?? Graphics.FromImage(BackBuffer); g.SetClip(new Rectangle(0, 0, e.ImageRectangle.Width, e.ImageRectangle.Height)); var indiceList = indices as IList <int> ?? indices.ToList(); Action <GraphicsPath, Rectangle, IEnumerable <int> > drawFeature = (graphPath, clipRect, features) => { foreach (int shp in features) { ShapeRange shape = DataSet.ShapeIndices[shp]; BuildLineString(graphPath, DataSet.Vertex, shape, e, clipRect); } }; if (DrawnStatesNeeded) { FastDrawnState[] states = DrawnStates; if (indiceList.Max() >= states.Length) { AssignFastDrawnStates(); states = DrawnStates; } Rectangle rTest = Rectangle.Empty; DotSpatial.Controls.Core.CGX_Mask cgxMask = DotSpatial.Controls.Core.CGX_Mask_List.GetMasks(this.Name); if (cgxMask != null) { foreach (DotSpatial.Controls.Core.CGX_MaskBounds mask in cgxMask.Masks) { RectangleF rectBounds = mask.Bounds; if (rectBounds.IsEmpty) { if (mask.Center != null) { Point pTest1 = e.ProjToPixel(mask.Center); pTest1.X -= (int)(mask.Width / 2); pTest1.Y -= (int)(mask.Height / 2); rectBounds = new RectangleF(pTest1, new SizeF((float)mask.Width, (float)mask.Height)); } } if (!rectBounds.IsEmpty) { float cx = rectBounds.X + (int)(mask.Width / 2); float cy = rectBounds.Y + +(int)(mask.Height / 2); System.Drawing.Drawing2D.Matrix oldTrans = g.Transform.Clone(); g.ResetTransform(); g.TranslateTransform(-cx, -cy, MatrixOrder.Append); g.RotateTransform((float)mask.Rotation, MatrixOrder.Append); g.TranslateTransform(cx, cy, MatrixOrder.Append); RectangleF rectWithMargin = new RectangleF( (float)((rectBounds.Location.X - cgxMask.OffsetLeft + 1)), (float)((rectBounds.Location.Y - cgxMask.OffsetTop + 1)), (float)((rectBounds.Width + cgxMask.OffsetLeft + cgxMask.OffsetRight)), (float)((rectBounds.Height + cgxMask.OffsetTop + cgxMask.OffsetBottom))); g.ExcludeClip(Rectangle.Round(rectWithMargin)); g.Transform = oldTrans; } } cgxMask.ResetBounds(); } if (selected && !states.Any(_ => _.Selected)) { return; } foreach (ILineCategory category in Symbology.Categories) { // Define the symbology based on the category and selection state ILineSymbolizer ls = selected ? category.SelectionSymbolizer : category.Symbolizer; var features = GetFeatures(indiceList, states, category, selected); DrawPath(g, ls, e, drawFeature, features); } g.ResetClip(); } else { // Selection state is disabled and there is only one category ILineSymbolizer ls = Symbology.Categories[0].Symbolizer; DrawPath(g, ls, e, drawFeature, indiceList); } if (e.Device == null) { g.Dispose(); } }
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(); }
private void DrawTile(MapArgs args, TileInfo info, Resolution resolution, byte[] buffer, TileReprojector tr = null) { if (buffer == null || buffer.Length == 0) return; tr = tr ?? new TileReprojector(args, _projection, _targetProjection); using (var bitmap = (Bitmap)Image.FromStream(new MemoryStream(buffer))) { var inWorldFile = new Reprojection.WorldFile(resolution.UnitsPerPixel, 0, 0, -resolution.UnitsPerPixel, info.Extent.MinX, info.Extent.MaxY); Reprojection.WorldFile outWorldFile; Bitmap outBitmap; tr.Reproject(inWorldFile, bitmap, out outWorldFile, out outBitmap); if (outWorldFile == null) return; var lt = args.ProjToPixel(outWorldFile.ToGround(0, 0)); var rb = args.ProjToPixel(outWorldFile.ToGround(outBitmap.Width, outBitmap.Height)); var rect = new Rectangle(lt, Size.Subtract(new Size(rb), new Size(lt))); args.Device.DrawImage(outBitmap, rect, 0, 0, outBitmap.Width, outBitmap.Height, GraphicsUnit.Pixel, _imageAttributes); if (outBitmap != bitmap) outBitmap.Dispose(); if (FrameTile) { if (FramePen != null) args.Device.DrawRectangle(FramePen, rect); } } }