Blog

All Blog Posts  |  Next Post  |  Previous Post

Extract route segments with TMS FNC Maps Summer Delphi project

Thursday, August 1, 2024

TMS Software Delphi  Components

Germany has a wonderful network of bike routes throughout the whole country. Many of these bike routes are well thought out, along remarkable places, areas or elements in nature. The bike routes are in many cases clearly indicated with little road signs using a unique symbol specific for the route.
Many of these classic & well-known routes are described in books or come with little booklets describing points of interest along the route and a website explaining it and offering GPX files for the routes for free download. It's almost a dream come true for bike lovers if it was not for the distance of these routes. Take the 100-Schlösser Radweg in the area of Münster Germany that consists of almost 1000km if biking routes.

TMS Software Delphi  Components

The 100 Schlösser Radweg is already divided in 4 routes, but even at almost 300km, it is a bit challenging to do this in one day. So, to prepare for a feasible one day bike tour, one would typically ride a part of this route, hence the need to extract a segment from the GPX route.

TMS FNC Maps polyline manipulation comes to help

In the latest version of TMS FNC Maps, we introduced several new helper functions that make it very easy to split or merge polylines or extract a polyline segment for a larger polyline. With it comes the handy feature to measure the distance of a polyline. In other words, we have all the tools in our hands to extract the desired distance for a bike route from an existing long bike route. 

The function we will use is:

NewPolyLine := TMSFNCMapsPolyLine.Segment(StartCoordinateIndex, EndCoordinateIndex);

and the distance from any polyline, thus also the extracted segment, can be retrieved with PolyLine.Distance: single. This distance is measured in metres.


User interaction to extract the desired segment

We want to allow the user to visually indicate the segment desired for a bike tour and immediate give feedback on the selected distance. So, after loading a GPX file, we click on the map nearby a route polyline and we can use the function TMSFNCMaps.FindNearestPolylineCoordinate. With this function, we can check the nearest point on the route to the point where we clicked on the map. The first parameter is the coordinate where clicked and the second parameter tells TMS FNC Maps to search for the route point within a specified distance (in metres). When found, the function returns true and it returns the index of the polyline (in case the map has several polylines), the index of the point in the polyline array as well as its geo-coordinate. 

In this example, we use the following code to set the start coordinate of the desired segment and add a green marker to it:

var
  pi,ci: integer;
  cr: TTMSFNCMapsCoordinateRec;
  mrk: TTMSFNCMapsMarker;

begin
  if TMSFNCMaps1.FindNearestPolylineCoordinate(AEventData.Coordinate.ToRec, 500, pi, ci, cr) then
  begin
    if TMSFNCMaps1.Markers.Count = 0 then
    begin
      startindex := ci;
      mrk := TMSFNCMaps1.AddMarker(cr);
      mrk.DefaultIcon.Enabled := true;
      mrk.DefaultIcon.Fill := clGreen;
      mrk.DefaultIcon.Size := 32;
    end;
  end;
end;

If there is already a marker, this means that the user clicked on the desired end point of the segment. So, in this case, we add the red marker for the endpoint.

  if TMSFNCMaps1.Markers.Count = 1 then
  begin
    endindex := ci;
    mrk := TMSFNCMaps1.AddMarker(cr);
    mrk.DefaultIcon.Enabled := true;
    mrk.DefaultIcon.Fill := clred;
    mrk.DefaultIcon.Size := 32;
  end;

When the start and endpoint is known, we can extract the route segment. As the result of the segement creation is a new segment, we also want to visualize this on the map by setting this new segement polyline color in red and somewhat thicker to be clearly visible:

  p := TMSFNCMaps1.Polylines[0].Segment(startindex,endindex);
  if Assigned(p) then
  begin
    TMSFNCMaps1.Polylines.BeginUpdate;
    p.StrokeColor := clRed;
    p.StrokeWidth := 4;
    p.StrokeOpacity := 1;
    TMSFNCMaps1.Polylines.EndUpdate;
    ShowDistance(p.Distance);
  end;
In the last step, you can see we also update a label indicating the distance along the chosen segment.

Interactively changing the segment 

When there are already 2 markers on the map, we use a bit of a shortcut by deleting the last added marker and the last added polyline segment and calling the TMSFNCMaps1MapClick again, so it will perform the steps as-if only one marker was added:

  if TMSFNCMaps1.Markers.Count = 2 then
  begin
    TMSFNCMaps1.Polylines.Delete(1);
    TMSFNCMaps1.Markers.Delete(1);
    TMSFNCMaps1MapClick(Self, AEventData);
  end;

Click on map versus click on polyline

When there is a polyline on the map, the user can either click on the map or click on the polyline. TMS FNC Maps generates two events for this, the OnMapClick event and the OnPolyElementClick event. As the event signature is fortunately the same, this makes it easy by assiging the same event handler to both events. 

The result becomes:

TMS Software Delphi  Components

Getting the result segment as GPX 

Also the last step is very easy. The segment polyline is the 2nd polyline on the map and the TMS FNC Maps component provides a direct method to export a polyline to GPX file with TMSFNCMaps.SaveToGPXFile()

In the app, this call is:

  if SaveDialog1.Execute then
  begin
    TMSFNCMaps1.SaveToGPXFile(TMSFNCMaps1.Polylines[1].Coordinates.ToArray, SaveDialog1.FileName);
  end;


Get started

Recently we've just released the newest version of the unique & feature-rich TMS FNC Maps product. The fully functional trial version can be downloaded and you can discover its power with all of the included mapping services, including the fully free OpenStreetMap or LeafletJS maps!

Grab the source code of the presented Delphi Summer project here. The project uses the fully free OpenStreetMap mapping service, so you can enjoy this project without any risk on costs. 


Bruno Fierens




This blog post has not received any comments yet.



Add a new comment

You will receive a confirmation mail with a link to validate your comment, please use a valid email address.
All fields are required.



All Blog Posts  |  Next Post  |  Previous Post