/// <summary> /// Filters a sequence of <see cref="IGeoCode"/> items based on a specified <see cref="GeoCodeRange"/>. /// Useful for database queries for better performance. /// </summary> public static IQueryable <T> WhereInGeoCodeRange <T>( this IQueryable <T> query, GeoCodeRange geoCodeRange) where T : IGeoCode { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (geoCodeRange == null) { throw new ArgumentNullException(nameof(geoCodeRange)); } // The logic for bounding coordinates is different depending on whether geoCodeRange includes the 180th meridian. Expression <Func <IGeoCode, bool> > geoCodeRangePredicate = geoCodeRange.IncludesMeridian180() ? (Expression <Func <IGeoCode, bool> >)(x => (x.LatitudeGeoCode >= geoCodeRange.MinimumLatitude && x.LatitudeGeoCode <= geoCodeRange.MaximumLatitude) && (x.LongitudeGeoCode >= geoCodeRange.MinimumLongitude || x.LongitudeGeoCode <= geoCodeRange.MaximumLongitude) ) : x => (x.LatitudeGeoCode >= geoCodeRange.MinimumLatitude && x.LatitudeGeoCode <= geoCodeRange.MaximumLatitude) && (x.LongitudeGeoCode >= geoCodeRange.MinimumLongitude && x.LongitudeGeoCode <= geoCodeRange.MaximumLongitude); return(((IQueryable <IGeoCode>)query) .Where(geoCodeRangePredicate) .Cast <T>()); }
/// <summary> /// Returns true if the <see cref="GeoCodeRange"/> spans the 180th meridian. /// </summary> public static bool IncludesMeridian180(this GeoCodeRange geoCodeRange) { if (geoCodeRange == null) { throw new ArgumentNullException(nameof(geoCodeRange)); } return(geoCodeRange.MinimumLongitude > geoCodeRange.MaximumLongitude); }