« Control interactive c… | Home | MBS FileMaker Plugin,… »

MBS Plugin Advent calendar: 20 - MapView

Door 20 - MapView

Fact of the day
The advantage of Apple Mapview is that you do not have a total quota of calls that are assigned to your app, but these calls apply per device and are therefore almost impossible to reach.

Did you know that you can use the map material from Apple Mapview on your Mac and iOS devices in FileMaker? I'll show you how it works in this door.

Show map with options

First of all, we want to display a map that we can then work with. Two functions are available to us for this purpose. One is MapView.CreateWithSize with which we can create the map in a window by specifying the position and size. We would like to use the second option MapView.CreateWithControl, because here we position the map with the help of a control. The control can be a rectangle, for example. We then give this control a name so that we can also address it. In our case Map. Then we call the function. First we specify the window reference. If the window is in the foreground, it is sufficient to enter a 0. Then the name of the control follows. If necessary, we can then specify an offset with X and Y. This is oriented to the top left corner of the control and causes the map to be shifted.

Set Variable [ $$MapView ; Value: MBS("MapView.CreateWithControl"; 0; "Map")

We can now go to the Exploration gate on the map. In the plugin we have some functions that can show and hide various options on the map. For example, you can display the outlines of buildings, traffic, points of interest such as places of interest and stores or your own position on the map. But also controls such as the compass, the scaling bar or the zoom controls can be displayed. We have a separate function for each of these properties. In our solution, we have now built in buttons with which you can switch these features on and off. For each feature there is also a field in the database that holds the current value for us. When creating the card, we switch all these properties off once and fill the corresponding fields with the value 0.

Set Variable [ $r ; Value: MBS("MapView.SetShowsBuildings"; $$MapView; 0) ] 
Set Field [ DoortTwenty::Buildings ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsTraffic"; $$MapView; 0) ] 
Set Field [ DoortTwenty::Traffic ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsPointsOfInterest"; $$MapView; 0) ] 
Set Field [ DoortTwenty::POI ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsUserLocation"; $$MapView; 0) ] 
Set Field [ DoortTwenty::UserLocation ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsCompass"; $$MapView; 0) ] 
Set Field [ DoortTwenty::Compass ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsScale"; $$MapView; 0) ] 
Set Field [ DoortTwenty::Scale ; 0 ] 
# 
Set Variable [ $r ; Value: MBS("MapView.SetShowsZoomControls"; $$MapView; 0) ] 
Set Field [ DoortTwenty::Zoom ; 0 ] 

Each button then gets a script that changes the value when the button is pressed. For the display of buildings, such a script looks like this:

If [ DoortTwenty::Buildings = 1 ] 
	Set Variable [ $buildings ; Value: 0 ] 
Else
	Set Variable [ $buildings ; Value: 1 ] 
End If
Set Field [ DoortTwenty::Buildings ; $buildings ] 
Set Variable [ $r ; Value: MBS( "MapView.SetShowsBuildings"; $$MapView; $buildings ) ] 

If the current value was 1, then the value of the variable is set to 0 and if it was not 1, then the value of the variable is set to 0. The variable now contains the new value, which is saved once in the corresponding field and is then used to set the appropriate function.

The button has a conditional formatting that colors the button green if the value of the corresponding field is one. Here you can see what the map can look like when the options are switched on.

Plan a route

But we can not only display a map, we can also calculate routes. To do this, we first need our starting point and our destination point. For the starting point, you could also use CurrentLocation to determine your location, for example. You saw how this works in door 8 of this calendar. We can use the MapView.PlanRoute function to plan a route between the start and end points. In addition to these two parameters, we pass a mode to the function. This mode determines how we see our route on the map and what our return looks like. We can choose from various options and combine them by adding the values.

Value Description
1 show route on map
2 show alternative routes on the map
4 show start of route with a pin
8 show end of route with a pin
16 zoom map to show whole of the router
32 return result as JSON
64 include poly lines in JSON

In this example, we have decided that the individual route should be displayed on the map. This should have a start and an end pin and should be displayed as large as possible in the center of the map. We would like to have the result for this route as JSON, because the JSON also provides us with some information that we will take a closer look at in a moment.

In the function we can also specify optional additional parameters to determine the transport method for which the route should be calculated. In addition, we can specify the names for the destination and start pin and also select the color of the two pins.

Set Variable [ $JSON ; Value: MBS( "MapView.PlanRoute"; 
      $$MapView; DoortTwenty::Start; DoortTwenty::Target; 1+4+8+16+32 ; 1  ) ]

We now receive a JSON as a return that we can continue to work with. This contains some information. Here you can see such a JSON. We have shortened the JSON in the route instructions.

 {
  "routes" : [
    {
      "distance" : 39063,
      "steps" : [
        {
          "notice" : null,
          "distance" : 0,
          "instructions" : null,
          "distanceText" : "0 m",
          "transportType" : 1
        },
        {
          "notice" : null,
          "distance" : 213.63,
          "instructions" : "Turn left onto Benrather Straße",
          "distanceText" : "200 m",
          "transportType" : 1
        },
        {
          "notice" : null,
          "distance" : 249.81999999999999,
          "instructions" : "Turn right onto Kasernenstraße",
          "distanceText" : "250 m",
          "transportType" : 1
        },
		…
        {
          "notice" : null,
          "distance" : 186.06,
          "instructions" : "Arrive at the destination",
          "distanceText" : "200 m",
          "transportType" : 1
        }
      ],
      "advisoryNotices" : [
        "Düsseldorf, DE, This zone comprises most major roads entering the city. Nevertheless, 
         the driving restriction does not apply to highways, thus an emissions stickers is not required 
         on the A44 north of the city and on the A46 south of the city.",
        "Cologne, DE, The zone covers a large part of the city of Cologne, 
         it extends beyond the city centre and affects both the east and west side of the Rhine.",
        "Directions begin at closest open road."
      ],
      "expectedTravelTime" : 3539,
      "distanceText" : "39 km",
      "name" : "A57",
      "transportType" : 1
    }
  ],
  "source" : {
    "ISOcountryCode" : "DE",
    "subThoroughfare" : null,
    "areasOfInterest" : null,
    "subLocality" : null,
    "administrativeArea" : "North Rhine-Westphalia",
    "country" : "Germany",
    "thoroughfare" : null,
    "ocean" : null,
    "latitude" : 51.225863400000001,
    "name" : "Düsseldorf",
    "altitude" : 0,
    "timeZone" : "CET",
    "longitude" : 6.7722986000000001,
    "postalCode" : null,
    "inlandWater" : null,
    "locality" : "Düsseldorf",
    "subAdministrativeArea" : "Düsseldorf"
  },
  "destination" : {
    "ISOcountryCode" : "DE",
    "subThoroughfare" : null,
    "areasOfInterest" : null,
    "subLocality" : null,
    "administrativeArea" : "North Rhine-Westphalia",
    "country" : "Germany",
    "thoroughfare" : null,
    "ocean" : null,
    "latitude" : 50.937522899999998,
    "name" : "Cologne",
    "altitude" : 0,
    "timeZone" : "CET",
    "longitude" : 6.9594800000000001,
    "postalCode" : null,
    "inlandWater" : null,
    "locality" : "Cologne",
    "subAdministrativeArea" : "Cologne"
  }
}

Now we can use JSON functions to read out the required data. In our case, this is the travel time, which we get in seconds and then have to divide this by 60 again to get the travel time in minutes.

Set Variable [ $time ; Value: JSONGetElement ($JSON ; "routes.[0].expectedTravelTime" ) ] 
Set Variable [ $time ; Value: Int ( $time/60) ] 
Set Field [ DoortTwenty::Time ; $time & " minutes" ] 

We also want to read out the route instructions. To do this, we first determine how many instructions are in the array and then go through them in a loop and put the instruction together with the distance information. Finally, we write the combined text into the appropriate field.

Set Variable [ $routeArray ; Value: JSONGetElement ( $JSON; "routes.[0].steps" ) ] 
Set Variable [ $count ; Value: MBS( "JSON.GetArraySize"; $RouteArray  ) ] 
Set Variable [ $i ; Value: 1 ] 
Set Variable [ $text ; Value: "Start: " & DoortTwenty::Start ] 
Loop
	Set Variable [ $inst ; Value: JSONGetElement ( $JSON ; "routes.[0].steps.["& $i &"].instructions" ) & 
		" in " & JSONGetElement ( $JSON ; "routes.[0].steps.["& $i &"].distanceText" ) ] 
	Set Variable [ $Text ; Value: $text & "¶¶" & $inst ] 
	Exit Loop If [ $i ≥ $count-1 ] 
	Set Variable [ $i ; Value: $i+1 ] 
End Loop
Set Variable [ $text ; Value: $text & "¶¶You have reached your destination: " & DoortTwenty::Target ] 
Set Field [ DoortTwenty::Route ; $text ] 

If we experiment with different start and destination locations, we see that the old routes and pins remain on the map. To avoid this, we remove the pins with MapView.RemoveAnnotations and the routes with MapView.RemoveOverlays when starting the route planning script.

Set Variable [ $r ; Value: MBS( "MapView.RemoveAnnotations"; $$MapView ) ] 
Set Variable [ $r ; Value: MBS( "MapView.RemoveOverlays"; $$MapView ) ] 
...

When we are finished and want to hide the map again, we call the MapView.ReleaseAll function. This and much more awaits you in the MapView component.

Then I hope that Santa Claus has also installed the navigation system in his sleigh so that he can find you at Christmas.


Monkeybread Software Logo with Monkey with Santa hat
19 👈 20 of 24 👉 21
Claris FileMaker Plugin
20 12 23 - 08:23