// Resize symbols slider value changed event handler
        private void symbolSizeSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
        {
            foreach (UIElement element in map.Children)
            {
                if (element is BubblePushpin)
                {
                    BubblePushpin bp = element as BubblePushpin;

                    if (e.NewValue == 0.0)
                    {
                        // revert back to original sizes
                        bp.BubbleSize = bp.OriginalBubbleSize;
                    }
                    else
                    {
                        if (e.NewValue < e.OldValue)
                        {
                            // shrinking bubbles so we divide to get the new size
                            // convert negative values to positive values to prevent
                            // the subsequent area calculations from breaking
                            if (e.NewValue < 0.0)
                            {
                                bp.BubbleSize = bp.BubbleSize / (e.NewValue * -1.0);
                            }
                            else
                            {
                                bp.BubbleSize = bp.BubbleSize / e.NewValue;
                            }
                        }
                        else
                        {
                            // growing bubbles - multiply
                            bp.BubbleSize = bp.BubbleSize * e.NewValue;
                        }
                    }
                }
            }
        }
        private async void CreateBubbles()
        {
            StringBuilder sb = new StringBuilder();
            byte[][] colourSchemeArray;
            int nClassesValue = 3;
            string colourSchemeComboBoxSelection = colourSchemeComboBox.SelectedValue.ToString();

            if (!_datasetModel.IsColourQualitative)
            {
                ComboBoxItem nClassesComboBoxSelection = (ComboBoxItem)numDataClassesComboBox.SelectedValue;
                nClassesValue = int.Parse(nClassesComboBoxSelection.Content.ToString());
                colourSchemeArray = _colourScheme.GetRGBColours(colourSchemeComboBoxSelection, nClassesValue);
            }
            else
            {
                nClassesValue = _distinctCategories.Count();
                colourSchemeArray = _colourScheme.GetRGBColours(colourSchemeComboBoxSelection, nClassesValue);
            }

            for (int i = 0; i < _datasetModel.Dataset.Count; i++)
            {
                string[] row = _datasetModel.Dataset[i];
                
                BubblePushpin bubble = new BubblePushpin();
                bubble.OriginalBubbleSize = double.Parse(row[_symbolSizeIndex]);
                bubble.BubbleSize = bubble.OriginalBubbleSize;
                bubble.ColourValue = row[_symbolColourIndex];

                // use StringBuilder to create the tooltip details
                sb.AppendLine(row[_placeNameIndex]);
                sb.Append(_datasetModel.ColumnHeadings[_symbolSizeIndex]);
                sb.Append(": ");
                sb.AppendLine(row[_symbolSizeIndex]);
                sb.Append(_datasetModel.ColumnHeadings[_symbolColourIndex]);
                sb.Append(": ");
                sb.Append(row[_symbolColourIndex]);
                if (!String.IsNullOrEmpty(this.Description))
                {
                    sb.Append(": ");
                    sb.Append(row[_descriptionIndex]);
                }
                bubble.Details = sb.ToString();

                // plot symbols on map - if lat/lon not set then geocode the place name
                if (String.IsNullOrEmpty(this.Latitude) || String.IsNullOrEmpty(this.Longitude) ||
                        String.IsNullOrEmpty(row[_latitideIndex]) || String.IsNullOrEmpty(row[_longitudeIndex]))
                {
                    Bing.Maps.Location geocodedLocation = await GeocodePlaceName(row[_placeNameIndex]);
                    bubble.LatLon = geocodedLocation;
                }
                else
                {
                    double latitude = 0.0;
                    double longitude = 0.0;
                    
                    if (!double.TryParse(row[_latitideIndex], out latitude) || 
                         !double.TryParse(row[_longitudeIndex], out longitude))
                    {
                        await new MessageDialog("Cannot parse latitude/longitude for " + row[_placeNameIndex], 
                            "Error parsing dataset").ShowAsync();
                    }
                    
                    bubble.LatLon = new Bing.Maps.Location(latitude, longitude);
                }

                // Apply colour
                if (_datasetModel.IsColourQualitative)
                {
                    int index = _distinctCategories.IndexOf(row[_symbolColourIndex]);
                    bubble.Colour = colourSchemeArray[index];
                }
                else
                {
                    double colourValue = double.Parse(row[_symbolColourIndex]);
                    double linearTransform = (colourValue - _datasetModel.ColourMinMax[0]) /
                        (_datasetModel.ColourMinMax[1] - _datasetModel.ColourMinMax[0]) * (nClassesValue - 1);
                    int colourIndex = (int)Math.Truncate(linearTransform);
                    bubble.Colour = colourSchemeArray[colourIndex];
                }
                
                _bubblePushpins.Add(bubble);
                sb.Clear();
            }

            Draw();
        }
        private async void CreateBubbles()
        {
            StringBuilder sb = new StringBuilder();

            byte[][] colourSchemeArray;
            int      nClassesValue = 3;
            string   colourSchemeComboBoxSelection = colourSchemeComboBox.SelectedValue.ToString();

            if (!_datasetModel.IsColourQualitative)
            {
                ComboBoxItem nClassesComboBoxSelection = (ComboBoxItem)numDataClassesComboBox.SelectedValue;
                nClassesValue     = int.Parse(nClassesComboBoxSelection.Content.ToString());
                colourSchemeArray = _colourScheme.GetRGBColours(colourSchemeComboBoxSelection, nClassesValue);
            }
            else
            {
                nClassesValue     = _distinctCategories.Count();
                colourSchemeArray = _colourScheme.GetRGBColours(colourSchemeComboBoxSelection, nClassesValue);
            }

            for (int i = 0; i < _datasetModel.Dataset.Count; i++)
            {
                string[] row = _datasetModel.Dataset[i];

                BubblePushpin bubble = new BubblePushpin();
                bubble.OriginalBubbleSize = double.Parse(row[_symbolSizeIndex]);
                bubble.BubbleSize         = bubble.OriginalBubbleSize;
                bubble.ColourValue        = row[_symbolColourIndex];

                // use StringBuilder to create the tooltip details
                sb.AppendLine(row[_placeNameIndex]);
                sb.Append(_datasetModel.ColumnHeadings[_symbolSizeIndex]);
                sb.Append(": ");
                sb.AppendLine(row[_symbolSizeIndex]);
                sb.Append(_datasetModel.ColumnHeadings[_symbolColourIndex]);
                sb.Append(": ");
                sb.Append(row[_symbolColourIndex]);
                if (!String.IsNullOrEmpty(this.Description))
                {
                    sb.Append(": ");
                    sb.Append(row[_descriptionIndex]);
                }
                bubble.Details = sb.ToString();

                // plot symbols on map - if lat/lon not set then geocode the place name
                if (String.IsNullOrEmpty(this.Latitude) || String.IsNullOrEmpty(this.Longitude) ||
                    String.IsNullOrEmpty(row[_latitideIndex]) || String.IsNullOrEmpty(row[_longitudeIndex]))
                {
                    Bing.Maps.Location geocodedLocation = await GeocodePlaceName(row[_placeNameIndex]);

                    bubble.LatLon = geocodedLocation;
                }
                else
                {
                    double latitude  = 0.0;
                    double longitude = 0.0;

                    if (!double.TryParse(row[_latitideIndex], out latitude) ||
                        !double.TryParse(row[_longitudeIndex], out longitude))
                    {
                        await new MessageDialog("Cannot parse latitude/longitude for " + row[_placeNameIndex],
                                                "Error parsing dataset").ShowAsync();
                    }

                    bubble.LatLon = new Bing.Maps.Location(latitude, longitude);
                }

                // Apply colour
                if (_datasetModel.IsColourQualitative)
                {
                    int index = _distinctCategories.IndexOf(row[_symbolColourIndex]);
                    bubble.Colour = colourSchemeArray[index];
                }
                else
                {
                    double colourValue     = double.Parse(row[_symbolColourIndex]);
                    double linearTransform = (colourValue - _datasetModel.ColourMinMax[0]) /
                                             (_datasetModel.ColourMinMax[1] - _datasetModel.ColourMinMax[0]) * (nClassesValue - 1);
                    int colourIndex = (int)Math.Truncate(linearTransform);
                    bubble.Colour = colourSchemeArray[colourIndex];
                }

                _bubblePushpins.Add(bubble);
                sb.Clear();
            }

            Draw();
        }