Unit conversion quirks in TI Nspire

The TI Nspire calculator provided a rich set of common units from area, length, mass, etc. Units start with an understore in Nspire, for example, kg is represented as _kg. User are free to create their own units. On the desktop version of the Nspire software, a short cut for the conversion symbol (► ) is “@>”.

Recently over a conversation with a friend living overseas we are curious of the lowest we can get for a cut of meat at our own places. I am getting 12 per 500 gm on discount a few days ago. He gets 7.8 per 1 lb at best.

Some mental calculations for we have different units, but I decided to fire up the Nspire for this inequality to see what will happen:
units1

Alas, doesn’t work. Obviously I was expecting a boolean. The more verbose inequality with some pre-calculation didn’t work either.
units2

That’s where I realize Nspire might not be handling unit in equations the way we expected. An easy fix of course is to times a common unit (e.g. _kg) on both sides, but that pretty much defeat the whole purpose of simplicity of calculations of this kind.

Advertisements

Consolidating real time traffic CCTV data from data.gov.hk with Goolge Map API

Real time CCTV snapshot images from major route and highways in Hong Kong are provided online at data.gov.hk. Considering availability of data and related technology in the last decade, we have made a huge progress from obtaining traffic jam information from the radio to real time traffic CCTV images on the web.

Advancement in web technology not only enabled access of information, but also provided information in a manner flexible enough to easily build new view of content from multiple sources. The term “mashups” generally refer to this type of web application, and one such example presented here being visualizing road traffic data in near real time images on the web. A demo page is available on this site.

As explained in a previous article demonstrating a practical neural network application, CCTV images from the Hong Kong road network are already made available online. Together with Google Map API, an integration of the two will no doubt a very interesting fusion of technology.

Firstly, visit data.gov.hk for a glimpse of the traffic data available. Each CCTV provides image data on the web via a fixed URL.

The next thing to do is to integrate these data in Google Map API. In an attempt for a quick demonstration, a simple out-of-the-box application is adapted to retrieve data from data.gov.hk. These include the camera image, and the best of all, the geographical information from each of these images, i.e. the longitude and latitude. data.gov.hk provided a complete list of geographical data of its cameras, but since they are encoded in a format not directly understood by Google Map (HK80), a translation is required.

After confirming the position of each camera, a simple CSV file is created and the resulting Javascript is generated using an AWK script. There can’t be a method possibly be simpler than this when a prototype page with the Google API has been worked out. The below is captured from the resulting web page showing a selection of location of interest from all available CCTV images from data.gov.hk.

hkdatagovcctv2

The map below in HTML created using Google Map API showing a complete list of CCTV location available at data.gov.hk. Clicking on each marker will open the real time image from the corresponding CCTV camera.hkdatagovcctv1

Excel is used to output a CSV data file for generating the Javascript file for use in the above example. The original file is in PDF but it is fairly easy to convert into Excel and then export from local coordinates in data.gov.hk (HK80) to something Google Map API can understand and render.hkdatagovcctv3

The layout of the CSV file is largely duplicated from the PDF file, and the line below is a sample. Most fields are self-explanatory, only the last three fields are additional to the data from the PDF file. Two of these are the converted coordinates for Google Map, and the last one is the default position of the CCTV image with respect to the marker. This can be either one of C,Q,W,A,S. For Q,W,A,S the image will be displayed on the corresponding quadrant as these characters are laid out on the keyboard, while C represent the display centered below the marker.


H106F,H106F.JPG,Connaught Road Central near Exchange Square,http://tdcctv.data.one.gov.hk/H106F.JPG,816365,834060,22.2861747,114.1554513,C

The AWK script below is used to loop through the CSV file to generate the part of the HTML content for each CCTV data.

BEGIN{
	FS=",";
	idx=1
}

{
	print "y0=" $7 ";x0=" $8;
	print "y1=y0+0.04;x1=x0+0.05;"
	print "var bounds" idx " = new google.maps.LatLngBounds(new google.maps.LatLng(y0,x0),new google.maps.LatLng(y1,x1));"
    print "var srcImage" idx " = '" $4 "';"
	print "var marker" idx " = new google.maps.Marker({position:new google.maps.LatLng(y0,x0),map:map,title: '" $1 "\\n" $3 "'});"
	print "var quadrant" idx " = \"C\";"
    print "overlay" idx " = new TrafficImageOverlay(bounds" idx ", srcImage" idx ", quadrant" idx ", map);"
	print "arr.push(overlay" idx ");"
	print "marker" idx ".addListener('click', function() {overlay" idx ".toggle();});"
	if ($9=="C") {
		print "overlay" idx ".toggle();"
	}
	idx++;
}

Finally, the HTML file.

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Hong Kong Real Time Road Traffic Camera Image</title>
<style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>

    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_SECRET_GOOGLEMAP_KEY"></script>
    <script>

    var overlay;
	var arr = [];
    TrafficImageOverlay.prototype = new google.maps.OverlayView();
    TrafficImageOverlay.prototype.toggle = function() {
      if (this.getMap()) {
		if (this.quadrant_=="A") {this.quadrant_="Q"; this.setMap(null); this.setMap(this.map_);}
		else if (this.quadrant_=="Q") {this.quadrant_="W"; this.setMap(null); this.setMap(this.map_);}
		else if (this.quadrant_=="W") {this.quadrant_="S"; this.setMap(null); this.setMap(this.map_);}
		else if (this.quadrant_=="S") {this.quadrant_="C"; this.setMap(null); this.setMap(this.map_);}
		else if (this.quadrant_=="C") {this.quadrant_="A"; this.setMap(null);}
		else
		this.setMap(null);
      } else {
        this.setMap(this.map_);
      }
    };

	TrafficImageOverlay.prototype.refreshImg = function() {
		try {
			this.img_.src=this.image_+'?rand=' + Math.random();
		}
		catch (err) {
			Console.log(err);
		}
	}

	function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
			zoom: 12,
			center: {lat: 22.308, lng: 114.1368}
        });

		var x0,x1,y0,y1;

		<!-- code block below is generated from awk script, showing only one block. One block for each CCTV data. -->

		y0=22.35110061;x0=114.0740287;
		y1=y0+0.04;x1=x0+0.05;
		var bounds1 = new google.maps.LatLngBounds(new google.maps.LatLng(y0,x0),new google.maps.LatLng(y1,x1));
        var srcImage1 = 'http://tdcctv.data.one.gov.hk/TC560F.JPG';
		var marker1 = new google.maps.Marker({position:new google.maps.LatLng(y0,x0),map:map,title: 'Tsing Ma Bridge'});
		var quadrant1 = "Q";
        overlay1 = new TrafficImageOverlay(bounds1, srcImage1, quadrant1, map);
		arr.push(overlay1);
		marker1.addListener('click', function() {overlay1.toggle();});

		<!-- end code block generated from awk script -->
	}

    function TrafficImageOverlay(bounds, image, quadrant, map) {this.bounds_ = bounds;this.image_ = image;this.quadrant_ = quadrant;this.map_ = map;this.div_ = null;this.setMap(map);}
		TrafficImageOverlay.prototype.onAdd = function() {
        var div = document.createElement('div');div.style.borderStyle = 'none';div.style.borderWidth = '0px';div.style.position = 'absolute';
        var img = document.createElement('img');img.src = this.image_;img.style.width = '100%';img.style.height = '100%';
		img.style.position = 'absolute';div.appendChild(img);this.div_ = div;
		var panes = this.getPanes();panes.overlayLayer.appendChild(div);
		this.img_=img;
    };

	TrafficImageOverlay.prototype.draw = function() {
        var overlayProjection = this.getProjection();
        var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
        var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
        var div = this.div_;div.style.left = sw.x+'px';div.style.top=ne.y+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		if (this.quadrant_=="Q") {
			div = this.div_;div.style.left = sw.x-(ne.x-sw.x)+'px';div.style.top=ne.y+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		}else if (this.quadrant_=="W") {
			div = this.div_;div.style.left = sw.x+'px';div.style.top=ne.y+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		}else if (this.quadrant_=="A") {
			div = this.div_;div.style.left = sw.x-(ne.x-sw.x)+'px';div.style.top=ne.y+(sw.y-ne.y)+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		}else if (this.quadrant_=="S") {
			div = this.div_;div.style.left = sw.x+'px';div.style.top=ne.y+(sw.y-ne.y)+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		}else if (this.quadrant_=="C") {
			div = this.div_;div.style.left = sw.x-(ne.x-sw.x)/2+'px';div.style.top=ne.y+(sw.y-ne.y)+'px';div.style.width=(ne.x-sw.x)+'px';div.style.height=(sw.y-ne.y)+'px';
		}
    };

	TrafficImageOverlay.prototype.onRemove = function() {
        this.div_.parentNode.removeChild(this.div_);this.div_ = null;
    };

    google.maps.event.addDomListener(window, 'load', initMap);

	var refreshIdx = 0;
	setInterval(
		function() {
			refreshIdx++;
			if (refreshIdx >= arr.length) {
				refreshIdx = 0;
			}
			try {
				arr[refreshIdx].refreshImg();
			} catch (err) {
				Console.log(err);
			}
		},10000
	);
    </script>
  </head>
  <body>
<div id="map"></div>
</body>
</html>

Visualizing WordPress stats with Excel Power Map

Power Map is a feature available in recent release of Microsoft Excel providing easy to use visualization of data in geographical form as well as temporal animation.

In a sample usage to understand where the readers of this blog are from this year, the WordPress stats data from 2016 are imported into Excel Power Map. WordPress already offered graphical presentation of visitor origin in a nice world map. For animating the data through a whole year by month, Excel Power Map is a nice and easy to use tool with just a little bit more effort to create such animation.

The statistic page should be familiar to all WordPress user. Download the data for each month as CSV and store on local drive.
powermap0

Now prepare the data by consolidating them all in a single Excel worksheet. I used the good ole awk as the source files are in plain text CSV to save some copy and paste efforts. For the animation to work, a new column indicating the time of data (e.g. data for USA in January 2016) has to be added for the Power Map to handle temporal attribute, and this column can not be in formula form.
powermap1a

When the source data are ready, select the whole region and click the 3D Map button under the Insert menu.
powermap2a

Now the Power Map UI will be displayed. A globe map will be displayed by default but since I preferred a flat map form instead of 3D so I clicked on the Flat Map button.
powermap3

The Power Map user interface works pretty much like a pivot table. You drop the dimension on the pre-defined attribute settings pane on the right hand side to tell Power Map how you would like the map to present your data. To create animation, just drag the date column to the “Time” section as the attribute and Power Map will be able to render accordingly.
powermap4

Now that everything is ready, the animation play nicely and Power Map will also be able to create the animation file.powermap5

Building blocks of genetic algorithm in TI Nspire

Genetic algorithm is one of the more popular evolutionary algorithm with wide range of usage including optimization. While there are a lot of implementation of this technique, including the one as an option in the Excel solver, building one is a very good choice to understand the underlying process.

The TI Nspire provided a rich set of matrix operations that can be utilized to model the data structure required genetic algorithm. For example, creating an initial population with arbitrary size of binary, integer, or real numbers.

ga1

The cross over operation can be modeled as extracting part of a matrix using the augment function.

ga2

Fitness function can be dynamically defined using the expr function available in the Nspire environment.ga3

 

Exploring Lorenz system in TI Nspire

The Lorenz system is a non-linear system involving three parameters. It is three dimensional and can be plotted for visualization. Although the Nspire is capable to plot 3D graphs, sequence functions is supported in 2D plot only. Even so, it is still good to explore this chaotic system.

The three axis x,y,z are represented using the sequence functions u1, u2, and u3 respectively.lorenz1
Clicking CTRL-T will open the Data page alongside the plot.
lorenz3

Resulting pattern in scatter plot resembles the famous 3D plot even if it is 2D.
lorenz2