Attempting to create a mileage log

I changed the return format to XML - until the new version of TBX is final:

<?xml version="1.0" encoding="UTF-8"?>
<DistanceMatrixResponse>
 <status>OK</status>
 <origin_address>Königsberger Str. 20, 40789 Monheim am Rhein, Germany</origin_address>
 <destination_address>Herzogstraße 18, 40217 Düsseldorf, Germany</destination_address>
 <row>
  <element>
   <status>OK</status>
   <duration>
    <value>14080</value>
    <text>3 hours 55 mins</text>
   </duration>
   <distance>
    <value>18953</value>
    <text>19.0 km</text>
   </distance>
  </element>
 </row>
</DistanceMatrixResponse>

Now I switch to the XML parser in TBX:

var:string returnedDestAddress = theResult.xml("/DistanceMatrixResponse/destination_address"); 
var:string returnedOrigAddress = theResult.xml("/DistanceMatrixResponse/origin_address"); 
var:string returnedDistance    = theResult.xml("/DistanceMatrixResponse/element/distance/text");

all three variables return “xml”???

the content will be returned by the cURL command.

Plain JSON or XML. See my demo file:

theResult = callDistanceMatrixAPI_Main_db(target, optional);

the variable “theResult” contains the raw JSON/XML.

It does not appear that AutoFetch will return JSON or XML to $Text or another attribute. We need @eastgate to explain how we retrieve the contents of the page that the URL returns. I suspect that AutoFetch ignores non-HTML content. Just a guess.

Yup, got it. This seems to work. I’m confused on how/why you strung these two commands together:
callDistanceMatrixAPI_db
buildDistanceMatrixAPI_payload_db

I think it would be easier if you could show me something. Some bit of logic/flow is escaping me.

you could merge the code into one function - I try to separate the code as much as possible - my functions should carry out only one part of a task.
The new demo has even one level more:

callDistanceMatrixAPI_Main_db
callDistanceMatrixAPI_db
buildDistanceMatrixAPI_latlon_db

but you still could change this and put all the code into one function. It is a matter of your personal taste :slight_smile:
And those demo files are work in progress. I’m playing around with the code - it’s not final

Use square brackets with .xml:

var:string returnedDestAddress = theResult.xml["/DistanceMatrixResponse/destination_address"];
1 Like
  1. A separate note for each trip sounds perfect.
  2. I’d be looking at nine different sites. They trip won’t always originate from the same point, so it needs to be a distance matrix. (I.e. same column and row headers with distances for each intersection.)

Yup, we just tested in backstage and it works great!

1 Like

Sorry for the typo using ( instead if [ - I’m getting old :wink:

But I think the XML parser has the same problem as the JSON parser: no access to the 2nd element in a list.

Ok, can you do us/me a favor. I’ll create demo for you.

Can you make up 9 sample addresses in your city (feel free to use real place but not the ones related to to your work, e.g., a Starbucks, local grocery, etc.).

We’ll create a resource note for each site.
We’ll then creat a trip prototype with site origin and site destination.
We’ll the calculate the distance.
We can calculate the reimbursement estimate as well, e.g., $0.33/mile.

Let’s start with the demo data first. :slight_smile:

1 Like

Thanks, Michael:

Here are 9 hotels:

  1. Days Inn Marion, 6138 Corridor Dr, Marion, IN 46953​
  2. C Boulevard Suites, 2120 W 2nd St, Marion, IN 46952​
  3. Super 8 Gas City Marion Area, 5172 Kaybee Dr, Gas City, IN 46933​
  4. Super 8 Motel Marion IN, 1615 N Baldwin Ave, Marion, IN 46952​
  5. Hampton Inn Marion, 1502 N Baldwin Ave, Marion, IN 46952​
  6. Hart Motel, 1411 N Baldwin Ave, Marion, IN 46952​
  7. Courtesy Economy Inn, 1370 N Baldwin Ave, Marion, IN 46952​
  8. Comfort Suites, 1345 N Baldwin Ave, Marion, IN 46952​
  9. Loft Inn, 7911 S 150 E, Fairmount, IN 46928​

Accounts payable will only reimburse me for their pre-determined distances. I believe someone in the organization from 35+ years ago (i.e. pre Google Maps) literally made the trip to each site and recorded the mileage to the nearest tenth and we still use that chart to this day. :slight_smile: When turning in my mileage, I always must reference the matrix, so we won’t be able to use Google Maps’ routes/distances in the real file, but I understand the need for addresses for demo purposes.

Thanks!

Brian

[1], ][2], [3] give you access to specific elements in a list. More useful in most cases is .each

$Text.xml.each(/response/row){...}
1 Like

Assuming travelling #1#2 is the same mileage as #2#1 (and no trips to/from the same location #1#1) the n(n-1)/2 formula means your 9 locations inply 36 discrete mileages to place in a dictionary or look-up table, or as 36 discrete notes holding the two end points and the allowed mileage.

Though #1#2 is the same mileage as #2#1, the start/end stored as a key gives two discrete keys (‘12’ vs. ‘21’. To avoid using 72 mileage keys (36 * 2) use a function where passing in ‘12’ or 21’ results in ‘12’ at output:

function tripTest( iTrip:string){
// we know trip codes are always 2 number characters in this scenario
// split the two digits
var:string vStart = iTrip.substr(0,1);
var:string vEnd = iTrip.substr(1,1);
// a variable for the result
var:string vResult = iTrip;
if (vStart > vEnd){
   vResult = vEnd+vStart;
}
return vResult;
}

var: string vTripCode
// for a trip '12'
vTripCode = tripTest( "12"); // returns '12'
// for a trip '21'
vTripCode = tripTest( "21"); // returns '12'

So you only need to store the mileage for ‘12’ and ‘21’ once, i.e. 36 discrete trip codes. Where, you store those codes (as notes or in a dictionary) is up to you.

Here is a mileange expense demo using all the elements of the thread above. The Trip Matrix Calculator will not work until you put a Google Maps API key in the TBXConfig note. The XML parser will not work until the next public release (which I understand is coming soon).

I used @webline’s Google API code to produce a list of trip options (see /Resources Folder/Trips Folder) to produce a trip matrix from @BrianP’s provided hotels.

I then use this matrix to calculate individual trip expenses (assume $0.33/km, see TBXConfig).

You can try it by adding a new trip in Expensed Trips and selecting a “Trip Route” from the selector. The Action code will look up the distance and time and calculate the expense. You can name the trip anything you’d like.

TBX L - Mileage with Google Maps ShareR3.tbx (491.5 KB)

2 Likes

and here is my final version of the demo - two stamps to play with the Google Distance Matrix library:

GetDistanceByLatLon will use the lat/lon attributes of a note (“Sample”) to calculate the distance, duration…
GetDistanceByAddress will do the same with two addresses (you find them in the code of the stamp).

The main function is callDistanceMatrixAPI_Main_db. You can call it with lat/lon of the origin and destination of your trip:

var:dictionary target;
var:dictionary optional;
var:dictionary theResult;

target["start_lat"] = $startLat;
target["start_lon"] = $StartLon;
target["dest_lat"]  = $destLat;
target["dest_lon"]  = $destLon;

optional["mode"]           = "walking";
optional["departure_time"] = "now";

theResult = callDistanceMatrixAPI_Main_db(target, optional);

$Text("result") = theResult["raw"];

doDebugLog_db("Destination Adress: " + theResult["dest"]);
doDebugLog_db("Origin Adress: " + theResult["orig"]);
doDebugLog_db("Distance: " + theResult["dist"]);
doDebugLog_db("Duration: " + theResult["dura"]);

The returned data format is a dictionary and contains the raw data returned, the addresses of destination and origin, the distance and the duration of the trip.
You can pass optional parameters like “mode” or the departure time if you like.

Don’t forget to enter your Google API key into the gPreferences note before playing with the API.

geolocation.tbx (179.7 KB)

2 Likes

@BrianP and I hoped on a zoom and we made a few updates to the demo file. For example, added basic reporting:

TBX L - Mileage with Google Maps ShareR3.tbx (491.5 KB)

2 Likes

just a minor one - I would change in the tTripReports template:

<tr>
  <td><b>Trip Route</b></td>
  <td><b>Date Trip</b></td>
  <td><b>Explanation</b></td>
  <td><b>Expense</b></td>
  <td><b>Distance (KM)</b></td>
  <td><b>Duration (Min)</b></td>
  <td><b>Reimburasement Rate</b></td>
</tr>

to

<tr>
  <th>Trip Route</th>
  <th>Date Trip</th>
  <th>Explanation</th>
  <th>Expense</th>
  <th>Distance (KM)</th>
  <th>Duration (Min)</th>
  <th>Reimburasement Rate</th>
</tr>

:wink:

2 Likes

Yup, that would work. We were just doing it fast, not really thinking about some of the styling details.

Here you go (@BrianP), v3, updated the styling.


TBX L - Mileage with Google Maps ShareR3.tbx (491.5 KB)

This version has also turned the units (metric vs. imperial) as a variable. I also removed my Google API key. :wink:

1 Like

I want to publicly thank @satikusala for taking time to work with me on this. He has graciously given up his time to develop this and has been super patient with my novice-level knowledge on the subject.

There is a lot of potential power behind keeping my mileage log in TB, so I’m excited about making this a part of my workflow.

As I gave generic sites for the demo, I will need to make revisions to tailor this to my own line of work. I thought it would be as easy as going into the ‘Places Folder’ and renaming the existing places to be in line with my actual sites. That didn’t do the trick, so next I dug deeper and thought I might need to rerun some code @satikusala mentioned that auto-generated the 81 different route combinations that are stored in the ‘Trips Folder’. I opened the action inspector for the ‘Trip Matrix Calculator’, went into the ‘Rule’ tab and clicked the “Run Now” button thinking that might create new route combinations, but no luck.

Since I have a mileage matrix I must adhere to, I won’t need the Google Maps option, but I feel pretty good about manually editing the route distances once I can get them renamed.

This process is exactly what I was looking for though. I think by having a model file from which I can work will help me learn a great deal. Exploration and trial and error is my key to learning, and this has been great, even if I haven’t figured it out yet. Any nudges in the right direction to accomplish this? At the risk of being tedious, I’d prefer nudges over direct answers if possible. :slight_smile:

Thanks!

Brian

1 Like

@BrianP here is an idea. Create a spreadsheet like the attached. Save it as CSV. Drag the CSV into TBX. Now you have all your possible routes. You can archive out or delete the existing notes. Take a look at the action code in the Trips Folder Rule, you’lls ee that this is populating the attribute $TripRoute with all the available trip options. That way, these routes will be available for you when you create your trips.

Matrix.csv.zip (1.4 KB)

1 Like