April 17, 2015, 04:44 PM
GavinL[SHARING] Google Map API made easy..
Since I can't hand out our database of city, state, zip, estimated population, latitude, and longitude, you guys will just have to look at the stored proc, we created a synonym for below. Ask if you have question.
This is what it looks like:
This is the code:
DEFINE FILE USP_GETZIPPOPBYSTATE ADD
ALLINFO/A255V=USP_GETZIPPOPBYSTATE.ANSWERSET1.CITY || ', ' | USP_GETZIPPOPBYSTATE.ANSWERSET1.STATE || ' ' | USP_GETZIPPOPBYSTATE.ANSWERSET1.ZIPCODE;
END
SET ASNAMES = ON
TABLE FILE USP_GETZIPPOPBYSTATE
SUM USP_GETZIPPOPBYSTATE.ANSWERSET1.ESTIMATEDPOPULATION
BY USP_GETZIPPOPBYSTATE.ANSWERSET1.LAT
BY USP_GETZIPPOPBYSTATE.ANSWERSET1.LONG
BY USP_GETZIPPOPBYSTATE.ANSWERSET1.TRUNCESTPOPULATION
BY USP_GETZIPPOPBYSTATE.ANSWERSET1.ALLINFO
WHERE USP_GETZIPPOPBYSTATE.INPUT.@STATE EQ 'FL';
ON TABLE HOLD AS MYFILE FORMAT FOCUS
END
-RUN
-HTMLFORM BEGIN
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerwithlabel/src/markerwithlabel.js" type="text/javascript"></script>
<style>
html,
body,
#googleMap {
margin: 0;
padding: 0;
height: 100%;
}
.googleLabel {
color: #000;
font-weight: bold;
text-align: center;
}
</style>
<script>
{
var showOnStartInfoWindows = true;
//create locations..
var arrayAll = [];
var marker = [];
var jax = new google.maps.LatLng(30.318028, -81.674474);
var leesburg = new google.maps.LatLng(28.810750, -81.880056);
var map = null;
//create locations..
-REPEAT HENDNUM FOR &MYDATA FROM 1 TO &LINES
-READFILE MYFILE
-SET &COUNTER = &MYDATA-1;
arrayAll[&COUNTER.EVAL] = {loc: new google.maps.LatLng(!IBI.AMP.LAT;, !IBI.AMP.LONG;), size: !IBI.AMP.ESTIMATEDPOPULATION;, alphasize: "!IBI.AMP.TRUNCESTPOPULATION;".trim(), info: "!IBI.AMP.ALLINFO;".trim()};
-HENDNUM
-ENDLOOP
//EO create locations..
}
function initialize()
{
//center the map on Black Knight
var mapProp = {
center:arrayAll[0].loc,
zoom:6,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
//set google's API and pass the DIV by ID.
map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
//var bounds = new google.maps.LatLngBounds(leesburg, jax);
//map.fitBounds(bounds);
var maxSize = 0;
for(var i = 0; i < arrayAll.length; i++)
{
if(maxSize<arrayAll[i].size)
maxSize = arrayAll[i].size;
}
for(var i = 0; i < arrayAll.length; i++)
{
var size = Math.round((arrayAll[i].size/maxSize)*100);
//alert('|' + arrayAll[i].info + '|') ;
//create marker
marker[i] = new MarkerWithLabel({
labelInBackground:false,
position: arrayAll[i].loc,
map: map,
title: arrayAll[i].info + '\n(' + arrayAll[i].alphasize + ')',
labelAnchor: new google.maps.Point((size * 1.8) / 2, (size / 3)),
labelClass: "googleLabel", // the CSS class for the label
labelStyle: {
width: (size * 1.8) + 'px',
height: (size / 1.5) + 'px',
lineHeight: (size / 1.5) + 'px',
fontSize: (size / 1.5) + 'px'
},
labelContent: arrayAll[i].alphasize,
markerInfo: arrayAll[i].info,
icon: {
path: google.maps.SymbolPath.CIRCLE,
fillOpacity: 0.3,
fillColor: '#FFFF00',
strokeOpacity: 1.0,
strokeColor: '#0000ff',
strokeWeight: 1.0,
scale: size, //pixels
}
});
marker[i].setMap(map);
marker_onclick(marker[i]);
//marker_info(marker[i]);
}
}
function marker_onclick(marker) {
google.maps.event.addListener(marker, 'dblclick', function(o) {
map.setZoom(18);
map.setCenter(marker.position);
});
google.maps.event.addListener(marker, 'click', function(o) {
map.setZoom(7);
map.setCenter(marker.position);
});
google.maps.event.addListener(marker, 'rightclick', function(o) {
alert('could be routing to fex: \n' + marker.position);
});
}
//no longer in use, but kept here for example code..
function marker_info(marker) {
//create popup notice..
var infowindow = new google.maps.InfoWindow({
content:marker.labelContent
});
if(showOnStartInfoWindows)
infowindow.open(map, marker);
google.maps.event.addListener(marker, 'mouseover', function (o) {
//alert('over');
infowindow.open(map, marker);
});
google.maps.event.addListener(marker, 'mouseout', function (o) {
//alert('out');
infowindow.close(map, marker);
});
//EO create popup notice..
}
{
google.maps.event.addDomListener(window, 'load', initialize);
}
</script>
</head>
<body>
<div id="googleMap" style="width:100%;height:90%;"></div>
</body>
</html>
-HTMLFORM END
April 20, 2015, 10:22 PM
StuBouyerWow, I just did a very simple version of the same thing but using the HTML Layout in App Studio
Instead of HTMLFORM, I used the new Ajax call Target Type to load the data into the HTML page.
I also used Circle class from google maps to draw circles based on population rather than markers.
I can share if you are interested
Regards
Stu
April 22, 2015, 01:23 PM
GavinLAwesome.. I'm still on Dev Studio and will not be going App Studio until 8.2. On the maps, I used the Circle class the first time, but I found I could custom all the markers to be anything not just circles, so I went that direction. Also, as an old school javascript developer, I'm not a big fan of the use of AJAX or mass libraries that execute a lot of code, I don't need. You can share though as I'm sure someone would like to see it.
May 04, 2015, 07:40 PM
StuBouyerHere is the javacript code that I added to the "Embedded Javascript/CSS" tab in HTML Compser in App Studio
// create an array to hold the circles so that we can erase them when needed
var cityCircles = new Array();
function drawCircle(citymap) {
//which map do we draw on?
var map = IbComposer_getMapObject('mapcontrol1');
// iterate thru the array and erase any existing circles
var cntr = cityCircles.length;
for (i=0; i < cntr ; i++) {
cityCircle = cityCircles.pop();
cityCircle.setMap(null);
cityCircle = null;
}
// iterate citymap, draw circel and push to array
for (var city in citymap) {
var populationOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center: citymap[city].center,
radius: Math.sqrt(citymap[city].population) * 100
};
cityCircle = new google.maps.Circle(populationOptions);
cityCircles.push(cityCircle);
}
}
function showData(xml) {
// make sure we are centered on the right map
panToPoint('-28.9361549', '132.7938332', 'mapcontrol1', '4');
var citymap = {};
// iterate through the XML results and create the list of lat/long and population for each city
$(xml).find('tr')
.each(function () {
var $thisTr = this;
var c0 = $($thisTr).find('td[colnum="c0"]').text();
var c1 = $($thisTr).find('td[colnum="c1"]').text();
var c2 = $($thisTr).find('td[colnum="c2"]').text();
var c3 = $($thisTr).find('td[colnum="c3"]').text();
citymap[c0] = {
center: new google.maps.LatLng(c2, c3),
population: c1
};
});
// call the function to draw the circles
drawCircle(citymap) ;
}
Then I added this fex to the "Requests & Data sources"
TABLE FILE POPULATION
PRINT
POPULATION.POPULATION.POPULATION
POPULATION.POPULATION.LAT
POPULATION.POPULATION.LONG
BY LOWEST POPULATION.POPULATION.CITY
WHERE POPULATION.POPULATION.YEAR EQ &YEAR.(FIND POPULATION.POPULATION.YEAR IN POPULATION).YEAR:.;
ON TABLE SET PAGE-NUM NOLEAD
ON TABLE SET ASNAMES ON
ON TABLE NOTOTAL
ON TABLE PCHOLD FORMAT XML
ON TABLE SET HTMLCSS ON
ON TABLE SET STYLE *
INCLUDE = IBFS:/EDA/EDASERVE/_EDAHOME/ETC/endeflt.sty,
$
ENDSTYLE
END
Then I added a button and in "Tasks & Aninmations" linked the Click of the button to Fex with a target type of "Ajax call" and the showData name for the function name.
This passes the results of the FEX in XML to the javascript funtion where I itterate through it and draw the circles. In this case the code is mostly good old plain Javascript with just one IBI specific function call - IbComposer_getMapObject('mapcontrol1')
Cheers
Stu
May 04, 2015, 07:43 PM
StuBouyerHere is the full HTML code for the page - you should be able to copy this over to a WebFOCUS 8009 or higher environment and open it in App Studio
<!DOCTYPE html>
<HTML><HEAD>
<META content=IE=Edge http-equiv=X-UA-Compatible>
<META name=mycharsetmeta content="text/html; charset=ISO-8859-1" http-equiv=Content-Type>
<META name=Generation content="Created in release 8009, Generation 4">
<META name=viewport content="width=device-width, initial-scale=1.0"><script type="text/javascript">
//confidential_id=IBI_OptionsScript
var bRuntimes=true;var szHtmlAlias="/ibi_apps/";var prefix="ibi_html/javaassist/ibi/html/js/";var is_mobile="false";var szRunTimeHtmlAlias="runTimeHtmlAlias";var cgipath="cgipath";var ib_composer="ib_composer";var map="ib_composer_map";var grid="ib_composer_grid";var ibiOptions = new Array(cgipath,ib_composer,map);if(typeof(szRunTimeHtmlAlias) === 'string' && szRunTimeHtmlAlias.indexOf('/') == 0)szHtmlAlias=szRunTimeHtmlAlias;document.write('<script src="'+szHtmlAlias+prefix+'ibigbl.js" type="text/javascript"><\/script>');</script><script type="text/javascript">
//confidential_id=IBI_ibigblloadCss
if(typeof ibigblloadCss === 'function'){ibigblloadCss(null);addIntlTranslatedJS("composertrans.js");}else {alert("JavaScript alias '/ibi_apps/' is not valid.");window.location("about:blank");}</script><TITLE>HtmlPage</TITLE>
<SCRIPT type=text/javascript>
//confidential_id=clientEventHandlersJS
if(typeof(bRuntime) != 'undefined') {
// TODO: Add your inline runtime code here
}
//Begin function window_onload
function window_onload() {
UpdateData();
// TODO: Add your event handler code here
//add onInitialUpdate() function to make changes before initial run of the reports
}
//End function window_onload
// create an array to hold the circles so that we can erase them when needed
var cityCircles = new Array();
function drawCircle(citymap) {
//which map do we draw on?
var map = IbComposer_getMapObject('mapcontrol1');
// iterate thru the array and erase any existing circles
var cntr = cityCircles.length;
for (i=0; i < cntr ; i++) {
cityCircle = cityCircles.pop();
cityCircle.setMap(null);
cityCircle = null;
}
// iterate citymap, draw circel and push to array
for (var city in citymap) {
var populationOptions = {
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
center: citymap[city].center,
radius: Math.sqrt(citymap[city].population) * 100
};
cityCircle = new google.maps.Circle(populationOptions);
cityCircles.push(cityCircle);
}
}
function showData(xml) {
// make sure we are centered on the right map
panToPoint('-28.9361549', '132.7938332', 'mapcontrol1', '4');
var citymap = {};
// iterate through the XML results and create the list of lat/long and population for each city
$(xml).find('tr')
.each(function () {
var $thisTr = this;
var c0 = $($thisTr).find('td[colnum="c0"]').text();
var c1 = $($thisTr).find('td[colnum="c1"]').text();
var c2 = $($thisTr).find('td[colnum="c2"]').text();
var c3 = $($thisTr).find('td[colnum="c3"]').text();
citymap[c0] = {
center: new google.maps.LatLng(c2, c3),
population: c1
};
});
// call the function to draw the circles
drawCircle(citymap) ;
}
</SCRIPT>
<STYLE></STYLE>
<!--//confidential_id=focus_xmlelement
<rootxmlnode focoption="_FOC_NULL" nextelementuniquenumber="2"><html_elements><html_body thumbnailscale="4" use_appl_css="no" maptype="0" autofitchildren="no" mobiledocument="no" edaconnectionrequired="true" ibiapp_app="Public" ismre="1" ibif_ex="/WFC/Repository/Public/circlemap.htm"><html_event eventname="load" eventhandlername="window_onload"/></html_body><html_element bindcontrolid="mapcontrol1" elementtype="41" inputcontrol="1" tabindex="1" myviewonautofit="dontyouever" dragging="yes" doubleclickzoom="no" continuouszoom="no" scrollwheelzoom="no" defaultzoomlevel="4" defaultmaptype="0" runcontrol="no" layervisrefreshcontrol="yes" polygoncontrol="no" polygonactionscopy="yes" polygonactionsdelete="yes" polygonactionsmove="yes" polygonactionsresize="yes" polygontooltipradius="yes" polygontooltipmarkercount="yes" polygontooltiparea="yes" bullseyenumofrings="3" bullseyeinnerringrad="10" bullseyeouterringrad="100" bullseyeunits="mi" inbinding="1" defaultinbindinglocation="0,0,20,60" StyleBack_rtFileName="cgipathsub/ibi_html/javaassist/ibi/html/describe/ibimapimage.gif" onetimepopulated="0" StyleBack_UserSuppliedFullPath="1"><link linktype="default" persistentuniqueid="compUid_1"><condition default="1" name="Default" whattodowithcontrol="0" valuescompareoperator="0" parameterscompareoperator="0" conditionmultiselectoperator="0"><data_info datatype="1" name="Layer1" sourcetype="typeAnyReport" checkForDuplicateValues="0" refresh_interval="0"></data_info><data_info datatype="1" name="centerofthemapdatainfo" sourcetype="typeMaster"></data_info></condition></link></html_element><html_element bindcontrolid="button1" myviewonautofit="dontyouever"/><html_element bindcontrolid="panel1" elementtype="34" form_dist_between_desc_and_input="10" form_newline_chain="1" form_prompt_location="1" form_number_of_columns="4" form_number_of_visible_rows="4" myviewonautofit="dontyouever" autofitchildren="no" containerdisplayas="child"><html_event eventname="submit" eventhandlername="onExecuteEventHandler"/>
</html_element><html_element bindcontrolid="combobox1" inputcontrol="1" elementtype="8" myviewonautofit="dontyouever" defaultselection="1" inbinding="1" defaultinbindinglocation="0,0,20,60" linktype="none" onetimepopulated="0"><link linktype="default" persistentuniqueid="compUid_2"><condition default="1" name="Default" whattodowithcontrol="0" valuescompareoperator="0" parameterscompareoperator="0" conditionmultiselectoperator="0"><data_info datatype="1" datasource="POPULATION.mas" ibif_ex="POPULATION" displayfield="POPULATION.POPULATION.YEAR" datafield="POPULATION.POPULATION.YEAR" sourcetype="typeMaster" selectedvalue="" ibiformat="I4" accept="0" addalloption="0" checkForDuplicateValues="0"><![CDATA[]]><selectionto_item type="variable" id="YEAR"></selectionto_item></data_info></condition></link></html_element><html_element rtFileName="cgipathsub/ibi_html/javaassist/ibi/html/composer/themes/nonBindows/IBI-Themes/default_theme.css" type="cssfile"/><html_element rtFileName="cgipathsub/ibi_html/javaassist/ibi/html/composer/themes/nonBindows/IBI-Themes/ibi.css" bindcontrolid="IBI_THEME_CSS" desc="Information Builders" type="cssfile"/></html_elements><variables><variable parametercreatedinreslay="0" type="unresolved" name="YEAR" default="" textvarname="" accept="0" select="0" create="1" requests_list="citymap" controltype="8"><data_info displayfield="POPULATION.POPULATION.YEAR" ibiformat="I4" datafield="POPULATION.POPULATION.YEAR" datasource="POPULATION.mas" ibif_ex="POPULATION" datatype="1" sourcetype="typeMaster" selectedvalue="" operation="" slider_range_from="" slider_range_to="" previewvalue=""/></variable></variables><requests nextrequestsid="1"><request requestid="citymap" sourcetype="typeFex" ibif_ex="/WFC/Repository/Public/citymap.fex" ibiapp_app="Public" activeType="-1" activereport="0" compoundreport="0"/></requests><tasks><task id="load" trigger="load"/><task id="task2" trigger="click" specifictrigger="button1"><taskitem id="citymap" sourcetype="typeFex" targettype="ajax" targetname="showData"/>
</task></tasks><animations></animations></rootxmlnode>
--><script type="text/javascript">
//confidential_id=updateHeadElements
if(typeof updateHeadElements === 'function'){updateHeadElements();}</script></HEAD>
<BODY class=IBI_PageBg>
<DIV style="Z-INDEX: 1; POSITION: absolute; WIDTH: 750px; HEIGHT: 470px; TOP: 90px; LEFT: 100px" id=mapcontrol1 class=IBI_ReportControlTarget></DIV><INPUT style="Z-INDEX: 2; POSITION: absolute; WIDTH: 110px; HEIGHT: 30px; TOP: 580px; LEFT: 260px" id=button1 class=IBI_button tabIndex=2 value="Draw Circles" type=button name="button1">
<DIV style="POSITION: absolute; WIDTH: 100px; HEIGHT: 52px; TOP: 570px; LEFT: 130px" id=panel1 class="IBI_ReportControlPanel IBI_rounded_m"><LABEL style="Z-INDEX: 3; POSITION: absolute; WIDTH: 32px; HEIGHT: 15px; CURSOR: default; TOP: 5px; LEFT: 5px" id=label1 class=IBI_ReportControlLabel for=combobox1>YEAR:</LABEL><SELECT style="Z-INDEX: 4; POSITION: absolute; WIDTH: 65px; TOP: 30px; LEFT: 5px" id=combobox1 class="IBI_ReportControlTarget IBI_rounded_s" tabIndex=3 size=1 sourcetype="typeMaster" firsttimeopen="1" name="combobox1"></SELECT></DIV></BODY><script type="text/javascript">
//confidential_id=IBI_loader
if(typeof doBeforeLoad === 'function'){doBeforeLoad();}function AdjustChildrenPosition(){
}
</script></HTML>
<!-- cc vpsr -->