void IFeatureRenderer.DrawPolyline(Feature feature, Graphics g, PolylineStyle style, TitleStyle titleStyle, BoundingRectangle viewBox, bool titleVisible, double scaleFactor) { DrawPolyline(feature, g, style, titleStyle, viewBox, titleVisible, scaleFactor); }
/// <summary> /// Drawing the line. /// </summary> protected virtual void DrawPolyline(Feature feature, Graphics g, PolylineStyle style, TitleStyle titleStyle, BoundingRectangle viewBox, bool titleVisible, double scaleFactor) { if (!_isSelectionRendering && feature.Selected) { PolylineBufferElement element = new PolylineBufferElement(feature, style, titleStyle, titleVisible); _selectedPolylines.Add(element); return; } double pixelsize = 1/scaleFactor; if (_reduceSubpixelDetails) { if (feature.BoundingRectangle.Width < pixelsize && feature.BoundingRectangle.Height < pixelsize) return; Polyline p1 = (Polyline) feature.Polyline.Clone(); p1.Weed(pixelsize); Feature tempFeature = new Feature(FeatureType.Polyline); tempFeature.Title = feature.Title; tempFeature.Selected = feature.Selected; tempFeature.Polyline = p1; feature = tempFeature; if (feature.Polyline.Paths.Count == 0) return; } using (Pen pen = style.GetPen()) { if (Math.Min(viewBox.Width/(feature.BoundingRectangle.Width), viewBox.Height/(feature.BoundingRectangle.Height)) < 2) drawPolylineWithIntersectCalculation(g, feature, style, viewBox, scaleFactor); else drawPolylineSimple(g, feature, style, viewBox, scaleFactor); // inscription if (!string.IsNullOrEmpty(feature.Title) && titleVisible) addTitleBufferElement(g, feature, titleStyle, viewBox, scaleFactor); } }
private void drawPolylineSimple(Graphics g, Feature feature, PolylineStyle style, BoundingRectangle viewBox, double scaleFactor) { foreach (LinePath path in feature.Polyline.Paths) { if (path.Vertices.Count < 2) continue; PointF[] points = new PointF[path.Vertices.Count]; for (int j = 0; j < path.Vertices.Count; j++) { points[j].X = (float)((path.Vertices[j].X - viewBox.MinX) * scaleFactor); points[j].Y = (float)((viewBox.MaxY - path.Vertices[j].Y) * scaleFactor); } //selection and Stroke if (style.UseOutline || feature.Selected) drawLinePathSelectionAndOutline(g, feature.Selected, points, style); using (Pen pen = style.GetPen()) { pen.DashOffset = 0; //main polyline g.DrawLines(pen, points); if (style.UseAnnexLine) using (Pen annexPen = style.GetAnnexPen()) { // additional line g.DrawLines(annexPen, points); } } } }
public PolylineBufferElement(Feature polyline, PolylineStyle style, TitleStyle titleStyle, bool titleVisible) { _style = style; _titleStyle = titleStyle; _polyline = polyline; _titleVisible = titleVisible; }
private void drawLinePathSelectionAndOutline(Graphics g, bool selected, PointF[] pathPoints, PolylineStyle style) { if (selected) { // allocation float w = style.Width + (style.UseOutline ? style.OutlineWidth * 2 + 2 : 3); using (Pen p = new Pen(_selectionColor, w)) { p.MiterLimit = 3; g.DrawLines(p, pathPoints); } } else { // Stroke if (style.UseOutline) using (Pen p = style.GetOutlinePen()) { p.MiterLimit = 3; g.DrawLines(p, pathPoints); } } }
private void drawPolylineWithIntersectCalculation(Graphics g, Feature feature, PolylineStyle style, BoundingRectangle viewBox, double scaleFactor) { //selection and rims do not contain dashes, so it is better to paint the entire if (style.UseOutline || feature.Selected) { foreach (LinePath path in feature.Polyline.Paths) { PointF[] points = new PointF[path.Vertices.Count]; for (int j = 0; j < path.Vertices.Count; j++) { points[j].X = (float)((path.Vertices[j].X - viewBox.MinX) * scaleFactor); points[j].Y = (float)((viewBox.MaxY - path.Vertices[j].Y) * scaleFactor); } if (style.UseOutline || feature.Selected) drawLinePathSelectionAndOutline(g, feature.Selected, points, style); } } List<ICoordinate> currentPath = new List<ICoordinate>(); using (Pen pen = style.GetPen()) { using(Pen annexPen = style.GetAnnexPen()) foreach (LinePath path in feature.Polyline.Paths) { if (path.Vertices.Count < 2) continue; currentPath.Clear(); double currentLength = 0; bool isInternalPath = viewBox.ContainsPoint(path.Vertices[0]); ICoordinate previousPoint = path.Vertices[0]; IList<ICoordinate> vertices = path.Vertices; for (int j = 0; j < path.Vertices.Count; j++) { if (isInternalPath) // the inside of the polyline { if (viewBox.ContainsPoint(vertices[j])) //stay inside { currentPath.Add(vertices[j]); continue; } else // go outside { // add a point of intersection List<ICoordinate> crossPoints = getCrossPoints(vertices[j], vertices[j - 1], viewBox); currentPath.Add(crossPoints[0]); //draw drawVisiblePolylinePartWithStyleDetection(g, currentPath, style, pen, annexPen, feature.Selected, viewBox, scaleFactor, currentLength); // are counting the length of a past currentLength += getPathLength(currentPath); // initialize the array outside of the points, polylines and continue execution currentPath.Clear(); currentPath.Add(crossPoints[0]); currentPath.Add(vertices[j]); isInternalPath = false; continue; } } else //the outer part of the polyline { if (viewBox.ContainsPoint(vertices[j])) // go inside { //add a point of intersection List<ICoordinate> crossPoints = getCrossPoints(vertices[j], vertices[j - 1], viewBox); currentPath.Add(crossPoints[0]); //are counting the length of a past currentLength += getPathLength(currentPath); // initialize the array of points inside the polyline and continue execution currentPath.Clear(); currentPath.Add(crossPoints[0]); currentPath.Add(vertices[j]); isInternalPath = true; continue; } else // cross twice, or remain outside { // look for the point of intersection if (j > 0) { List<ICoordinate> crossPoints = getCrossPoints(vertices[j], vertices[j - 1], viewBox); if (crossPoints.Count == 0) // remained outside { currentPath.Add(vertices[j]); continue; } if (crossPoints.Count == 2) // crossed 2 times { //determine which of the points of intersection must be added to the current path double d0 = PlanimetryAlgorithms.Distance(crossPoints[0], vertices[j - 1]); double d1 = PlanimetryAlgorithms.Distance(crossPoints[1], vertices[j - 1]); if (d0 < d1) currentPath.Add(crossPoints[0]); else currentPath.Add(crossPoints[1]); // are counting the length of a past currentLength += getPathLength(currentPath); currentPath.Clear(); currentPath.Add(crossPoints[d0 < d1 ? 0 : 1]); currentPath.Add(crossPoints[d0 < d1 ? 1 : 0]); //draw a segment drawVisiblePolylinePartWithStyleDetection(g, currentPath, style, pen, annexPen, feature.Selected, viewBox, scaleFactor, currentLength); // consider the length currentLength += PlanimetryAlgorithms.Distance(crossPoints[0], crossPoints[1]); // initialize the external part of the polyline currentPath.Clear(); if (d0 < d1) currentPath.Add(crossPoints[1]); else currentPath.Add(crossPoints[0]); currentPath.Add(vertices[j]); isInternalPath = false; continue; } } else // 1st point you just need to add to the list { currentPath.Add(vertices[j]); continue; } } } } //Draw a polyline part, if the internal if (isInternalPath) drawVisiblePolylinePartWithStyleDetection(g, currentPath, style, pen, annexPen, feature.Selected, viewBox, scaleFactor, currentLength); } } }
private static void drawVisiblePolylinePartWithStyleDetection(Graphics g, List<ICoordinate> path, PolylineStyle style, Pen defaultPen, Pen annexPen, bool selected, BoundingRectangle viewBox, double scaleFactor, double lengthFromBegining) { // Necessary to calculate the displacement pattern of the pen before drawing a polyline, or generated images will not be used for cross-linking. // Pattern in the zero offset polyline vertex set equal to zero. // Knowing the length of the zero-vertex to the portion of the polyline, you can calculate the shift pattern at the beginning of the portion. float relativeDashSize = getRelativeDashSize(defaultPen); float dashSize = style.Width * relativeDashSize; float dashOffset = (float)((lengthFromBegining * scaleFactor) % dashSize) / style.Width; defaultPen.DashOffset = dashOffset; if (style.UseAnnexLine) { relativeDashSize = getRelativeDashSize(annexPen); dashSize = style.Width * relativeDashSize; dashOffset = (float)((lengthFromBegining * scaleFactor) % dashSize) / style.Width; annexPen.DashOffset = dashOffset; } // main polyline drawVisiblePolylinePart(g, path, defaultPen, viewBox, scaleFactor); if (style.UseAnnexLine) { // More polyline drawVisiblePolylinePart(g, path, annexPen, viewBox, scaleFactor); } }
/// <summary/> protected void processPolylineStyle(XmlNode layerNode, PolylineStyle PolylineStyle) { XmlNode polylineStyle = tryGetNodeByName(layerNode.ChildNodes, "polyline_style"); if (polylineStyle != null) { PolylineStyle.Width = int.Parse(polylineStyle.Attributes["width"].Value, CultureInfo.InvariantCulture); PolylineStyle.Color = ColorTranslator.FromHtml(polylineStyle.Attributes["color"].Value); PolylineStyle.DashStyle = (DashStyle)int.Parse(polylineStyle.Attributes["dash_style"].Value, CultureInfo.InvariantCulture); if (polylineStyle.Attributes["dash_cap"] != null) PolylineStyle.DashCap = (DashCap)int.Parse(polylineStyle.Attributes["dash_cap"].Value, CultureInfo.InvariantCulture); if (polylineStyle.Attributes["dash_pattern"] != null) PolylineStyle.DashPattern = stringToFloatArray(polylineStyle.Attributes["dash_pattern"].Value); if (polylineStyle.Attributes["is_compound"] != null) PolylineStyle.IsCompound = polylineStyle.Attributes["is_compound"].Value == "1"; if (polylineStyle.Attributes["compound"] != null) PolylineStyle.Compound = stringToFloatArray(polylineStyle.Attributes["compound"].Value); if (polylineStyle.Attributes["use_annex_line"] != null) { PolylineStyle.UseAnnexLine = polylineStyle.Attributes["use_annex_line"].Value == "1"; PolylineStyle.AnnexColor = ColorTranslator.FromHtml(polylineStyle.Attributes["annex_color"].Value); PolylineStyle.AnnexDashStyle = (DashStyle)int.Parse(polylineStyle.Attributes["annex_dash_style"].Value, CultureInfo.InvariantCulture); if (polylineStyle.Attributes["annex_dash_cap"] != null) PolylineStyle.AnnexDashCap = (DashCap)int.Parse(polylineStyle.Attributes["annex_dash_cap"].Value, CultureInfo.InvariantCulture); if (polylineStyle.Attributes["annex_dash_pattern"] != null) PolylineStyle.AnnexDashPattern = stringToFloatArray(polylineStyle.Attributes["annex_dash_pattern"].Value); if (polylineStyle.Attributes["is_annex_compound"] != null) PolylineStyle.IsAnnexCompound = polylineStyle.Attributes["is_annex_compound"].Value == "1"; if (polylineStyle.Attributes["annex_compound"] != null) PolylineStyle.AnnexCompound = stringToFloatArray(polylineStyle.Attributes["annex_compound"].Value); } if (polylineStyle.Attributes["use_outline"] != null) PolylineStyle.UseOutline = polylineStyle.Attributes["use_outline"].Value == "1"; if (polylineStyle.Attributes["outline_color"] != null) PolylineStyle.OutlineColor = ColorTranslator.FromHtml(polylineStyle.Attributes["outline_color"].Value); if (polylineStyle.Attributes["outline_width"] != null) PolylineStyle.OutlineWidth = int.Parse(polylineStyle.Attributes["outline_width"].Value, CultureInfo.InvariantCulture); if (polylineStyle.Attributes["outline_transparent"] != null) PolylineStyle.OutlineColor = Color.FromArgb(int.Parse(polylineStyle.Attributes["outline_transparent"].Value, CultureInfo.InvariantCulture), PolylineStyle.OutlineColor); } }
/// <summary/> protected void addPolylineStyleElement(PolylineStyle PolylineStyle, XmlDocument doc, XmlElement layerElement) { XmlElement polylineStyleElement = doc.CreateElement("polyline_style"); layerElement.AppendChild(polylineStyleElement); addAttribute( polylineStyleElement, "width", PolylineStyle.Width.ToString(CultureInfo.InvariantCulture)); addAttribute( polylineStyleElement, "use_annex_line", PolylineStyle.UseAnnexLine ? "1" : "0"); addAttribute( polylineStyleElement, "color", ColorTranslator.ToHtml(PolylineStyle.Color)); addAttribute( polylineStyleElement, "dash_style", ((int)PolylineStyle.DashStyle).ToString(CultureInfo.InvariantCulture)); addAttribute( polylineStyleElement, "dash_cap", ((int)PolylineStyle.DashCap).ToString(CultureInfo.InvariantCulture)); if (PolylineStyle.DashPattern != null) addAttribute( polylineStyleElement, "dash_pattern", floatArrayToString(PolylineStyle.DashPattern)); addAttribute( polylineStyleElement, "is_compound", PolylineStyle.IsCompound ? "1" : "0"); if (PolylineStyle.Compound != null) addAttribute( polylineStyleElement, "compound", floatArrayToString(PolylineStyle.Compound)); addAttribute( polylineStyleElement, "annex_color", ColorTranslator.ToHtml(PolylineStyle.AnnexColor)); addAttribute( polylineStyleElement, "annex_dash_style", ((int)PolylineStyle.AnnexDashStyle).ToString(CultureInfo.InvariantCulture)); addAttribute( polylineStyleElement, "annex_dash_cap", ((int)PolylineStyle.AnnexDashCap).ToString(CultureInfo.InvariantCulture)); if (PolylineStyle.DashPattern != null) addAttribute( polylineStyleElement, "annex_dash_pattern", floatArrayToString(PolylineStyle.AnnexDashPattern)); addAttribute( polylineStyleElement, "is_annex_compound", PolylineStyle.IsAnnexCompound ? "1" : "0"); if (PolylineStyle.AnnexCompound != null) addAttribute( polylineStyleElement, "annex_compound", floatArrayToString(PolylineStyle.AnnexCompound)); addAttribute( polylineStyleElement, "use_outline", PolylineStyle.UseOutline ? "1" : "0"); addAttribute( polylineStyleElement, "outline_width", PolylineStyle.OutlineWidth.ToString(CultureInfo.InvariantCulture)); addAttribute( polylineStyleElement, "outline_color", ColorTranslator.ToHtml(PolylineStyle.OutlineColor)); addAttribute( polylineStyleElement, "outline_transparent", PolylineStyle.OutlineColor.A.ToString(CultureInfo.InvariantCulture)); }