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); } } } }
/// <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 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); } } }