Rendering Arrows Tutorial |
Directional arrows are useful visual indicators when navigating a route, clearly identifying the direction a vehicle should take from one RouteStop to the next.
These directional arrows are added to an existing Directions object using the Directions properties RenderArrowWidth, RenderArrowLength, RenderArrowColor, and RenderArrowSpacing then rendered directly on a map above a route highlight using the IMapRenderer interface. The direction of these arrows is specified by the Directions object.
Arrows can also be overlaid above arbitrary LineString objects and rendered on a map. The direction of these arrows is specified by the creation order of the line's points.
In this tutorial we will create an application that demonstrates the use of:
directional arrows above a route highlight, indicating the direction of travel to be taken from the route's start location, through any subsequent stops, to its final stop
directional arrows above a LineString object, indicating the direction along the line from the first point to the last
Create a new Visual Studio Project (a Windows Forms Application) called 'Arrows'.
Add a reference to geobase.net.dll. Then, to make the code simpler and more readable, add the following using directives to the top of the project form (Form1.cs).
using Telogis.GeoBase; using Telogis.GeoBase.Geometry; using Telogis.GeoBase.Routing; using Telogis.GeoBase.Mapping;
Return to the 'Design' view (Shift+F7) and add the following controls to the form:
When run, your new application should appear similar to the screenshot below:
Next, add the following code to the top of the project such that the items are global (immediately above the Form1 constructor). Here we create a renderlist object to display the map, and an empty route object.
// Create rendererlist RendererList renderList = new RendererList(); // Create a route Route myRoute = new Route();
Copy the following displayRouteDirections method below the Form1 constructor. This will create a directions object from the route using GetRouteHighlight, then configure the directions object's arrow renderer using RenderArrowWidth, RenderArrowLength, RenderArrowColor, and RenderArrowSpacing.
We then add the directions object to the renderlist and invalidate the map, forcing a map redraw.
private void displayRouteDirections() { // Create directions using route highlight Directions dir = myRoute.GetRouteHighlight(); // Configure render arrows dir.RenderArrowColor = Color.Blue; dir.RenderArrowLength = 20; dir.RenderArrowWidth = 15; dir.RenderArrowSpacing = 40; dir.RenderColor = Color.LightSkyBlue; // Add route and highlight directions renderList.Add(dir); // Force redraw mapMain.Invalidate(); }
Copy and paste the following displayLineDirections method directly below the displayRouteDirections() method. In it we create a new LineString object, then construct a new ArrowRenderer object and set its LatLons using the line's Points.
We then instantiate a new ArrowProperties object and specify the arrow color, length, width and spacing interval along the line (in pixels) before adding the ArrowRenderer object to the renderlist and invalidating the map.
private void displayLineDirections() { // Create a line Telogis.GeoBase.Geometry.LineString myLine = new Telogis.GeoBase.Geometry.LineString( new Telogis.GeoBase.LatLon[] { new Telogis.GeoBase.LatLon(33.604893,-117.755952), new Telogis.GeoBase.LatLon(33.604896,-117.736347), new Telogis.GeoBase.LatLon(33.588719,-117.736539), new Telogis.GeoBase.LatLon(33.588799,-117.755851), new Telogis.GeoBase.LatLon(33.604893,-117.755952) }); // Create an arrow renderer ArrowRenderer myArrowLine = new ArrowRenderer(); myArrowLine.LatLons = myLine.Points; myArrowLine.LineColor = Color.Black; myArrowLine.LineWidth = 3; // Specify ArrowProperties myArrowLine.ArrowProperties = new ArrowProperties { Color = Color.Red, Length = 20, Width = 10, Spacing = 20 }; // Add arrow line to renderer renderList.Add(myArrowLine); // Force redraw mapMain.Invalidate(); }
Add a load event to mapMain, then edit the mapMain_Load method to match the following code. This sets the location and zoom of the map, then creates a Route containing four RouteStops before adding the route to the renderlist.
private void mapMain_Load(object sender, EventArgs e) { mapMain.Center = new LatLon(33.596687, -117.731421); mapMain.Zoom = 4; mapMain.Renderer = renderList; // Create stops RouteStop s1 = new RouteStop(new LatLon(33.605135, -117.708917)); RouteStop s2 = new RouteStop(new LatLon(33.605057, -117.728619)); RouteStop s3 = new RouteStop(new LatLon(33.588961, -117.728621)); RouteStop s4 = new RouteStop(new LatLon(33.588959, -117.709116)); // Add stops to route myRoute.AddStops(new RouteStop[] { s1, s2, s3, s4 }); // Add to renderer renderList.Add(myRoute); }
Add click events to the two buttonLine and buttonRoute buttons. These click events will be used to trigger the route and line arrow renderers specified above. Edit the buttonRoute_Click and buttonLine_Click methods to match the following code:
private void buttonRoute_Click(object sender, EventArgs e) { displayRouteDirections(); } private void buttonLine_Click(object sender, EventArgs e) { displayLineDirections(); }
Run the application. After clicking the 'Line Direction' and 'Route Direction' buttons the map will be updated with arrow renderers for the specified route and linestring objects.
The complete code for this example project is included below:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Telogis.GeoBase; using Telogis.GeoBase.Geometry; using Telogis.GeoBase.Routing; using Telogis.GeoBase.Mapping; namespace Arrows { public partial class Form1 : Form { // Create rendererlist RendererList renderList = new RendererList(); // Create a route Route myRoute = new Route(); public Form1() { InitializeComponent(); } private void displayRouteDirections() { // Create directions using route highlight Directions dir = myRoute.GetRouteHighlight(); // Configure render arrows dir.RenderArrowColor = Color.Blue; dir.RenderArrowLength = 20; dir.RenderArrowWidth = 15; dir.RenderArrowSpacing = 40; dir.RenderColor = Color.LightSkyBlue; // Add route and highlight directions renderList.Add(dir); // Force redraw mapMain.Invalidate(); } private void displayLineDirections() { // Create a line Telogis.GeoBase.Geometry.LineString myLine = new Telogis.GeoBase.Geometry.LineString( new Telogis.GeoBase.LatLon[] { new Telogis.GeoBase.LatLon(33.604893,-117.755952), new Telogis.GeoBase.LatLon(33.604896,-117.736347), new Telogis.GeoBase.LatLon(33.588719,-117.736539), new Telogis.GeoBase.LatLon(33.588799,-117.755851), new Telogis.GeoBase.LatLon(33.604893,-117.755952) }); // Create an arrow renderer ArrowRenderer myArrowLine = new ArrowRenderer(); myArrowLine.LatLons = myLine.Points; myArrowLine.LineColor = Color.Black; myArrowLine.LineWidth = 3; // Specify ArrowProperties myArrowLine.ArrowProperties = new ArrowProperties { Color = Color.Red, Length = 20, Width = 10, Spacing = 20 }; // Add arrow line to renderer renderList.Add(myArrowLine); // Force redraw mapMain.Invalidate(); } private void mapMain_Load(object sender, EventArgs e) { mapMain.Center = new LatLon(33.596687, -117.731421); mapMain.Zoom = 4; mapMain.Renderer = renderList; // Create stops RouteStop s1 = new RouteStop(new LatLon(33.605135, -117.708917)); RouteStop s2 = new RouteStop(new LatLon(33.605057, -117.728619)); RouteStop s3 = new RouteStop(new LatLon(33.588961, -117.728621)); RouteStop s4 = new RouteStop(new LatLon(33.588959, -117.709116)); // Add stops to route myRoute.AddStops(new RouteStop[] { s1, s2, s3, s4 }); // Add to renderer renderList.Add(myRoute); } private void buttonRoute_Click(object sender, EventArgs e) { displayRouteDirections(); } private void buttonLine_Click(object sender, EventArgs e) { displayLineDirections(); } } }