Commits

Jay Lonnquist committed bffb952

Major changes:
- Compile against AIR 3.3.
- Change over to official Safecast API for data retrieval.
- Custom, private database no longer required!
- Load data on touch/click implemented.
- Orientation changes introduced in AIR3.3 integrated.
- Updated Mad Components libraries.

Comments (0)

Files changed (12)

AIRSafecast.as3proj

     <movie width="480" />
     <movie height="800" />
     <movie version="3" />
-    <movie minorVersion="2" />
+    <movie minorVersion="3" />
     <movie platform="AIR Mobile" />
     <movie background="#FFFFFF" />
   </output>
     <element path="lib\ExtendedMadnessLib0_1_4.swc" />
     <element path="lib\MadComponentsLib0_7_2.swc" />
     <element path="lib\MQFlashMapsAPI_7.1.1_OSM_MOBILE.swc" />
+    <element path="lib\ExtendedMadnessLib0_1_5.swc" />
+    <element path="lib\MadComponentsLib0_7_3.swc" />
+    <element path="lib\MadComponentsPureHelpers.swc" />
   </libraryPaths>
   <!-- External Libraries -->
   <externalLibraryPaths>
 <?xml version="1.0" encoding="utf-8"?>
-<application xmlns="http://ns.adobe.com/air/application/3.2">
+<application xmlns="http://ns.adobe.com/air/application/3.3">
   <id>air.com.mobiledesign.airsafecast.AIRSafecast</id>
   <versionNumber>0.1</versionNumber>
   <supportedProfiles>mobileDevice</supportedProfiles>
     <fullScreen>true</fullScreen>
     <!--<renderMode>direct</renderMode>-->
     <autoOrients>true</autoOrients>
-    <aspectRatio>portrait</aspectRatio>
+    <aspectRatio>any</aspectRatio>
     <systemChrome>standard</systemChrome>
   </initialWindow>
   <icon>

lib/ExtendedMadnessLib0_1_4.swc

Binary file removed.

lib/ExtendedMadnessLib0_1_5.swc

Binary file added.

lib/MadComponentsLib0_7_2.swc

Binary file removed.

lib/MadComponentsLib0_7_3.swc

Binary file added.

lib/MadComponentsPureHelpers.swc

Binary file added.

src/com/mobiledesign/airsafecast/Application.as

 	///////////////////////////
 	//Tweener classes.
 	import caurina.transitions.Tweener;
-	//Skinnable Minimal Components.
-	import com.bit101.components.PushButton;
-	import com.bit101.components.HSlider;
-	import com.dgrigg.skins.*;
 	//Mad Components.
 	import com.danielfreeman.madcomponents.UIActivity;
 	
 		//Internal class variables.
 		//////////////////////////////
 		//Instance.
-		private var _php_params:Object = {};
-		private var _driveid_date:Object = {};
-		private var _driveid_latlang:Object = {};
-		private var _driveid_idlatlang:Object = {};
-		private var _actind_init:Sprite;
 		private var _actind_demand:Sprite;
-		private var _driveid_slider:HSlider;
 		private var _app_width:Number;
 		private var _app_height:Number;
 		private var _app_dpi:Number;
-		private var _driveid_num:Number;
-		private var _driveid_txt:TextField;
-		private var _serverdata_btn:PushButton;
 		private var _nominatim_popup_bg:Sprite;
 		private var _nominatim_popup_scaled:Boolean = false;
+		private var _latlong_popup_bg:Sprite;
+		private var _latlong_popup_txt:TextField;
+		private var _ot_lat:String;
+		private var _ot_lon:String;
+		
+		//Safecast API key. https://api.safecast.org
+		private var _safecast_api_key:String = '';
 		
 		//Custom class instances.
 		private var _safecastmap:Map;
-		private var _safecastloaddata:Httpserv;
 		private var _safecastdata:Httpserv;
 		private var _ui:Interface = new Interface();
 		private var _orientation:Orientation;
 		public function Application(stage:Stage, app_dpi:Number) {
 			
 			///////////////////////////
+			//Device DPI.
+			///////////////////////////
+			_app_dpi = app_dpi;
+			///////////////////////////
+			
+			//////////////////////////////
+			//Init Tweener overwrite.
+			//////////////////////////////
+			Tweener.autoOverwrite = false;
+			//////////////////////////////
+			
+			///////////////////////////
 			//Device orientation.
 			///////////////////////////
 			//Initial orientation.
 			_orientation.addEventListener('ORIENTATION_CHANGED', orientationChangedHandler);
 			///////////////////////////
 			
-			///////////////////////////
-			//Device DPI.
-			///////////////////////////
-			_app_dpi = app_dpi;
-			///////////////////////////
-			
 			//////////////////////////////
-			//Init Tweener overwrite.
+			//Populate display, map, etc.
 			//////////////////////////////
-			Tweener.autoOverwrite = false;
+			initSafecastMap();
+			//////////////////////////////
+		}
+		
+		//////////////////////////////
+		//////////////////////////////
+		//Private methods.
+		//////////////////////////////
+		//////////////////////////////
+		
+		//////////////////////////////
+		//Init Safecast map & UI elements.
+		//////////////////////////////
+		private function initSafecastMap():void {
+			//////////////////////////////
+			//Primary map and touch/over listeners.
+			//////////////////////////////
+			_safecastmap = new Map(_app_width, _app_height, 37.551654, 140.880812, 5, _orientation.orient_str);
+			addChild(_safecastmap);
+			_safecastmap.addEventListener('MAP_OVER_COORD_COMPLETE', safecastMapOverTouchHandler);
+			_safecastmap.addEventListener('MAP_TOUCH_COORD_COMPLETE', safecastMapOverTouchHandler);
 			//////////////////////////////
 			
 			//////////////////////////////
-			//Audio device handling.
-			//Mic, line-in etc.
-			//CPM feedback/recording.
+			//Latitude & Longitude popup display.
 			//////////////////////////////
-			var cpm_counter:AudioHandler = new AudioHandler();
-			addChild(cpm_counter);
+			_latlong_popup_bg = _ui.drawMatte(2, 0xffffff, 0x000000, 5, (_app_height - 100), 155, 30, 'roundrect', 10, 10, 0.8, true, 'latlong_popup_bg');
+			addChild(_latlong_popup_bg);
+			_latlong_popup_txt = _ui.drawTextfield(Fontlib.DroidSans, 0, 0, 0xffffff, 5, 5, 155, 20, 16, false, 0xffffff, false, 0x8CC63F, 'dynamic', 'left', false, '_latlong_popup_txt', false, true, true, false);
+			_latlong_popup_bg.addChild(_latlong_popup_txt);
 			//////////////////////////////
 			
 			//////////////////////////////
-			//Send/retrieve initial Safecast data.
+			//Add activity indicator (on demand).
 			//////////////////////////////
-			//Add activity indicator (initial data load).
-			_actind_init = _ui.buildActivityIndicator((_app_width / 2), (_app_height / 2), _app_width, _app_height);
-			_actind_init.alpha = 0;
-			addChild(_actind_init);
-			//Initial data load.
-			//HTTP service.
-			_safecastloaddata = new Httpserv('http://path/to/scjsondata.php', 'GET', 'text', null);
-			//HTTP service listener.
-			_safecastloaddata.addEventListener('HTTPSERV_COMPLETE', safecastDataLoadHandler);
-			//Display activity indicator.
-			Tweener.addTween(_actind_init, {alpha: 0.8, time: 2});
-		}
-		
-		//////////////////////////////
-		//////////////////////////////
-		//Private methods.
-		//////////////////////////////
-		//////////////////////////////
-		
-		//////////////////////////////
-		//Safecast data on initial load handler.
-		//Return all unique 'drive ids'.
-		//Manipulate via slider comp.
-		//Reverse geocoding info.
-		//////////////////////////////
-		private function safecastDataLoadHandler(e:Event):void {
-			//////////////////////////////
-			//Add objects to display list.
-			//Safecast map & UI elements.
-			//////////////////////////////
-			_safecastmap = new Map(_app_width, _app_height, 37.551654, 140.880812, 5, _orientation.orient_str);
-			addChild(_safecastmap);
-			//Add activity indicator (on demand).
 			_actind_demand = _ui.buildActivityIndicator((_app_width / 2), (_app_height / 2), _app_width, _app_height);
 			_actind_demand.alpha = 0;
-			//Load Safecast data on demand button. 
-			_serverdata_btn = _ui.drawPushButton(this, 'Load', (_app_width / 1.3), 50, (_app_width / 8), (_app_height - 60));
-			_serverdata_btn.enabled = false;
-			//Drive ID display (via slider).
-			_driveid_txt = _ui.drawTextfield(Fontlib.DroidSansBold, 0, 0, 0xffffff, 0, (_app_height - 145), _app_width, 30, 16, false, 0xffffff, false, 0x8CC63F, 'dynamic', 'center', false, '_driveid_txt', true);
-			var driveid_txt_bg:Sprite = _ui.drawMatte(1, 0xffffff, 0x000000, 0, (_app_height - 150), _app_width, 70, 'rect', undefined, undefined, 0.7, true, 'driveid_txt_bg');
-			_driveid_txt.text = "Drag Slider To Choose Location"
-			addChild(driveid_txt_bg);
-			addChild(_driveid_txt);
+			//////////////////////////////
+			
+			//////////////////////////////
 			//Nominatim data display.
-			//Background and Safecast icon.
+			//////////////////////////////
 			var safecast_icon:DisplayObject = new SafecastIcon();
 			safecast_icon.x = 12;
 			safecast_icon.y = 12;
 			//Scale nominatim popup.
 			_nominatim_popup_bg.addEventListener(MouseEvent.CLICK, nomPopUpClickHandler, false, 0, false);
 			//////////////////////////////
-			//Load Safecast data on demand.
-			//////////////////////////////
-			_serverdata_btn.addEventListener(MouseEvent.MOUSE_UP, getDataTapHandler);
-			//////////////////////////////
 			
 			//////////////////////////////
-			//Divide required data into selected objects.
-			//Build slider.
+			//Audio device handling.
+			//Mic, line-in etc.
+			//CPM feedback/recording.
 			//////////////////////////////
-			var max_drive_val:Number;
-			for each (var value:Object in _safecastloaddata.json_container) {
-				//Drive ID & date.
-				_driveid_date[value.drive_id] = value.r_date;
-				//Latitude & longitude.
-				_driveid_latlang[value.latitude] = value.longitude;
-				//Drive ID & latitude, longitude.
-				var drivedat:Object = {};
-				drivedat.id = value.drive_id;
-				drivedat.lat = value.latitude;
-				drivedat.lon = value.longitude;
-				_driveid_idlatlang[value.drive_id] = drivedat;
-				max_drive_val = value.drive_id;
-			}
-			//Drive ID picker slider.
-			_driveid_slider = _ui.buildHSlider(this, 0, (_app_height - 110), max_drive_val);
-			_driveid_slider.width = _app_width;
-			_driveid_slider.addEventListener(Event.CHANGE, driveIdSliderChanged);
-			
+			var cpm_counter:AudioHandler = new AudioHandler();
+			addChild(cpm_counter);
 			//////////////////////////////
-			//Cleanup
-			//////////////////////////////
-			//Cleanup json data.
-			_safecastloaddata.json_container = null;
-			//Remove HTTPService listener.
-			_safecastloaddata.removeEventListener('HTTPSERV_COMPLETE', safecastDataLoadHandler);
-			//Hide activity indicator, remove on completion.
-			Tweener.addTween(_actind_init, {alpha: 0, time: 2, onComplete: remObj, onCompleteParams: [_actind_init]});
-		}
-		
-		//////////////////////////////
-		//Load data on demand button.
-		//////////////////////////////
-		private function getDataTapHandler(e:MouseEvent):void {
-			//Clean up old Nominatim data.
-			while (_nominatim_popup_bg.numChildren > 2) {
-				_nominatim_popup_bg.removeChildAt(2);
-			}
-			//DriveID, pass back to server.
-			_php_params.driveid = _driveid_num;
-			//HTTP service.
-			_safecastdata = new Httpserv('http://path/to/scjsondata.php', 'POST', 'text', _php_params);
-			//HTTP service listener.
-			_safecastdata.addEventListener('HTTPSERV_COMPLETE', safecastDataDemandHandler);
-			//Display ativity indicator.
-			addChild(_actind_demand);
-			Tweener.addTween(_actind_demand, {alpha: 0.8, time: 2});
 		}
 		
 		//////////////////////////////
 		}
 		
 		//////////////////////////////
-		//Drive ID slider data handler.
+		//Return mouse over/press/touch coordinates.
+		//Load data.
 		//////////////////////////////
-		private function driveIdSliderChanged(e:Event):void {
-			_driveid_num = _driveid_slider.value;
-			var d_data:String = (_driveid_date[_driveid_slider.value] != undefined) ? _driveid_date[_driveid_slider.value] : 'No Data Available';
-			_driveid_txt.text = 'Drive ID: ' + _driveid_slider.value.toString() + ' / ' + d_data;
-			//Enable/disable data loading based on availability.
-			(_driveid_date[_driveid_slider.value] != undefined) ? _serverdata_btn.enabled = true : _serverdata_btn.enabled = false;
+		private function safecastMapOverTouchHandler(e:Event):void {
+			switch (e.type) {
+				//Over map.
+				case 'MAP_OVER_COORD_COMPLETE':
+					var oc:Array = _safecastmap.latlongover_point.split(",");
+					var oc_lat:String = oc[0].slice(0, -4);
+					var oc_lon:String = oc[1].slice(0, -4);
+					_latlong_popup_txt.htmlText = 'lat: ' + oc_lat + ' / ' + 'lon: ' + oc_lon;
+					break;
+				//Touch map.
+				case 'MAP_TOUCH_COORD_COMPLETE':
+					var ot:Array = _safecastmap.latlongclick_point.split(",");
+					_ot_lat = ot[0];
+					_ot_lon = ot[1];
+					//Get Safecast data.
+					getDataOnTapHandler(_ot_lat, _ot_lon);
+					break;
+			}
+		}
+		
+		//////////////////////////////
+		//Load data on demand.
+		//////////////////////////////
+		private function getDataOnTapHandler(ot_lat:String, ot_lon:String):void {
+			//Clean up old Nominatim data.
+			while (_nominatim_popup_bg.numChildren > 2) {
+				_nominatim_popup_bg.removeChildAt(2);
+			}
+			//Construct query string.
+			var lat_str:String = '&latitude=' + ot_lat;
+			var lon_str:String = '&longitude=' + ot_lon;
+			var dist_str:String = '&distance=1000';
+			var safecast_url:String = 'https://api.safecast.org/api/measurements.json?api_key=' + _safecast_api_key + lat_str + lon_str + dist_str;
+			//Safecast API.
+			_safecastdata = new Httpserv(safecast_url, 'GET', 'text', null);
+			//HTTP service listener.
+			_safecastdata.addEventListener('HTTPSERV_COMPLETE', safecastDataOnDemandHandler);
+			//Display ativity indicator.
+			addChild(_actind_demand);
+			Tweener.addTween(_actind_demand, {alpha: 0.8, time: 2});
 		}
 		
 		//////////////////////////////
 		//Safecast data on demand handler.
 		//////////////////////////////
-		private function safecastDataDemandHandler(e:Event):void {
-			//cleanup any extant 'pois' before loading new data.
+		private function safecastDataOnDemandHandler(e:Event):void {
+			//Cleanup any extant 'pois' before loading new data.
 			_safecastmap.removepoi();
-			for each (var value:Object in _safecastdata.json_container) {
-				var latitude:Number = value.latitude;
-				var longitude:Number = value.longitude;
-				var reading_value:String = value.reading_value;
-				var alt_reading_value:String = value.alt_reading_value;
-				var reading_date:String = value.reading_date;
-				var drive_id:Number = value.drive_id;
-				//Add pois to map.
-				_safecastmap.buildpoi(latitude, longitude, reading_value, alt_reading_value, reading_date, drive_id);
+			//Build 'pois'.
+			for each (var val:Object in _safecastdata.json_container) {
+				var latitude:Number = val.latitude;
+				var longitude:Number = val.longitude;
+				var reading_value:Number = val.value;
+				var reading_date:String = val.captured_at;
+				_safecastmap.buildpoi(latitude, longitude, reading_value, reading_date);
 			}
+			
 			//Nominatim. Reverse Geocoding.
-			_safecastmap.returnominatim(_driveid_idlatlang, _driveid_num);
+			_safecastmap.returnominatim(_ot_lat, _ot_lon);
 			_safecastmap.addEventListener('NOMINATIM_COMPLETE', nominatimDataLoadHandler);
 			function nominatimDataLoadHandler(e:Event):void {
 				var txt_y_position:int = -5;
 			//Cleanup json data.
 			_safecastdata.json_container = null;
 			//Remove HTTPService listener.
-			_safecastdata.removeEventListener('HTTPSERV_COMPLETE', safecastDataDemandHandler);
+			_safecastdata.removeEventListener('HTTPSERV_COMPLETE', safecastDataOnDemandHandler);
 			//Hide activity indicator.
 			Tweener.addTween(_actind_demand, {alpha: 0, time: 2, onComplete: remObj, onCompleteParams: [_actind_demand]});
 		}
 		
 		//////////////////////////////
 		//Orientation change handler.
-		//'Reload' data on change.
 		//////////////////////////////
 		private function orientationChangedHandler(e:Event):void {
 			var current_width:Number = _orientation.current_width;
 			//Application width and height based on orientation change.
 			_app_width = current_width;
 			_app_height = current_height;
-			
 			//////////////////////////////
-			//Resend/retrieve Safecast data.
+			//Re-populate display, map, etc.
 			//////////////////////////////
-			//Add activity indicator (initial data load).
-			_actind_init = _ui.buildActivityIndicator((_app_width / 2), (_app_height / 2), _app_width, _app_height);
-			_actind_init.alpha = 0;
-			addChild(_actind_init);
-			//Initial data load.
-			//HTTP service.
-			_safecastloaddata = new Httpserv('http://path/to/scjsondata.php', 'GET', 'text', null);
-			//HTTP service listener.
-			_safecastloaddata.addEventListener('HTTPSERV_COMPLETE', safecastDataLoadHandler);
-			//Display activity indicator, remove on load completion.
-			Tweener.addTween(_actind_init, {alpha: 0.8, time: 2, onComplete: remObj, onCompleteParams: [_actind_init]});
+			initSafecastMap();
+			//////////////////////////////
 		}
 		
 		//////////////////////////////
 				}
 			}
 		}
-		//////////////////////////////
 	}
-}
-
+}

src/com/mobiledesign/airsafecast/AudioHandler.as

 	import flash.display.*;
 	import flash.events.*;
 	import flash.media.Microphone;
-	
 	//ByteArray.org MicRecorder class.
 	import org.bytearray.micrecorder.MicRecorder;
 	import org.bytearray.micrecorder.encoder.WaveEncoder;
 	import org.bytearray.micrecorder.events.RecordingEvent;
+	//Mad Components.
+	import com.danielfreeman.extendedMadness.UIDropWindow;
 	
 	public class AudioHandler extends Sprite {
 		//////////////////////////////
 		public function AudioHandler() {
 			//Get list of available audio devices.
 			getAudioDeviceList();
+			//Build device picker callout menu.
+			var callout:UIDropWindow = _ui.buildCallout(50, 50, 180, 135, _audiodevicelist);
+			//addChild(callout);
 			//Initialize device.
 			initDevice();
 			//Initialize recorder object.

src/com/mobiledesign/airsafecast/Httpserv.as

 		//Instance.
 		private var _httpservice:HTTPService = new HTTPService();
 		private var _prop:Object;
-		//Public data container.
+		//Public data.
 		public var json_container:Object = {};
 		//////////////////////////////
 		//Constructor.

src/com/mobiledesign/airsafecast/Interface.as

 	import com.dgrigg.skins.*;
 	//Mad Components.
 	import com.danielfreeman.madcomponents.UIActivity;
+	import com.danielfreeman.extendedMadness.UIDropWindow;
+	import com.danielfreeman.madcomponents.UIButton;
+	import com.danielfreeman.madcomponents.Attributes;
+	import com.danielfreeman.madcomponents.UI;
+	//Mad Components - Pure Helpers.
+	import pureHelpers.UIFormMaker;
 	
 	//////////////////////////////
 	public class Interface extends Sprite {
 		}
 		
 		//////////////////////////////
+		//Build callout menu.
+		//////////////////////////////
+		public function buildCallout(xpos:Number, ypos:Number, width:Number, height:Number, formdat:Array):UIDropWindow {
+			var callout:UIDropWindow = new UIDropWindow(this,     <null/>, new Attributes(0, 0, width, height));
+			callout.x = xpos;
+			callout.y = ypos;
+			var form:UIFormMaker = new UIFormMaker(callout, width, height);
+			for (var ad:int = 0; ad < formdat.length; ad++) {
+				var button:PushButton = drawPushButton(this, formdat[ad], width, 40, 0, 0);
+				form.attachVertical(button);
+			}
+			form.x = form.y = -UI.PADDING;
+			return callout;
+		}
+		
+		//////////////////////////////
 		//Build text fields.
 		//////////////////////////////
 		public function drawTextfield(font:*, sharp:Number, thick:Number, col:uint, xpos:int, ypos:int, wd:int, txtht:int, txtfontsize:Number, txtback:Boolean, txtbackcol:uint, txtfldborder:Boolean, txtfldbordercol:uint, txtfldtype:String, txtalign:String, txtselect:Boolean, txtname:String, txtembed:Boolean, wordwrap:Boolean = true, multiline:Boolean = true, underline:Boolean = false):TextField {

src/com/mobiledesign/airsafecast/Map.as

 ///////////////////////////
 package com.mobiledesign.airsafecast {
 	import flash.display.*;
+	import flash.geom.Point;
 	import flash.events.*;
 	import flash.text.*;
 	import mx.controls.*;
 	import com.mapquest.tilemap.pois.*;
 	import com.mapquest.tilemap.overlays.*;
 	import com.mapquest.services.nominatim.*;
-	
 	///////////////////////////
 	
 	public class Map extends Sprite {
 		private var _nominatim:Nominatim;
 		private var _app_width:Number;
 		private var _app_height:Number;
-		//Public data container.
+		//Public data.
 		public var nomdata:Object = {};
+		public var latlongover_point:String;
+		public var latlongclick_point:String;
 		
 		//////////////////////////////
 		//Constructor.
 			addChild(_map);
 			//Nominatim.
 			buildnominatim();
+			//Return mouse over/press/touch coordinates.
+			_map.addEventListener(MouseEvent.MOUSE_MOVE, onMouseOverTouchCoordinateHandler);
+			_map.addEventListener(TileMapEvent.CLICK, onMouseClickTouchCoordinateHandler);
 		}
 		
 		//////////////////////////////
 		//////////////////////////////
 		//Build poi.
 		//////////////////////////////
-		public function buildpoi(latitude:Number, longitude:Number, reading_value:String, alt_reading_value:String, reading_date:String, drive_id:Number):void {
+		public function buildpoi(latitude:Number, longitude:Number, reading_value:Number, reading_date:String):void {
 			//Latitude, longitude object.
 			var ll:LatLng = new LatLng(latitude, longitude);
 			//Define poi.
 			var poi:Poi = new Poi(ll);
 			poi.draggable = true;
+			poi.keepRolloverOnDrag = true;
+			//Poi events.
+			poi.addEventListener(MouseEvent.CLICK, onPoiClickHander, false, 0, true);
+			//Calculate millisieverts.
+			var rad_val:Number = (reading_value / 350);
+			var rad_val_round:Number = Math.round(rad_val * 100) / 100;
 			//Title.
-			poi.rolloverAndInfoTitleText = reading_value + 'mSv / ' + alt_reading_value + 'cpm';
+			poi.rolloverAndInfoTitleText = rad_val_round + 'uSv/h | ' + reading_value + 'cpm';
 			//Content popup window.
 			var strContent:String = new String();
-			var lat_round:String = latitude.toFixed(2);
-			var lon_round:String = longitude.toFixed(2);
+			var lat_cut:String = latitude.toFixed(2);
+			var lon_cut:String = longitude.toFixed(2);
 			strContent += reading_date;
 			strContent += '<br />----------------------------<br />';
-			strContent += '<b><font color="#980e10">Drive ID:</font></b> ' + drive_id + '<br />';
-			strContent += '<b><font color="#980e10">Latitude:</font></b> ' + lat_round + '<br />';
-			strContent += '<b><font color="#980e10">Longitude:</font></b> ' + lon_round + '<br />';
+			strContent += '<b><font color="#980e10">Latitude:</font></b> ' + lat_cut + '<br />';
+			strContent += '<b><font color="#980e10">Longitude:</font></b> ' + lon_cut + '<br />';
 			poi.infoContent = (strContent);
 			//Custom icon.
-			var rad_val:Number = new Number(reading_value);
 			var ico:MapIcon = new MapIcon();
 			//Colour of point based on severity of contamination.
 			switch (true) {
 				//Green.
-				case(rad_val <= 0.2):
+				case(rad_val_round <= 0.2):
 					ico.setImage(new RadPointGreen(), 32, 37);
 					break;
 				//Yellow.
-				case(rad_val > 0.2 && rad_val <= 0.5):
+				case(rad_val_round > 0.2 && rad_val_round <= 0.5):
 					ico.setImage(new RadPointYellow(), 32, 37);
 					break;
 				//Pink.
-				case(rad_val > 0.5 && rad_val <= 1.0):
+				case(rad_val_round > 0.5 && rad_val_round <= 1.0):
 					ico.setImage(new RadPointPink(), 32, 37);
 					break;
 				//Blue.
-				case(rad_val > 1.0 && rad_val <= 5.0):
+				case(rad_val_round > 1.0 && rad_val_round <= 5.0):
 					ico.setImage(new RadPointBlue(), 32, 37);
 					break;
 				//Red.
-				case(rad_val > 5.0 && rad_val <= 12.0):
+				case(rad_val_round > 5.0 && rad_val_round <= 12.0):
 					ico.setImage(new RadPointRed(), 32, 37);
 					break;
 				//Black.
-				case(rad_val > 12.0):
+				case(rad_val_round > 12.0):
 					ico.setImage(new RadPointBlack(), 32, 37);
 					break;
 			}
 		//////////////////////////////
 		//Return nominatim data.
 		//////////////////////////////
-		public function returnominatim(driveid_idlatlang:Object, driveid_num:Number):void {
+		public function returnominatim(ot_lat:String, ot_lon:String):void {
 			//Nominatim. Reverse Geocoding.
-			var ll:LatLng = new LatLng(Number(driveid_idlatlang[driveid_num].lat), Number(driveid_idlatlang[driveid_num].lon));
+			var ll:LatLng = new LatLng(Number(ot_lat), Number(ot_lon));
 			_nominatim.reverseByLatLng(ll);
 		}
 		
 			map.mapFriction = 1.8;
 			map.mapType = 'map';
 			map.name = 'Safecast - Japan';
+			map.showMobileCursor = true;
 			//Add controls. Position based on device orientation.
 			switch (orient_str) {
 				case 'landscape':
 		//////////////////////////////
 		
 		//////////////////////////////
+		//Poi events.
+		//////////////////////////////
+		//Prevent click on Poi from propagating to map underneath.
+		private function onPoiClickHander(e:MouseEvent):void {
+			e.stopImmediatePropagation();
+		}
+		
+		//////////////////////////////
+		//Return mouse over/press/touch coordinates.
+		//////////////////////////////
+		private function onMouseOverTouchCoordinateHandler(e:MouseEvent):void {
+			latlongover_point = _map.pixToLL(new Point(_map.mouseX, _map.mouseY)).toString();
+			dispatchEvent(new Event('MAP_OVER_COORD_COMPLETE', true));
+		}
+		private function onMouseClickTouchCoordinateHandler(e:TileMapEvent):void {
+			latlongclick_point = _map.pixToLL(new Point(_map.mouseX, _map.mouseY)).toString();
+			dispatchEvent(new Event('MAP_TOUCH_COORD_COMPLETE', true));
+		}
+		
+		//////////////////////////////
 		//Nominatim handlers.
 		//////////////////////////////
 		private function onNominatimResult(e:NominatimEvent):void {