/// <summary> /// Creates a SimpleSymbol with the specified color, shape and size. The size is used for /// both the horizontal and vertical directions. /// </summary> /// <param name="color">The color of the symbol.</param> /// <param name="shape">The shape of the symbol.</param> /// <param name="size">The size of the symbol.</param> public SimpleSymbol(Color color, PointShape shape, double size) { Configure(); _color = color; _pointShape = shape; Size = new Size2D(size, size); }
/// <summary> /// Calculates the bounding size for this entire symbol. /// </summary> /// <param name="self"></param> /// <returns></returns> public static Size2D GetBoundingSize(this IList<ISymbol> self) { Size2D size = new Size2D(); foreach (ISymbol symbol in self) { Size2D bsize = symbol.GetBoundingSize(); size.Width = Math.Max(size.Width, bsize.Width); size.Height = Math.Max(size.Height, bsize.Height); } return size; }
/// <summary> /// Converts a string into a Size2D /// </summary> /// <param name="context"></param> /// <param name="culture"></param> /// <param name="value"></param> /// <returns></returns> public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value is string) { try { string s = (string)value; string[] converterParts = s.Split(','); double x; double y; if (converterParts.Length > 1) { x = double.Parse(converterParts[0].Trim()); y = double.Parse(converterParts[1].Trim()); } else if (converterParts.Length == 1) { x = double.Parse(converterParts[0].Trim()); y = 0; } else { x = 0; y = 0; } Size2D result = new Size2D(x, y); return result; } catch { throw new ArgumentException("Cannot convert [" + value + "] to Size2D"); } } if (value is Size2D) { return value; } return base.ConvertFrom(context, culture, value); }
/// <summary> /// Initializes a new instance of the <see cref="PictureSymbol"/> class from the specified image. /// The larger dimension from the image will be adjusted to fit the size, /// while the smaller dimension will be kept proportional. /// </summary> /// <param name="image">The image to use for this symbol.</param> /// <param name="size">The double size to use for the larger of the two dimensions of the image.</param> public PictureSymbol(Image image, double size) { SymbolType = SymbolType.Picture; _opacity = 1F; Image = image; if (image == null) { return; } double scale; if (image.Width > image.Height) { scale = size / image.Width; } else { scale = size / image.Height; } Size = new Size2D(scale * image.Width, scale * image.Height); }
/// <inheritdoc /> public override Size GetLegendSymbolSize() { Size2D sz = GetSize(); int w = (int)sz.Width; int h = (int)sz.Height; if (w < 1) { w = 1; } if (w > 128) { w = 128; } if (h < 1) { h = 1; } if (h > 128) { h = 128; } return(new Size(w, h)); }
/// <summary> /// Creates a new instance of Symbol /// </summary> public Symbol() { _size = new Size2D(4, 4); _offset = new Position2D(0, 0); }
/// <summary> /// Creates a new instance of CharacterSymbol /// </summary> /// <param name="character">The character to use for the symbol</param> /// <param name="fontFamily">The font family for the character</param> /// <param name="color">The color for the character</param> /// <param name="size">The size for the symbol</param> public CharacterSymbol(char character, string fontFamily, Color color, double size) { _character = character; _fontFamilyName = fontFamily; _color = color; _style = FontStyle.Regular; Size = new Size2D(size, size); base.SymbolType = SymbolType.Character; }
/// <summary> /// This replaces the constant size calculation with a size /// calculation that is appropriate for features. /// </summary> /// <param name="count">The integer count of the number of sizes to create.</param> /// <returns>A list of double valued sizes.</returns> protected override List<double> GetSizeSet(int count) { List<double> result = new List<double>(); if (EditorSettings.UseSizeRange) { double start = EditorSettings.StartSize; double dr = (EditorSettings.EndSize - start); double dx = dr / count; if (!EditorSettings.RampColors) { Random rnd = new Random(DateTime.Now.Millisecond); for (int i = 0; i < count; i++) { result.Add(start + rnd.NextDouble() * dr); } } else { for (int i = 0; i < count; i++) { result.Add(start + i * dx); } } } else { Size2D sizes = new Size2D(2, 2); IPointSymbolizer ps = EditorSettings.TemplateSymbolizer as IPointSymbolizer; if (ps != null) sizes = ps.GetSize(); double size = Math.Max(sizes.Width, sizes.Height); for (int i = 0; i < count; i++) { result.Add(size); } } return result; }
/// <summary> /// Initializes a new instance of the <see cref="SimpleSymbol"/> class with the specified color, shape and size. The size is used for /// both the horizontal and vertical directions. /// </summary> /// <param name="color">The color of the symbol.</param> /// <param name="shape">The shape of the symbol.</param> /// <param name="size">The size of the symbol.</param> public SimpleSymbol(Color color, PointShape shape, double size) : this(color, shape) { Size = new Size2D(size, size); }
/// <summary> /// This assumes that you wish to simply scale the various sizes. /// It will adjust all of the sizes so that the maximum size is /// the same as the specified size. /// </summary> /// <param name="value">The Size2D of the new maximum size</param> public void SetSize(Size2D value) { Size2D oldSize = _symbols.GetBoundingSize(); double dX = value.Width / oldSize.Width; double dY = value.Height / oldSize.Height; foreach (ISymbol symbol in _symbols) { Size2D os = symbol.Size; symbol.Size = new Size2D(os.Width * dX, os.Height * dY); } }
/// <summary> /// Given the points on this line decoration, this will cycle through and handle /// the drawing as dictated by this decoration. /// </summary> /// <param name="g">The graphics object used for drawing.</param> /// <param name="path">The path of the line.</param> /// <param name="scaleWidth">The double scale width for controling markers</param> public void Draw(Graphics g, GraphicsPath path, double scaleWidth) { if (NumSymbols == 0) { return; } GraphicsPathIterator myIterator = new GraphicsPathIterator(path); myIterator.Rewind(); int start, end; bool isClosed; Size2D symbolSize = _symbol.GetSize(); Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height); Graphics sg = Graphics.FromImage(symbol); _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height)); sg.Dispose(); Matrix oldMat = g.Transform; PointF[] points; if (path.PointCount == 0) { return; } try { points = path.PathPoints; } catch { return; } while (myIterator.NextSubpath(out start, out end, out isClosed) > 0) { if (NumSymbols == 1) { // single decoration spot if (_percentualPosition == 0) { // at start of the line DrawImage(g, points[start], points[start + 1], points[start], FlipFirst ^ FlipAll, symbol, oldMat); } else if (_percentualPosition == 100) { // at end of the line DrawImage(g, points[end - 1], points[end], points[end], FlipFirst ^ FlipAll, symbol, oldMat); } else { // somewhere in between start and end double totalLength = GetLength(points, start, end); double span = totalLength * _percentualPosition / 100; List <DecorationSpot> spot = GetPosition(points, span, start, end); if (spot.Count > 1) { DrawImage(g, spot[1].Before, spot[1].After, spot[1].Position, FlipFirst ^ FlipAll, symbol, oldMat); } } } else { // more than one decoration spot double totalLength = GetLength(points, start, end); double span = Math.Round(totalLength / (NumSymbols - 1), 4); List <DecorationSpot> spots = GetPosition(points, span, start, end); spots.Add(new DecorationSpot(points[end - 1], points[end], points[end])); // add the missing end point for (int i = 0; i < spots.Count; i++) { DrawImage(g, spots[i].Before, spots[i].After, spots[i].Position, i == 0 ? (FlipFirst ^ FlipAll) : FlipAll, symbol, oldMat); } } } }
private void DrawMarker(Graphics g, GraphicsPath path, double scaleWidth) { if (Marker == null) { return; } if (DashButtons == null || DashButtons.Length <= 1) { return; } GraphicsPathIterator myIterator = new GraphicsPathIterator(path); myIterator.Rewind(); int start, end; bool isClosed; Size2D symbolSize = Marker.GetSize(); Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height); using (Graphics sg = Graphics.FromImage(symbol)) { Marker.Draw(sg, new Rectangle(0, 0, symbol.Width, symbol.Height)); } Matrix oldMat = g.Transform; PointF[] points; if (path.PointCount == 0) { return; } try { points = path.PathPoints; } catch { return; } while (myIterator.NextSubpath(out start, out end, out isClosed) > 0) { double totalLength = GetLength(points, start, end); PointF startPoint = points[start]; PointF endPoint = points[end]; double totalUsedLength = 0; if (DashButtons.Length == 2) { bool dash = DashButtons[0]; if (!dash) { totalUsedLength = (float)(totalLength / 2); double usedLength = 0; for (int i = start; i < end; i++) { startPoint = points[i]; endPoint = points[i + 1]; double segmentLength = Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2)); if (usedLength + segmentLength > totalUsedLength) { if (segmentLength >= symbol.Width / 2) // 线长度大于点符号宽度的一半才绘制 { double length = totalUsedLength - usedLength; PointF location = GetPoint(startPoint, endPoint, length); DrawImage(g, startPoint, endPoint, location, symbol); } break; } usedLength += segmentLength; } } } else { int k = 0; for (int i = start; i < end; i++) { startPoint = points[i]; endPoint = points[i + 1]; double segmentLength = Math.Sqrt(Math.Pow(endPoint.X - startPoint.X, 2) + Math.Pow(endPoint.Y - startPoint.Y, 2)); double usedLength = 0; while (totalUsedLength < totalLength && usedLength < segmentLength) { if (k == DashButtons.Length) { k = 0; } bool dash = DashButtons[k]; if (!dash) { PointF location = GetPoint(startPoint, endPoint, usedLength); DrawImage(g, startPoint, endPoint, location, symbol); } totalUsedLength++; usedLength++; k++; } } } } }
/// <summary> /// Given the points on this line decoration, this will cycle through and handle /// the drawing as dictated by this decoration. /// </summary> /// <param name="g"></param> /// <param name="path"></param> /// <param name="scaleWidth">The double scale width for controling markers</param> public void Draw(Graphics g, GraphicsPath path, double scaleWidth) { if (NumSymbols == 0) { return; } GraphicsPathIterator myIterator = new GraphicsPathIterator(path); myIterator.Rewind(); int start, end; bool isClosed; Size2D symbolSize = _symbol.GetSize(); Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height); Graphics sg = Graphics.FromImage(symbol); _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height)); sg.Dispose(); Matrix oldMat = g.Transform; PointF[] points; if (path.PointCount == 0) { return; } try { points = path.PathPoints; } catch { return; } PointF offset; int count = 0; while (myIterator.NextSubpath(out start, out end, out isClosed) > 0) { count = count + 1; // First marker PointF startPoint = points[start]; PointF stopPoint = points[start + 1]; float angle = 0F; if (_rotateWithLine) { angle = GetAngle(startPoint, stopPoint); } if (FlipFirst && !FlipAll) { FlipAngle(ref angle); } offset = GetOffset(startPoint, stopPoint); startPoint = new PointF(startPoint.X + offset.X, startPoint.Y + offset.Y); Matrix rotated = g.Transform; rotated.RotateAt(angle, startPoint); g.Transform = rotated; DrawImage(g, startPoint, symbol); g.Transform = oldMat; // Second marker if (NumSymbols > 1) { angle = 0F; if (_rotateWithLine) { angle = GetAngle(points[end - 1], points[end]); } if (FlipAll) { FlipAngle(ref angle); } offset = GetOffset(points[end - 1], points[end]); PointF endPoint = new PointF(points[end].X + offset.X, points[end].Y + offset.Y); rotated = g.Transform; rotated.RotateAt(angle, endPoint); g.Transform = rotated; DrawImage(g, endPoint, symbol); g.Transform = oldMat; } if (NumSymbols > 2) { double totalLength = GetLength(points, start, end); double span = totalLength / (NumSymbols - 1); for (int i = 1; i < NumSymbols - 1; i++) { DecorationSpot spot = GetPosition(points, span * i, start, end); angle = 0F; if (_rotateWithLine) { angle = GetAngle(spot.Before, spot.After); } offset = GetOffset(spot.Before, spot.After); PointF location = new PointF(spot.Position.X + offset.X, spot.Position.Y + offset.Y); if (FlipAll) { FlipAngle(ref angle); } rotated = g.Transform; rotated.RotateAt(angle, location); g.Transform = rotated; DrawImage(g, location, symbol); g.Transform = oldMat; } } } }
/// <summary> /// Creates a new instance of a PictureSymbol from the specified image. /// The larger dimension from the image will be adjusted to fit the size, /// while the smaller dimension will be kept proportional. /// </summary> /// <param name="image">The image to use for this symbol</param> /// <param name="size">The double size to use for the larger of the two dimensions of the image.</param> public PictureSymbol(Image image, double size) { base.SymbolType = SymbolType.Picture; _opacity = 1F; Image = image; if (image == null) return; double scale; if (image.Width > image.Height) { scale = size / image.Width; } else { scale = size / image.Height; } Size = new Size2D(scale * image.Width, scale * image.Height); }
/// <summary> /// Only copies the shared placement aspects (Size, Offset, Angle) from the specified symbol. /// </summary> /// <param name="symbol">The symbol to copy values from.</param> public void CopyPlacement(ISymbol symbol) { if (_innerSymbol != null) { _innerSymbol.CopyPlacement(symbol); return; } _size = symbol.Size.Copy(); _offset = symbol.Offset.Copy(); _angle = symbol.Angle; }
/// <summary> /// Tests for equality against another size. /// </summary> /// <param name="size">the size to compare this size to</param> /// <returns>boolean, true if the height and width are the same in each case.</returns> public bool Equals(Size2D size) { if (((object)size) == null) return false; return (size.Width == Width && size.Height == Height); }
/// <summary> /// Initializes a new instance of the <see cref="Symbol"/> class. /// </summary> public Symbol() { _size = new Size2D(4, 4); _offset = new Position2D(0, 0); }
private Bitmap CreateDefaultSymbol(Color color, int symbolSize) { double scaleSize = 1; Size2D size = new Size2D(symbolSize, symbolSize); Bitmap normalSymbol = new Bitmap((int)(size.Width * scaleSize) + 1, (int)(size.Height * scaleSize) + 1); Graphics bg = Graphics.FromImage(normalSymbol); Random rnd = new Random(); Color randomColor = Color.FromArgb(rnd.Next(0, 255), rnd.Next(0, 255), rnd.Next(0, 255)); PointSymbolizer sym = new PointSymbolizer(randomColor, DotSpatial.Symbology.PointShape.Rectangle, 4); PointCategory category = new PointCategory(sym); bg.SmoothingMode = category.Symbolizer.Smoothing ? SmoothingMode.AntiAlias : SmoothingMode.None; Matrix trans = bg.Transform; trans.Translate(((float)(size.Width * scaleSize) / 2 - 1), (float)(size.Height * scaleSize) / 2 - 1); bg.Transform = trans; category.Symbolizer.Draw(bg, 1); return normalSymbol; }
/// <summary> /// Given the points on this line decoration, this will cycle through and handle /// the drawing as dictated by this decoration. /// </summary> /// <param name="g">The graphics object used for drawing.</param> /// <param name="path">The path of the line.</param> /// <param name="scaleWidth">The double scale width for controling markers</param> public void Draw(Graphics g, GraphicsPath path, double scaleWidth) { // CGX TRY CATCH try { if (NumSymbols == 0) { return; } GraphicsPathIterator myIterator = new GraphicsPathIterator(path); myIterator.Rewind(); bool isClosed; Size2D symbolSize = _symbol.GetSize(); symbolSize.Height = Math.Ceiling(symbolSize.Height * scaleWidth); symbolSize.Width = Math.Ceiling(symbolSize.Width * scaleWidth); Bitmap symbol = new Bitmap((int)symbolSize.Width, (int)symbolSize.Height); Graphics sg = Graphics.FromImage(symbol); _symbol.Draw(sg, new Rectangle(0, 0, (int)symbolSize.Width, (int)symbolSize.Height)); sg.Dispose(); Matrix oldMat = g.Transform; GraphicsPath gp = new GraphicsPath(); GraphicsPath pastGP = new GraphicsPath(); while (myIterator.NextSubpath(gp, out isClosed) > 0) { PointF[] points = gp.PathPoints; int start = 0, end = points.Length - 1; if (NumSymbols == 1) { // single decoration spot if (_percentualPosition == 0) { // at start of the line DrawImage(g, points[start], points[start + 1], points[start], FlipFirst ^ FlipAll, symbol, oldMat, scaleWidth); } else if (_percentualPosition == 100) { // at end of the line DrawImage(g, points[end - 1], points[end], points[end], FlipFirst ^ FlipAll, symbol, oldMat, scaleWidth); } else { // somewhere in between start and end double totalLength = GetLength(points, start, end); double span = totalLength * _percentualPosition / 100; List <DecorationSpot> spot = GetPosition(points, span, start, end); if (spot.Count > 1) { DrawImage(g, spot[1].Before, spot[1].After, spot[1].Position, FlipFirst ^ FlipAll, symbol, oldMat, scaleWidth); } } } else { // more than one decoration spot double totalLength = GetLength(points, start, end); List <DecorationSpot> spots = new List <DecorationSpot>(); double span = 0.0; if (_useSpacing) { var dpi = g.DpiX; var mm = GetSpacingValue_mm(); span = ((mm * dpi) / 25.4) * scaleWidth; if (DotSpatial.Symbology.Core.Constants.IsPrinting) { float fRes = (float)g.DpiX; span = span * 97.0F / fRes; } } else { span = Math.Round(totalLength / (NumSymbols - 1), 4); } if (span > 0) { spots = GetPosition(points, span, start, end); } for (int i = 0; i < spots.Count; i++) { using (var pen = new Pen(Color.Black, 2)) { if (!pastGP.IsOutlineVisible(spots[i].Position, pen)) { DrawImage(g, spots[i].Before, spots[i].After, spots[i].Position, i == 0 ? (FlipFirst ^ FlipAll) : FlipAll, oldMat, scaleWidth); } } } } pastGP.AddPath(gp, false); } } catch (Exception) { } }