# New utility methods to help make your life easier!

In the most recent release of the JavaScript API, we've included several new utility methods to help make developing web-based applications with Fleet Freedom easier.

### A generic Ramer–Douglas–Peucker algorithm

Found in the trakit.fleetfreedom.utility object, the douglasPeucker function takes an array of coordinates and will return a new array containing only those points that meet or exceed the “kink” tolerance. A full description of the output of the algorithm is available on Wikipedia, but our generic version will work for any kind of two-dimensional path.

To use the algorithm, you need to write a function to determine ”triangle height”, and a tolerance value. The triangleHeight function you need to write takes three arguments; the three coordinates that define a triangle in order: first, middle, last.

Here’s an example that works with the trakit.fleetfreedom.Point class based on the function we use ourselves in the trakit.fleetfreedom.drawing.pathReduce function.

`/**`

* A function which returns the height of a triangle on a flat surface.

* @param {trakit.fleetfreedom.Point} first Starting point of the triangle

* @param {trakit.fleetfreedom.Point} middle Top-most point of the triangle

* @param {trakit.fleetfreedom.Point} last Ending point of the triangle

* @returns {number} The orthogonal height of the triangle

*/

function triangleHeight(first, middle, last) {

// the height being returned

var height = 0;

// first, get the width of the triangle

// this way we can account for invalid triangles such as those where

// the first and last points are at the same coordinates

var width = first.distanceTo(last);

if (width > 0) {

// using a bit of trigonometry, we create the triangle (a polygon)

var triangle = [first, middle, last];

// and get the area of the triangle

var area = trakit.fleetfreedom.drawing.polyArea(triangle);

// then, we can calculate the triangle's height as the area

// divided by its width and multiplied by two

height = area / width * 2;

} else {

// in case this is an invalid triangle, we still may want to keep the topmost point,

// so we take a shortcut and simply set the height to the distance from the first

// (which is also equal to last) point to the middle point

height = first.distanceTo(middle);

}

return height;

}

One of the great things about this algorithm is that it will work with any type of coordinate system as long are you write your function properly.

The other great thing is that our algorithm is that it will not throw a stack overflow error. Many implementations use a recursive design which is far more likely to cause a problem with the limited resources of a browser (especially on a mobile phone or tablet). Our implementation works with an internal queueing system and will continue to work until there are no more candidate points to process.

Note: Be sure to have your function always return a positive number.

### Calculating the next time your automatically recurring report will be ready

The ReportRecurrence class has a new function: calculateNextRange.. This function calculates the next recurring date range for the ReportTemplate’s schedule. It returns an array of either zero items or an array with two Dates.

If the schedule will not allow the ReportTemplate to run again, the array is empty. Otherwise, the first element is the next starting date, and the second element is the next ending date.

Please note that this function only works in your local timezone, so if the timezone of the schedule is different than your own, the times may be off. The server accounts for all timezones as well as time shifting during overlaps with daylight savings time.

### Asset#getPlaces and Place#getAssets

As assets move around the map, they will enter and exit Places. Being able to quickly find out which Places an Asset is visiting (or leaving), or which Assets are currently visiting (or leaving) a Place is so much easier now. Asset#getPlaces will return an array of places an asset is currently visiting, and Place#getAssets will return an array of asset currently visiting the place.

Both getPlaces and getAssets allow you to use an option array of AssetPlaceStatusTypes so you can filter out only those assets that are leaving, or all assets that have just arrived.

### User#getUserGroups and UserGroup#getUsers

These two utility functions allow you to quickly find group membership, and group members.

Please note, that all users and groups should be loaded and synchronized before calling those functions to avoid missing data.

### The StreetAddress class

The StreetAddress class represents all the pieces of a reverse-geocoded address. Since Fleet Freedom performs a reverse-geocoded on every new GPS position received, you can find it as part of every Position object instance.

This object will, over the course of the next few releases, be getting added to any object that contains or requires address information. It will replace any strings used as addresses, and we will do our best to offer both a simple text property, and the advanced StreetAddress.