Blog
All Blog Posts | Next Post | Previous PostExtract route segments with TMS FNC Maps Summer Delphi project
Thursday, August 1, 2024
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.
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:
The result becomes:
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.
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.
All Blog Posts | Next Post | Previous Post