Skip to content

Commit

Permalink
Merge pull request #554 from Esri/ncastle/ah-datepicker
Browse files Browse the repository at this point in the history
Update Analyze Hotspots to use a date picker control
  • Loading branch information
nCastle1 authored Oct 17, 2018
2 parents a82383d + 32d2d9c commit f6f3bee
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
</Grid.RowDefinitions>
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Label Margin="10,0,0,0">Start Date:</Label>
<Entry Text="1/01/98" x:Name="StartDate"/>
<Label Margin="10,0,0,0" HorizontalOptions="Start">Start Date:</Label>
<DatePicker Date="1/01/98" x:Name="StartDate" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Margin="10,0,0,0">EndDate:</Label>
<Entry Text="1/31/98" x:Name="EndDate"/>
<Label Margin="10,0,0,0" HorizontalOptions="Start">EndDate:</Label>
<DatePicker Date="1/31/98" x:Name="EndDate" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<Button Text="Run Analysis" Clicked="OnRunAnalysisClicked"/>
</StackLayout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,8 @@ private async void OnRunAnalysisClicked(object sender, EventArgs e)
MyActivityIndicator.IsVisible = true;
MyActivityIndicator.IsRunning = true;

// Get the 'from' and 'to' dates from the date pickers for the geoprocessing analysis
DateTime myFromDate;
DateTime myToDate;
try
{
myFromDate = Convert.ToDateTime(StartDate.Text);
myToDate = Convert.ToDateTime(EndDate.Text);
} catch (Exception)
{
// Handle badly formatted dates
await ((Page)Parent).DisplayAlert("Invalid date", "Please enter a valid date", "OK");

// Remove the busy activity indication
MyActivityIndicator.IsRunning = false;
MyActivityIndicator.IsVisible = false;
return;
}

// The end date must be at least one day after the start date
if (myToDate <= myFromDate.AddDays(1))
if (EndDate.Date <= StartDate.Date.AddDays(1))
{
// Show error message
await ((Page)Parent).DisplayAlert("Invalid date range", "Please select valid time range. There has to be at least one day in between To and From dates.", "OK");
Expand All @@ -99,7 +81,7 @@ private async void OnRunAnalysisClicked(object sender, EventArgs e)
GeoprocessingParameters myHotspotParameters = new GeoprocessingParameters(GeoprocessingExecutionType.AsynchronousSubmit);

// Construct the date query
string myQueryString = $"(\"DATE\" > date '{myFromDate:yyyy-MM-dd} 00:00:00' AND \"DATE\" < date '{myToDate:yyyy-MM-dd} 00:00:00')";
string myQueryString = $"(\"DATE\" > date '{StartDate.Date:yyyy-MM-dd} 00:00:00' AND \"DATE\" < date '{EndDate.Date:yyyy-MM-dd} 00:00:00')";

// Add the query that contains the date range used in the analysis
myHotspotParameters.Inputs.Add("Query", new GeoprocessingString(myQueryString));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@
<Compile Include="Samples\Symbology\SimpleRenderers\SimpleRenderers.cs" />
<Compile Include="Samples\Symbology\UseDistanceCompositeSym\UseDistanceCompositeSym.cs" />
<Compile Include="Samples\Data\ReadShapefileMetadata\MetadataDisplayViewController.cs" />
<Compile Include="Samples\Geoprocessing\AnalyzeHotspots\DateSelectionViewController.cs" />
<Compile Include="Samples\Security\IntegratedWindowsAuth\IntegratedWindowsAuth.cs" />
</ItemGroup>
<!-- Miscellaneous Configuration -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,20 @@
namespace ArcGISRuntime.Samples.AnalyzeHotspots
{
[Register("AnalyzeHotspots")]
[ArcGISRuntime.Samples.Shared.Attributes.ClassFile("DateSelectionViewController")]
[ArcGISRuntime.Samples.Shared.Attributes.Sample(
"Analyze hotspots",
"Geoprocessing",
"This sample demonstrates how to execute the GeoprocessingTask asynchronously to calculate a hotspot analysis based on the frequency of 911 calls. It calculates the frequency of these calls within a given study area during a specified constrained time period set between 1/1/1998 and 5/31/1998.",
"To run the hotspot analysis, select a data range and click on the 'Run analysis' button. Note the larger the date range, the longer it may take for the task to run and send back the results.")]
public class AnalyzeHotspots : UIViewController
{
// Create and hold references to the UI controls.
private readonly MapView _myMapView = new MapView();
private readonly UIToolbar _toolbar = new UIToolbar();
private UILabel _startDateLabel;
private UITextField _startDateTextField;
private UILabel _endDateLabel;
private UITextField _endDateTextField;
private UIButton _runAnalysisButton;
// Hold references to the UI controls.
private MapView _myMapView;
private UIToolbar _toolbar;
private UIBarButtonItem _configureButton;
private UIBarButtonItem _startButton;
private DateSelectionViewController _selectionView;
private UIActivityIndicatorView _progressBar;

// URL for the geoprocessing service.
Expand All @@ -55,39 +54,9 @@ public override void ViewDidLoad()
{
base.ViewDidLoad();

CreateLayout();
Initialize();
}

public override void ViewDidLayoutSubviews()
{
try
{
nfloat topMargin = NavigationController.NavigationBar.Frame.Height + UIApplication.SharedApplication.StatusBarFrame.Height;
nfloat margin = 5;
nfloat controlHeight = 30;
nfloat columnSplit = 100;
nfloat topStart = topMargin;

// Reposition the controls.
_myMapView.Frame = new CGRect(0, 0, View.Bounds.Width, View.Bounds.Height);
_toolbar.Frame = new CGRect(0, topStart, View.Bounds.Width, controlHeight * 3 + margin * 4);
_startDateLabel.Frame = new CGRect(margin, topStart + margin, columnSplit - 2 * margin, controlHeight);
_startDateTextField.Frame = new CGRect(columnSplit + margin, topStart + margin, View.Bounds.Width - columnSplit - 2 * margin, controlHeight);
_endDateLabel.Frame = new CGRect(margin, topStart + controlHeight + 2 * margin, columnSplit - 2 * margin, controlHeight);
_endDateTextField.Frame = new CGRect(columnSplit + margin, topStart + controlHeight + 2 * margin, View.Bounds.Width - columnSplit - 2 * margin, controlHeight);
_runAnalysisButton.Frame = new CGRect(margin, topStart + 2 * controlHeight + 3 * margin, View.Bounds.Width - 2 * margin, controlHeight);
_myMapView.ViewInsets = new UIEdgeInsets(topMargin + _toolbar.Frame.Height, 0, 0, 0);
_progressBar.Frame = new CGRect(0, topMargin, View.Bounds.Width, View.Bounds.Height - topMargin);

base.ViewDidLayoutSubviews();
}
// Needed to prevent crash when NavigationController is null. This happens sometimes when switching between samples.
catch (NullReferenceException)
{
}
}

private async void Initialize()
{
// Create and show a map with a topographic basemap.
Expand All @@ -106,25 +75,8 @@ private async void OnRunAnalysisClicked(object sender, EventArgs e)
_progressBar.StartAnimating();

// Get the 'from' and 'to' dates from the date pickers for the geoprocessing analysis.
DateTime fromDate;
DateTime toDate;
try
{
fromDate = Convert.ToDateTime(_startDateTextField.Text);
toDate = Convert.ToDateTime(_endDateTextField.Text);
}
catch (Exception)
{
// Handle badly formatted dates.
UIAlertController alert = UIAlertController.Create("Invalid date", "Please enter a valid date", UIAlertControllerStyle.Alert);
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, null));
PresentViewController(alert, true, null);

// Stop the progress bar from animating (which also hides it as well).
_progressBar.StopAnimating();

return;
}
DateTime fromDate = (DateTime)_selectionView.StartPicker.Date;
DateTime toDate = (DateTime)_selectionView.EndPicker.Date;

// The end date must be at least one day after the start date.
if (toDate <= fromDate.AddDays(1))
Expand Down Expand Up @@ -196,73 +148,53 @@ private async void OnRunAnalysisClicked(object sender, EventArgs e)
}
}

private void CreateLayout()
private void ShowConfiguration(object sender, EventArgs e)
{
// Create label for the start date.
_startDateLabel = new UILabel
{
Text = "Start date:",
AdjustsFontSizeToFitWidth = true,
TextAlignment = UITextAlignment.Right
};

// Create text field for the initial start date "1/1/98" for the analysis.
_startDateTextField = new UITextField
{
Text = "1/01/98",
AdjustsFontSizeToFitWidth = true,
BackgroundColor = UIColor.FromWhiteAlpha(1, .8f),
BorderStyle = UITextBorderStyle.RoundedRect
};

// Allow pressing 'return' to dismiss the keyboard.
_startDateTextField.ShouldReturn += textField =>
{
textField.ResignFirstResponder();
return true;
};
NavigationController.PushViewController(_selectionView, true);
}

// Create label for the end date.
_endDateLabel = new UILabel
{
Text = "End date:",
AdjustsFontSizeToFitWidth = true,
TextAlignment = UITextAlignment.Right
};
public override void LoadView()
{
View = new UIView();
View.BackgroundColor = UIColor.White;

// Create text field for the initial end date "1/31/98" for the analysis.
_endDateTextField = new UITextField
{
Text = "1/31/98",
AdjustsFontSizeToFitWidth = true,
BackgroundColor = UIColor.FromWhiteAlpha(1, .8f),
BorderStyle = UITextBorderStyle.RoundedRect
};
_selectionView = new DateSelectionViewController();

// Allow pressing 'return' to dismiss the keyboard.
_endDateTextField.ShouldReturn += textField =>
{
textField.ResignFirstResponder();
return true;
};
_myMapView = new MapView();
_myMapView.TranslatesAutoresizingMaskIntoConstraints = false;
View.AddSubview(_myMapView);

// Create button to invoke the geoprocessing request.
_runAnalysisButton = new UIButton();
_runAnalysisButton.SetTitle("Run analysis", UIControlState.Normal);
_runAnalysisButton.SetTitleColor(View.TintColor, UIControlState.Normal);
_configureButton = new UIBarButtonItem("Configure", UIBarButtonItemStyle.Plain, ShowConfiguration);
_startButton = new UIBarButtonItem("Run analysis", UIBarButtonItemStyle.Plain, OnRunAnalysisClicked);
UIBarButtonItem spacer = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);

// Hook to touch event to do geoprocessing request.
_runAnalysisButton.TouchUpInside += OnRunAnalysisClicked;
_toolbar = new UIToolbar();
_toolbar.TranslatesAutoresizingMaskIntoConstraints = false;
_toolbar.Items = new[] { _configureButton, spacer, _startButton };
View.AddSubview(_toolbar);

// Hide the activity indicator (progress bar) when stopped.
_progressBar = new UIActivityIndicatorView
{
BackgroundColor = UIColor.FromWhiteAlpha(0, .5f),
HidesWhenStopped = true
HidesWhenStopped = true,
TranslatesAutoresizingMaskIntoConstraints = false
};
View.AddSubview(_progressBar);

_myMapView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor).Active = true;
_myMapView.BottomAnchor.ConstraintEqualTo(_toolbar.TopAnchor).Active = true;
_myMapView.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor).Active = true;
_myMapView.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor).Active = true;

_toolbar.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor).Active = true;
_toolbar.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor).Active = true;
_toolbar.BottomAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.BottomAnchor).Active = true;

// Add all of the UI controls to the page.
View.AddSubviews(_myMapView, _toolbar, _startDateLabel, _startDateTextField, _endDateLabel, _endDateTextField, _runAnalysisButton, _progressBar);
_progressBar.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor).Active = true;
_progressBar.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor).Active = true;
_progressBar.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor).Active = true;
_progressBar.BottomAnchor.ConstraintEqualTo(View.BottomAnchor).Active = true;
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2018 Esri.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
// You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
// language governing permissions and limitations under the License.

using System;
using Foundation;
using UIKit;

namespace ArcGISRuntime.Samples.AnalyzeHotspots
{
public class DateSelectionViewController : UIViewController
{
public UIDatePicker StartPicker;
public UIDatePicker EndPicker;

public DateSelectionViewController()
{
Title = "Select a date range";
StartPicker = new UIDatePicker();
StartPicker.SetDate((NSDate)new DateTime(1998, 1, 1, 0, 0, 0, DateTimeKind.Local), false);
EndPicker = new UIDatePicker();
EndPicker.SetDate((NSDate)new DateTime(1998, 1, 31, 0, 0, 0, DateTimeKind.Local), false);
}

public override void LoadView()
{
View = new UIView();
View.BackgroundColor = UIColor.White;

UIStackView stackView = new UIStackView();
stackView.Axis = UILayoutConstraintAxis.Vertical;
stackView.TranslatesAutoresizingMaskIntoConstraints = false;
stackView.Spacing = 8;
View.AddSubview(stackView);

stackView.LeadingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.LeadingAnchor, 8).Active = true;
stackView.TrailingAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TrailingAnchor, -8).Active = true;
stackView.TopAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.TopAnchor, 8).Active = true;
stackView.BottomAnchor.ConstraintEqualTo(View.SafeAreaLayoutGuide.BottomAnchor, -8).Active = true;

UILabel startLabel = new UILabel();
startLabel.TranslatesAutoresizingMaskIntoConstraints = false;
startLabel.Text = "Start date:";
stackView.AddArrangedSubview(startLabel);

StartPicker.TranslatesAutoresizingMaskIntoConstraints = false;
StartPicker.Mode = UIDatePickerMode.Date;
stackView.AddArrangedSubview(StartPicker);

UILabel endLabel = new UILabel();
endLabel.TranslatesAutoresizingMaskIntoConstraints = false;
endLabel.Text = "End date:";
stackView.AddArrangedSubview(endLabel);

EndPicker.TranslatesAutoresizingMaskIntoConstraints = false;
EndPicker.Mode = UIDatePickerMode.Date;
stackView.AddArrangedSubview(EndPicker);

// Spacing.
stackView.AddArrangedSubview(new UIView());
}
}
}

0 comments on commit f6f3bee

Please sign in to comment.