Source Code iOSEditionSample AnalyzeVisual.zip
AppDelegate.cs
using Foundation;
using UIKit;
namespace AnalyzingVisualization
{
// The UIApplicationDelegate for the application. This class is responsible for launching the
// User Interface of the application, as well as listening (and optionally responding) to
// application events from iOS.
[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
// class-level declarations
public override UIWindow Window
{
get;
set;
}
// This method is invoked when the application is about to move from active to inactive state.
// OpenGL applications should use this method to pause.
public override void OnResignActivation(UIApplication application)
{
}
// This method should be used to release shared resources and it should store the application state.
// If your application supports background exection this method is called instead of WillTerminate
// when the user quits.
public override void DidEnterBackground(UIApplication application)
{
}
// This method is called as part of the transiton from background to active state.
public override void WillEnterForeground(UIApplication application)
{
}
// This method is called when the application is about to terminate. Save data, if needed.
public override void WillTerminate(UIApplication application)
{
}
}
}
Main.cs
using UIKit;
namespace AnalyzingVisualization
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}
MainViewController.cs
using MonoTouch.Dialog;
using UIKit;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace AnalyzingVisualization
{
public partial class MainViewController : UIViewController
{
public MainViewController(IntPtr handle)
: base(handle)
{ }
public override void ViewDidLoad()
{
base.ViewDidLoad();
SliderViewController navigation = new SliderViewController();
navigation.Position = FlyOutPosition.Left;
navigation.View.Frame = UIScreen.MainScreen.Bounds;
View.AddSubview(navigation.View);
AddChildViewController(navigation);
XDocument xDoc = XDocument.Load("AppData/SampleList.xml");
Section section = new Section("Style List");
if (xDoc.Root != null)
{
Collection<UIViewController> styleList = new Collection<UIViewController>();
foreach (var element in xDoc.Root.Elements())
{
string image = element.Attribute("Image").Value;
string className = element.Attribute("Class").Value;
string name = element.Attribute("Name").Value;
UIImage icon = UIImage.FromBundle(image);
BadgeElement iconItem = new BadgeElement(icon, name);
section.Add(iconItem);
DetailViewController rootController = (DetailViewController)Activator.CreateInstance(Assembly.GetExecutingAssembly().GetType("AnalyzingVisualization." + className));
rootController.DetailButtonClick = navigation.ToggleMenu;
rootController.Title = name;
UINavigationController mainController = new UINavigationController(rootController);
styleList.Add(mainController);
}
navigation.ViewControllers = styleList.ToArray();
}
navigation.NavigationRoot = new RootElement("Style List") { section };
}
}
}
MainViewController.designer.cs
// WARNING
//
// This file has been generated automatically by Xamarin Studio from the outlets and
// actions declared in your storyboard file.
// Manual changes to this file will not be maintained.
//
using System;
using Foundation;
using UIKit;
using System.CodeDom.Compiler;
namespace AnalyzingVisualization
{
[Register|("MainViewController")]
partial class MainViewController
{
void ReleaseDesignerOutlets ()
{
}
}
}
DotDenstyStyleViewContoller.cs
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class DotDenstyStyleViewContoller : DetailViewController
{
public DotDenstyStyleViewContoller()
{ }
protected override void InitializeMap()
{
base.InitializeMap();
MapView.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
MapView.Overlays.Add(worldOverlay);
ShapeFileFeatureLayer usLayer = new ShapeFileFeatureLayer("AppData/usStatesCensus2010.shp");
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(usLayer);
MapView.Overlays.Add(layerOverlay);
usLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
usLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(20, GeoColor.FromHtml("#00e6fe")), GeoColor.StandardColors.Gray));
usLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetDotDensityStyle());
usLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
MapView.ZoomTo(new PointShape(-96.8150, 39.6948), MapView.ZoomLevelSet.ZoomLevel05.Scale);
}
private static DotDensityStyle GetDotDensityStyle()
{
double pointToValueRatio = 0.0000094778167166538189;
PointStyle pointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Black, 7);
DotDensityStyle dotDensityStyle = new DotDensityStyle("Population", pointToValueRatio, pointStyle);
dotDensityStyle.CustomPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromHtml("#a57431"), 5);
return dotDensityStyle;
}
}
}
HeatStyleViewContoller.cs
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class HeatStyleViewContoller : DetailViewController
{
public HeatStyleViewContoller()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.DecimalDegree;
MapView.CurrentExtent = new RectangleShape(-124.097208477811, 48.9471097666172, -110.242106301448, 28.7359794668483);
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
MapView.Overlays.Add(worldOverlay);
ShapeFileFeatureLayer usEarthquakeLayer = new ShapeFileFeatureLayer("AppData/usEarthquake_Simplified.shp");
MapView.Overlays.Add(new LayerOverlay(new Layer[] { usEarthquakeLayer }));
usEarthquakeLayer.DrawingMarginPercentage = 100;
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(new HeatStyle(10, 150, "MAGNITUDE", 0, 12, 100, DistanceUnit.Kilometer));
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
MapView.Refresh();
}
}
}
IconStyleViewController.cs
using System.Globalization;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class IconStyleViewController : DetailViewController
{
public IconStyleViewController()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.DecimalDegree;
View.AddSubview(MapView);
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
MapView.Overlays.Add(worldOverlay);
ShapeFileFeatureLayer iconStyleFeatureLayer = new ShapeFileFeatureLayer("AppData/Vehicles.shp");
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.TileType = TileType.SingleTile;
layerOverlay.Layers.Add(iconStyleFeatureLayer);
MapView.Overlays.Add(layerOverlay);
iconStyleFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
iconStyleFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetIconStyle("AppData/Images/vehicle"));
iconStyleFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
MapView.ZoomTo(new PointShape(-96.7689, 33.1620), MapView.ZoomLevelSet.ZoomLevel14.Scale);
}
private static ValueStyle GetIconStyle(string imagePath)
{
ValueStyle valueStyle = new ValueStyle();
valueStyle.ColumnName = "TYPE";
GeoFont font = new GeoFont("Arial", 12, DrawingFontStyles.Bold);
GeoSolidBrush brush = new GeoSolidBrush(GeoColor.StandardColors.Black);
for (int i = 1; i <= 7; i++)
{
IconStyle iconStyle = new IconStyle(imagePath + i + ".png", "Type", font, brush);
iconStyle.HaloPen = new GeoPen(GeoColor.SimpleColors.White);
ValueItem valueItem = new ValueItem(i.ToString(CultureInfo.InvariantCulture), iconStyle);
valueStyle.ValueItems.Add(valueItem);
}
return valueStyle;
}
}
}
DetailViewController.cs
using CoreGraphics;
using Foundation;
using System;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
using UIKit;
namespace AnalyzingVisualization
{
[Register("DetailViewController")]
public class DetailViewController : UIViewController
{
private UIView settingContainerView;
private UIBarButtonItem settingButton;
protected MapView MapView;
public Action SettingButtonClick;
public Action DetailButtonClick;
public DetailViewController() { }
protected UIView SettingContainerView
{
get { return settingContainerView; }
}
protected UIBarButtonItem SettingButton
{
get { return settingButton; }
}
protected float SettingContainerHeight { get; set; }
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.BackgroundColor = UIColor.Red;
View.AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth;
MapView = new MapView(View.Frame);
MapView.BackgroundColor = UIColor.FromRGB(244, 242, 238);
MapView.MapTools.ZoomMapTool.Center = new CGPoint(MapView.MapTools.ZoomMapTool.Center.X + 10, MapView.MapTools.ZoomMapTool.Center.Y + 55);
View.Add(MapView);
InitializeMap();
InitializeToolbar();
InitializeSettingView();
}
public override void WillAnimateRotation(UIInterfaceOrientation toInterfaceOrientation, double duration)
{
base.WillAnimateRotation(toInterfaceOrientation, duration);
double resolution = Math.Max(MapView.CurrentExtent.Width / MapView.Frame.Width, MapView.CurrentExtent.Height / MapView.Frame.Height);
MapView.Frame = View.Bounds;
MapView.CurrentExtent = GetExtentRetainScale(MapView.CurrentExtent.GetCenterPoint(), MapView.Frame, resolution);
MapView.Refresh();
}
/// <summary>
/// This method customizes the map for a specific sample.
/// We could add overlays, layers, styles inside of this method.
/// </summary>
protected virtual void InitializeMap()
{ }
/// <summary>
/// Gets the extent retain scale.
/// </summary>
/// <param name="currentLocationInMecator">The current location in mecator.</param>
/// <param name="frame">The frame.</param>
/// <param name="resolution">The resolution.</param>
/// <returns>RectangleShape.</returns>
private static RectangleShape GetExtentRetainScale(PointShape currentLocationInMecator, CGRect frame, double resolution)
{
double left = currentLocationInMecator.X - resolution * frame.Width * .5;
double right = currentLocationInMecator.X + resolution * frame.Width * .5;
double top = currentLocationInMecator.Y + resolution * frame.Height * .5;
double bottom = currentLocationInMecator.Y - resolution * frame.Height * .5;
return new RectangleShape(left, top, right, bottom);
}
private void InitializeToolbar()
{
UIBarButtonItem detailButton = new UIBarButtonItem(UIImage.FromBundle("detail40"), UIBarButtonItemStyle.Plain,
OnDetailButtonClick);
detailButton.TintColor = UIColor.Black;
NavigationItem.SetLeftBarButtonItem(detailButton, true);
settingButton = new UIBarButtonItem(UIImage.FromBundle("settings40"), UIBarButtonItemStyle.Plain,
OnSettingButtonClick);
settingButton.TintColor = UIColor.Black;
settingButton.Enabled = false;
NavigationItem.SetRightBarButtonItems(new[] { settingButton }, true);
}
private void InitializeSettingView()
{
if (settingContainerView == null)
{
settingContainerView = new UIView();
settingContainerView.TranslatesAutoresizingMaskIntoConstraints = false;
NSLayoutConstraint[] settingViewConstraints =
{
NSLayoutConstraint.Create(settingContainerView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 0),
NSLayoutConstraint.Create(settingContainerView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, View, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(settingContainerView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, SettingContainerHeight),
NSLayoutConstraint.Create(settingContainerView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, 0)
};
View.Add(settingContainerView);
View.AddConstraints(settingViewConstraints);
}
}
private void OnSettingButtonClick(object sender, EventArgs e)
{
if (SettingButtonClick != null) SettingButtonClick();
}
private void OnDetailButtonClick(object sender, EventArgs e)
{
if (DetailButtonClick != null) DetailButtonClick();
}
}
}
InstructionView.cs
using CoreGraphics;
using System;
using UIKit;
namespace AnalyzingVisualization
{
internal class InstructionView : UIView
{
private Action InstructionViewTopChanged;
private Action<UIView> ResetChildrenLayout;
public InstructionView(Action<UIView> initializeChildrenContent, Action instructionViewTopChanged)
{
ResetChildrenLayout = initializeChildrenContent;
InstructionViewTopChanged = instructionViewTopChanged;
InitializeComponentLayout();
}
private static int DescriptionMarginLeft
{
get { return iOSCapabilityHelper.IsOnIPhone ? 10 : 20; }
}
private void CollapseButtonTouchDown(object sender, EventArgs e)
{
if (InstructionViewTopChanged != null) InstructionViewTopChanged();
}
private void InitializeComponentLayout()
{
float titleHeight = 40;
Alpha = 0.9f;
BackgroundColor = UIColor.FromRGBA(126, 124, 129, 255);
UIView topLine = new UIView(new CGRect(0, 0, Frame.Width, 2));
topLine.BackgroundColor = UIColor.DarkGray;
topLine.Layer.CornerRadius = 4;
topLine.Layer.ShadowRadius = 3;
topLine.Layer.ShadowOpacity = .8f;
topLine.Layer.ShadowColor = UIColor.Black.CGColor;
topLine.Layer.ShadowOffset = new CGSize(1, 0);
topLine.TranslatesAutoresizingMaskIntoConstraints = false;
Add(topLine);
UIButton titleView = new UIButton();
titleView.BackgroundColor = UIColor.FromRGBA(126, 124, 129, 255);
titleView.TouchUpInside += CollapseButtonTouchDown;
titleView.TranslatesAutoresizingMaskIntoConstraints = false;
Add(titleView);
UILabel instructionLable = new UILabel();
instructionLable.BackgroundColor = BackgroundColor;
instructionLable.Text = "Setting";
instructionLable.Font = UIFont.FromName("Helvetica-Bold", 20);
instructionLable.TextColor = UIColor.White;
instructionLable.ShadowColor = UIColor.Gray;
instructionLable.ShadowOffset = new CGSize(1, 1);
instructionLable.TextAlignment = UITextAlignment.Left;
instructionLable.TranslatesAutoresizingMaskIntoConstraints = false;
titleView.Add(instructionLable);
UIButton collapseButton = UIButton.FromType(UIButtonType.RoundedRect);
collapseButton.SetImage(UIImage.FromBundle("More"), UIControlState.Normal);
collapseButton.TintColor = UIColor.White;
collapseButton.TouchUpInside += CollapseButtonTouchDown;
collapseButton.TranslatesAutoresizingMaskIntoConstraints = false;
titleView.Add(collapseButton);
float contentViewTop = titleHeight + 5;
UIView contentView = new UIView();
contentView.TranslatesAutoresizingMaskIntoConstraints = false;
Add(contentView);
NSLayoutConstraint[] instructionViewConstraints = new[]
{
NSLayoutConstraint.Create(topLine, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, 0),
NSLayoutConstraint.Create(topLine, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(topLine, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0),
NSLayoutConstraint.Create(topLine, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 2),
NSLayoutConstraint.Create(collapseButton, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 55),
NSLayoutConstraint.Create(collapseButton, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, 5),
NSLayoutConstraint.Create(collapseButton, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 10),
NSLayoutConstraint.Create(collapseButton, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 30),
NSLayoutConstraint.Create(instructionLable, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, DescriptionMarginLeft),
NSLayoutConstraint.Create(instructionLable, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(instructionLable, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0),
NSLayoutConstraint.Create(instructionLable, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, titleHeight),
NSLayoutConstraint.Create(titleView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, 0),
NSLayoutConstraint.Create(titleView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(titleView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, 0),
NSLayoutConstraint.Create(titleView, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, titleHeight),
NSLayoutConstraint.Create(contentView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, this, NSLayoutAttribute.Left, 1, DescriptionMarginLeft),
NSLayoutConstraint.Create(contentView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, this, NSLayoutAttribute.Right, 1, DescriptionMarginLeft),
NSLayoutConstraint.Create(contentView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, this, NSLayoutAttribute.Top, 1, contentViewTop),
NSLayoutConstraint.Create(contentView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, this, NSLayoutAttribute.Bottom, 1, 0),
};
AddConstraints(instructionViewConstraints);
if (ResetChildrenLayout != null) ResetChildrenLayout(contentView);
}
}
}
SliderViewController.cs
using CoreGraphics;
using Foundation;
using MediaPlayer;
using MonoTouch.Dialog;
using ObjCRuntime;
using System;
using System.Drawing;
using UIKit;
namespace AnalyzingVisualization
{
public enum FlyOutPosition
{
Left = 0, // default
Right
};
[Register("SilderViewController")]
public class SliderViewController : UIViewController
{
private const float sidebarFlickVelocity = 1000.0f;
private const int menuWidth = 240;
private bool hideShadow;
private UIButton closeButton;
private FlyOutPosition position;
private DialogViewController leftNavigation;
private int selectedIndex;
private UIView shadowView;
private nfloat startX;
private UIView statusImage;
private UIViewController[] viewControllers;
private bool isIos7;
private bool isOpen;
public event UITouchEventArgs ShouldReceiveTouch;
public Action SelectedIndexChanged;
public SliderViewController(IntPtr handle)
: base(handle)
{
Initialize();
}
public SliderViewController(UITableViewStyle navigationStyle = UITableViewStyle.Plain)
{
Initialize(navigationStyle);
}
public FlyOutPosition Position
{
get
{
return position;
}
set
{
position = value;
shadowView.Layer.ShadowOffset = new CGSize(Position == FlyOutPosition.Left ? -5 : 5, -1);
}
}
public bool AlwaysShowLandscapeMenu { get; set; }
public bool ForceMenuOpen { get; set; }
public bool HideShadow
{
get { return hideShadow; }
set
{
if (value == hideShadow)
return;
hideShadow = value;
if (hideShadow)
{
if (mainView != null)
View.InsertSubviewBelow(shadowView, mainView);
}
else
{
shadowView.RemoveFromSuperview();
}
}
}
public UIColor ShadowViewColor
{
get { return shadowView.BackgroundColor; }
set { shadowView.BackgroundColor = value; }
}
public UIViewController CurrentViewController { get; set; }
public UIView mainView
{
get
{
if (CurrentViewController == null)
return null;
return CurrentViewController.View;
}
}
public RootElement NavigationRoot
{
get { return leftNavigation.Root; }
set { EnsureInvokedOnMainThread(delegate { leftNavigation.Root = value; }); }
}
public UITableView NavigationTableView
{
get { return leftNavigation.TableView; }
}
public UIViewController[] ViewControllers
{
get { return viewControllers; }
set
{
EnsureInvokedOnMainThread(delegate
{
viewControllers = value;
NavigationItemSelected(GetIndexPath(SelectedIndex));
});
}
}
public bool IsOpen
{
get
{
if (Position == FlyOutPosition.Left)
{
return mainView.Frame.X == menuWidth;
}
else
{
return mainView.Frame.X == -menuWidth;
}
}
set
{
isOpen = value;
if (value)
HideMenu();
else
ShowMenu();
}
}
public bool ShouldStayOpen
{
get
{
if (ForceMenuOpen || (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad &&
AlwaysShowLandscapeMenu && (InterfaceOrientation == UIInterfaceOrientation.LandscapeLeft
|| InterfaceOrientation == UIInterfaceOrientation.LandscapeRight)))
return true;
return false;
}
}
public int SelectedIndex
{
get { return selectedIndex; }
set
{
if (selectedIndex == value)
return;
selectedIndex = value;
EnsureInvokedOnMainThread(delegate { NavigationItemSelected(value); });
}
}
public bool DisableRotation { get; set; }
public override bool ShouldAutorotateToInterfaceOrientation(UIInterfaceOrientation toInterfaceOrientation)
{
if (DisableRotation)
return toInterfaceOrientation == InterfaceOrientation;
bool theReturn = CurrentViewController == null
? true
: CurrentViewController.ShouldAutorotateToInterfaceOrientation(toInterfaceOrientation);
return theReturn;
}
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
if (CurrentViewController != null)
return CurrentViewController.GetSupportedInterfaceOrientations();
return UIInterfaceOrientationMask.All;
}
public override void ViewDidLayoutSubviews()
{
base.ViewDidLayoutSubviews();
CGRect navFrame = View.Bounds;
// navFrame.Y += UIApplication.SharedApplication.StatusBarFrame.Height;
// navFrame.Height -= navFrame.Y;
//this.statusbar
navFrame.Width = menuWidth;
if (Position == FlyOutPosition.Right)
navFrame.X = mainView.Frame.Width - menuWidth;
if (leftNavigation.View.Frame != navFrame)
leftNavigation.View.Frame = navFrame;
}
public override void ViewWillAppear(bool animated)
{
CGRect navFrame = leftNavigation.View.Frame;
navFrame.Width = menuWidth;
if (Position == FlyOutPosition.Right)
navFrame.X = mainView.Frame.Width - menuWidth;
navFrame.Location = PointF.Empty;
leftNavigation.View.Frame = navFrame;
View.BackgroundColor = NavigationTableView.BackgroundColor;
var frame = mainView.Frame;
setViewSize();
SetLocation(frame);
base.ViewWillAppear(animated);
}
private void Initialize(UITableViewStyle navigationStyle = UITableViewStyle.Plain)
{
DisableStatusBarMoving = true;
statusImage = new UIView { ClipsToBounds = true }.SetAccessibilityId("statusbar");
leftNavigation = new DialogViewController(navigationStyle, null);
leftNavigation.OnSelection += NavigationItemSelected;
CGRect navFrame = leftNavigation.View.Frame;
navFrame.Width = menuWidth;
if (Position == FlyOutPosition.Right)
navFrame.X = mainView.Frame.Width - menuWidth;
leftNavigation.View.Frame = navFrame;
View.AddSubview(leftNavigation.View);
var version = new Version(UIDevice.CurrentDevice.SystemVersion);
isIos7 = version.Major >= 7;
if (isIos7)
{
leftNavigation.TableView.TableHeaderView = new UIView(new CGRect(0, 0, 320, 22))
{
BackgroundColor = UIColor.Clear
};
leftNavigation.TableView.SectionHeaderHeight = 50;
}
leftNavigation.TableView.TableFooterView = new UIView(new CGRect(0, 0, 100, 100)) { BackgroundColor = UIColor.Clear };
leftNavigation.TableView.ScrollsToTop = false;
shadowView = new UIView();
shadowView.BackgroundColor = UIColor.White;
shadowView.Layer.ShadowOffset = new CGSize(Position == FlyOutPosition.Left ? -5 : 5, -1);
shadowView.Layer.ShadowColor = UIColor.Black.CGColor;
shadowView.Layer.ShadowOpacity = .75f;
closeButton = new UIButton();
closeButton.TouchUpInside += delegate { HideMenu(); };
AlwaysShowLandscapeMenu = true;
View.AddGestureRecognizer(new OpenMenuGestureRecognizer(DragContentView, shouldReceiveTouch));
UIButton moreButton = UIButton.FromType(UIButtonType.System);
moreButton.SetImage(UIImage.FromBundle("more40"), UIControlState.Normal);
moreButton.TintColor = UIColor.Black;
moreButton.TranslatesAutoresizingMaskIntoConstraints = false;
moreButton.TouchUpInside += (sender, args) => UIApplication.SharedApplication.OpenUrl(new NSUrl("http://www.thinkgeo.com/"));
NSLayoutConstraint[] moreButtonConstraints = new[]
{
NSLayoutConstraint.Create(moreButton, NSLayoutAttribute.Left, NSLayoutRelation.Equal, View, NSLayoutAttribute.Left, 1, 7),
NSLayoutConstraint.Create(moreButton, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, View, NSLayoutAttribute.Bottom, 1, -7),
NSLayoutConstraint.Create(moreButton, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 44),
NSLayoutConstraint.Create(moreButton, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 44),
};
View.Add(moreButton);
View.AddConstraints(moreButtonConstraints);
}
private void DragContentView(UIPanGestureRecognizer panGesture)
{
//if (ShouldStayOpen || mainView == null)
if (mainView == null)
return;
if (!HideShadow)
View.InsertSubviewBelow(shadowView, mainView);
leftNavigation.View.Hidden = false;
CGRect frame = mainView.Frame;
shadowView.Frame = frame;
nfloat translation = panGesture.TranslationInView(View).X;
if (panGesture.State == UIGestureRecognizerState.Began)
{
startX = frame.X;
}
else if (panGesture.State == UIGestureRecognizerState.Changed)
{
frame.X = translation + startX;
if (Position == FlyOutPosition.Left)
{
if (frame.X < 0)
frame.X = 0;
else if (frame.X > menuWidth)
frame.X = menuWidth;
}
else
{
if (frame.X > 0)
frame.X = 0;
else if (frame.X < -menuWidth)
frame.X = -menuWidth;
}
SetLocation(frame);
}
else if (panGesture.State == UIGestureRecognizerState.Ended)
{
nfloat velocity = panGesture.VelocityInView(View).X;
nfloat newX = translation + startX;
bool show = Math.Abs(velocity) > sidebarFlickVelocity ? velocity > 0 : newX > (menuWidth / 2);
if (Position == FlyOutPosition.Right)
{
show = Math.Abs(velocity) > sidebarFlickVelocity ? velocity < 0 : newX < -(menuWidth / 2);
}
if (show)
{
ShowMenu();
}
else
{
HideMenu();
}
}
}
private bool shouldReceiveTouch(UIGestureRecognizer gesture, UITouch touch)
{
if (ShouldReceiveTouch != null)
return ShouldReceiveTouch(gesture, touch);
return true;
}
private void NavigationItemSelected(NSIndexPath indexPath)
{
int index = GetIndex(indexPath);
NavigationItemSelected(index);
}
private void NavigationItemSelected(int index)
{
if (selectedIndex == index && CurrentViewController != null)
{
HideMenu();
return;
}
selectedIndex = index;
if (viewControllers == null || viewControllers.Length <= index || index < 0)
{
if (SelectedIndexChanged != null)
SelectedIndexChanged();
return;
}
if (ViewControllers[index] == null)
{
if (SelectedIndexChanged != null)
SelectedIndexChanged();
return;
}
if (!DisableStatusBarMoving)
//if (!DisableStatusBarMoving && !ShouldStayOpen)
UIApplication.SharedApplication.SetStatusBarHidden(false, UIStatusBarAnimation.Fade);
//bool isOpen = false;
//if (mainView != null)
//{
// mainView.RemoveFromSuperview();
// isOpen = IsOpen;
//}
//isOpen = false;
CurrentViewController = ViewControllers[SelectedIndex];
CGRect frame = View.Bounds;
//if (isOpen || ShouldStayOpen)
if (isOpen)
{
frame.X = Position == FlyOutPosition.Left ? menuWidth : -menuWidth;
frame.Width = frame.Width - frame.X;
}
//setViewSize();
SetLocation(frame);
View.AddSubview(mainView);
AddChildViewController(CurrentViewController);
//if (!ShouldStayOpen)
HideMenu();
if (SelectedIndexChanged != null)
SelectedIndexChanged();
}
//bool isOpen {get{ return mainView.Frame.X == menuWidth; }}
private void ShowMenu()
{
if (mainView == null)
return;
EnsureInvokedOnMainThread(delegate
{
//navigation.ReloadData ();
//isOpen = true;
leftNavigation.View.Hidden = false;
closeButton.Frame = mainView.Frame;
shadowView.Frame = mainView.Frame;
var statusFrame = statusImage.Frame;
statusFrame.X = mainView.Frame.X;
statusImage.Frame = statusFrame;
//if (!ShouldStayOpen)
View.AddSubview(closeButton);
if (!HideShadow)
View.InsertSubviewBelow(shadowView, mainView);
UIView.BeginAnimations("slideMenu");
UIView.SetAnimationCurve(UIViewAnimationCurve.EaseIn);
UIView.SetAnimationDuration(.3);
setViewSize();
CGRect frame = mainView.Frame;
frame.X = Position == FlyOutPosition.Left ? menuWidth : -menuWidth;
SetLocation(frame);
setViewSize();
frame = mainView.Frame;
shadowView.Frame = frame;
closeButton.Frame = frame;
statusFrame.X = mainView.Frame.X;
statusImage.Frame = statusFrame;
UIView.CommitAnimations();
isOpen = true;
});
}
private void setViewSize()
{
CGRect frame = View.Bounds;
//frame.Location = PointF.Empty;
//if (ShouldStayOpen)
if (isOpen)
frame.Width -= menuWidth;
if (mainView.Bounds == frame)
return;
mainView.Bounds = frame;
}
private void SetLocation(CGRect frame)
{
mainView.Layer.AnchorPoint = new CGPoint(.5f, .5f);
frame.Y = 0;
if (mainView.Frame.Location == frame.Location)
return;
frame.Size = mainView.Frame.Size;
var center = new CGPoint(frame.Left + frame.Width / 2,
frame.Top + frame.Height / 2);
mainView.Center = center;
shadowView.Center = center;
if (Math.Abs(frame.X - 0) > float.Epsilon)
{
getStatus();
var statusFrame = statusImage.Frame;
statusFrame.X = mainView.Frame.X;
statusImage.Frame = statusFrame;
}
}
private bool DisableStatusBarMoving { get; set; }
private void getStatus()
{
//if (DisableStatusBarMoving || !isIos7 || statusImage.Superview != null || ShouldStayOpen)
if (DisableStatusBarMoving || !isIos7 || statusImage.Superview != null)
return;
var image = captureStatusBarImage();
if (image == null)
return;
this.View.AddSubview(statusImage);
foreach (var view in statusImage.Subviews)
view.RemoveFromSuperview();
statusImage.AddSubview(image);
statusImage.Frame = UIApplication.SharedApplication.StatusBarFrame;
UIApplication.SharedApplication.StatusBarHidden = true;
}
private UIView captureStatusBarImage()
{
try
{
UIView screenShot = UIScreen.MainScreen.SnapshotView(false);
return screenShot;
}
catch (Exception ex)
{
return null;
}
}
private void hideStatus()
{
if (!isIos7)
return;
statusImage.RemoveFromSuperview();
UIApplication.SharedApplication.StatusBarHidden = false;
}
private void HideMenu()
{
//if (mainView == null || mainView.Frame.X == 0)
if (mainView == null)
return;
EnsureInvokedOnMainThread(delegate
{
isOpen = false;
leftNavigation.FinishSearch();
closeButton.RemoveFromSuperview();
shadowView.Frame = mainView.Frame;
var statusFrame = statusImage.Frame;
statusFrame.X = mainView.Frame.X;
statusImage.Frame = statusFrame;
UIView.Animate(.5, () =>
{
UIView.SetAnimationCurve(UIViewAnimationCurve.EaseInOut);
CGRect frame = View.Bounds;
frame.X = 0;
setViewSize();
SetLocation(frame);
shadowView.Frame = frame;
statusFrame.X = 0;
statusImage.Frame = statusFrame;
}, hideComplete);
});
}
[Export("animationEnded")]
private void hideComplete()
{
hideStatus();
shadowView.RemoveFromSuperview();
leftNavigation.View.Hidden = true;
}
private void ResignFirstResponders(UIView view)
{
if (view.Subviews == null)
return;
foreach (UIView subview in view.Subviews)
{
if (subview.IsFirstResponder)
subview.ResignFirstResponder();
ResignFirstResponders(subview);
}
}
public void ToggleMenu()
{
EnsureInvokedOnMainThread(delegate
{
if (!IsOpen && CurrentViewController != null && CurrentViewController.IsViewLoaded)
ResignFirstResponders(CurrentViewController.View);
if (IsOpen)
HideMenu();
else
ShowMenu();
});
}
private int GetIndex(NSIndexPath indexPath)
{
int section = 0;
int rowCount = 0;
while (section < indexPath.Section)
{
rowCount += leftNavigation.Root[section].Count;
section++;
}
return rowCount + indexPath.Row;
}
private NSIndexPath GetIndexPath(int index)
{
if (leftNavigation.Root == null)
return NSIndexPath.FromRowSection(0, 0);
int currentCount = 0;
int section = 0;
foreach (Section element in leftNavigation.Root)
{
if (element.Count + currentCount > index)
break;
currentCount += element.Count;
section++;
}
int row = index - currentCount;
return NSIndexPath.FromRowSection(row, section);
}
//public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
//{
// base.DidRotate(fromInterfaceOrientation);
// if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone)
// return;
// switch (InterfaceOrientation)
// {
// case UIInterfaceOrientation.LandscapeLeft:
// case UIInterfaceOrientation.LandscapeRight:
// ShowMenu();
// break;
// default:
// HideMenu();
// break;
// }
//}
private void EnsureInvokedOnMainThread(Action action)
{
if (NSThread.Current.IsMainThread)
{
action();
return;
}
BeginInvokeOnMainThread(() =>
action()
);
}
}
internal static class Helpers
{
static readonly IntPtr selAccessibilityIdentifier_Handle = Selector.GetHandle("accessibilityIdentifier");
public static UIView SetAccessibilityId(this UIView view, string id)
{
var nsId = NSString.CreateNative(id);
//Messaging.void_objc_msgSend_IntPtr(view.Handle, selAccessibilityIdentifier_Handle, nsId);
return view;
}
}
internal class OpenMenuGestureRecognizer : UIPanGestureRecognizer
{
public OpenMenuGestureRecognizer(Action<UIPanGestureRecognizer> callback, Func<UIGestureRecognizer, UITouch, bool> shouldReceiveTouch)
: base(callback)
{
ShouldReceiveTouch += (sender, touch) =>
{
//Ugly hack to ignore touches that are on a cell that is moving...
bool isMovingCell = touch.View.ToString().IndexOf("UITableViewCellReorderControl", StringComparison.InvariantCultureIgnoreCase) > -1;
if (touch.View is UISlider || touch.View is MPVolumeView || isMovingCell)
return false;
return shouldReceiveTouch(sender, touch);
};
}
}
}
ClassBreakChartView.cs
using CoreAnimation;
using CoreGraphics;
using Foundation;
using System;
using System.Linq;
using ThinkGeo.MapSuite.Core;
using UIKit;
namespace AnalyzingVisualization
{
public class ClassBreakChartView : UIView
{
public ClassBreakChartView(CGPoint lowerLeftPoint, ClassBreakStyle classBreakStyle)
{
InitializeClassBreakChartView(lowerLeftPoint, classBreakStyle);
}
private void InitializeClassBreakChartView(CGPoint lowerLeftPoint, ClassBreakStyle classBreakStyle)
{
ClassBreakChartLayer chartLayer = new ClassBreakChartLayer(classBreakStyle);
chartLayer.Opacity = .9f;
chartLayer.SetNeedsDisplay();
Layer.AddSublayer(chartLayer);
Frame = new CGRect(new CGPoint(lowerLeftPoint.X, lowerLeftPoint.Y - chartLayer.Frame.Height), chartLayer.Frame.Size);
}
private class ClassBreakChartLayer : CALayer
{
private static readonly UIFont font = UIFont.FromName("Arial", 12);
private ClassBreakStyle classBreakStyle;
private float paddingTop;
private float paddingLeft;
private float segmentWidth;
private float segmentHeight;
private float textMargin;
public ClassBreakChartLayer(ClassBreakStyle classBreakStyle)
{
this.classBreakStyle = classBreakStyle;
float paddingRight = 2;
float paddingBottom = 5;
paddingTop = 2;
paddingLeft = 5;
segmentWidth = 24;
segmentHeight = 20;
textMargin = 4;
nfloat maxTextWidth = classBreakStyle.ClassBreaks.Select(c => new NSString(c.Value.ToString("R0")).StringSize(font).Width).Max();
Frame = new CGRect(0, 0, paddingLeft + segmentWidth + textMargin + maxTextWidth + paddingRight, paddingTop + paddingBottom + segmentHeight * classBreakStyle.ClassBreaks.Count);
}
public override void DrawInContext(CGContext ctx)
{
base.DrawInContext(ctx);
ctx.SetFillColor(UIColor.White.CGColor);
ctx.FillRect(new CGRect(paddingLeft - 2, paddingTop - 2, segmentWidth + 4, segmentHeight * classBreakStyle.ClassBreaks.Count + 4));
for (int i = 0; i < classBreakStyle.ClassBreaks.Count; i++)
{
int currentIndex = classBreakStyle.ClassBreaks.Count - i - 1;
float barLeft = paddingLeft;
float barTop = paddingTop + i * segmentHeight;
ctx.SetFillColor(GetCGColor(classBreakStyle.ClassBreaks[currentIndex]));
ctx.FillRect(new CGRect(barLeft, barTop, segmentWidth, segmentHeight));
NSString text = new NSString(classBreakStyle.ClassBreaks[currentIndex].Value.ToString("R0"));
CGSize textSize = text.StringSize(font);
nfloat textTop = barTop + segmentHeight - textSize.Height;
nfloat textLeft = barLeft + segmentWidth + textMargin;
ctx.SetTextDrawingMode(CGTextDrawingMode.Stroke);
ctx.SetFillColor(UIColor.White.CGColor);
ctx.SetLineWidth(1);
UIGraphics.PushContext(ctx);
text.DrawString(new CGPoint(textLeft, textTop), font);
UIGraphics.PopContext();
ctx.SetTextDrawingMode(CGTextDrawingMode.Fill);
ctx.SetFillColor(UIColor.Black.CGColor);
UIGraphics.PushContext(ctx);
text.DrawString(new CGPoint(textLeft, textTop), font);
UIGraphics.PopContext();
}
}
private static CGColor GetCGColor(ClassBreak classBreak)
{
GeoColor color = classBreak.DefaultAreaStyle.FillSolidBrush.Color;
return UIColor.FromRGBA(color.RedComponent, color.GreenComponent, color.BlueComponent, color.AlphaComponent).CGColor;
}
}
}
}
ClassBreakStyleViewController.cs
using CoreGraphics;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class ClassBreakStyleViewController : DetailViewController
{
public ClassBreakStyleViewController()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
worldOverlay.TileType = TileType.MultiTile;
MapView.Overlays.Add(worldOverlay);
ClassBreakStyle classBreakStyle = GetClassBreakStyle();
ShapeFileFeatureLayer usLayer = new ShapeFileFeatureLayer("AppData/usStatesCensus2010.shp");
usLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
usLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(classBreakStyle);
usLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(usLayer);
MapView.Overlays.Add(layerOverlay);
MapView.ZoomTo(new PointShape(-96.8150, 39.6948), MapView.ZoomLevelSet.ZoomLevel05.Scale);
ClassBreakChartView chartView = new ClassBreakChartView(new CGPoint(5, View.Frame.Height - 5), classBreakStyle);
View.AddSubview(chartView);
}
private static ClassBreakStyle GetClassBreakStyle()
{
double[] classBreakValues = { 0, 814180.0, 1328361.0, 2059179.0, 2967297.0, 4339367.0, 5303925.0, 6392017.0, 8791894.0 };
GeoColor fromColor = GeoColor.FromArgb(255, 116, 160, 255);
GeoColor toColor = GeoColor.FromArgb(255, 220, 52, 56);
Collection<GeoColor> familyColors = GeoColor.GetColorsInQualityFamily(fromColor, toColor, 10, ColorWheelDirection.CounterClockwise);
ClassBreakStyle classBreakStyle = new ClassBreakStyle("Population", BreakValueInclusion.IncludeValue);
GeoColor outlineColor = GeoColor.FromHtml("#f05133");
for (int i = 0; i < classBreakValues.Length; i++)
{
GeoColor fillColor = new GeoColor(200, familyColors[i]);
AreaStyle areaStyle = AreaStyles.CreateSimpleAreaStyle(fillColor, outlineColor, 1);
classBreakStyle.ClassBreaks.Add(new ClassBreak(classBreakValues[i], areaStyle));
}
return classBreakStyle;
}
}
}
ClassBreakClusterPointStyle.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
[Serializable]
public class ClassBreakClusterPointStyle : Style
{
[Obfuscation(Exclude|= true)]
private Dictionary<int, PointStyle> classBreakPoint;
[Obfuscation(Exclude|= true)]
private int cellSize = 100;
[Obfuscation(Exclude|= true)]
private TextStyle textSytle = new TextStyle();
public ClassBreakClusterPointStyle()
: base()
{
classBreakPoint = new Dictionary<int, PointStyle>();
}
public Dictionary<int, PointStyle> ClassBreakPoint
{
get { return classBreakPoint; }
}
public TextStyle TextStyle
{
get { return textSytle; }
set { textSytle = value; }
}
public int CellSize
{
get { return cellSize; }
set { cellSize = value; }
}
protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
double scale = ExtentHelper.GetScale(canvas.CurrentWorldExtent, canvas.Width, canvas.MapUnit);
MapSuiteTileMatrix mapSuiteTileMatrix = new MapSuiteTileMatrix(scale, cellSize, cellSize, canvas.MapUnit);
IEnumerable<TileMatrixCell> tileMatricCells = mapSuiteTileMatrix.GetContainedCells(canvas.CurrentWorldExtent);
Dictionary<string, string> unusedFeatures = new Dictionary<string, string>();
foreach (Feature feature in features)
{
if (feature.GetWellKnownType() != WellKnownType.Point && feature.GetWellKnownType() != WellKnownType.Multipoint)
{
continue;
}
unusedFeatures.Add(feature.Id, feature.Id);
}
foreach (TileMatrixCell cell in tileMatricCells)
{
int featureCount = 0;
MultipointShape tempMultiPointShape = new MultipointShape();
foreach (Feature feature in features)
{
// Make sure the feature has not been used in another cluster
if (unusedFeatures.ContainsKey(feature.Id))
{
// Check if the cell contains the feature
if (cell.BoundingBox.Contains(feature.GetBoundingBox()))
{
featureCount++;
unusedFeatures.Remove(feature.Id);
if (feature.GetWellKnownType() == WellKnownType.Multipoint)
{
MultipointShape multipointShape = feature.GetShape() as MultipointShape;
foreach (var item in multipointShape.Points)
{
tempMultiPointShape.Points.Add(item);
}
}
else
{
tempMultiPointShape.Points.Add(feature.GetShape() as PointShape);
}
}
}
}
if (featureCount > 0)
{
// Add the feature count to the new feature we created. The feature will be placed
// at the center of gravity of all the clustered features of the cell we created.
Dictionary<string, string> featureValues = new Dictionary<string, string>();
featureValues.Add("FeatureCount", featureCount.ToString(CultureInfo.InvariantCulture));
bool isMatch = false;
for (int i = 0; i < classBreakPoint.Count - 1; i++)
{
var startItem = classBreakPoint.ElementAt(i);
var endItem = classBreakPoint.ElementAt(i + 1);
if (featureCount >= startItem.Key && featureCount < endItem.Key)
{
//Draw the point shape
startItem.Value.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers);
isMatch = true;
break;
}
}
if (!isMatch && featureCount >= classBreakPoint.LastOrDefault().Key)
{
classBreakPoint.LastOrDefault().Value.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers);
}
if (featureCount != 1)
{
// Draw the text style to show how many feaures are consolidated in the cluster
textSytle.Draw(new Feature[] { new Feature(tempMultiPointShape.GetCenterPoint(), featureValues) }, canvas, labelsInThisLayer, labelsInAllLayers);
}
}
}
}
}
}
ClusterPointStyleViewController.cs
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class ClusterPointStyleViewController : DetailViewController
{
public ClusterPointStyleViewController()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
MapView.Overlays.Add(worldOverlay);
ShapeFileFeatureLayer usEarthquakeLayer = new ShapeFileFeatureLayer("AppData/usEarthquake.shp");
usEarthquakeLayer.DrawingMarginPercentage = 100;
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetClusterPointStyle());
usEarthquakeLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(usEarthquakeLayer);
MapView.Overlays.Add(layerOverlay);
MapView.ZoomTo(new PointShape(-96.8150, 39.6948), MapView.ZoomLevelSet.ZoomLevel05.Scale);
}
private static ClassBreakClusterPointStyle GetClusterPointStyle()
{
ClassBreakClusterPointStyle clusterPointStyle = new ClassBreakClusterPointStyle();
clusterPointStyle.CellSize = 65;
PointStyle pointStyle1 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 222, 226, 153)), new GeoPen(GeoColor.FromArgb(100, 222, 226, 153), 5), 8);
PointStyle pointStyle2 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 222, 226, 153)), new GeoPen(GeoColor.FromArgb(100, 222, 226, 153), 8), 15);
PointStyle pointStyle3 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 255, 183, 76)), new GeoPen(GeoColor.FromArgb(100, 255, 183, 76), 10), 25);
PointStyle pointStyle4 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 243, 193, 26)), new GeoPen(GeoColor.FromArgb(100, 243, 193, 26), 15), 35);
PointStyle pointStyle5 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 245, 7, 10)), new GeoPen(GeoColor.FromArgb(100, 245, 7, 10), 15), 40);
PointStyle pointStyle6 = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(250, 245, 7, 10)), new GeoPen(GeoColor.FromArgb(100, 245, 7, 10), 20), 50);
clusterPointStyle.ClassBreakPoint.Add(1, pointStyle1);
clusterPointStyle.ClassBreakPoint.Add(2, pointStyle2);
clusterPointStyle.ClassBreakPoint.Add(50, pointStyle3);
clusterPointStyle.ClassBreakPoint.Add(150, pointStyle4);
clusterPointStyle.ClassBreakPoint.Add(350, pointStyle5);
clusterPointStyle.ClassBreakPoint.Add(500, pointStyle6);
clusterPointStyle.TextStyle = TextStyles.CreateSimpleTextStyle("FeatureCount", "Arail", 10, DrawingFontStyles.Regular, GeoColor.SimpleColors.Black);
clusterPointStyle.TextStyle.PointPlacement = PointPlacement.Center;
return clusterPointStyle;
}
}
}
CustomGeoImageLineStyle.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class CustomGeoImageLineStyle : LineStyle
{
private Collection<GeoImage> geoImages;
private int spacing;
private LineStyle lineStyle;
private SymbolSide side;
public CustomGeoImageLineStyle(LineStyle lineStyle, GeoImage geoImage, int spacing, SymbolSide side)
: this(lineStyle, new Collection<GeoImage> { geoImage }, spacing, side)
{ }
public CustomGeoImageLineStyle(LineStyle lineStyle, IEnumerable<GeoImage> geoImages, int spacing, SymbolSide side)
{
this.side = side;
this.spacing = spacing;
this.lineStyle = lineStyle;
this.geoImages = new Collection<GeoImage>();
foreach (var geoImage in geoImages)
{
this.geoImages.Add(geoImage);
}
}
protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
PointStyle[] pointStyles = geoImages.Select(geoImage => new PointStyle(geoImage) { DrawingLevel = DrawingLevel.LevelThree }).ToArray();
foreach (Feature feature in features)
{
LineShape lineShape = (LineShape)feature.GetShape();
lineStyle.Draw(new BaseShape[] { lineShape }, canvas, labelsInThisLayer, labelsInAllLayers);
int index = 0;
double totalDist = 0;
for (int i = 0; i < lineShape.Vertices.Count - 1; i++)
{
PointShape pointShape1 = new PointShape(lineShape.Vertices[i]);
PointShape pointShape2 = new PointShape(lineShape.Vertices[i|+ 1]);
LineShape tempLineShape = new LineShape();
tempLineShape.Vertices.Add(lineShape.Vertices[i]);
tempLineShape.Vertices.Add(lineShape.Vertices[i|+ 1]);
double angle = GetAngleFromTwoVertices(lineShape.Vertices[i], lineShape.Vertices[i|+ 1]);
//Left side
if (side == SymbolSide.Left)
{
if (angle >= 270) { angle = angle - 180; }
}
//Right side
else
{
if (angle <= 90) { angle = angle + 180; }
}
//pointStyle.RotationAngle = (float)angle;
foreach (var pointStyle in pointStyles) pointStyle.RotationAngle = (float)angle;
float screenDist = ExtentHelper.GetScreenDistanceBetweenTwoWorldPoints(canvas.CurrentWorldExtent, pointShape1,
pointShape2, canvas.Width, canvas.Height);
double currentDist = Math.Round(pointShape1.GetDistanceTo(pointShape2, canvas.MapUnit, DistanceUnit.Meter), 2);
double worldInterval = (currentDist * spacing) / screenDist;
while (totalDist <= currentDist)
{
PointStyle pointStyle = pointStyles[index|% pointStyles.Length];
PointShape tempPointShape = tempLineShape.GetPointOnALine(StartingPoint.FirstPoint, totalDist, canvas.MapUnit, DistanceUnit.Meter);
pointStyle.Draw(new BaseShape[] { tempPointShape }, canvas, labelsInThisLayer, labelsInAllLayers);
totalDist = totalDist + worldInterval;
index++;
}
totalDist = totalDist - currentDist;
}
}
}
private static double GetAngleFromTwoVertices(Vertex b, Vertex c)
{
double alpha = 0;
double tangentAlpha = (c.Y - b.Y) / (c.X - b.X);
double Peta = Math.Atan(tangentAlpha);
if (c.X > b.X)
{
alpha = 90 + (Peta * (180 / Math.PI));
}
else if (c.X < b.X)
{
alpha = 270 + (Peta * (180 / Math.PI));
}
else
{
if (c.Y > b.Y) alpha = 0;
if (c.Y < b.Y) alpha = 180;
}
double offset;
if (b.X > c.X)
{ offset = 90; }
else { offset = -90; }
return alpha + offset;
}
public enum SymbolSide
{
Right = 0,
Left = 1
}
}
}
CustomStyleViewContoller.cs
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class CustomStyleViewContoller : DetailViewController
{
public CustomStyleViewContoller()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.Meter;
MapView.CurrentExtent = new RectangleShape(-13886070, 6660597, -8906057, 3382985);
LineStyle lineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.FromArgb(255, 50, 0, 249), 4, false);
//Cold Front
CustomGeoImageLineStyle coldFrontLineStyle = GetCustomLineStyle(lineStyle, 19, "offset_circle_red_bl.png", "offset_triangle_blue_revert.png");
InMemoryFeatureLayer coldFrontLineLayer = new InMemoryFeatureLayer();
coldFrontLineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(coldFrontLineStyle);
coldFrontLineLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
coldFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/ColdFront2.txt")));
coldFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/ColdFront3.txt")));
//Warm Front
CustomGeoImageLineStyle warmFrontLineStyle = GetCustomLineStyle(lineStyle, 30, "offset_circle_blue.png");
InMemoryFeatureLayer warmFrontLineLayer = new InMemoryFeatureLayer();
warmFrontLineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(warmFrontLineStyle);
warmFrontLineLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
warmFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/WarmFront5.txt")));
warmFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/WarmFront6.txt")));
warmFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/WarmFront7.txt")));
warmFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/WarmFront8.txt")));
//Occluded Front
CustomGeoImageLineStyle occludedFrontLineStyle = GetCustomLineStyle(lineStyle, 45, "offset_triangle_and_circle_blue.png", "offset_triangle_and_circle_red.png");
InMemoryFeatureLayer occludedFrontLineLayer = new InMemoryFeatureLayer();
occludedFrontLineLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(occludedFrontLineStyle);
occludedFrontLineLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
occludedFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/OccludedFront9.txt")));
occludedFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/OccludedFront10.txt")));
occludedFrontLineLayer.InternalFeatures.Add(new Feature(File.ReadAllText(@"AppData/CustomStyles/OccludedFront11.txt")));
PressureValueStyle pressureValueStyle = new PressureValueStyle();
pressureValueStyle.ColumnName = "Pressure";
InMemoryFeatureLayer pressureFeatureLayer = new InMemoryFeatureLayer();
pressureFeatureLayer.Open();
pressureFeatureLayer.Columns.Add(new FeatureSourceColumn("Pressure"));
pressureFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(pressureValueStyle);
pressureFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
pressureFeatureLayer.InternalFeatures.Add(new Feature(MapView.CurrentExtent.GetCenterPoint()));
Random random = new Random();
string[] pressures = { "H", "L" };
for (int i = 0; i < 20; i++)
{
Feature pressurePoint = new Feature(random.Next(-13886070, -8906057), random.Next(3382985, 6660597));
pressurePoint.ColumnValues["Pressure"] = pressures[random.Next(0,|2)];
pressureFeatureLayer.InternalFeatures.Add(pressurePoint);
}
WindPointStyle windStyle1 = new WindPointStyle("TEXT", "LEVEL", "ANGLE", GeoColor.FromHtml("#0AF8F8"));
WindPointStyle windStyle2 = new WindPointStyle("TEXT", "LEVEL", "ANGLE", GeoColor.FromHtml("#0FF5B0"));
WindPointStyle windStyle3 = new WindPointStyle("TEXT", "LEVEL", "ANGLE", GeoColor.FromHtml("#F7F70D"));
WindPointStyle windStyle4 = new WindPointStyle("TEXT", "LEVEL", "ANGLE", GeoColor.FromHtml("#FBE306"));
ClassBreakStyle windClassBreakStyle = new ClassBreakStyle();
windClassBreakStyle.ColumnName = "TEXT";
windClassBreakStyle.ClassBreaks.Add(new ClassBreak(10, new Collection<Style> { windStyle1 }));
windClassBreakStyle.ClassBreaks.Add(new ClassBreak(20, new Collection<Style> { windStyle2 }));
windClassBreakStyle.ClassBreaks.Add(new ClassBreak(30, new Collection<Style> { windStyle3 }));
windClassBreakStyle.ClassBreaks.Add(new ClassBreak(40, new Collection<Style> { windStyle4 }));
InMemoryFeatureLayer windFeatureLayer = new InMemoryFeatureLayer();
windFeatureLayer.Open();
windFeatureLayer.Columns.Add(new FeatureSourceColumn("TEXT"));
windFeatureLayer.Columns.Add(new FeatureSourceColumn("ANGLE"));
windFeatureLayer.Columns.Add(new FeatureSourceColumn("LEVEL"));
windFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(windClassBreakStyle);
windFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
for (int i = 0; i < 20; i++)
{
Feature windFeature = new Feature(random.Next(-13886070, -8906057), random.Next(3382985, 6660597));
windFeature.ColumnValues["TEXT"] = random.Next(10, 40).ToString(CultureInfo.InvariantCulture);
windFeature.ColumnValues["ANGLE"] = random.Next(0, 360).ToString(CultureInfo.InvariantCulture);
windFeature.ColumnValues["LEVEL"] = random.Next(0, 5).ToString(CultureInfo.InvariantCulture);
windFeatureLayer.InternalFeatures.Add(windFeature);
}
// Base overlay.
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
worldOverlay.Projection = WorldMapKitProjection.SphericalMercator;
MapView.Overlays.Add(worldOverlay);
LayerOverlay dynamicOverlay = new LayerOverlay();
dynamicOverlay.Layers.Add(coldFrontLineLayer);
dynamicOverlay.Layers.Add(warmFrontLineLayer);
dynamicOverlay.Layers.Add(occludedFrontLineLayer);
dynamicOverlay.Layers.Add(pressureFeatureLayer);
dynamicOverlay.Layers.Add(windFeatureLayer);
MapView.Overlays.Add(dynamicOverlay);
MapView.Refresh();
}
private static CustomGeoImageLineStyle GetCustomLineStyle(LineStyle lineStyle, int space, params string[] imagePaths)
{
return new CustomGeoImageLineStyle(lineStyle, imagePaths.Select(p => new GeoImage(Path.Combine("AppData/CustomStyles", p))), space, CustomGeoImageLineStyle.SymbolSide.Right);
}
}
}
PressureValueStyle.cs
using System;
using System.Collections.Generic;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class PressureValueStyle : ValueStyle
{
public PressureValueStyle()
{
SquareTextPointStyle highPressurePointStyle = new SquareTextPointStyle();
highPressurePointStyle.Text = "H";
highPressurePointStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.FromArgb(255, 39, 39, 245));
SquareTextPointStyle lowPressurePointStyle = new SquareTextPointStyle();
lowPressurePointStyle.Text = "L";
lowPressurePointStyle.SymbolSolidBrush = new GeoSolidBrush(GeoColor.StandardColors.Red);
ValueItems.Add(new ValueItem("L", lowPressurePointStyle));
ValueItems.Add(new ValueItem("H", highPressurePointStyle));
}
public class SquareTextPointStyle : PointStyle
{
private string text;
private GeoFont font;
private GeoBrush textBrush;
public SquareTextPointStyle()
{
SymbolType = PointSymbolType.Square;
SymbolSize = 30;
PointType = PointType.Symbol;
font = new GeoFont("Verdana", 14);
textBrush = new GeoSolidBrush(GeoColor.StandardColors.White);
SymbolPen = new GeoPen(GeoColor.StandardColors.White, 1);
}
public string Text
{
get { return text; }
set { text = value; }
}
protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
{
base.DrawCore(features, canvas, labelsInThisLayer, labelsInAllLayers);
double resolution = Math.Max(canvas.CurrentWorldExtent.Width / canvas.Width, canvas.CurrentWorldExtent.Height / canvas.Height);
foreach (Feature feature in features)
{
PointShape pointShape = feature.GetShape() as PointShape;
if (pointShape != null)
{
float screenOffsetX = (float)((pointShape.X - canvas.CurrentWorldExtent.UpperLeftPoint.X) / resolution);
float screenOffsetY = (float)((canvas.CurrentWorldExtent.UpperLeftPoint.Y - pointShape.Y) / resolution);
canvas.DrawTextWithScreenCoordinate(Text, font, textBrush, screenOffsetX, screenOffsetY, DrawingLevel.LabelLevel);
}
}
}
}
}
}
WindPointStyle.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class WindPointStyle : Style
{
private string textColumn;
private string angleColumn;
private string windLevelColumn;
private GeoFont font;
private GeoBrush textBrush;
private GeoSolidBrush fillBrush;
private GeoSolidBrush blackBrush;
private float directionLineLength1;
private float directionLineLength2;
private GeoPen outlinePen;
private GeoPen innerlinePen;
public WindPointStyle()
: this(string.Empty, string.Empty, string.Empty, GeoColor.StandardColors.Orange)
{ }
public WindPointStyle(string textColumn, string levelColumn, string angleColumn, GeoColor fillColor)
{
this.directionLineLength1 = 40;
this.directionLineLength2 = 10;
this.blackBrush = new GeoSolidBrush(GeoColor.SimpleColors.Black);
this.font = new GeoFont("Verdana", 14);
this.textBrush = new GeoSolidBrush(GeoColor.StandardColors.Black);
this.fillBrush = new GeoSolidBrush(fillColor);
this.outlinePen = new GeoPen(GeoColor.StandardColors.Black, 4);
this.innerlinePen = new GeoPen(fillBrush, 2);
this.textColumn = textColumn;
this.windLevelColumn = levelColumn;
this.angleColumn = angleColumn;
}
protected override Collection<string> GetRequiredColumnNamesCore()
{
return new Collection<string> { textColumn, angleColumn, windLevelColumn };
}
protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
{
double resolution = Math.Max(canvas.CurrentWorldExtent.Width / canvas.Width, canvas.CurrentWorldExtent.Height / canvas.Height);
foreach (var feature in features)
{
PointShape pointShape = feature.GetShape() as PointShape;
if (pointShape != null)
{
float screenOffsetX = (float)((pointShape.X - canvas.CurrentWorldExtent.UpperLeftPoint.X) / resolution);
float screenOffsetY = (float)((canvas.CurrentWorldExtent.UpperLeftPoint.Y - pointShape.Y) / resolution);
string angle = feature.ColumnValues[angleColumn];
string level = feature.ColumnValues[windLevelColumn];
int windLevel = int.Parse(level);
ScreenPointF[] directionLine = null;
ScreenPointF[] levelLine1 = null;
ScreenPointF[] levelLine2 = null;
if (!string.IsNullOrEmpty(angle))
{
double radian1 = double.Parse(angle) * Math.PI / 180;
float x1 = (float)(directionLineLength1 * Math.Cos(radian1));
float y1 = (float)(directionLineLength1 * Math.Sin(radian1));
double radian2 = (double.Parse(angle) - 90) * Math.PI / 180;
float x2 = (float)(directionLineLength2 * Math.Cos(radian2));
float y2 = (float)(directionLineLength2 * Math.Sin(radian2));
float x3 = (float)((directionLineLength1 - 8) * Math.Cos(radian1));
float y3 = (float)((directionLineLength1 - 8) * Math.Sin(radian1));
float x4 = (float)(directionLineLength2 * Math.Cos(radian2));
float y4 = (float)(directionLineLength2 * Math.Sin(radian2));
if (windLevel >= 1)
{
directionLine = new ScreenPointF[2];
directionLine[0] = new ScreenPointF(screenOffsetX, screenOffsetY);
directionLine[1] = new ScreenPointF(screenOffsetX + x1, screenOffsetY + y1);
}
if (windLevel >= 2)
{
levelLine1 = new ScreenPointF[2];
levelLine1[0] = new ScreenPointF(screenOffsetX + x1, screenOffsetY + y1);
levelLine1[1] = new ScreenPointF(screenOffsetX + x1 + x2, screenOffsetY + y1 + y2);
}
if (windLevel >= 3)
{
levelLine2 = new ScreenPointF[2];
levelLine2[0] = new ScreenPointF(screenOffsetX + x3, screenOffsetY + y3);
levelLine2[1] = new ScreenPointF(screenOffsetX + x3 + x4, screenOffsetY + y3 + y4);
}
}
// draw back
canvas.DrawEllipse(feature, 26, 26, blackBrush, DrawingLevel.LevelOne);
if (directionLine != null) canvas.DrawLine(directionLine, outlinePen, DrawingLevel.LevelOne, 0, 0);
if (levelLine1 != null) canvas.DrawLine(levelLine1, outlinePen, DrawingLevel.LevelOne, 0, 0);
if (levelLine2 != null) canvas.DrawLine(levelLine2, outlinePen, DrawingLevel.LevelOne, 0, 0);
//draw fore
canvas.DrawEllipse(feature, 24, 24, fillBrush, DrawingLevel.LevelTwo);
if (directionLine != null) canvas.DrawLine(directionLine, innerlinePen, DrawingLevel.LevelTwo, 0, 0);
if (levelLine1 != null) canvas.DrawLine(levelLine1, innerlinePen, DrawingLevel.LevelTwo, 0, 0);
if (levelLine2 != null) canvas.DrawLine(levelLine2, innerlinePen, DrawingLevel.LevelTwo, 0, 0);
string text = feature.ColumnValues[textColumn];
if (!string.IsNullOrEmpty(text))
{
canvas.DrawTextWithScreenCoordinate(text, font, textBrush, screenOffsetX, screenOffsetY, DrawingLevel.LabelLevel);
}
}
}
}
}
}
FilterConditionDefaultValues.cs
using System;
using System.Collections.Generic;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class FilterConditionDefaultValues : Dictionary<SimpleFilterConditionType, Tuple<string, string>>
{
public FilterConditionDefaultValues()
{
Add(SimpleFilterConditionType.Equal, "STATE_NAME", "Texas");
Add(SimpleFilterConditionType.Contains, "STATE_NAME", "T");
Add(SimpleFilterConditionType.StartsWith, "STATE_NAME", "T");
Add(SimpleFilterConditionType.EndsWith, "STATE_NAME", "a");
Add(SimpleFilterConditionType.DoesNotEqual, "STATE_NAME", "Texas");
Add(SimpleFilterConditionType.DoesNotContain, "STATE_NAME", "Te");
Add(SimpleFilterConditionType.GreaterThan, "POP1990", "1100000");
Add(SimpleFilterConditionType.GreaterThanOrEqualTo, "POP1990", "1003464");
Add(SimpleFilterConditionType.LessThan, "POP1990", "1003464");
Add(SimpleFilterConditionType.LessThanOrEqualTo, "POP1990", "1003464");
Add(SimpleFilterConditionType.IsEmpty, "STATE_NAME", string.Empty);
Add(SimpleFilterConditionType.IsNotEmpty, "STATE_NAME", string.Empty);
}
private void Add(SimpleFilterConditionType conditionType, string columnName, string matchValue)
{
Add(conditionType, new Tuple<string, string>(columnName, matchValue));
}
}
}
FilterStyleConditionModel.cs
using UIKit;
using System;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class FilterStyleConditionModel : UIPickerViewModel
{
public Action<SimpleFilterConditionType> RowSelected;
public override nint GetComponentCount(UIPickerView picker)
{
return 1;
}
public override nint GetRowsInComponent(UIPickerView picker, nint component)
{
return Enum.GetValues(typeof(SimpleFilterConditionType)).Length;
}
public override UIView GetView(UIPickerView picker, nint row, nint component, UIView view)
{
UILabel lable = new UILabel();
lable.Text = ((SimpleFilterConditionType)(int)row).ToString();
lable.TextColor = UIColor.White;
if (iOSCapabilityHelper.IsOnIPhone) lable.Font = UIFont.FromName("Arial", 13);
return lable;
}
public override void Selected(UIPickerView picker, nint row, nint component)
{
if (RowSelected != null) RowSelected((SimpleFilterConditionType)(int)row);
}
}
}
FilterStyleViewController.cs
using CoreAnimation;
using CoreGraphics;
using System;
using System.Linq;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
using UIKit;
namespace AnalyzingVisualization
{
public class FilterStyleViewController : DetailViewController
{
private UIButton btnApply;
private UILabel lblColumn;
private UITextField inputText;
private InstructionView instructionView;
private FilterStyle filterStyle;
private SimpleFilterConditionType currentSimpleFilterConditionType;
private ShapeFileFeatureLayer statesLayer;
public FilterStyleViewController()
{
SettingContainerHeight = 120;
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
InitializeSettingView();
ApplyFilterStyle();
}
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.DecimalDegree;
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
MapView.Overlays.Add(worldOverlay);
statesLayer = new ShapeFileFeatureLayer("AppData/states.shp");
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(statesLayer);
MapView.Overlays.Add("LayerOverlay", layerOverlay);
GeoColor strokeColor = GeoColor.FromHtml("#333333");
GeoColor fillColor = GeoColor.FromArgb(130, GeoColor.FromHtml("#ffb74c"));
filterStyle = new FilterStyle();
filterStyle.Conditions.Add(new FilterCondition("Population", ">2967297"));
filterStyle.Styles.Add(AreaStyles.CreateSimpleAreaStyle(fillColor, strokeColor));
statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(filterStyle);
statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
MapView.ZoomTo(new PointShape(-96.8150, 39.6948), MapView.ZoomLevelSet.ZoomLevel05.Scale);
}
public override void ViewWillAppear(bool animated)
{
base.ViewWillAppear(animated);
CALayer attributionLayer = MapView.EventView.Layer.Sublayers.FirstOrDefault(l => l.Name.Equals("AttributionLayer"));
attributionLayer.Frame = new CGRect(0, -SettingContainerHeight, attributionLayer.Frame.Width, attributionLayer.Frame.Height);
}
private void InitializeSettingView()
{
SettingButton.Enabled = true;
instructionView = new InstructionView(RefreshInstructionView, InstructionExpandStateChanged);
SettingButtonClick = InstructionExpandStateChanged;
instructionView.TranslatesAutoresizingMaskIntoConstraints = false;
NSLayoutConstraint[] instructionConstraints =
{
NSLayoutConstraint.Create(instructionView, NSLayoutAttribute.Left, NSLayoutRelation.Equal, SettingContainerView, NSLayoutAttribute.Left, 1, 0),
NSLayoutConstraint.Create(instructionView, NSLayoutAttribute.Right, NSLayoutRelation.Equal, SettingContainerView, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(instructionView, NSLayoutAttribute.Top, NSLayoutRelation.Equal, SettingContainerView, NSLayoutAttribute.Top, 1, 0),
NSLayoutConstraint.Create(instructionView, NSLayoutAttribute.Bottom, NSLayoutRelation.Equal, SettingContainerView, NSLayoutAttribute.Bottom, 1, 0)
};
SettingContainerView.Add(instructionView);
SettingContainerView.AddConstraints(instructionConstraints);
View.BringSubviewToFront(SettingContainerView);
}
private void RefreshInstructionView(UIView contentView)
{
contentView.ClipsToBounds = true;
FilterConditionDefaultValues filterConditionDefaultValues = new FilterConditionDefaultValues();
lblColumn = new UILabel();
lblColumn.Text = filterConditionDefaultValues.FirstOrDefault().Value.Item1;
if (iOSCapabilityHelper.IsOnIPhone) lblColumn.Font = UIFont.FromName("Arial", 13);
lblColumn.TextColor = UIColor.White;
lblColumn.TranslatesAutoresizingMaskIntoConstraints = false;
inputText = new UITextField();
inputText.Text = filterConditionDefaultValues.FirstOrDefault().Value.Item2;
inputText.TextAlignment = UITextAlignment.Center;
inputText.TextColor = UIColor.White;
if (iOSCapabilityHelper.IsOnIPhone) inputText.Font = UIFont.FromName("Arial", 13);
inputText.TranslatesAutoresizingMaskIntoConstraints = false;
UIPickerView filterConditionTypePicker = new UIPickerView();
filterConditionTypePicker.Model = new FilterStyleConditionModel
{
RowSelected = s =>
{
currentSimpleFilterConditionType = s;
lblColumn.Text = filterConditionDefaultValues.SingleOrDefault(t => t.Key.Equals(s)).Value.Item1;
inputText.Text = filterConditionDefaultValues.SingleOrDefault(t => t.Key.Equals(s)).Value.Item2;
inputText.Hidden = s.ToString().Contains("Empty");
}
};
filterConditionTypePicker.ShowSelectionIndicator = true;
filterConditionTypePicker.TranslatesAutoresizingMaskIntoConstraints = false;
btnApply = new UIButton(UIButtonType.RoundedRect);
btnApply.BackgroundColor = UIColor.DarkGray;
btnApply.TintColor = UIColor.White;
btnApply.SetTitle("Apply", UIControlState.Normal);
btnApply.TouchUpInside += (sender, args) => ApplyFilterStyle();
if (iOSCapabilityHelper.IsOnIPhone) btnApply.Font = UIFont.FromName("Arial", 13);
btnApply.TranslatesAutoresizingMaskIntoConstraints = false;
int columnWidth = 120;
int filterConditionTypePickerWidth = 180;
int btnApplyLeft = 80;
int btnApplyTop = 10;
if (iOSCapabilityHelper.IsOnIPhone)
{
columnWidth = 95;
filterConditionTypePickerWidth = 137;
btnApplyLeft = 10;
btnApplyTop = 40;
}
NSLayoutConstraint[] settingViewConstraints =
{
NSLayoutConstraint.Create(lblColumn, NSLayoutAttribute.Left, NSLayoutRelation.Equal, contentView, NSLayoutAttribute.Left, 1, 0),
NSLayoutConstraint.Create(lblColumn, NSLayoutAttribute.Top, NSLayoutRelation.Equal, contentView, NSLayoutAttribute.Top, 1, 10),
NSLayoutConstraint.Create(lblColumn, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, columnWidth),
NSLayoutConstraint.Create(lblColumn, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 30),
NSLayoutConstraint.Create(filterConditionTypePicker, NSLayoutAttribute.Left, NSLayoutRelation.Equal, lblColumn, NSLayoutAttribute.Right, 1, 0),
NSLayoutConstraint.Create(filterConditionTypePicker, NSLayoutAttribute.Top, NSLayoutRelation.Equal, contentView, NSLayoutAttribute.Top, 1, 10),
NSLayoutConstraint.Create(filterConditionTypePicker, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, filterConditionTypePickerWidth),
NSLayoutConstraint.Create(filterConditionTypePicker, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 30),
NSLayoutConstraint.Create(inputText, NSLayoutAttribute.Left, NSLayoutRelation.Equal, filterConditionTypePicker, NSLayoutAttribute.Right, 1, 1),
NSLayoutConstraint.Create(inputText, NSLayoutAttribute.Top, NSLayoutRelation.Equal, contentView, NSLayoutAttribute.Top, 1, 10),
NSLayoutConstraint.Create(inputText, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 70),
NSLayoutConstraint.Create(inputText, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 30),
NSLayoutConstraint.Create(btnApply, NSLayoutAttribute.Left, NSLayoutRelation.Equal, filterConditionTypePicker, NSLayoutAttribute.Right, 1,btnApplyLeft),
NSLayoutConstraint.Create(btnApply, NSLayoutAttribute.Top, NSLayoutRelation.Equal, contentView, NSLayoutAttribute.Top, 1, btnApplyTop),
NSLayoutConstraint.Create(btnApply, NSLayoutAttribute.Width, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 50),
NSLayoutConstraint.Create(btnApply, NSLayoutAttribute.Height, NSLayoutRelation.Equal, null, NSLayoutAttribute.NoAttribute, 1, 30)
};
contentView.Add(lblColumn);
contentView.Add(filterConditionTypePicker);
contentView.Add(inputText);
contentView.Add(btnApply);
contentView.AddConstraints(settingViewConstraints);
}
private void InstructionExpandStateChanged()
{
float y = SettingContainerHeight;
CALayer attributionLayer = MapView.EventView.Layer.Sublayers.FirstOrDefault(l => l.Name.Equals("AttributionLayer"));
if (SettingContainerView.Hidden)
{
SettingContainerView.AnimatedShow(AnimateType.Up);
}
else
{
SettingContainerView.AnimatedHide(AnimateType.Down);
y = 0;
}
attributionLayer.Frame = new CGRect(0, -y, attributionLayer.Frame.Width, attributionLayer.Frame.Height);
}
private void ApplyFilterStyle()
{
filterStyle.Conditions.Clear();
SimpleFilterCondition newCondition = new SimpleFilterCondition(lblColumn.Text, currentSimpleFilterConditionType, inputText.Text);
filterStyle.Conditions.Add(newCondition);
MapView.Overlays["LayerOverlay"].Refresh();
}
}
}
EarthquakeIsoLineFeatureLayer.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using ThinkGeo.MapSuite.Core;
namespace AnalyzingVisualization
{
public class EarthquakeIsoLineFeatureLayer : FeatureLayer
{
private DynamicIsoLineLayer isoLineLayer;
private ClassBreakStyle levelClassBreakStyle;
public EarthquakeIsoLineFeatureLayer()
: this(null)
{ }
public EarthquakeIsoLineFeatureLayer(FeatureSource featureSource)
{
FeatureSource = featureSource;
}
public new FeatureSource FeatureSource
{
get { return base.FeatureSource; }
set
{
base.FeatureSource = value;
Initialize();
}
}
public Collection<double> IsoLineLevels
{
get { return isoLineLayer.IsoLineLevels; }
}
protected override void DrawCore(GeoCanvas canvas, Collection<SimpleCandidate> labelsInAllLayers)
{
isoLineLayer.Draw(canvas, labelsInAllLayers);
}
private void Initialize()
{
Collection<GeoColor> levelAreaColors = new Collection<GeoColor>();
levelAreaColors.Add(GeoColor.FromHtml("#FFFFBE"));
levelAreaColors.Add(GeoColor.FromHtml("#FDFF9E"));
levelAreaColors.Add(GeoColor.FromHtml("#FDFF37"));
levelAreaColors.Add(GeoColor.FromHtml("#FDDA04"));
levelAreaColors.Add(GeoColor.FromHtml("#FFA701"));
levelAreaColors.Add(GeoColor.FromHtml("#FF6F02"));
levelAreaColors.Add(GeoColor.FromHtml("#EC0000"));
levelAreaColors.Add(GeoColor.FromHtml("#B90000"));
levelAreaColors.Add(GeoColor.FromHtml("#850100"));
levelAreaColors.Add(GeoColor.FromHtml("#620001"));
levelAreaColors.Add(GeoColor.FromHtml("#450005"));
levelAreaColors.Add(GeoColor.FromHtml("#2B0804"));
FeatureSource.Open();
Dictionary<PointShape, double> dataPoints = GetDataPoints();
GridInterpolationModel interpolationModel = new InverseDistanceWeightedGridInterpolationModel(3, double.MaxValue);
isoLineLayer = new DynamicIsoLineLayer(dataPoints, GetClassBreakValues(dataPoints.Values, 12), interpolationModel, IsoLineType.ClosedLinesAsPolygons);
isoLineLayer.CellWidthInPixel = 32;
isoLineLayer.CellHeightInPixel = 32;
levelClassBreakStyle = new ClassBreakStyle(isoLineLayer.DataValueColumnName);
levelClassBreakStyle.ClassBreaks.Add(new ClassBreak(double.MinValue, new AreaStyle(new GeoPen(GeoColor.FromHtml("#FE6B06"), 1), new GeoSolidBrush(new GeoColor(100, levelAreaColors[0])))));
for (int i = 0; i < IsoLineLevels.Count - 1; i++)
{
if (!levelClassBreakStyle.ClassBreaks.Any(c => c.Value == IsoLineLevels[i|+ 1]))
{
levelClassBreakStyle.ClassBreaks.Add(new ClassBreak(IsoLineLevels[i|+ 1],
new AreaStyle(new GeoPen(GeoColor.FromHtml("#FE6B06"), 1),
new GeoSolidBrush(new GeoColor(100, levelAreaColors[i|+ 1])))));
}
}
isoLineLayer.CustomStyles.Add(levelClassBreakStyle);
TextStyle textStyle = TextStyles.CreateSimpleTextStyle(isoLineLayer.DataValueColumnName, "Arial", 8, DrawingFontStyles.Bold, GeoColor.StandardColors.Black, 0, 0);
textStyle.HaloPen = new GeoPen(GeoColor.StandardColors.White, 2);
textStyle.OverlappingRule = LabelOverlappingRule.NoOverlapping;
textStyle.SplineType = SplineType.StandardSplining;
textStyle.DuplicateRule = LabelDuplicateRule.UnlimitedDuplicateLabels;
textStyle.TextLineSegmentRatio = 9999999;
textStyle.FittingLineInScreen = true;
textStyle.SuppressPartialLabels = true;
textStyle.NumericFormat = "{0:0.00}";
isoLineLayer.CustomStyles.Add(textStyle);
}
private Dictionary<PointShape, double> GetDataPoints()
{
return (from feature in FeatureSource.GetAllFeatures(GetReturningColumns())
where double.Parse(feature.ColumnValues["MAGNITUDE"]) > 0
select new PointShape
{
X = double.Parse(feature.ColumnValues["LONGITUDE"], CultureInfo.InvariantCulture),
Y = double.Parse(feature.ColumnValues["LATITIUDE"], CultureInfo.InvariantCulture),
Z = double.Parse(feature.ColumnValues["MAGNITUDE"], CultureInfo.InvariantCulture)
}).ToDictionary(point => point, point => point.Z);
}
private static IEnumerable<double> GetClassBreakValues(IEnumerable<double> values, int count)
{
Collection<double> result = new Collection<double>();
double[] sortedValues = values.OrderBy(v => v).ToArray();
int classCount = sortedValues.Length / count;
for (int i = 1; i < count; i++)
{
result.Add(sortedValues[i|* classCount]);
}
return result;
}
private static IEnumerable<string> GetReturningColumns()
{
//LONGITUDE
yield return "LONGITUDE";
//LATITIUDE
yield return "LATITIUDE";
//MAGNITUDE
yield return "MAGNITUDE";
}
}
}
IsolineStyleViewContoller.cs
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.iOSEdition;
namespace AnalyzingVisualization
{
public class IsolineStyleViewContoller : DetailViewController
{
public IsolineStyleViewContoller()
{ }
protected override void InitializeMap()
{
MapView.MapUnit = GeographyUnit.Meter;
MapView.CurrentExtent = new RectangleShape(-15116491.8671313, 8720801.79162702, -11021545.2583953, 2603975.29482756);
WorldMapKitOverlay worldOverlay = new WorldMapKitOverlay();
worldOverlay.Projection = WorldMapKitProjection.SphericalMercator;
MapView.Overlays.Add(worldOverlay);
ShapeFileFeatureSource usEarthquakeIsoSource = new ShapeFileFeatureSource("AppData/usEarthquake_Simplified.shp");
EarthquakeIsoLineFeatureLayer usEarthquakeIsoLayer = new EarthquakeIsoLineFeatureLayer(usEarthquakeIsoSource);
LayerOverlay layerOverlay = new LayerOverlay();
layerOverlay.Layers.Add(usEarthquakeIsoLayer);
layerOverlay.TileHeight = 512;
layerOverlay.TileWidth = 512;
MapView.Overlays.Add(layerOverlay);
MapView.Refresh();
}
}
}
AssemblyInfo.cs
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly:|AssemblyTitle("AnalyzingVisualization")]
[assembly: AssemblyDescription("")]
[assembly:|AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly:|AssemblyProduct("AnalyzingVisualization")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly:|AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly:|ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly:|Guid("84efb68d-6dbd-4d6e-a2e8-f4ef414d8ee0")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly:|AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("9.0.0.0")]
[assembly:|AssemblyFileVersion("9.0.0.0")]
AnimateType.cs
namespace AnalyzingVisualization
{
public enum AnimateType
{
Up,
Down
}
}
ExtensionHelper.cs
using CoreGraphics;
using System;
using UIKit;
namespace AnalyzingVisualization
{
static class ExtensionHelper
{
public static void AnimatedShow(this UIView view, AnimateType animateType)
{
CGRect targetFrame = view.Frame;
nfloat y = animateType == AnimateType.Up
? targetFrame.Y + targetFrame.Height
: targetFrame.Y - targetFrame.Height;
view.Frame = new CGRect(new CGPoint(targetFrame.X, y), targetFrame.Size);
UIView.Animate(0.2, () =>
{
view.Hidden = false;
view.Frame = targetFrame;
});
}
public static void AnimatedHide(this UIView view, AnimateType animateType)
{
CGRect oldFrame = view.Frame;
nfloat y = animateType == AnimateType.Up ? oldFrame.Y - oldFrame.Height : oldFrame.Y + oldFrame.Height;
CGRect targetFrame = new CGRect(new CGPoint(view.Frame.X, y), view.Frame.Size);
UIView.Animate(0.2, () =>
{
view.Frame = targetFrame;
}, () =>
{
view.Hidden = true;
view.Frame = oldFrame;
});
}
}
}
iOSCapabilityHelper.cs
using UIKit;
namespace AnalyzingVisualization
{
internal static class iOSCapabilityHelper
{
public static bool IsOnIPhone
{
get { return UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone; }
}
}
}