AW Gmaps - Web Hosting at UMass Amherst

Going Beyond the
Address Push-Pin
Extending Advance
Web Lookups with
Google Maps
Presented by: Tom Jamate,
University of Massachusetts, Amherst
April 8, 2013
Session ID 2521
Session ID 2521
1
Introduction
•
In this presentation we will provide an overview and demonstrate the key technical
details of creating a Google map display from Advance Web Lookup results,
hopefully enough to get your feet wet to try some of these techniques on your
own.
•
This is one example of the increasing capability of the browser environment.
Javascript, DOM, CSS and HTML5 have become a powerful platform that can
consume and present a variety of web services.
•
This enhancement is experimental and under revision. This is one approach, any
number of variations are possible.
Session ID 2521
2
Problem
•
•
•
Alumni and development operations need to quickly find key demographic clusters.
Text-only reports do not easily lend themselves to this task.
By integrating geographic visualizations to Advance Web lookups, users can easily
create any number of specialized demographic views to help find Alumni ‘hotspots’, to
assist with prospect trip planning or event planning.
Session ID 2521
3
Enhancement benefit
One example: Advance Web Lookup to find all School of Engineering
alumni who graduated before 2002, gave at least $1000 and live in
Florida.
Session ID 2521
4
Agenda
1.
Review of the Google map heatmap visualization library. The API is one
example of a rich web service that can be connected to any browser based
application such as Advance Web.
2.
Create an Advance Web form a container for the map to be rendered in, with
a Javascript helper file. Review two methods of getting map data inside the
form’s HTML-Javascript control.
3.
A database stored procedure (Oracle, et, al) reads the lookup result table
(temp_web_report_keys) and outputs the data as a string formatted as a JS
data array. City or town longitude and latitude are pulled from the zip_city
table.
4.
Variations of a theme: the Circle ‘ratio’ map.
5.
Review / Resources.
Session ID 2521
5
Programming knowledge needed for this enhancement.
1.
Client-side browser: Javascript, HTML
2.
Oracle PL/SQL, the ability to create stored
procedures.
3.
ASP VB.Net (Visual Studio, or text editor).
4.
Advance Config Utility web form designer.
Session ID 2521
6
Overview
• Google maps work within Advance Web through the Client-side
Javascript layer. Here are the major players:
Database (Oracle, et al)
IIS Web Server
Advance Web
User’s web browser
AW Web report form
Store Procedure to query
address,
temp_web_report_key,
zip_city (latitude,
longitude).
JS data
Object
Javascript API Call
Rendered
Map
Session ID 2521
7
Google Maps
API Server
Google map Heatmap visualization
library.
Session ID 2521
8
What is a Heatmap?
• A Heatmap is a data visualization technique that renders the intensity
and distribution of data points on a map. A color gradient is used to
reflect the variation of point values, the higher the value, the ‘hotter’ the
color used for the data point on the map.
• Heatmaps serve as a good general reference to quickly reveal clusters
or 'hotspots' for a given dataset:
Clusters of
top donors
in Texas:
Session ID 2521
9
What a Heatmap is not, or why cartographers hate Heatmaps.
•
Google Heatmaps are not a substitute for sophisticated demographic analysis
tools. Tools such as esri Arcmap can provide precise classifications and visual
representations of demographic data. (See Choropleths, Isopleths and Jenks
breaks)
•
The ability to use the Google map api to create Heatmaps and Circle-ratio
maps is a step towards it becoming a serious GIS platform. A trend that will
probably continue.
Session ID 2521
10
The Google maps API
• Google maps are created in the browser’s Javascript
environment and are rendered inside a <DIV> tag with a
unique ID.
• To display a map on an Advance Web form, the DIV tag
needs to exist in an HTML control on the form.
• The Google map API is called from within a <script> tag
on a web page.
• Weighted map points are created with a data object
array within the map <script> tag.
Session ID 2521
11
Calling the Google Heatmap API, client-side javascript.
<script type=“text/javascript”
src="https://maps.googleapis.com/maps/
api/js?v=3.exp&sensor=false&libraries=visualization">
</script>
<div id="map_canvas" style="height: 600px;
width: 800px;"></div>
The map data object lives within a JS script tag. We’ll need to generate
and place this data object on the page:
var geoData
[
{location:
{location:
{location:
];
Session ID 2521
=
new google.maps.LatLng(37.782551, -122.445368),weight:6},
new google.maps.LatLng(26.8486, -80.0588),weight:6},
new google.maps.LatLng(37.783273, -122.440324),weight:3}
12
Creating the map, client-side javascript
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(39.50, -98.35),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new
google.maps.Map(document.getElementById(‘map_canvas’),
mapOptions);
// Create the map object.
pointArray = new google.maps.MVCArray(geoData);
heatmap = new google.maps.visualization.HeatmapLayer({
data: pointArray
});
// Create the heat map layer.
heatmap.setMap(map);
Session ID 2521
13
Google map Heatmap example
If you want to quickly get your feet wet, a great way to learn
is to try out the demo code of a Google Heatmap example
from on your workstation.
A working Heatmap example can be found here:
https://google-developers.appspot.com/maps/
documentation/javascript/examples/layer-heatmap
Session ID 2521
14
The Advance web-form map container.
Session ID 2521
15
Two methods for pushing map-point data into web form.
1.
Use the traditional Advance Web Data Command – Data
Transaction referenced by a web form. Limited to varchar2
output size.
2.
Use a small custom Vb.Net aspx handler program to insert
the data from a <script> tag reference on the web page. A
little more work but allows for unlimited output from a
looping refcursor, not vendor supported.
( This is similar to current web development methods of
delivering a web service-like JSON object into a client-side
javascript environment for presentation.)
Session ID 2521
16
Method 1, Data access - stored procedure
We have all the components to create a weighted map point:
Population (entity) counts from lookup
temp_web_report_keys
Where they live: addresses
Zip code level Longitude and latitude: zip_city
The count of homes per city is used for the map’s weighted
map points.
Session ID 2521
17
Method 1, Data access – create the stored procedure
Data access for the context-report web form references a stored procedure that
queries the lookup results and outputs the JS object array.
The count of homes per city is used for the map’s weighted map points:
CURSOR g_cnt IS
select '{location: new google.maps.LatLng('||
z.latitude||', '||z.longitude||'),'||
'weight:'||count(unique e.id_number)||'},' m_dat,
count(unique e.id_number) cnt, z.city, z.state,
substr(h.zipcode,1,5) a_zip, z.latitude, z.longitude
from temp_web_report_keys k, address h, zip_city z, entity e
where
k.session_id = in_session_id
and k.id_number = e.id_number
and k.id_number = h.id_number
and substr(h.zipcode,1,5) = substr(z.start_zip,1,5)
and h.addr_status_code = 'A'
and h.addr_type_code in ( 'H') -- home
group by z.city, z.state, substr(h.zipcode,1,5), z.latitude, z.longitude
order by cnt desc
Session ID 2521
18
Method 1, stored procedure to AW form to output string.
The stored procedure loops through the SQL cursor to build the JS object
array string that’s passed to the web form and into the Javascript
environment:
…
FOR gr in g_cnt
Loop
JSMTXT := JSMTXT ||' '||gr.m_dat;
End loop;
open RC1 for
select rtrim(JSMTXT,',') "JSMTXT“ from
dual;
Session ID 2521
19
Method 1, data access command/transaction
Data access for the web form is provided from a typical AW command/data
transaction via the Config utility:
Session ID 2521
20
Advance web-form container
Create an Advance Web report form for a context sensitive
report. An HTML control sets up the JS environment for the
map:
Session ID 2521
21
Javascript helper file, holds the code for the map definition.
var map, pointarray, heatmap;
function makeHeatmap(divID) {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(39.50, -98.35),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById(divID),
mapOptions);
pointArray = new google.maps.MVCArray(taxiData);
heatmap = new google.maps.visualization.HeatmapLayer({
data: pointArray
});
heatmap.setMap(map);
}
Session ID 2521
22
Method 2. Use a custom Vb.net handler to populate the map.
Use a small custom Vb.Net aspx handler program to
insert the data from a <script> tag reference. A little
more work but allows for unlimited output from a
looping refcursor, not vendor supported.
This is similar to current web development methods of
delivering a web service-like JSON object into a
client-side javascript environment for presentation.
Session ID 2521
23
Method 2, refcursor output, database side.
First create the stored procedure using a refcursor output parameter:
open RC1 for
select
'{location: new google.maps.LatLng('||
z.latitude||', '||z.longitude||'),'||
'weight:'||count(unique e.id_number)||'},' m_dat,
count(unique e.id_number) cnt,
z.city, z.state,
substr(h.zipcode,1,5) a_zip, z.latitude, z.longitude
from temp_web_report_keys k, address h ,
zip_city z, entity e
where
k.session_id = in_session_id
and k.id_number = e.id_number
and k.id_number = h.id_number
and substr(h.zipcode,1,5) = substr(z.start_zip,1,5)
and h.addr_status_code = 'A'
and h.addr_type_code in ( 'H') -- home
group by z.city, z.state, substr(h.zipcode,1,5), z.latitude, z.longitude
order by cnt desc;
Session ID 2521
24
Method 2, create the custom VB.Net aspx program on web folder.
Using the AdvanceWebPageInformation object you can get access to the Advance Web user
login context. You can use it to test for authentication as well as the db connection handle.
Customizations at the VB.Net level are not vendor supported:
Protected Function GetAdvPInfo() As AdvanceWebPageInformation
Dim _AdvPInfo = New AdvanceWebPageInformation
With _AdvPInfo
.InitCollections(Me.Controls, Me.Request.Form, Me.Request.QueryString,
Me.Session, Me.Validators)
.User = DirectCast(Session("AdvUser"), IAdvanceUser)
.Request = Me.Request
.Response = Me.Response
.PageType = Page.GetType()
.InstanceId = _instanceId
End With
Return _AdvPInfo
End Function
If not ( IsDBNull(Me.GetAdvPInfo().User.Database ) ) Then
dbi2 = New DBInterface( Me.GetAdvPInfo().User.Database)
dbconn2 = dbi2.GetConnection()
End If
Session ID 2521
25
Method 2, aspx file, execute the stored procedure, loop through
refcursor.
propCMD = New OracleCommand(“ADV_SCHEMA._geo_hm_hmap_js_wkeys_rc", dbconn2)
propCMD.Parameters.Add("in_session_id",
Oracle.DataAccess.Client.OracleDbType.Varchar2).Value = Session.SessionID
…
Response.Write( NL + " var geoData = [" )
Dim mr as string = ""
Do While propDatarowIndex < propDsS.Tables(0).Rows.Count
If not ( IsDBNull(propDsS.Tables(0).Rows(propDatarowIndex)("M_DAT")) ) Then
mr = propDsS.Tables(0).Rows(propDatarowIndex)("M_DAT")
‘Remove trailing ‘,’
if propDatarowIndex = (propDsS.Tables(0).Rows.Count - 1) then
mr = mr.substring( 0, mr.length-1)
end if
Response.Write( NL + mr )
End If
propDatarowIndex += 1
Loop 'Do While propDatarowIndex < propDsS.Tables(0).Rows.Count)
Response.Write( NL + "];" )
Session ID 2521
26
Method 2, reference the custom aspx file from script tag.
The script tag call the custom VB.Net program, which generates data for
the map points:
Now the only practical limit is browser-side memory and network bandwidth.
Session ID 2521
27
Web form to report application.
The web form is then referenced by an AW application for a context
sensitive report and made available to users:
Session ID 2521
28
Variations of a theme: the Circle-ratio
map
Session ID 2521
29
Circle-ratio map.
• The Circle-ratio is another type of mapping visualization:
Session ID 2521
30
Circle ratio data array, client-side javascript
• The Circle ratio takes a slightly different JS data array, a
center object with a population parameter:
// Create an object containing LatLng, population.
var myLatLng = new google.maps.LatLng( 42.22, -71.75 );
var myOptions = { zoom: 8, center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN };
var cir_factor = 6;
var citymap = {};
citymap['MA Pittsfield'] = { center: new google.maps.LatLng(42.4665, 73.2893), population: 1470000 /cir_factor };
citymap['MA Amherst'] = { center: new google.maps.LatLng(42.3729, -72.4509),
population: 1000000 /cir_factor };
citymap['MA Westfield'] = { center: new google.maps.LatLng(42.1627, 72.7713), population: 890000 /cir_factor };
Session ID 2521
31
Variations of a theme: the Circle ratio map.
• Loop through the citymap array to render the circle :
for (var city in citymap) {
// Construct the circle for each value in citymap.
// We scale population by 20.
var populationOptions = {
strokeColor: "#FF0000",
strokeOpacity: 0.7,
strokeWeight: 1,
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map,
center: citymap[city].center,
radius: citymap[city].population / 20
};
cityCircle = new google.maps.Circle(populationOptions);
}
Session ID 2521
32
The Google Maps API license
– Google has a restriction on the number of free maps rendered per
application (currently 25,000 map loads per day, but that can change).
– Many institutions have site license agreements with Google, yours
may.
– Non-profits aren’t affected by the Maps API limits and can apply for a
free Maps API for Business license through the Google Earth
Outreach grants program.
(see: www.google.com/earth/outreach/grants/software/ )
– Business enterprise licenses are also available.
(see: www.google.com/enterprise/earthmaps/maps-apis.html )
Session ID 2521
33
Summary
•
•
•
•
•
What is a Heatmap?
Details of the Google map api
Connected map to an Advance Web form
Map point data from AW command
Map point data from an external custom
Vb.Net
• Circle ratio maps.
Session ID 2521
34
Questions? Answers?
?
Session ID 2521
35
Thank You!
Presenter Tom Jamate
tomas@admin.umass.edu
Please complete the online session evaluation form
Session ID 2521
.
Session ID 2521
© 2013 Ellucian. All rights reserved.
36