I can see how to capture GPS locations in the app, but how do I display a captured GPS location on a map in the application?
If you just want to display the contents of a GPS location that was captured in the application, then you can do this by programmatically accessing and displaying any of the underlying values that form part of the set of GPS coordinates.
VIEW XML
<info-table>
<row label="Latitude" value="{location.latitude}" />
<row label="Longitude" value="{location.longitude}" />
<row label="Horizontal Accuracy" value="{location.horizontal_accuracy}" />
</info-table>
<capture-coordinates bind="location" />
example contents of a set of GPS coordinates in JS:
{
"latitude": -25.92593042155752,
"longitude": 28.15002065192829,
"altitude": 1570.0,
"horizontal_accuracy": 10.0,
"vertical_accuracy": null,
"timestamp": "2013-10-17T07:25:21Z"
}
However, If you want to display GPS coordinates on a MAP you will need to use an external map service like Google Maps, MapBox or MapQuest.
You can do this by displaying a static HTML file using the html
component, or by dynamically updating and serving an HTML file using CloudCode
and custom web tasks.
PS. It is also possible to do this dynamically in the application JS using HTML Bridge and the html
component, but this is fairly complicated and is only useful if the map is required offline.
For now let's only look at the first two options.
STATIC HTML EXAMPLE
This example will display two markers on a map using a static HTML file that was added to the application's assets. It uses a mapbox JS library to render the map and the markers. It will require a MapBox API token to work
HTML FILE
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
<script src='https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
height: 800px;
}
.map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 800px
}
</style>
</head>
<body>
<div id='map-popups' class='map'> </div>
<script>
L.mapbox.accessToken = ''; // <<<<====== INSERT MAPBOX API TOKEN HERE ======>>>>
L.mapbox.config.FORCE_HTTPS = true;
var mapPopups = L.mapbox.map('map-popups', 'mapbox.light')
.setView([38.8, -95], 5);
var myLayer = L.mapbox.featureLayer().addTo(mapPopups);
var geojson = [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.413682, 37.775408]
},
properties: {
title: 'NOV - Casper [Rover]',
description: 'SN: EZY13209; Next Cal: 2007-09-13',
'marker-color': '#d81e05',
'marker-size': 'medium',
'marker-symbol': 'airport'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.031952, 38.913184]
},
properties: {
title: 'Pathfinder - Broussard [Grunter]',
description: 'SN: NPU37555; Next Cal: 2009-01-15',
'marker-color': '#9a2979',
'marker-size': 'medium',
'marker-symbol': 'monument'
}
}
];
myLayer.setGeoJSON(geojson);
</script>
</body>
</html>
VIEW XML
<html src="html/maps-example.html" show-fullscreen-button="true"/>
DYNAMIC HTML EXAMPLE
This example will display a map that is being served from a CloudCode webtask (called view_map) on a specific URL with several map markers populated from data in the DB. It uses a mapbox JS library to render the map and the markers, and a handlebars template to generate the HTML. It to will require a MapBox API token to work.
CLOUDCODE TASK JS
import handlebars from 'handlebars';
// This must be defined, and should return either access.authorized() or access.unauthorized()
export async function authenticate({request, access}) {
return access.authorized();
}
// HTTP GET request
export async function get({params, request, response, authContext}) {
// Handle the request here
let mapMarkers = await DB.map_marker.all().toArray();
let geoJSON = mapMarkers.map(function (marker) {
return {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [marker.coordinates_lat, marker.coordinates_lon]
},
properties: {
title: marker.title,
description: marker.description,
'marker-color': marker.marker_color,
'marker-size': 'medium',
'marker-symbol': marker.marker_symbol
}
};
});
let mapPage = handlebars.compile(`
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
<script src='https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v3.0.1/mapbox.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
height: 800px;
}
.map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 800px
}
</style>
</head>
<body>
<div id='map-popups' class='map'> </div>
<script>
L.mapbox.accessToken = ''; // <<<<====== INSERT MAPBOX API TOKEN HERE ======>>>>
L.mapbox.config.FORCE_HTTPS = true;
var mapPopups = L.mapbox.map('map-popups', 'mapbox.light')
.setView([38.8, -95], 5);
var myLayer = L.mapbox.featureLayer().addTo(mapPopups);
var geojson = {{{mapMarkers}}}
myLayer.setGeoJSON(geojson);
</script>
</body>
</html>
`);
let data = {mapMarkers: JSON.stringify(geoJSON)};
let html = mapPage(data);
response.contentType('text/html');
return html;
}
VIEW XML
<html src="https://{some_url}.poweredbyjourney.com/view_map" show-fullscreen-button="true"/>
A correction/update:
The geoJSON object, under geometry.coordinates, must be [longitude, latitude] and not latitude first (as is the assumed standard)
Also, the traditional Mapbox.js is out of development now so it would be useful to use Mapbox GL syntax instead:
This post is basically deprecated now since we have enhanced our coordinates components, for both capturing and displaying coordinates on a map.
Please see docs for standard JourneyApps components
That’s fantastic. Any suggestion for converting addresses to coordinates?
Hey @jwyrick
That is possible with most Maps APIs (Google Maps, MapBox, etc.) and is called “geocoding” or “address geocoding” or “forward geocoding”, but it is typically a paid service.