WolframAlpha.com
WolframCloud.com
All Sites & Public Resources...
Products & Services
Wolfram|One
Mathematica
Wolfram|Alpha Notebook Edition
Programming Lab
Finance Platform
SystemModeler
Wolfram Player
Wolfram Engine
WolframScript
Enterprise Private Cloud
Enterprise Mathematica
Wolfram|Alpha Appliance
Enterprise Solutions
Corporate Consulting
Technical Consulting
Wolfram|Alpha Business Solutions
Resource System
Data Repository
Neural Net Repository
Function Repository
Wolfram|Alpha
Wolfram|Alpha Pro
Problem Generator
API
Data Drop
Products for Education
Mobile Apps
Wolfram Player
Wolfram Cloud App
Wolfram|Alpha for Mobile
Wolfram|Alpha-Powered Apps
Services
Paid Project Support
Wolfram U
Summer Programs
All Products & Services »
Technologies
Wolfram Language
Revolutionary knowledge-based programming language.
Wolfram Cloud
Central infrastructure for Wolfram's cloud products & services.
Wolfram Science
Technology-enabling science of the computational universe.
Wolfram Notebooks
The preeminent environment for any technical workflows.
Wolfram Engine
Software engine implementing the Wolfram Language.
Wolfram Natural Language Understanding System
Knowledge-based broadly deployed natural language.
Wolfram Data Framework
Semantic framework for real-world data.
Wolfram Universal Deployment System
Instant deployment across cloud, desktop, mobile, and more.
Wolfram Knowledgebase
Curated computable knowledge powering Wolfram|Alpha.
All Technologies »
Solutions
Engineering, R&D
Aerospace & Defense
Chemical Engineering
Control Systems
Electrical Engineering
Image Processing
Industrial Engineering
Mechanical Engineering
Operations Research
More...
Finance, Statistics & Business Analysis
Actuarial Sciences
Bioinformatics
Data Science
Econometrics
Financial Risk Management
Statistics
More...
Education
All Solutions for Education
Trends
Machine Learning
Multiparadigm Data Science
Internet of Things
High-Performance Computing
Hackathons
Software & Web
Software Development
Authoring & Publishing
Interface Development
Web Development
Sciences
Astronomy
Biology
Chemistry
More...
All Solutions »
Learning & Support
Learning
Wolfram Language Documentation
Fast Introduction for Programmers
Wolfram U
Videos & Screencasts
Wolfram Language Introductory Book
Webinars & Training
Summer Programs
Books
Need Help?
Support FAQ
Wolfram Community
Contact Support
Premium Support
Paid Project Support
Technical Consulting
All Learning & Support »
Company
About
Company Background
Wolfram Blog
Events
Contact Us
Work with Us
Careers at Wolfram
Internships
Other Wolfram Language Jobs
Initiatives
Wolfram Foundation
MathWorld
Computer-Based Math
A New Kind of Science
Wolfram Technology for Hackathons
Student Ambassador Program
Wolfram for Startups
Demonstrations Project
Wolfram Innovator Awards
Wolfram + Raspberry Pi
Summer Programs
More...
All Company »
Search
WOLFRAM COMMUNITY
Connect with users of Wolfram technologies to learn, solve problems and share ideas
Join
Sign In
Dashboard
Groups
People
Search
Message Boards
Answer
(
Unmark
)
Mark as an Answer
GROUPS:
Staff Picks
Software Development
Curated Data
Graphics and Visualization
Wolfram Language
User Interface
Geographic Information System
6
Martin Siegenthaler
Make mobile maps: navigation app for images' GPS locations
Martin Siegenthaler, self
Posted
21 days ago
742 Views
|
1 Reply
|
6 Total Likes
Follow this post
|
Make mobile maps: navigation app for images’ GPS locations
by Martin Siegenthaler
I present a set of smart phone applications that capture images and render maps using Wolfram Cloud. The Mobile applications are:
•
Using the phone’s hardware, capturing photos and GPS locations and saving them to the Wolfram Cloud.
•
On the phone, browse the captured photos, and generate directions to the capture point from the current location.
In addition to the Mobile applications, a Notebook application to browse and edit captured points.
Overview Applications Flow
I've produced a suite of three applications to collect features, provide return direction to them and edit them. Features are locations that I may want to return. A feature consists of an image, GPS, location, type and note. The Collect and Return applications run on a smartphone utilizing the GPS and camera. Collect writes to a DataBin[], Return uses a DataStore[] and Edit updates the DataStore[]
1
.
The ‘Feature Collect’ application on the smartphone, collects the current location, image and class of ‘feature’. The collected features are written to a Databin.
The 'yourPosition' value is derived from the phone. "Submit" pushes the data into Wolfram Cloud where the data is stored in a Databin[].
2
.
The “Feature Return” application, generates directions from your current location back to the ‘feature’, using the phone’s GPS . It has a two page prompt . .
Select the feature type to return to. The number in parenthesis indicate the number of feature collected. The slider selects the maximum number of destinations.
2
.
1
.
U
p
o
n
s
u
b
m
i
t
t
i
n
g
t
h
e
1
s
t
p
a
g
e
t
h
e
s
e
c
o
n
d
p
a
g
e
c
o
l
l
e
c
t
s
t
h
e
c
u
r
r
e
n
t
G
P
S
l
o
c
a
t
i
o
n
.
T
h
e
p
a
g
e
s
p
e
c
i
f
i
e
s
…
2
.
1
.
1
.
The image of the location to return.
2
.
1
.
2
.
The method used to return.
2
.
1
.
3
.
The form of the return directions.
3
.
The resulting directions are dependent upon the 'Directions' selected.
3
.
1
.
Google : The application generates a redirect to Google maps
3
.
2
.
Map : Mathematica’s TravelDirections[] with graphics rendering.
3
.
3
.
T
u
r
n
b
y
t
u
r
n
:
M
a
t
h
e
m
a
t
i
c
a
’
s
T
r
a
v
e
l
D
i
r
e
c
t
i
o
n
s
[
]
w
i
t
h
D
a
t
a
s
e
t
r
e
n
d
e
r
i
n
g
.
The Notebook application
W
i
t
h
t
h
e
n
o
t
e
b
o
o
k
a
p
p
l
i
c
a
t
i
o
n
y
o
u
c
a
n
b
r
o
w
s
e
t
h
e
f
e
a
t
u
r
e
s
c
o
l
l
e
c
t
e
d
u
s
i
n
g
t
h
e
D
y
n
a
m
i
c
G
e
o
G
r
a
p
h
i
c
s
[
]
,
c
h
a
n
g
e
t
h
e
i
r
f
e
a
t
u
r
e
d
e
s
i
g
n
a
t
i
o
n
,
u
p
d
a
t
e
t
h
e
n
o
t
e
f
i
e
l
d
a
n
d
d
e
l
e
t
e
a
f
e
a
t
u
r
e
.
D
a
t
a
F
l
o
w
Configuration / Initialization
I
n
[
]
:
=
Enable Location Services:
Collect and Return uses the phone’s geolocation. Using this feature requires enabling the platform's Location Services . The article
How to Enable Location Services for Chrome, Safari, Edge, and Android/iOS Devices | GPS Setting
goes through the process of enabling Location Services for various platforms (I develop on Apple hardware).
The phone applications works on desktop Chrome. Enabling the Location Services in Chrome will enable the application to fetch your desktop's GPS location.
I
n
[
]
:
=
Initialization
The applications use two named data resources Databin[] and CloudExpression[] to store Features. Below the Databin[] and CloudExpression[] are named.
Name the Databin[], written to by the Collect:
I
n
[
]
:
=
A
c
t
B
i
n
N
a
m
e
=
"
f
e
a
t
u
r
e
s
3
"
;
Name the CloudExpresion[] the backing store of the Dataset[], used by Edit and Return:
I
n
[
]
:
=
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
=
"
s
t
o
r
e
C
l
d
E
x
p
"
;
I
n
[
]
:
=
Create Databin when Necessary
The Databin stores data collected by Collect. Data is never removed from the Databin. The data is mirrored in a Dataset where items are edited, and CloudExpression is a backing store.
If the Databin does not exist, create it, set the ActBinId:
I
n
[
]
:
=
n
a
m
e
I
d
A
s
s
o
c
=
T
a
b
l
e
[
r
o
w
[
"
N
a
m
e
"
]
-
>
r
o
w
[
"
S
h
o
r
t
I
D
"
]
,
{
r
o
w
,
D
a
t
a
b
i
n
s
[
]
}
]
/
/
A
s
s
o
c
i
a
t
i
o
n
;
I
f
[
M
i
s
s
i
n
g
Q
[
n
a
m
e
I
d
A
s
s
o
c
[
A
c
t
B
i
n
N
a
m
e
]
]
,
C
r
e
a
t
e
D
a
t
a
b
i
n
[
A
c
t
B
i
n
N
a
m
e
]
,
N
o
n
e
]
;
T
a
b
l
e
[
r
o
w
[
"
N
a
m
e
"
]
-
>
r
o
w
[
"
S
h
o
r
t
I
D
"
]
,
{
r
o
w
,
D
a
t
a
b
i
n
s
[
]
}
]
/
/
A
s
s
o
c
i
a
t
i
o
n
;
A
c
t
B
i
n
I
d
=
%
[
A
c
t
B
i
n
N
a
m
e
]
;
S
t
y
l
e
[
"
A
c
t
i
v
e
B
i
n
N
a
m
e
:
"
<
>
A
c
t
B
i
n
N
a
m
e
<
>
"
A
c
t
i
v
e
B
i
n
I
d
:
"
<
>
A
c
t
B
i
n
I
d
,
B
l
u
e
]
O
u
t
[
]
=
A
c
t
i
v
e
B
i
n
N
a
m
e
:
f
e
a
t
u
r
e
s
3
A
c
t
i
v
e
B
i
n
I
d
:
T
h
n
9
0
r
R
6
I
n
[
]
:
=
Prompt for CloudExpression Initialization
CloudExpression holds the state of the collected Features. The Edit application reads/writes values while Return reads them. New entries in the Databin are migrated to this storage. You will want to initialize the first time through or to reset the edits.
Prompt to initialize/reset the backing store:
I
n
[
]
:
=
i
n
i
t
i
a
l
i
z
e
S
a
v
e
D
s
:
=
{
D
e
l
e
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
]
,
P
a
u
s
e
[
5
]
,
A
c
t
C
l
o
u
d
E
x
p
=
C
r
e
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
M
i
s
s
i
n
g
[
"
N
O
D
a
t
a
"
]
,
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
]
}
p
r
o
m
p
t
:
=
C
h
o
i
c
e
D
i
a
l
o
g
[
S
t
y
l
e
[
"
I
n
i
t
i
a
l
i
z
e
t
h
e
s
a
v
e
d
d
a
t
a
s
e
t
:
\
n
E
d
i
t
s
w
i
l
l
b
e
l
o
s
t
!
"
,
R
e
d
]
]
;
I
f
[
p
r
o
m
p
t
,
i
n
i
t
i
a
l
i
z
e
S
a
v
e
D
s
,
"
N
o
t
I
n
i
t
a
l
i
z
i
n
g
"
]
;
I
n
[
]
:
=
Common variables
ColorMarkMap defines the name of the the features and the color they are rendered on the Edit map:
I
n
[
]
:
=
F
e
a
t
u
r
e
C
o
l
o
r
M
a
p
=
"
O
d
i
n
"
,
"
S
t
u
d
y
"
,
"
O
t
h
e
r
"
,
"
C
a
f
e
"
,
"
R
e
t
u
r
n
"
,
"
V
e
h
i
c
l
e
"
,
"
P
a
r
k
i
n
g
"
,
"
P
i
c
n
i
c
"
,
"
S
a
m
u
r
a
i
"
;
I
n
[
]
:
=
F
e
a
t
u
r
e
s
=
K
e
y
s
[
F
e
a
t
u
r
e
C
o
l
o
r
M
a
p
]
;
F
e
a
t
u
r
e
C
o
l
o
r
s
=
V
a
l
u
e
s
[
F
e
a
t
u
r
e
C
o
l
o
r
M
a
p
]
;
I
n
[
]
:
=
Populate the Databin with test data
Generate test data with Hospitals close by along with random images of Hospitals:
I
n
[
]
:
=
t
e
s
t
I
d
e
n
t
i
f
i
e
r
=
"
T
e
s
t
S
a
m
p
l
e
"
;
g
e
n
e
r
a
t
e
T
e
s
t
S
a
m
p
l
e
[
c
o
u
n
t
_
I
n
t
e
g
e
r
]
:
=
M
o
d
u
l
e
{
l
o
c
s
,
i
m
g
s
}
,
l
o
c
s
=
G
e
o
N
e
a
r
e
s
t
[
"
H
o
s
p
i
t
a
l
"
,
H
e
r
e
,
c
o
u
n
t
]
;
i
m
g
s
=
W
e
b
I
m
a
g
e
S
e
a
r
c
h
[
"
H
o
s
p
i
t
a
l
"
,
c
o
u
n
t
]
;
T
a
b
l
e
"
p
h
o
t
o
"
T
h
u
m
b
n
a
i
l
[
i
m
g
s
〚
i
d
x
〛
]
,
"
p
o
s
i
t
i
o
n
"
l
o
c
s
i
d
x
p
o
s
i
t
i
o
n
,
"
f
e
a
t
u
r
e
"
"
S
a
m
u
r
a
i
"
,
"
n
o
t
e
"
t
e
s
t
I
d
e
n
t
i
f
i
e
r
,
{
i
d
x
,
c
o
u
n
t
}
Only load the data once, check if the 'testIdentifier' value is in the note field to prevent reloads of the test data:
I
n
[
]
:
=
I
f
[
0
=
=
L
e
n
g
t
h
[
S
e
l
e
c
t
[
D
a
t
a
b
i
n
[
A
c
t
B
i
n
I
d
]
[
"
V
a
l
u
e
s
"
]
[
"
n
o
t
e
"
]
,
S
t
r
i
n
g
M
a
t
c
h
Q
[
t
e
s
t
I
d
e
n
t
i
f
i
e
r
]
]
]
,
T
a
b
l
e
[
D
a
t
a
b
i
n
A
d
d
[
D
a
t
a
b
i
n
[
A
c
t
B
i
n
I
d
]
,
e
l
e
]
,
{
e
l
e
,
g
e
n
e
r
a
t
e
T
e
s
t
S
a
m
p
l
e
[
3
]
}
]
,
"
S
a
m
p
l
e
d
a
t
a
i
n
p
l
a
c
e
a
l
r
e
a
d
y
"
]
O
u
t
[
]
=
D
a
t
a
b
i
n
N
a
m
e
:
f
e
a
t
u
r
e
s
3
E
n
t
r
y
c
o
u
n
t
:
M
i
s
s
i
n
g
[
]
,
D
a
t
a
b
i
n
N
a
m
e
:
f
e
a
t
u
r
e
s
3
E
n
t
r
y
c
o
u
n
t
:
M
i
s
s
i
n
g
[
]
,
D
a
t
a
b
i
n
N
a
m
e
:
f
e
a
t
u
r
e
s
3
E
n
t
r
y
c
o
u
n
t
:
M
i
s
s
i
n
g
[
]
Feature Collect - Web Application
The Collect application retrieves the current GPS location, collects a photo using the camera, has a feature dropdown list and a note text field. On submission, the collected data is pushed to the Cloud and stored in the Databin.
Retrieving the GPS involves invoking a JavaScript function in the browser,
navigator.geolocation.getCurrentPosition().
The community posting, '
Exact GeoPosition From Form Function
' is where I learned about interfacing to the browser's geolocation functions and utilizing Google's map service.
I
n
[
]
:
=
Code - collect: photo, GPS, feature and store in Databin.
Code Notes:
◼
The JavaScript (<script>..</script>) has the callback of
getCurrentPosition
() and writes the GPS location into
yourPosition
.
◼
An image is collected from the phone's photo roll or the camera written into
photo.
◼
A drop down will be composed of Features list elements, the selected feature will be written to
feature
◼
A text line input will be written to
note
.
◼
"Submit" pushes the data to Cloud server. At the server the
photo
is reduced via Thumbnail[] and saved to the Databin along with
yourPosition
,
feature
and
note.
Build and deploy to the cloud the web application:
I
n
[
]
:
=
a
p
p
G
p
s
I
D
=
C
l
o
u
d
D
e
p
l
o
y
[
F
o
r
m
F
u
n
c
t
i
o
n
[
{
E
m
b
e
d
d
e
d
H
T
M
L
@
S
t
r
i
n
g
J
o
i
n
[
"
<
s
c
r
i
p
t
>
f
u
n
c
t
i
o
n
i
n
i
t
Y
o
u
r
P
o
s
i
t
i
o
n
(
p
o
s
i
t
i
o
n
)
{
d
o
c
u
m
e
n
t
.
g
e
t
E
l
e
m
e
n
t
s
B
y
N
a
m
e
(
'
y
o
u
r
P
o
s
i
t
i
o
n
'
)
[
0
]
.
v
a
l
u
e
=
'
'
+
p
o
s
i
t
i
o
n
.
c
o
o
r
d
s
.
l
a
t
i
t
u
d
e
+
'
,
'
+
p
o
s
i
t
i
o
n
.
c
o
o
r
d
s
.
l
o
n
g
i
t
u
d
e
;
}
<
/
s
c
r
i
p
t
>
"
,
"
<
s
c
r
i
p
t
>
n
a
v
i
g
a
t
o
r
.
g
e
o
l
o
c
a
t
i
o
n
.
g
e
t
C
u
r
r
e
n
t
P
o
s
i
t
i
o
n
(
i
n
i
t
Y
o
u
r
P
o
s
i
t
i
o
n
)
<
/
s
c
r
i
p
t
>
"
]
,
"
y
o
u
r
P
o
s
i
t
i
o
n
"
"
G
e
o
C
o
o
r
d
i
n
a
t
e
s
"
,
"
p
h
o
t
o
"
"
I
m
a
g
e
"
"
h
t
t
p
s
:
/
/
u
p
l
o
a
d
.
w
i
k
i
m
e
d
i
a
.
o
r
g
/
w
i
k
i
p
e
d
i
a
/
e
n
/
4
/
4
8
/
B
l
a
n
k
.
J
P
G
"
,
"
f
e
a
t
u
r
e
"
F
e
a
t
u
r
e
s
,
{
"
n
o
t
e
"
,
"
C
o
m
m
e
n
t
"
}
"
T
e
x
t
L
i
n
e
"
"
"
}
,
M
o
d
u
l
e
[
{
}
,
D
a
t
a
b
i
n
A
d
d
[
D
a
t
a
b
i
n
[
A
c
t
B
i
n
I
d
]
,
{
"
p
h
o
t
o
"
T
h
u
m
b
n
a
i
l
[
#
p
h
o
t
o
]
,
"
f
e
a
t
u
r
e
"
#
f
e
a
t
u
r
e
,
"
n
o
t
e
"
#
n
o
t
e
,
"
p
o
s
i
t
i
o
n
"
#
y
o
u
r
P
o
s
i
t
i
o
n
}
]
;
H
T
T
P
R
e
d
i
r
e
c
t
[
U
R
L
B
u
i
l
d
[
"
h
t
t
p
s
:
/
/
u
p
l
o
a
d
.
w
i
k
i
m
e
d
i
a
.
o
r
g
/
w
i
k
i
p
e
d
i
a
/
c
o
m
m
o
n
s
/
1
/
1
d
/
G
e
o
r
g
_
v
o
n
_
R
o
s
e
n
_
-
_
O
d
e
n
_
s
o
m
_
v
a
n
d
r
i
n
g
s
m
a
n
%
2
C
_
1
8
8
6
_
%
2
8
O
d
i
n
%
2
C
_
t
h
e
_
W
a
n
d
e
r
e
r
%
2
9
.
j
p
g
"
]
]
]
&
,
A
p
p
e
a
r
a
n
c
e
R
u
l
e
s
<
|
"
T
i
t
l
e
"
"
F
e
a
t
u
r
e
C
o
l
l
e
c
t
"
,
"
D
e
s
c
r
i
p
t
i
o
n
"
"
C
o
l
l
e
c
t
F
e
a
t
u
r
e
a
n
d
L
o
c
a
t
i
o
n
.
"
|
>
]
,
"
f
e
a
t
u
r
e
C
o
l
l
e
c
t
"
,
P
e
r
m
i
s
s
i
o
n
s
"
P
u
b
l
i
c
"
]
O
u
t
[
]
=
C
l
o
u
d
O
b
j
e
c
t
h
t
t
p
s
:
/
/
w
w
w
.
w
o
l
f
r
a
m
c
l
o
u
d
.
c
o
m
/
o
b
j
/
m
a
r
t
i
n
2
/
f
e
a
t
u
r
e
C
o
l
l
e
c
t
Generate a QR code for easy phone access:
I
n
[
]
:
=
B
a
r
c
o
d
e
I
m
a
g
e
[
L
a
s
t
[
a
p
p
G
p
s
I
D
]
,
"
Q
R
"
]
O
u
t
[
]
=
Migrate from Databin[] to Dataset[]
The Databin is used to collect data, It’s easy to add new entries (AddDatabin[]) and retrieve (Get[<databin>]) all entries. Databin functionality does not include editing entries. To get around this limitation, the features are migrated to a Dataset[] for manipulation. The Dataset is written to a CloudExpression where it is accessed by the Return and Edit applications.
Having a duplicate copy of the data requires keeping them synchronized. This is accomplished with the MigrateEntries[Dataset, Databin] function that is invoked before features are used. ( simple - but clumsy.)
The UUID is used to synchronize the storage. This does not remove entries from the Dataset, setting
deleted
field removes the entry from the view.
MigrateEntries[Dataset, Databin] : Migrate Data
MigrateEntries[] migrates features from the Databin[] to the Dataset[] . "StartTime" specification on the Databin retrieves entries to be migrated . As new entries are added to the Dataset[] they are enhanced. The updated Databin[] is written to CloudExpression[] for storage.
Clean up:
I
n
[
]
:
=
C
l
e
a
r
A
l
l
[
a
p
p
e
n
d
D
a
t
a
b
i
n
,
M
i
g
r
a
t
e
E
n
t
r
i
e
s
]
;
Append Databin to Dataset - deriving columns:timestamp, uuid and deleted fields:
I
n
[
]
:
=
a
p
p
e
n
d
D
a
t
a
b
i
n
[
d
s
_
D
a
t
a
s
e
t
,
d
b
S
e
l
e
c
t
_
D
a
t
a
b
i
n
/
;
d
b
S
e
l
e
c
t
[
"
E
n
t
r
y
C
o
u
n
t
"
]
0
]
:
=
d
s
;
a
p
p
e
n
d
D
a
t
a
b
i
n
[
d
s
_
D
a
t
a
s
e
t
,
d
b
S
e
l
e
c
t
_
D
a
t
a
b
i
n
]
:
=
M
o
d
u
l
e
[
{
f
r
e
s
h
E
n
t
r
i
e
s
D
s
,
u
p
d
a
t
e
d
D
s
=
d
s
}
,
f
r
e
s
h
E
n
t
r
i
e
s
D
s
=
D
a
t
a
s
e
t
[
A
p
p
e
n
d
[
#
[
"
D
a
t
a
"
]
,
{
"
t
i
m
e
s
t
a
m
p
"
-
>
#
[
"
T
i
m
e
s
t
a
m
p
"
]
,
"
u
u
i
d
"
#
[
"
U
U
I
D
"
]
,
"
d
e
l
e
t
e
d
"
F
a
l
s
e
}
]
&
/
@
G
e
t
[
d
b
S
e
l
e
c
t
]
]
;
T
a
b
l
e
[
A
p
p
e
n
d
T
o
[
u
p
d
a
t
e
d
D
s
,
n
e
w
E
n
t
r
y
]
,
{
n
e
w
E
n
t
r
y
,
N
o
r
m
a
l
[
f
r
e
s
h
E
n
t
r
i
e
s
D
s
]
}
]
;
u
p
d
a
t
e
d
D
s
]
Get the most recent entry of the dataset to select the newest entries to the databin:
I
n
[
]
:
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
d
s
_
D
a
t
a
s
e
t
,
d
b
_
D
a
t
a
b
i
n
]
:
=
M
o
d
u
l
e
[
{
l
a
s
t
T
i
m
e
S
t
a
m
p
,
d
b
S
e
l
e
c
t
}
,
l
a
s
t
T
i
m
e
S
t
a
m
p
=
d
s
[
T
a
k
e
L
a
r
g
e
s
t
[
1
]
,
"
t
i
m
e
s
t
a
m
p
"
]
/
/
L
a
s
t
;
d
b
S
e
l
e
c
t
=
D
a
t
a
b
i
n
[
d
b
,
<
|
"
S
t
a
r
t
T
i
m
e
"
l
a
s
t
T
i
m
e
S
t
a
m
p
|
>
]
;
a
p
p
e
n
d
D
a
t
a
b
i
n
[
d
s
,
d
b
S
e
l
e
c
t
]
]
Initially nothing is in the Dataset, extract everything from Databin :
I
n
[
]
:
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
d
s
_
M
i
s
s
i
n
g
,
d
b
_
D
a
t
a
b
i
n
]
:
=
M
o
d
u
l
e
[
{
}
,
D
a
t
a
s
e
t
[
A
p
p
e
n
d
[
#
[
"
D
a
t
a
"
]
,
{
"
t
i
m
e
s
t
a
m
p
"
-
>
#
[
"
T
i
m
e
s
t
a
m
p
"
]
,
"
u
u
i
d
"
#
[
"
U
U
I
D
"
]
,
"
d
e
l
e
t
e
d
"
F
a
l
s
e
}
]
&
/
@
G
e
t
[
d
b
]
]
]
Handle various input combinations :
I
n
[
]
:
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
c
l
o
u
d
E
x
p
r
e
s
s
i
o
n
I
d
_
S
t
r
i
n
g
,
d
b
_
D
a
t
a
b
i
n
]
:
=
M
o
d
u
l
e
[
{
}
,
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
c
l
o
u
d
E
x
p
r
e
s
s
i
o
n
I
d
]
[
]
,
d
b
]
]
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
c
l
o
u
d
E
x
p
r
e
s
s
i
o
n
I
d
_
S
t
r
i
n
g
,
d
a
t
a
B
i
n
I
d
_
S
t
r
i
n
g
]
:
=
M
o
d
u
l
e
[
{
}
,
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
c
l
o
u
d
E
x
p
r
e
s
s
i
o
n
I
d
]
[
]
,
D
a
t
a
b
i
n
[
d
a
t
a
B
i
n
I
d
]
]
]
I
n
[
]
:
=
Migrate from Databin to Dataset and save to CloudExpression
Initialize if necessary, make sure everything is in order
Pull data from CloudExpression (Dataset) and update it with new Databin values:
I
n
[
]
:
=
S
t
o
r
e
D
s
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
,
A
c
t
B
i
n
I
d
]
;
Commit the changes, store the updated Dataset to the CloudExpression, it is necessary to delete the CloudExpression before rewriting.
I
n
[
]
:
=
D
e
l
e
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
]
P
a
u
s
e
[
1
0
]
;
C
r
e
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
S
t
o
r
e
D
s
,
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
]
;
Load the CloudExpression contents, used for verification tests:
I
n
[
]
:
=
A
c
t
C
l
o
u
d
E
x
p
=
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
]
;
Verify the migration:
I
n
[
]
:
=
a
c
t
B
i
n
=
D
a
t
a
b
i
n
[
A
c
t
B
i
n
I
d
]
;
I
f
[
L
e
n
g
t
h
[
A
c
t
C
l
o
u
d
E
x
p
[
]
]
≠
a
c
t
B
i
n
[
"
E
n
t
r
y
C
o
u
n
t
"
]
,
S
t
y
l
e
[
"
C
o
m
m
i
t
F
a
i
l
u
r
e
:
D
a
t
a
b
i
n
a
n
d
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
n
o
t
E
q
u
a
l
.
.
.
"
,
R
e
d
,
L
a
r
g
e
]
,
S
t
y
l
e
[
"
C
o
m
m
i
t
O
k
"
,
B
l
u
e
]
]
O
u
t
[
]
=
C
o
m
m
i
t
O
k
Feature Edit - Notebook Application
The FeatureEdit notebook application is used to browse and edit features collected with FeatureCollect Application. It moves collected data into Dataset for editing. When done ‘Save Changes’ writes the data out to a CloudExpression.
◼
Note: Running this Notebook application in the wolframcloud, the Tooltip buttons do not appear in DynamicGeoGraphics, I developed this on the desktop.
Load the Dataset with the most current version of the data:
I
n
[
]
:
=
S
t
o
r
e
D
s
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
,
A
c
t
B
i
n
I
d
]
;
Clean the memory:
I
n
[
]
:
=
C
l
e
a
r
A
l
l
[
i
m
a
g
e
A
c
t
i
v
e
,
e
l
e
m
e
n
t
A
c
t
i
o
n
,
n
o
t
e
A
c
t
i
v
e
,
f
e
a
t
u
r
e
A
c
t
i
v
e
,
t
e
x
t
A
c
t
i
v
e
,
s
e
l
e
c
t
o
r
F
e
a
t
u
r
e
s
,
t
i
m
e
F
m
t
,
u
u
i
d
T
i
m
e
F
m
t
,
u
i
V
a
r
s
U
p
d
a
t
e
,
g
e
n
e
r
a
t
e
G
e
o
G
r
a
p
h
i
c
s
,
g
e
n
e
r
a
t
e
G
e
o
P
o
i
n
t
s
,
u
p
d
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
]
I
n
[
]
:
=
Support routines for Edit functionality.
Feature name to color mapping:
I
n
[
]
:
=
c
o
l
o
r
M
a
r
k
[
f
e
a
t
u
r
e
_
S
t
r
i
n
g
]
:
=
G
r
a
p
h
i
c
s
[
{
F
e
a
t
u
r
e
C
o
l
o
r
M
a
p
[
f
e
a
t
u
r
e
]
,
O
p
a
c
i
t
y
[
.
9
]
,
D
i
s
k
[
{
.
5
,
.
5
}
]
}
]
Time formatting:
I
n
[
]
:
=
t
i
m
e
F
m
t
[
t
s
_
D
a
t
e
O
b
j
e
c
t
]
:
=
D
a
t
e
S
t
r
i
n
g
[
t
s
,
{
"
D
a
y
N
a
m
e
"
,
"
"
,
"
M
o
n
t
h
"
,
"
/
"
,
"
Y
e
a
r
S
h
o
r
t
"
}
]
;
u
u
i
d
T
i
m
e
F
m
t
=
S
t
o
r
e
D
s
[
A
l
l
,
#
u
u
i
d
-
>
t
i
m
e
F
m
t
[
#
t
i
m
e
s
t
a
m
p
]
&
]
/
/
N
o
r
m
a
l
/
/
A
s
s
o
c
i
a
t
i
o
n
;
Association to organize the map’s features color and the corresponding radio button:
I
n
[
]
:
=
s
e
l
e
c
t
o
r
F
e
a
t
u
r
e
s
=
T
a
b
l
e
[
A
p
p
l
y
[
S
t
y
l
e
,
e
l
e
]
,
{
e
l
e
,
P
a
r
t
i
t
i
o
n
[
R
i
f
f
l
e
[
F
e
a
t
u
r
e
s
,
F
e
a
t
u
r
e
C
o
l
o
r
s
]
,
2
]
}
]
;
c
o
l
o
r
F
e
a
t
u
r
e
s
=
T
a
b
l
e
[
T
o
S
t
r
i
n
g
[
e
l
e
]
e
l
e
,
{
e
l
e
,
s
e
l
e
c
t
o
r
F
e
a
t
u
r
e
s
}
]
/
/
A
s
s
o
c
i
a
t
i
o
n
;
Update dynamic variables of Feature:
I
n
[
]
:
=
u
i
V
a
r
s
U
p
d
a
t
e
[
u
u
i
d
P
a
r
m
_
S
t
r
i
n
g
]
:
=
{
(
*
u
p
d
a
t
e
d
y
n
a
m
i
c
v
a
r
i
a
b
l
e
s
t
h
a
t
t
o
d
i
s
p
l
a
y
f
e
a
t
u
r
e
s
s
p
e
c
i
f
i
c
*
)
e
l
e
m
e
n
t
A
c
t
i
o
n
=
Q
u
e
r
y
[
S
e
l
e
c
t
F
i
r
s
t
[
#
u
u
i
d
u
u
i
d
P
a
r
m
&
]
,
A
l
l
]
@
S
t
o
r
e
D
s
;
i
m
a
g
e
A
c
t
i
v
e
=
e
l
e
m
e
n
t
A
c
t
i
o
n
[
"
p
h
o
t
o
"
]
;
f
e
a
t
u
r
e
A
c
t
i
v
e
=
c
o
l
o
r
F
e
a
t
u
r
e
s
[
e
l
e
m
e
n
t
A
c
t
i
o
n
[
"
f
e
a
t
u
r
e
"
]
]
;
n
o
t
e
A
c
t
i
v
e
=
e
l
e
m
e
n
t
A
c
t
i
o
n
[
"
n
o
t
e
"
]
;
t
e
x
t
A
c
t
i
v
e
=
u
u
i
d
P
a
r
m
"
\
n
"
<
>
u
u
i
d
T
i
m
e
F
m
t
[
u
u
i
d
P
a
r
m
]
;
}
u
i
V
a
r
s
U
p
d
a
t
e
[
S
t
o
r
e
D
s
[
[
1
]
]
[
"
u
u
i
d
"
]
]
;
(
*
i
n
i
t
a
l
i
z
e
v
a
r
i
a
b
l
e
s
*
)
D
y
n
a
m
i
c
[
e
l
e
m
e
n
t
A
c
t
i
o
n
]
;
D
y
n
a
m
i
c
[
i
m
a
g
e
A
c
t
i
v
e
]
;
Locate the median of all the points, center the map:
I
n
[
]
:
=
g
e
o
M
a
p
C
e
n
t
e
r
=
S
t
o
r
e
D
s
[
A
l
l
,
"
p
o
s
i
t
i
o
n
"
]
/
/
N
o
r
m
a
l
/
/
S
p
a
t
i
a
l
M
e
d
i
a
n
;
Generate points with a tooltip:
I
n
[
]
:
=
g
e
n
e
r
a
t
e
G
e
o
P
o
i
n
t
s
[
s
t
o
r
e
D
s
_
]
:
=
T
o
o
l
t
i
p
[
B
u
t
t
o
n
[
G
e
o
M
a
r
k
e
r
[
#
[
[
1
]
]
,
c
o
l
o
r
M
a
r
k
[
#
[
[
3
]
]
]
]
,
u
i
V
a
r
s
U
p
d
a
t
e
[
#
[
[
2
]
]
]
]
,
u
u
i
d
T
i
m
e
F
m
t
[
#
[
[
2
]
]
]
]
&
/
@
N
o
r
m
a
l
[
s
t
o
r
e
D
s
[
S
e
l
e
c
t
[
#
d
e
l
e
t
e
d
F
a
l
s
e
&
]
,
{
"
p
o
s
i
t
i
o
n
"
,
"
u
u
i
d
"
,
"
f
e
a
t
u
r
e
"
}
]
]
;
Generate map using the points:
I
n
[
]
:
=
g
e
n
e
r
a
t
e
G
e
o
G
r
a
p
h
i
c
s
[
s
t
o
r
e
D
s
_
]
:
=
D
y
n
a
m
i
c
G
e
o
G
r
a
p
h
i
c
s
[
g
e
n
e
r
a
t
e
G
e
o
P
o
i
n
t
s
[
s
t
o
r
e
D
s
]
,
G
e
o
R
a
n
g
e
Q
u
a
n
t
i
t
y
[
7
,
"
M
i
l
e
s
"
]
,
G
e
o
Z
o
o
m
L
e
v
e
l
1
1
,
G
e
o
C
e
n
t
e
r
g
e
o
M
a
p
C
e
n
t
e
r
,
P
l
o
t
L
a
b
e
l
"
A
l
l
F
e
a
t
u
r
e
s
"
]
;
Save the updates back to CloudExpression:
I
n
[
]
:
=
u
p
d
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
c
l
d
E
x
p
I
d
_
S
t
r
i
n
g
,
s
t
o
r
e
D
s
_
D
a
t
a
s
e
t
]
:
=
M
o
d
u
l
e
[
{
s
t
o
r
e
C
l
d
E
x
p
}
,
D
e
l
e
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
c
l
d
E
x
p
I
d
]
;
s
t
o
r
e
C
l
d
E
x
p
=
C
r
e
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
s
t
o
r
e
D
s
,
c
l
d
E
x
p
I
d
]
;
I
f
[
L
e
n
g
t
h
[
s
t
o
r
e
C
l
d
E
x
p
[
]
]
!
=
L
e
n
g
t
h
[
s
t
o
r
e
D
s
]
,
S
t
y
l
e
[
"
C
o
m
m
i
t
F
a
i
l
u
r
e
:
D
a
t
a
s
e
t
a
n
d
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
n
o
t
E
q
u
a
l
.
.
.
"
,
R
e
d
,
L
a
r
g
e
]
,
S
t
y
l
e
[
"
C
o
m
m
i
t
O
k
"
,
B
l
u
e
]
]
]
Bring up the application
Fold all the support functions into a Grid that is Dynamic:
I
n
[
]
:
=
D
y
n
a
m
i
c
M
o
d
u
l
e
[
{
g
e
o
G
r
a
p
h
i
c
s
=
g
e
n
e
r
a
t
e
G
e
o
G
r
a
p
h
i
c
s
[
S
t
o
r
e
D
s
]
}
,
D
y
n
a
m
i
c
[
G
r
i
d
[
{
{
R
a
d
i
o
B
u
t
t
o
n
B
a
r
[
D
y
n
a
m
i
c
[
f
e
a
t
u
r
e
A
c
t
i
v
e
]
,
s
e
l
e
c
t
o
r
F
e
a
t
u
r
e
s
,
A
p
p
e
a
r
a
n
c
e
"
V
e
r
t
i
c
a
l
"
]
,
D
y
n
a
m
i
c
[
S
h
o
w
[
i
m
a
g
e
A
c
t
i
v
e
,
I
m
a
g
e
S
i
z
e
M
e
d
i
u
m
]
]
,
g
e
o
G
r
a
p
h
i
c
s
,
}
,
{
C
o
l
u
m
n
[
{
B
u
t
t
o
n
[
"
U
p
d
a
t
e
"
,
{
u
u
i
d
I
d
x
=
P
o
s
i
t
i
o
n
I
n
d
e
x
[
N
o
r
m
a
l
[
S
t
o
r
e
D
s
[
A
l
l
,
"
u
u
i
d
"
]
]
]
[
e
l
e
m
e
n
t
A
c
t
i
o
n
[
"
u
u
i
d
"
]
]
/
/
F
i
r
s
t
,
S
t
o
r
e
D
s
=
R
e
p
l
a
c
e
P
a
r
t
[
S
t
o
r
e
D
s
,
{
u
u
i
d
I
d
x
,
"
n
o
t
e
"
}
n
o
t
e
A
c
t
i
v
e
]
,
S
t
o
r
e
D
s
=
R
e
p
l
a
c
e
P
a
r
t
[
S
t
o
r
e
D
s
,
{
u
u
i
d
I
d
x
,
"
f
e
a
t
u
r
e
"
}
T
o
S
t
r
i
n
g
[
f
e
a
t
u
r
e
A
c
t
i
v
e
]
]
,
u
i
V
a
r
s
U
p
d
a
t
e
[
u
u
i
d
I
d
x
]
}
]
,
B
u
t
t
o
n
[
"
D
e
l
e
t
e
"
,
{
u
u
i
d
I
d
x
=
P
o
s
i
t
i
o
n
I
n
d
e
x
[
N
o
r
m
a
l
[
S
t
o
r
e
D
s
[
A
l
l
,
"
u
u
i
d
"
]
]
]
[
e
l
e
m
e
n
t
A
c
t
i
o
n
[
"
u
u
i
d
"
]
]
/
/
F
i
r
s
t
,
S
t
o
r
e
D
s
=
R
e
p
l
a
c
e
P
a
r
t
[
S
t
o
r
e
D
s
,
{
u
u
i
d
I
d
x
,
"
d
e
l
e
t
e
d
"
}
T
r
u
e
]
,
g
e
o
G
r
a
p
h
i
c
s
=
g
e
n
e
r
a
t
e
G
e
o
G
r
a
p
h
i
c
s
[
S
t
o
r
e
D
s
]
}
]
,
B
u
t
t
o
n
[
"
S
a
v
e
C
h
a
n
g
e
s
"
,
{
t
e
x
t
A
c
t
i
v
e
=
u
p
d
a
t
e
C
l
o
u
d
E
x
p
r
e
s
s
i
o
n
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
,
S
t
o
r
e
D
s
]
}
]
}
]
,
I
n
p
u
t
F
i
e
l
d
[
D
y
n
a
m
i
c
[
n
o
t
e
A
c
t
i
v
e
]
,
S
t
r
i
n
g
]
,
D
y
n
a
m
i
c
[
t
e
x
t
A
c
t
i
v
e
]
}
}
,
F
r
a
m
e
A
l
l
]
]
,
S
a
v
e
D
e
f
i
n
i
t
i
o
n
s
T
r
u
e
]
O
d
i
n
S
t
u
d
y
O
t
h
e
r
C
a
f
e
R
e
t
u
r
n
V
e
h
i
c
l
e
P
a
r
k
i
n
g
P
i
c
n
i
c
S
a
m
u
r
a
i
U
p
d
a
t
e
D
e
l
e
t
e
S
a
v
e
C
h
a
n
g
e
s
T
e
s
t
S
a
m
p
l
e
d
a
t
a
b
6
9
4
6
a
e
f
-
7
f
2
0
-
4
8
e
e
-
a
5
c
1
-
d
2
6
a
0
7
7
1
f
1
7
8
F
r
i
d
a
y
0
2
/
2
1
Return to Feature - Web Application
The ReturnFeature web application prompts for the Feature type to return to, followed by the RadioButton list of photo Features. Returning to a Feature involves using the current location and the Feature’s capture location to build a set of directions. Directions come in three forms : Google Map, Wolfram Map or Wolfram turn-by-turn.
This is a two stage selection. The first selects the type of feature to render followed, by the a list of all the features of the specified type. Selecting the features brings up a map to the feature.
Load the Dataset with the most current version of the data:
I
n
[
]
:
=
S
t
o
r
e
D
s
=
M
i
g
r
a
t
e
E
n
t
r
i
e
s
[
A
c
t
C
l
o
u
n
d
E
x
p
N
a
m
e
,
A
c
t
B
i
n
I
d
]
;
I
n
[
]
:
=
Generate a map - test
Bring the data up to date, migrating new Features from the Databin to the Dataset, and work with the Dataset exclusively after migration.
I
n
[
]
:
=
generateMapPathHtml : build map.
Get an entry from the test set:
I
n
[
]
:
=
h
o
s
p
i
t
a
l
E
n
t
r
y
=
S
t
o
r
e
D
s
[
S
e
l
e
c
t
[
"
T
e
s
t
S
a
m
p
l
e
"
#
n
o
t
e
&
]
]
/
/
F
i
r
s
t
;
e
n
d
=
h
o
s
p
i
t
a
l
E
n
t
r
y
[
"
p
o
s
i
t
i
o
n
"
]
O
u
t
[
]
=
G
e
o
P
o
s
i
t
i
o
n
[
{
3
8
.
3
9
7
1
,
-
1
2
2
.
8
1
9
}
]
Get a feel for the various TravelMethods:
I
n
[
]
:
=
s
t
a
r
t
=
H
e
r
e
;
e
n
d
=
h
o
s
p
i
t
a
l
E
n
t
r
y
[
"
p
o
s
i
t
i
o
n
"
]
;
L
a
s
t
[
S
t
o
r
e
D
s
]
[
"
p
o
s
i
t
i
o
n
"
]
;
T
a
b
V
i
e
w
[
#
-
>
G
e
o
G
r
a
p
h
i
c
s
[
S
t
y
l
e
[
L
i
n
e
[
T
r
a
v
e
l
D
i
r
e
c
t
i
o
n
s
[
{
s
t
a
r
t
,
e
n
d
}
,
T
r
a
v
e
l
M
e
t
h
o
d
#
]
]
,
T
h
i
c
k
,
R
e
d
]
]
&
/
@
{
"
D
r
i
v
i
n
g
"
,
"
B
i
k
i
n
g
"
,
"
W
a
l
k
i
n
g
"
}
]
O
u
t
[
]
=
D
r
i
v
i
n
g
B
i
k
i
n
g
W
a
l
k
i
n
g
I
n
[
]
:
=
Build Return to Feature page (prompt and render)
◼
build rule list image -> gps location
◼
display list on frame
◼
get current location from browser
◼
selector for output: map, turn-by-turn direction list
◼
generate TravelDirections
◼
render directions based on selector
◼
compose WebForm
◼
deploy
photoSelectorBuild[] : Map from Image to GPS for Form’s selector
Build a list of images sorted by time, constrained by feature and deleted set to False with a maximum of recent elements. Present at the browser in a checkbox list to select the Feature destination.
Build image->position selector list:
I
n
[
]
:
=
C
l
e
a
r
A
l
l
[
p
h
o
t
o
S
e
l
e
c
t
o
r
B
u
i
l
d
]
p
h
o
t
o
S
e
l
e
c
t
o
r
B
u
i
l
d
[
s
t
o
r
e
D
s
_
D
a
t
a
s
e
t
,
f
e
a
t
u
r
e
_
S
t
r
i
n
g
:
"
R
e
t
u
r
n
"
,
r
e
c
e
n
t
_
I
n
t
e
g
e
r
:
4
]
:
=
M
o
d
u
l
e
[
{
r
e
c
e
n
t
O
r
d
e
r
e
d
,
a
c
t
F
e
a
t
u
r
e
s
,
p
h
o
t
o
G
p
s
L
i
s
t
}
,
a
c
t
F
e
a
t
u
r
e
s
=
s
t
o
r
e
D
s
[
S
e
l
e
c
t
[
#
f
e
a
t
u
r
e
f
e
a
t
u
r
e
&
&
N
o
t
[
#
d
e
l
e
t
e
d
]
&
]
]
;
r
e
c
e
n
t
O
r
d
e
r
e
d
=
a
c
t
F
e
a
t
u
r
e
s
[
T
a
k
e
L
a
r
g
e
s
t
B
y
[
"
t
i
m
e
s
t
a
m
p
"
,
U
p
T
o
[
r
e
c
e
n
t
]
]
]
;
p
h
o
t
o
G
p
s
L
i
s
t
=
I
m
a
g
e
R
e
s
i
z
e
[
#
[
"
p
h
o
t
o
"
]
,
M
e
d
i
u
m
]
#
[
"
p
o
s
i
t
i
o
n
"
]
&
/
@
N
o
r
m
a
l
[
r
e
c
e
n
t
O
r
d
e
r
e
d
]
;
p
h
o
t
o
G
p
s
L
i
s
t
]
Verify photSelectorBuild[], using the test data:
I
n
[
]
:
=
p
h
o
t
o
S
e
l
e
c
t
o
r
B
u
i
l
d
[
S
t
o
r
e
D
s
,
"
S
a
m
u
r
a
i
"
,
2
5
]
O
u
t
[
]
=
G
e
o
P
o
s
i
t
i
o
n
[
{
3
8
.
4
7
1
5
,
-
1
2
2
.
7
2
6
}
]
,
G
e
o
P
o
s
i
t
i
o
n
[
{
3
8
.
4
4
3
7
,
-
1
2
2
.
7
0
1
}
]
,
G
e
o
P
o
s
i
t
i
o
n
[
{
3
8
.
3
9
7
1
,
-
1
2
2
.
8
1
9
}
]
I
n
[
]
:
=
travelScale[] :
Determine scale based upon TravelDistance and Method:
I
n
[
]
:
=
t
r
a
v
e
l
S
c
a
l
e
[
t
r
a
v
e
l
_
T
r
a
v
e
l
D
i
r
e
c
t
i
o
n
s
D
a
t
a
,
m
e
t
h
o
d
_
S
t
r
i
n
g
]
:
=
M
o
d
u
l
e
[
{
}
,
R
e
t
u
r
n
[
I
f
[
m
e
t
h
o
d
"
W
a
l
k
i
n
g
"
,
1
,
I
f
[
m
e
t
h
o
d
=
=
"
B
i
k
i
n
g
"
,
2
,
5
]
]
]
]
generateMapPathHtml[] : build the bike, car, walking routes - (polymorphic)
Generate the map depending on the GPS start and end locations, method of travel (car, bicycle, walk) type of directions (Google map, TravelDirections map, turn-by-turn).
◼
Note the '/;display == value' to select which type of map to display: Wolfram , Turn-by-Turn or Google.
◼
Example of URL to build the redirect to goggle maps, template for building redirect
https://www.google.com/maps/dir/?api=1&origin=37.7796936019619,-122.47587202694933&destination=47.5951518,-122.3316393&travelmode=bicycling
Generate map using TravelDirections[]:
I
n
[
]
:
=
g
e
n
e
r
a
t
e
M
a
p
P
a
t
h
H
t
m
l
[
s
t
a
r
t
_
G
e
o
P
o
s
i
t
i
o
n
,
e
n
d
_
G
e
o
P
o
s
i
t
i
o
n
,
m
e
t
h
o
d
_
S
t
r
i
n
g
:
"
B
i
k
i
n
g
"
,
d
i
s
p
l
a
y
_
S
t
r
i
n
g
:
"
m
a
p
"
]
:
=
M
o
d
u
l
e
[
{
s
c
a
l
e
,
t
r
a
v
e
l
D
i
r
e
c
t
}
,
t
r
a
v
e
l
D
i
r
e
c
t
=
T
r
a
v
e
l
D
i
r
e
c
t
i
o
n
s
[
{
s
t
a
r
t
,
e
n
d
}
,
T
r
a
v
e
l
M
e
t
h
o
d
m
e
t
h
o
d
]
;
s
c
a
l
e
=
t
r
a
v
e
l
S
c
a
l
e
[
t
r
a
v
e
l
D
i
r
e
c
t
,
m
e
t
h
o
d
]
;
G
e
o
G
r
a
p
h
i
c
s
[
S
t
y
l
e
[
L
i
n
e
[
t
r
a
v
e
l
D
i
r
e
c
t
]
,
T
h
i
c
k
,
L
i
g
h
t
e
r
[
R
e
d
]
]
,
G
e
o
R
a
n
g
e
Q
u
a
n
t
i
t
y
[
s
c
a
l
e
,
"
M
i
l
e
s
"
]
,
I
m
a
g
e
S
i
z
e
{
7
5
0
,
1
3
3
4
}
]
]
/
;
d
i
s
p
l
a
y
"
m
a
p
"
Static HTML to render the turn-by-turn directions:
I
n
[
]
:
=
b
a
c
k
B
u
t
t
o
n
H
t
m
l
=
"
<
b
u
t
t
o
n
o
n
c
l
i
c
k
=
\
"
g
o
B
a
c
k
(
)
\
"
>
B
A
C
K
<
/
b
u
t
t
o
n
>
"
;
s
c
r
i
p
t
H
t
m
l
=
"
<
s
c
r
i
p
t
>
f
u
n
c
t
i
o
n
g
o
B
a
c
k
(
)
{
w
i
n
d
o
w
.
h
i
s
t
o
r
y
.
b
a
c
k
(
)
;
}
<
/
s
c
r
i
p
t
>
"
;
s
t
y
l
e
H
t
m
l
=
S
t
r
i
n
g
I
c
o
n
;
Generate an HTML page with turn-by-turn directions using TravelDirections[]:
I
n
[
]
:
=
g
e
n
e
r
a
t
e
M
a
p
P
a
t
h
H
t
m
l
[
s
t
a
r
t
_
G
e
o
P
o
s
i
t
i
o
n
,
e
n
d
_
G
e
o
P
o
s
i
t
i
o
n
,
m
e
t
h
o
d
_
S
t
r
i
n
g
:
"
B
i
k
i
n
g
"
,
d
i
s
p
l
a
y
_
S
t
r
i
n
g
:
N
o
n
e
]
:
=
M
o
d
u
l
e
[
{
h
e
a
d
H
t
m
l
,
t
a
b
l
e
H
t
m
l
,
r
o
w
s
H
t
m
l
,
t
d
,
d
s
,
r
o
w
s
}
,
t
d
=
T
r
a
v
e
l
D
i
r
e
c
t
i
o
n
s
[
{
s
t
a
r
t
,
e
n
d
}
,
T
r
a
v
e
l
M
e
t
h
o
d
m
e
t
h
o
d
]
;
d
s
=
t
d
[
"
D
a
t
a
s
e
t
"
]
[
A
l
l
,
{
"
D
e
s
c
r
i
p
t
i
o
n
"
,
"
D
i
s
t
a
n
c
e
"
,
"
M
a
n
e
u
v
e
r
T
y
p
e
"
}
]
;
h
e
a
d
H
t
m
l
=
"
<
t
h
>
"
~
~
#
~
~
"
<
/
t
h
>
"
&
/
@
K
e
y
s
[
N
o
r
m
a
l
[
d
s
[
[
1
]
]
]
]
/
/
S
t
r
i
n
g
J
o
i
n
;
r
o
w
s
=
T
a
b
l
e
[
S
t
r
i
n
g
J
o
i
n
[
"
<
t
d
>
"
~
~
T
o
S
t
r
i
n
g
[
#
]
~
~
"
<
/
t
d
>
"
&
/
@
V
a
l
u
e
s
[
N
o
r
m
a
l
[
e
l
e
]
]
]
,
{
e
l
e
,
N
o
r
m
a
l
[
d
s
]
}
]
;
r
o
w
s
H
t
m
l
=
"
<
t
r
>
"
~
~
#
~
~
"
<
/
t
r
>
"
&
/
@
r
o
w
s
;
t
a
b
l
e
H
t
m
l
=
S
t
r
i
n
g
J
o
i
n
[
"
<