Focal Point
[SHARING] Google Map API made easy..

This topic can be found at:
https://forums.informationbuilders.com/eve/forums/a/tpc/f/7971057331/m/8497046576

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




- FOCUS Man, just FOCUS!
-----------------------------
Product: WebFOCUS
Version: 8.1.04
Server: Windows 2008 Server
April 20, 2015, 10:22 PM
StuBouyer
Wow, 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


WebFOCUS 8.2.03 (8.2.06 in testing)
April 22, 2015, 01:23 PM
GavinL
Awesome.. 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.



- FOCUS Man, just FOCUS!
-----------------------------
Product: WebFOCUS
Version: 8.1.04
Server: Windows 2008 Server
May 04, 2015, 07:40 PM
StuBouyer
Here 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


WebFOCUS 8.2.03 (8.2.06 in testing)
May 04, 2015, 07:43 PM
StuBouyer
Here 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 -->  



WebFOCUS 8.2.03 (8.2.06 in testing)