//Determine whether or not to filter the input time series per the input criteria - private List<TimeSeriesViewModel> filterTimeSeries(List<TimeSeriesViewModel> series, clientFilterAndSearchCriteria filterAndSearchCriteria) { //Validate/initialize input parameters... if (null == series || 0 >= series.Count || filterAndSearchCriteria.isEmpty()) { //Null or empty time series list and/or criteria - return early return series; } //Prior to applying the criteria - copy the input time series List<TimeSeriesViewModel> listFiltered = null; //Initialize the LINQ predicate... System.Linq.Expressions.Expression<Func<TimeSeriesViewModel, bool>> predicate; //Apply search string (case-insensitive), if indicated... //NOTE: The search string main contain space-delimited sub strings (e.g., 'SNOTEL 784' ) string search = filterAndSearchCriteria.search; if (! String.IsNullOrWhiteSpace(search)) { //Initialize the LINQ predicate... //NOTE: Initializing the predicate to always return false and then adding ORs // will select only those timeseries with values matching the search criteria predicate = LinqPredicateBuilder.Create<TimeSeriesViewModel>(item => false); //Scan datasources... StringComparer comparer = StringComparer.CurrentCultureIgnoreCase; foreach ( var datasource in filterAndSearchCriteria.dataSources) { if (! datasource.searchable) { continue; //NOT searchable - continue } //Searchable... add value to predicate... if (null != datasource.dataSource) { //Value in TimeSeriesViewModel property... var source = datasource.dataSource; //Add TimeSeriesViewModel property to LINQ predicate //NOTE: MUST specify a case-insensitive contains... // Use null coalescing operator (??) to avoid null reference errors... // source: http://stackoverflow.com/questions/16490509/how-to-assign-empty-string-if-the-value-is-null-in-linq-query predicate = predicate.Or(item => (item.GetType().GetProperty(source).GetValue(item, null) ?? String.Empty).ToString().Contains(search, StringComparison.CurrentCultureIgnoreCase, new SearchStringComparer())); } else if (null != datasource.title) { //Lookup value from title... // Use null coalescing operator (??) to avoid null reference errors... // source: http://stackoverflow.com/questions/16490509/how-to-assign-empty-string-if-the-value-is-null-in-linq-query predicate = predicate.Or(item => (LookupValueFromTitle(datasource, item) ?? String.Empty).ToString().Contains(search, StringComparison.CurrentCultureIgnoreCase, new SearchStringComparer())); } } //Apply search criteria to current timeseries var queryable = series.AsQueryable(); try { listFiltered = queryable.Where(predicate).ToList(); } catch (Exception ex) { string msg = ex.Message; //Error in filtering - set filtered list to unfiltered list... listFiltered = series; } } //Apply filters (case-insensitive), if indicated... List<clientFilter> filters = filterAndSearchCriteria.filters; if (0 < filters.Count) { //Initialize the LINQ predicate... //NOTE: Initializing the predicate to always return true and then adding ANDs // will select only those timeseries with values matching the filter(s) predicate = LinqPredicateBuilder.Create<TimeSeriesViewModel>(item => true); //Set the queryable collection - listFiltered (if search criteria already applied, otherwise series) var queryable = (null != listFiltered) ? listFiltered.AsQueryable() : series.AsQueryable(); foreach (var filter in filters) { var source = filter.dataSource; var value = filter.value; //Add TimeSeriesViewModel property to LINQ predicate //NOTE: MUST specify a case-insensitive equals... predicate = predicate.And(item => item.GetType().GetProperty(source).GetValue(item, null).ToString().Equals(value, StringComparison.CurrentCultureIgnoreCase)); } //Apply search criteria to current timeseries listFiltered = queryable.Where(predicate).ToList(); } //Processing complete - return return listFiltered; }
public List<ClusteredPin> transformSeriesDataCartIntoClusteredPin(List<TimeSeriesViewModel> series, clientFilterAndSearchCriteria filterAndSearchCriteria) { List<ClusteredPin> clusterPins = new List<ClusteredPin>(); bool bUseFilter = ! (null == filterAndSearchCriteria || filterAndSearchCriteria.isEmpty()); if ( bUseFilter) { //Retrieve COPIES of all time series which match filter criteria... series = filterTimeSeries(series, filterAndSearchCriteria); } for (int i = 0; i < series.Count; i++) { var cl = new ClusteredPin(); cl.Loc = new LatLong(series[i].Latitude, series[i].Longitude); cl.assessmentids.Add(series[i].SeriesId); cl.PinType = "point"; //Retain the service code, title and highest value count for later reference... string key = series[i].ServCode; string title = series[i].ServTitle; cl.ServiceCodeToTitle[key] = title; clusterPins.Add(cl); } return clusterPins; }