public void CourseEquals() { SymbolDB symbolDB = new SymbolDB(Util.GetFileInAppDirectory("symbols.xml")); UndoMgr undomgr = new UndoMgr(5); EventDB eventDB = new EventDB(undomgr); CourseView courseView, courseView2; CourseLayout course, course2; eventDB.Load(TestUtil.GetTestFile("courselayout\\marymoor1.coursescribe")); eventDB.Validate(); // Create the a course view and layout courseView = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(3))); course = new CourseLayout(); course.SetLayerColor(CourseLayer.Descriptions, 0, "Black", 0, 0, 0, 1F, false); course.SetLayerColor(CourseLayer.MainCourse, 12, "Purple", 0.2F, 1, 0, 0.1F, false); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, CourseLayer.MainCourse); // Create it again courseView2 = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(3))); course2 = new CourseLayout(); course2.SetLayerColor(CourseLayer.Descriptions, 0, "Black", 0, 0, 0, 1F, false); course2.SetLayerColor(CourseLayer.MainCourse, 12, "Purple", 0.2F, 1, 0, 0.1F, false); CourseFormatter.FormatCourseToLayout(symbolDB, courseView2, defaultCourseAppearance, course2, CourseLayer.MainCourse); // Make sure that they are equal. Assert.AreEqual(course, course, "CourseLayouts that are equivalent should compare equal."); Assert.AreEqual(course, course2, "CourseLayouts that are equivalent should compare equal."); }
// Create a single PDF file void CreateOneBitmap(string fileName, CourseDesignator courseDesignator) { RectangleF mapRectangle = controller.GetCurrentPrintAreaRectangle(courseDesignator); // Get the course view for the course we are printing. CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, courseDesignator); // Get the correct purple color to print the course in. short ocadId; float purpleC, purpleM, purpleY, purpleK; bool purpleOverprint; FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint); // Create a course layout from the view. CourseLayout layout = new CourseLayout(); layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false); layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse); // Set the course layout into the map display mapDisplay.SetCourse(layout); mapDisplay.SetPrintArea(null); ExportBitmap exportBitmap = new ExportBitmap(mapDisplay); exportBitmap.CreateBitmap(fileName, mapRectangle, GetImageFormat(), bitmapCreationSettings.Dpi, bitmapCreationSettings.WorldFile ? mapDisplay.CoordinateMapper : null); }
CourseLayout CreateCourseLayout(CourseView courseView) { // Create the CourseLayout. CourseLayout courseLayout = new CourseLayout(); courseLayout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false); courseLayout.SetLayerColor(CourseLayer.MainCourse, NormalCourseAppearance.courseOcadId, NormalCourseAppearance.courseColorName, creationSettings.cyan, creationSettings.magenta, creationSettings.yellow, creationSettings.black, creationSettings.purpleOverprint); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, courseAppearance, courseLayout, CourseLayer.MainCourse); return(courseLayout); }
void CheckCourse(string filename, CourseDesignator courseDesignator, bool addAllControls, string testName, RectangleF rect, CourseAppearance appearance) { SymbolDB symbolDB = new SymbolDB(Util.GetFileInAppDirectory("symbols.xml")); UndoMgr undomgr = new UndoMgr(5); EventDB eventDB = new EventDB(undomgr); CourseView courseView; CourseLayout course; eventDB.Load(TestUtil.GetTestFile(filename)); eventDB.Validate(); // Create the course courseView = CourseView.CreateViewingCourseView(eventDB, courseDesignator); course = new CourseLayout(); course.SetLayerColor(CourseLayer.Descriptions, 0, "Black", 0, 0, 0, 1F, false); course.SetLayerColor(CourseLayer.MainCourse, 11, "Purple", 0.2F, 1.0F, 0.0F, 0.07F, false); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, course, CourseLayer.MainCourse); // Add all controls if requested. if (addAllControls && courseDesignator.IsNotAllControls) { courseView = CourseView.CreateFilteredAllControlsView(eventDB, new CourseDesignator[] { courseDesignator }, ControlPointKind.None, new CourseViewOptions() { showNonDescriptionSpecials = false, showDescriptionSpecials = true }); course.SetLayerColor(CourseLayer.AllControls, 12, "LightPurple", 0.1F, 0.5F, 0.0F, 0.0F, false); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, course, CourseLayer.AllControls); } // Render to a map Map map = course.RenderToMap(new CourseLayout.MapRenderOptions()); // Render map to the graphics. Bitmap bm = new Bitmap(1000, 1000); using (Graphics g = Graphics.FromImage(bm)) { RenderOptions options = new RenderOptions(); options.usePatternBitmaps = true; options.minResolution = (float)(rect.Width / bm.Width); options.renderTemplates = RenderTemplateOption.MapAndTemplates; g.ScaleTransform((float)(bm.Width / rect.Width), -(float)(bm.Height / rect.Height)); g.TranslateTransform(-rect.Left, -rect.Top - rect.Height); g.Clear(Color.White); using (map.Read()) map.Draw(new GDIPlus_GraphicsTarget(g), rect, options, null); } TestUtil.CheckBitmapsBase(bm, "courserenderer\\" + testName); }
public void HitTest() { SymbolDB symbolDB = new SymbolDB(Util.GetFileInAppDirectory("symbols.xml")); UndoMgr undomgr = new UndoMgr(5); EventDB eventDB = new EventDB(undomgr); CourseView courseView; CourseLayout course; eventDB.Load(TestUtil.GetTestFile("courselayout\\marymoor1.coursescribe")); eventDB.Validate(); // Create the all controls course courseView = CourseView.CreateViewingCourseView(eventDB, CourseDesignator.AllControls); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); CheckHitTest(course, new PointF(9.0F, 12.4F), 0, null, "Water: special:1 scale:1 location:(7.996275,12.34392)"); CheckHitTest(course, new PointF(54.7F, 12.2F), 0, null, null); CheckHitTest(course, new PointF(0.5F, 9.0F), 0, null, "Control: control:72 scale:1 location:(-0.7,10.3) gaps:"); CheckHitTest(course, new PointF(58.5F, -9.2F), 0, null, "Start: control:1 scale:1 location:(56.8,-8.7) orientation:0"); CheckHitTest(course, new PointF(46.6F, -15.9F), 0, null, @"Code: control:52 scale:1 text:52 top-left:(45.56,-12.18) font-name:Roboto Condensed font-style:Bold font-height:4.18"); // Create course 3 courseView = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(3))); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); CheckHitTest(course, new PointF(-3.5F, 10.3F), 0, null, "Control: control:72 course-control:305 scale:1 location:(-0.7,10.3) gaps:"); CheckHitTest(course, new PointF(35.6F, 17.7F), 0, null, null); CheckHitTest(course, new PointF(59.2F, 18.5F), 0, null, "Leg: control:71 course-control:307 scale:1 course-control2:308 path:N(42.92,17.55)--N(71.88,19.05)"); CheckHitTest(course, new PointF(72.1F, 33.5F), 0, null, @"ControlNumber: control:75 course-control:311 scale:1 text:10 top-left:(66.57,37.12) font-name:Roboto font-style:Regular font-height:5.57"); CheckHitTest(course, new PointF(50.2F, -2.9F), 0, null, @"Finish: control:2 course-control:315 scale:1 location:(53.2,-2.8) gaps:"); // Add in all controls. Test with true and false for all Layers. courseView = CourseView.CreateFilteredAllControlsView(eventDB, new CourseDesignator[] { Designator(3) }, ControlPointKind.Normal, new CourseViewOptions() { showNonDescriptionSpecials = false, showDescriptionSpecials = true }); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, CourseLayer.AllControls); CheckHitTest(course, new PointF(5.1F, -5.1F), CourseLayer.All, null, @"Control: layer:12 control:76 scale:1 location:(5.6,-5.7) gaps:"); CheckHitTest(course, new PointF(5.1F, -5.1F), CourseLayer.MainCourse, null, null); // Test the type filter CheckHitTest(course, new PointF(59.2F, 18.5F), CourseLayer.MainCourse, (co => co is LegCourseObj), "Leg: control:71 course-control:307 scale:1 course-control2:308 path:N(42.92,17.55)--N(71.88,19.05)"); CheckHitTest(course, new PointF(59.2F, 18.5F), CourseLayer.MainCourse, (co => co is PointCourseObj), null); CheckHitTest(course, new PointF(-3.5F, 10.3F), CourseLayer.MainCourse, (co => co is PointCourseObj), "Control: control:72 course-control:305 scale:1 location:(-0.7,10.3) gaps:"); CheckHitTest(course, new PointF(-3.5F, 10.3F), CourseLayer.MainCourse, (co => co is LineCourseObj), null); }
public void BoundingRect() { SymbolDB symbolDB = new SymbolDB(Util.GetFileInAppDirectory("symbols.xml")); UndoMgr undomgr = new UndoMgr(5); EventDB eventDB = new EventDB(undomgr); CourseView courseView; CourseLayout course; eventDB.Load(TestUtil.GetTestFile("courselayout\\marymoor1.coursescribe")); eventDB.Validate(); // Create the all controls course courseView = CourseView.CreateViewingCourseView(eventDB, CourseDesignator.AllControls); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); RectangleF bounding = course.BoundingRect(); RectangleF expected = new RectangleF(-16.41F, -34.3F, 152.17F, 79.95F); TestUtil.AssertEqualRect(expected, bounding, 0.01F, "Bounding rect all controls"); // Try course 1 courseView = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(1))); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); bounding = course.BoundingRect(); expected = new RectangleF(-2.11F, -32.9F, 64.73F, 60.43F); TestUtil.AssertEqualRect(expected, bounding, 0.1F, "Bounding rect course 1"); // Try course with control descriptions on it. courseView = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(10))); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); bounding = course.BoundingRect(); expected = new RectangleF(6.0F, -40.1F, 121.94F, 77.22F); TestUtil.AssertEqualRect(expected, bounding, 0.1F, "Bounding rect course 10"); // Do an empty course courseView = CourseView.CreateViewingCourseView(eventDB, new CourseDesignator(CourseId(11))); course = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, defaultCourseAppearance, course, 0); bounding = course.BoundingRect(); expected = RectangleF.FromLTRB(0, 0, 0, 0); TestUtil.AssertEqualRect(expected, bounding, 0.001F, "Bounding rect blank course"); }
// The core printing routine. void DrawPage(IGraphicsTarget graphicsTarget, CoursePage page) { // Get the course view for the course we are printing. CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator); // Get the correct purple color to print the course in. short ocadId; float purpleC, purpleM, purpleY, purpleK; bool purpleOverprint; FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint); // Create a course layout from the view. CourseLayout layout = new CourseLayout(); layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false); layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse); // Set the course layout into the map display mapDisplay.SetCourse(layout); mapDisplay.SetPrintArea(null); // Set the transform, and the clip. Matrix transform = Geometry.CreateInvertedRectangleTransform(page.mapRectangle, page.printRectangle); PushRectangleClip(graphicsTarget, page.printRectangle); graphicsTarget.PushTransform(transform); // Determine the resolution in map coordinates. Matrix inverseTransform = transform.Clone(); inverseTransform.Invert(); float minResolutionPage = 100F / 2400F; // Assume 2400 DPI as the base resolution, to get very accurate print. float minResolutionMap = Geometry.TransformDistance(minResolutionPage, inverseTransform); // And draw. mapDisplay.Draw(graphicsTarget, page.mapRectangle, minResolutionMap); graphicsTarget.PopTransform(); graphicsTarget.PopClip(); }
// Update the course void UpdateCourse() { CourseAppearance appearance = controller.GetCourseAppearance(); // Get purple color. short purpleOcadId; float purpleC, purpleM, purpleY, purpleK; bool purpleOverprint; controller.GetPurpleColor(out purpleOcadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint); // Place the active course in the layout. activeCourse = new CourseLayout(); activeCourse.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false); activeCourse.SetLayerColor(CourseLayer.MainCourse, NormalCourseAppearance.courseOcadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, (purpleOverprint && (extraCourses == null || extraCourses.Count == 0))); CourseFormatter.FormatCourseToLayout(symbolDB, activeCourseView, appearance, activeCourse, CourseLayer.MainCourse); if (showAllControls && !activeCourseDesignator.IsAllControls) { // Create the all controls view. CourseView allControlsView = CourseView.CreateFilteredAllControlsView(eventDB, new CourseDesignator[] { activeCourseDesignator }, allControlsFilter, new CourseViewOptions() { showNonDescriptionSpecials = false, showDescriptionSpecials = false }); // Add it to the CourseLayout. activeCourse.SetLayerColor(CourseLayer.AllControls, NormalCourseAppearance.allControlsOcadId, NormalCourseAppearance.allControlsColorName, NormalCourseAppearance.allControlsColorC, NormalCourseAppearance.allControlsColorM, NormalCourseAppearance.allControlsColorY, NormalCourseAppearance.allControlsColorK, purpleOverprint); CourseFormatter.FormatCourseToLayout(symbolDB, allControlsView, appearance, activeCourse, CourseLayer.AllControls); } if (extraCourses != null && extraCourses.Count > 0) { for (int i = 0; i < extraCourses.Count; ++i) { Id<Course> courseId = extraCourses[i]; if (eventDB.IsCoursePresent(courseId)) { AddExtraCourseToLayout(activeCourse, courseId, i % CourseLayout.EXTRACOURSECOUNT); } } } }
// extraCourseIndex indicates the color/layer. private void AddExtraCourseToLayout(CourseLayout courseLayout, Id<Course> courseId, int extraCourseIndex) { if (extraCourseIndex >= CourseLayout.EXTRACOURSECOUNT) return; CourseAppearance appearance = controller.GetCourseAppearance(); CourseLayer layer = CourseLayer.OtherCourse1 + extraCourseIndex; // Create the course view. CourseView courseView = CourseView.CreateCourseView(eventDB, new CourseDesignator(courseId), new CourseViewOptions() { showNonDescriptionSpecials = false, showDescriptionSpecials = false, showControlNumbers = false }); // Add it to the CourseLayout. courseLayout.SetLayerColor(layer, (short) (NormalCourseAppearance.extraCourseOcadId + extraCourseIndex), string.Format(NormalCourseAppearance.allControlsColorName, extraCourseIndex + 1), NormalCourseAppearance.extraCourseC[extraCourseIndex], NormalCourseAppearance.extraCourseM[extraCourseIndex], NormalCourseAppearance.extraCourseY[extraCourseIndex], NormalCourseAppearance.extraCourseK[extraCourseIndex], false); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, courseLayout, layer, new CourseFormatterOptions() { showControlNumbers = false }); }
// Get the area of the map we want to print, in map coordinates, and the print scale. // if the courseId is None, do all controls. // If asked for, crop to a single page size. RectangleF GetPrintAreaForCourse(CourseDesignator courseDesignator, out bool landscape, out PaperSize paperSize, out int margins, out float scaleRatio, out string description) { // Get the course view to get the scale ratio. CourseView courseView = CourseView.CreatePositioningCourseView(eventDB, courseDesignator); scaleRatio = courseView.ScaleRatio; description = courseView.CourseFullName; RectangleF printRectangle = controller.GetCurrentPrintAreaRectangle(courseDesignator); PrintArea printArea = controller.GetCurrentPrintArea(courseDesignator); landscape = printArea.pageLandscape; paperSize = new PaperSize("", printArea.pageWidth, printArea.pageHeight); margins = printArea.pageMargins; if (cropLargePrintArea) { // Crop the print area to a single page, portrait or landscape. // Try to keep CourseObjects in view as much as possible. CourseLayout layout = new CourseLayout(); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, 0); RectangleF courseObjectsArea = layout.BoundingRect(); courseObjectsArea.Intersect(printRectangle); // We may need to crop the print area to fit. float areaCovered; RectangleF printableArea = GetPrintablePageArea(landscape, paperSize, margins); RectangleF croppedRectangle = CropPrintArea(printRectangle, courseObjectsArea, GetScaledPrintableSizeInMapUnits(printableArea, scaleRatio), out areaCovered); return(croppedRectangle); } else { return(printRectangle); } }
// The core printing routine. The origin of the graphics is the upper-left of the margins, // and the printArea in the size to draw into (in hundreths of an inch). protected override void DrawPage(IGraphicsTarget graphicsTarget, int pageNumber, SizeF printArea, float dpi) { CoursePage page = pages[pageNumber]; // Get the course view for the course we are printing. CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator); // Get the correct purple color to print the course in. short ocadId; float purpleC, purpleM, purpleY, purpleK; bool purpleOverprint; FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint); // Create a course layout from the view. CourseLayout layout = new CourseLayout(); layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false); layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint); CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse); // Set the course layout into the map display mapDisplay.SetCourse(layout); this.mapDisplay.SetPrintArea(null); // Collecting garbage should make out of memory less common. GC.Collect(); if (graphicsTarget is GDIPlus_GraphicsTarget) { // We print to intermediate bands of bitmaps. This is the only way to get purple blending correct. // Other code ensure that if purple blending is on, we always take this code path. GDIPlus_GraphicsTarget gdiGraphicsTarget = ((GDIPlus_GraphicsTarget)graphicsTarget); Graphics g = gdiGraphicsTarget.Graphics; // Save and restore state so we can mess with stuff. GraphicsState graphicsState = g.Save(); // Printing via a bitmap. Works best with some print drivers. dpi = AdjustDpi(dpi); const long MAX_PIXELS_PER_BAND = 20000000; // 20M pixels = 60M bytes (3 bytes per pixel). List <CoursePage> bands = BandPageToLimitBitmapSize(page, dpi, MAX_PIXELS_PER_BAND); // Create the bitmap. Can do this once because each band is the same size. int bitmapWidth = (int)Math.Round(bands[0].printRectangle.Width * dpi / 100F); int bitmapHeight = (int)Math.Round(bands[0].printRectangle.Height * dpi / 100F); Bitmap bitmap = new Bitmap(bitmapWidth, bitmapHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); foreach (CoursePage band in bands) { // Set the transform Matrix transform = Geometry.CreateInvertedRectangleTransform(band.mapRectangle, new RectangleF(0, 0, bitmapWidth, bitmapHeight)); mapDisplay.Draw(bitmap, transform); try { // Draw the bitmap on the printer. g.DrawImage(bitmap, band.printRectangle); } catch (Exception) { } } // restore state. g.Restore(graphicsState); bitmap.Dispose(); } else { // Print directly. Used only when prerasterization is off. // Set the transform, and the clip. Matrix transform = Geometry.CreateInvertedRectangleTransform(page.mapRectangle, page.printRectangle); PushRectangleClip(graphicsTarget, page.printRectangle); graphicsTarget.PushTransform(transform); // Determine the resolution in map coordinates. Matrix inverseTransform = transform.Clone(); inverseTransform.Invert(); float minResolutionPage = 100F / dpi; float minResolutionMap = Geometry.TransformDistance(minResolutionPage, inverseTransform); // And draw. mapDisplay.Draw(graphicsTarget, page.mapRectangle, minResolutionMap); graphicsTarget.PopTransform(); graphicsTarget.PopClip(); } }