示例#1
0
        public override BoundingBox GetExtents()
        {
            BoundingBox box = null;

            using (var conn = new SQLiteConnection(ConnectionString))
            {
                string strSQL =
                    "SELECT Min(minx) AS MinX, Min(miny) AS MinY, Max(maxx) AS MaxX, Max(maxy) AS MaxY FROM " + Table;
                if (!String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL += " WHERE " + DefinitionQuery;
                }
                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    conn.Open();
                    using (SQLiteDataReader dr = command.ExecuteReader())
                        if (dr.Read())
                        {
                            box = new BoundingBox((double)dr[0], (double)dr[2], (double)dr[1], (double)dr[3]);
                        }
                    conn.Close();
                }
                return(box);
            }
        }
示例#2
0
        public override Collection <uint> GetObjectIDsInView(BoundingBox bbox)
        {
            var objectlist = new Collection <uint>();

            using (var conn = new SQLiteConnection(ConnectionID))
            {
                var strSQL = "SELECT " + ObjectIdColumn + " ";
                strSQL += "FROM " + Table + " WHERE ";

                strSQL += GetBoxClause(bbox);

                if (!String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL += " AND " + DefinitionQuery + " AND ";
                }

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    conn.Open();
                    using (var dr = command.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            if (dr[0] != DBNull.Value)
                            {
                                var id = (uint)(int)dr[0];
                                objectlist.Add(id);
                            }
                        }
                    }
                    conn.Close();
                }
            }
            return(objectlist);
        }
示例#3
0
        public override void ExecuteIntersectionQuery(BoundingBox box, FeatureDataSet ds)
        {
            using (var conn = new SQLiteConnection(ConnectionID))
            {
                string strSQL = "SELECT *, " + GeometryColumn + " AS sharpmap_tempgeometry ";
                strSQL += "FROM " + Table + " WHERE ";
                strSQL += GetBoxClause(box);

                if (!String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL += " AND " + DefinitionQuery;
                }

                using (SQLiteDataAdapter adapter = new SQLiteDataAdapter(strSQL, conn))
                {
                    conn.Open();
                    DataSet ds2 = new DataSet();
                    adapter.Fill(ds2);
                    conn.Close();
                    if (ds2.Tables.Count > 0)
                    {
                        FeatureDataTable fdt = new FeatureDataTable(ds2.Tables[0]);
                        foreach (DataColumn col in ds2.Tables[0].Columns)
                        {
                            if (col.ColumnName != GeometryColumn && col.ColumnName != "sharpmap_tempgeometry" &&
                                !col.ColumnName.StartsWith("Envelope_"))
                            {
                                fdt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
                            }
                        }
                        foreach (DataRow dr in ds2.Tables[0].Rows)
                        {
                            FeatureDataRow fdr = fdt.NewRow();
                            foreach (DataColumn col in ds2.Tables[0].Columns)
                            {
                                if (col.ColumnName != GeometryColumn && col.ColumnName != "sharpmap_tempgeometry" &&
                                    !col.ColumnName.StartsWith("Envelope_"))
                                {
                                    fdr[col.ColumnName] = dr[col];
                                }
                            }
                            if (dr["sharpmap_tempgeometry"] != DBNull.Value)
                            {
                                fdr.Geometry = GeometryFromWKT.Parse((string)dr["sharpmap_tempgeometry"]);
                            }
                            fdt.AddRow(fdr);
                        }
                        ds.Tables.Add(fdt);
                    }
                }
            }
        }
示例#4
0
        public override Collection <Geometry> GetGeometriesInView(BoundingBox bbox)
        {
            var features = new Collection <Geometry>();

            using (var conn = new SQLiteConnection(ConnectionID))
            {
                var boxIntersect = GetBoxClause(bbox);

                var strSQL = "SELECT " + GeometryColumn + " AS Geom ";
                strSQL += "FROM " + Table + " WHERE ";
                strSQL += boxIntersect;
                if (!String.IsNullOrEmpty(_definitionQuery))
                {
                    strSQL += " AND " + DefinitionQuery;
                }

                using (var command = new SQLiteCommand(strSQL, conn))
                {
                    conn.Open();
                    using (var dr = command.ExecuteReader())
                    {
                        while (dr.Read())
                        {
                            if (dr[0] != DBNull.Value)
                            {
                                var geom = GeometryFromWKT.Parse((string)dr[0]);
                                if (geom != null)
                                {
                                    features.Add(geom);
                                }
                            }
                        }
                    }
                    conn.Close();
                }
            }
            return(features);
        }
示例#5
0
        /// <summary>
        /// Get the value from the dictionary for the specified 'key' and return it as an Envelope.
        /// </summary>
        /// <param name="dict"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static NetTopologySuite.Geometries.Envelope GetEnvelopNullValue(this IDictionary <string, Microsoft.Extensions.Primitives.StringValues> dict, string key, NetTopologySuite.Geometries.Envelope defaultValue = null)
        {
            if (!dict.TryGetValue(key, out Microsoft.Extensions.Primitives.StringValues value))
            {
                return(defaultValue);
            }

            var values = value.ToString().Split(',');

            return(NetTopologySuite.Geometries.Envelope.Parse($"Env[{values[0]}:{values[1]},{values[2]}:{values[3]}]"));
        }
示例#6
0
 private static string GetBoxClause(BoundingBox bbox)
 {
     return(String.Format(Map.NumberFormatEnUs,
                          "(minx < {0} AND maxx > {1} AND miny < {2} AND maxy > {3})",
                          bbox.MaxX, bbox.MinX, bbox.MaxY, bbox.MinY));
 }
        private void filterGeoPosition(String fileName, double minX, double maxX, double minY, double maxY)
        {
            var jsonDoc     = "";
            var batch       = new List <string>();
            var boundingBox = new NetTopologySuite.Geometries.Envelope(minX, maxX, minY, maxY);
            var feature     = new NetTopologySuite.Features.Feature();

            using (FileStream s = File.Open(fileName, FileMode.Open))
                using (var streamReader = new StreamReader(s))
                {
                    var file      = Path.GetFileNameWithoutExtension(fileName).Split(".");
                    var topicname = file[1];

                    using (var jsonreader = new Newtonsoft.Json.JsonTextReader(streamReader))
                    {
                        while (jsonreader.Read())
                        {
                            var reader = new NetTopologySuite.IO.GeoJsonReader();
                            if (jsonreader.TokenType == Newtonsoft.Json.JsonToken.StartObject)
                            {
                                while (jsonreader.Read())
                                {
                                    if (jsonreader.TokenType == Newtonsoft.Json.JsonToken.StartArray)
                                    {
                                        while (jsonreader.Read())
                                        {
                                            try
                                            {
                                                if (jsonreader != null)
                                                {
                                                    feature = reader.Read <NetTopologySuite.Features.Feature>(jsonreader);
                                                }

                                                var geo = feature.Geometry;
                                                var atr = feature.Attributes;
                                                if (boundingBox.Intersects(geo.EnvelopeInternal))
                                                {
                                                    jsonDoc = createGeoObject(atr, geo);
                                                    batch.Add(jsonDoc);
                                                    if (batch.Count >= 5000)
                                                    {
                                                        _producer.Produce(topicname, batch);
                                                        _logger.LogInformation("Wrote " + batch.Count + " objects into " + topicname);
                                                        batch.Clear();
                                                    }
                                                }
                                            }
                                            //Loop gives reader exception when it reaches the last element from the file
                                            catch (Newtonsoft.Json.JsonReaderException e)
                                            {
                                                _logger.LogError("Error writing data: {0}.", e.GetType().Name);
                                                var geo = feature.Geometry;
                                                var atr = feature.Attributes;

                                                jsonDoc = createGeoObject(atr, geo);
                                                batch.Add(jsonDoc);
                                                _producer.Produce(topicname, batch);
                                                _logger.LogInformation("Wrote " + batch.Count + " objects into " + topicname);
                                                batch.Clear();
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (batch != null)
                            {
                                _producer.Produce(topicname, batch);
                                _logger.LogInformation("Wrote " + batch.Count + " objects into " + topicname);
                                batch.Clear();
                            }
                        }
                    }
                }
        }
示例#8
0
        /// <summary>
        /// Get an array of parcels within the specified filter.
        /// Will not return sensitive parcels unless the user has the `sensitive-view` claim and belongs to the owning agency.
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        public Paged <Parcel> Get(ParcelFilter filter)
        {
            filter.ThrowIfNull(nameof(filter));
            this.User.ThrowIfNotAuthorized(Permissions.SystemAdmin, Permissions.AgencyAdmin);

            if (filter.Page < 1)
            {
                throw new ArgumentException("Argument must be greater than or equal to 1.", nameof(filter.Page));
            }
            if (filter.Quantity < 1)
            {
                throw new ArgumentException("Argument must be greater than or equal to 1.", nameof(filter.Quantity));
            }

            // Check if user has the ability to view sensitive properties.
            var userAgencies  = this.User.GetAgenciesAsNullable();
            var viewSensitive = this.User.HasPermission(Security.Permissions.SensitiveView);

            // Users may only view sensitive properties if they have the `sensitive-view` claim and belong to the owning agency.
            var query = this.Context.Parcels.AsNoTracking();

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                var poly = new NetTopologySuite.Geometries.Envelope(filter.NELongitude.Value, filter.SWLongitude.Value, filter.NELatitude.Value, filter.SWLatitude.Value).ToPolygon();
                query = query.Where(p => poly.Contains(p.Location));
            }

            if (filter.Agencies?.Any() == true)
            {
                var filterAgencies = filter.Agencies.Select(a => (int?)a);
                query = query.Where(p => filterAgencies.Contains(p.AgencyId));
            }
            if (filter.ClassificationId.HasValue)
            {
                query = query.Where(p => p.ClassificationId == filter.ClassificationId);
            }
            if (!String.IsNullOrWhiteSpace(filter.ProjectNumber))
            {
                query = query.Where(p => EF.Functions.Like(p.ProjectNumber, $"{filter.ProjectNumber}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Description))
            {
                query = query.Where(p => EF.Functions.Like(p.Description, $"%{filter.Description}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.AdministrativeArea))
            {
                query = query.Where(p => EF.Functions.Like(p.Address.AdministrativeArea, $"%{filter.AdministrativeArea}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Zoning))
            {
                query = query.Where(p => EF.Functions.Like(p.Zoning, $"%{filter.Zoning}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.ZoningPotential))
            {
                query = query.Where(p => EF.Functions.Like(p.ZoningPotential, $"%{filter.ZoningPotential}%"));
            }

            // TODO: Parse the address information by City, Postal, etc.
            if (!String.IsNullOrWhiteSpace(filter.Address))
            {
                query = query.Where(p => EF.Functions.Like(p.Address.Address1, $"%{filter.Address}%") || EF.Functions.Like(p.Address.AdministrativeArea, $"%{filter.Address}%"));
            }

            if (filter.MinLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea >= filter.MinLandArea);
            }
            if (filter.MaxLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea <= filter.MaxLandArea);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinMarketValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinMarketValue <= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Market)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }
            if (filter.MaxMarketValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxMarketValue >= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Market)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinAssessedValue <= p.Evaluations
                                    .FirstOrDefault(e => e.Date == this.Context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }
            if (filter.MaxAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxAssessedValue >= p.Evaluations
                                    .FirstOrDefault(e => e.Date == this.Context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }

            if (filter.Sort?.Any() == true)
            {
                query = query.OrderByProperty(filter.Sort);
            }

            var pagedEntities = query.Skip((filter.Page - 1) * filter.Quantity).Take(filter.Quantity);

            return(new Paged <Parcel>(pagedEntities, filter.Page, filter.Quantity, query.Count()));
        }
示例#9
0
        /// <summary>
        /// Generate an SQL statement for the specified 'user' and 'filter'.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="query"></param>
        /// <param name="user"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        private static IQueryable <Entity.Views.Property> GenerateCommonQuery(this PimsContext context, IQueryable <Entity.Views.Property> query, ClaimsPrincipal user, Entity.Models.AllPropertyFilter filter)
        {
            filter.ThrowIfNull(nameof(filter));
            filter.ThrowIfNull(nameof(user));

            // Check if user has the ability to view sensitive properties.
            var userAgencies  = user.GetAgenciesAsNullable();
            var viewSensitive = user.HasPermission(Permissions.SensitiveView);
            var isAdmin       = user.HasPermission(Permissions.AdminProperties);

            // By default do not include the following property classifications.
            if (filter.ClassificationId.HasValue)
            {
                query = query.Where(p => p.ClassificationId == filter.ClassificationId);
            }
            else
            {
                query = query.Where(p => p.ClassificationId != (int)Entities.ClassificationTypes.Disposed &&
                                    p.ClassificationId != (int)Entities.ClassificationTypes.Demolished &&
                                    p.ClassificationId != (int)Entities.ClassificationTypes.Subdivided);
            }

            // Users are not allowed to view sensitive properties outside of their agency or sub-agencies.
            if (!viewSensitive)
            {
                query = query.Where(p => !p.IsSensitive);
            }

            // Display buildings or land/subdivisions
            if (filter.PropertyType == Entities.PropertyTypes.Building)
            {
                query = query.Where(p => p.PropertyTypeId == Entities.PropertyTypes.Building);
            }
            else if (filter.PropertyType == Entities.PropertyTypes.Land)
            {
                query = query.Where(p => p.PropertyTypeId == Entities.PropertyTypes.Land || p.PropertyTypeId == Entities.PropertyTypes.Subdivision);
            }

            // Where rentable area is less than or equal to the filter.
            if (filter.RentableArea.HasValue)
            {
                query = query.Where(p => p.RentableArea <= filter.RentableArea);
            }

            if (filter.BareLandOnly == true)
            {
                query = from p in query
                        join pa in context.Parcels on new { p.Id, PropertyTypeId = (int)p.PropertyTypeId } equals new { pa.Id, PropertyTypeId = (int)pa.PropertyTypeId }
                where p.PropertyTypeId == Entity.PropertyTypes.Land &&
                pa.Buildings.Count() == 0
                select p;
            }

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                var poly = new NetTopologySuite.Geometries.Envelope(filter.NELongitude.Value, filter.SWLongitude.Value, filter.NELatitude.Value, filter.SWLatitude.Value).ToPolygon();
                query = query.Where(p => poly.Contains(p.Location));
            }

            if (filter.Agencies?.Any() == true)
            {
                IEnumerable <int?> filterAgencies;
                if (!isAdmin)
                {
                    // Users can only search their own agencies.
                    filterAgencies = filter.Agencies.Intersect(userAgencies.Select(a => (int)a)).Select(a => (int?)a);
                }
                else
                {
                    // TODO: Ideally this list would be provided by the frontend, as it is expensive to do it here.
                    // Get list of sub-agencies for any agency selected in the filter.
                    filterAgencies = filter.Agencies.Select(a => (int?)a);
                }
                if (filterAgencies.Any())
                {
                    var agencies = filterAgencies.Concat(context.Agencies.AsNoTracking().Where(a => filterAgencies.Contains(a.Id)).SelectMany(a => a.Children.Select(ac => (int?)ac.Id)).ToArray()).Distinct();
                    query = query.Where(p => agencies.Contains(p.AgencyId));
                }
            }
            if (filter.ParcelId.HasValue)
            {
                query = query.Where(p => p.ParcelId == filter.ParcelId);
            }
            if (!String.IsNullOrWhiteSpace(filter.ProjectNumber))
            {
                query = query.Where(p => p.ProjectNumbers.Contains(filter.ProjectNumber));
            }
            if (filter.IgnorePropertiesInProjects == true)
            {
                query = query.Where(p => p.ProjectNumbers == null || p.ProjectNumbers == "[]");
            }
            if (filter.InSurplusPropertyProgram == true)
            {
                query = query.Where(p => !String.IsNullOrWhiteSpace(p.ProjectNumbers) && p.ProjectNumbers != "[]");
            }
            if (!String.IsNullOrWhiteSpace(filter.Description))
            {
                query = query.Where(p => EF.Functions.Like(p.Description, $"%{filter.Description}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Name))
            {
                query = query.Where(p => EF.Functions.Like(p.Name, $"%{filter.Name}%"));
            }

            if (!String.IsNullOrWhiteSpace(filter.PID))
            {
                var pidValue = filter.PID.Replace("-", "").Trim();
                if (Int32.TryParse(pidValue, out int pid))
                {
                    query = query.Where(p => p.PID == pid || p.PIN == pid);
                }
            }
            if (!String.IsNullOrWhiteSpace(filter.AdministrativeArea))
            {
                query = query.Where(p => EF.Functions.Like(p.AdministrativeArea, $"%{filter.AdministrativeArea}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Zoning))
            {
                query = query.Where(p => EF.Functions.Like(p.Zoning, $"%{filter.Zoning}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.ZoningPotential))
            {
                query = query.Where(p => EF.Functions.Like(p.ZoningPotential, $"%{filter.ZoningPotential}%"));
            }

            if (filter.ConstructionTypeId.HasValue)
            {
                query = query.Where(p => p.BuildingConstructionTypeId == filter.ConstructionTypeId);
            }
            if (filter.PredominateUseId.HasValue)
            {
                query = query.Where(p => p.BuildingPredominateUseId == filter.PredominateUseId);
            }
            if (filter.FloorCount.HasValue)
            {
                query = query.Where(p => p.BuildingFloorCount == filter.FloorCount);
            }
            if (!String.IsNullOrWhiteSpace(filter.Tenancy))
            {
                query = query.Where(p => EF.Functions.Like(p.BuildingTenancy, $"%{filter.Tenancy}%"));
            }

            if (!String.IsNullOrWhiteSpace(filter.Address))
            {
                query = query.Where(p => EF.Functions.Like(p.Address, $"%{filter.Address}%") || EF.Functions.Like(p.AdministrativeArea, $"%{filter.Address}%"));
            }

            if (filter.MinLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea >= filter.MinLandArea);
            }
            if (filter.MaxLandArea.HasValue)
            {
                query = query.Where(b => b.LandArea <= filter.MaxLandArea);
            }

            if (filter.MinRentableArea.HasValue)
            {
                query = query.Where(p => p.RentableArea >= filter.MinRentableArea);
            }
            if (filter.MaxRentableArea.HasValue)
            {
                query = query.Where(b => b.RentableArea <= filter.MaxRentableArea);
            }

            if (filter.MinMarketValue.HasValue)
            {
                query = query.Where(p => p.Market >= filter.MinMarketValue);
            }
            if (filter.MaxMarketValue.HasValue)
            {
                query = query.Where(p => p.Market <= filter.MaxMarketValue);
            }

            if (filter.MinAssessedValue.HasValue)
            {
                query = query.Where(p => p.AssessedLand >= filter.MinAssessedValue || p.AssessedBuilding >= filter.MinAssessedValue);
            }
            if (filter.MaxAssessedValue.HasValue)
            {
                query = query.Where(p => p.AssessedLand <= filter.MaxAssessedValue || p.AssessedBuilding <= filter.MaxAssessedValue);
            }

            if (filter.Sort?.Any() == true)
            {
                query = query.OrderByProperty(filter.Sort);
            }
            else
            {
                query = query.OrderBy(p => p.AgencyCode).ThenBy(p => p.PID).ThenBy(p => p.PIN).ThenBy(p => p.PropertyTypeId);
            }

            return(query);
        }
示例#10
0
        /// <summary>
        /// Generate a query for the specified 'filter'.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static IQueryable <Entity.Parcel> GenerateQuery(this PimsContext context, ClaimsPrincipal user, Entity.Models.ParcelFilter filter)
        {
            filter.ThrowIfNull(nameof(user));
            filter.ThrowIfNull(nameof(filter));

            // Check if user has the ability to view sensitive properties.
            var userAgencies  = user.GetAgenciesAsNullable();
            var viewSensitive = user.HasPermission(Permissions.SensitiveView);
            var isAdmin       = user.HasPermission(Permissions.AdminProperties);

            // Users may only view sensitive properties if they have the `sensitive-view` claim and belong to the owning agency.
            var query = context.Parcels.AsNoTracking();

            if (!isAdmin)
            {
                query = query.Where(p =>
                                    p.IsVisibleToOtherAgencies ||
                                    ((!p.IsSensitive || viewSensitive) &&
                                     userAgencies.Contains(p.AgencyId)));
            }

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                var poly = new NetTopologySuite.Geometries.Envelope(filter.NELongitude.Value, filter.SWLongitude.Value, filter.NELatitude.Value, filter.SWLatitude.Value).ToPolygon();
                query = query.Where(p => poly.Contains(p.Location));
            }

            if (filter.Agencies?.Any() == true)
            {
                // Get list of sub-agencies for any agency selected in the filter.
                var filterAgencies = filter.Agencies.Select(a => (int?)a);
                var agencies       = filterAgencies.Concat(context.Agencies.AsNoTracking().Where(a => filterAgencies.Contains(a.Id)).SelectMany(a => a.Children.Select(ac => (int?)ac.Id)).ToArray()).Distinct();
                query = query.Where(p => agencies.Contains(p.AgencyId));
            }
            if (filter.ClassificationId.HasValue)
            {
                query = query.Where(p => p.ClassificationId == filter.ClassificationId);
            }
            if (!String.IsNullOrWhiteSpace(filter.ProjectNumber))
            {
                query = query.Where(p => EF.Functions.Like(p.ProjectNumber, $"{filter.ProjectNumber}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Description))
            {
                query = query.Where(p => EF.Functions.Like(p.Description, $"%{filter.Description}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.AdministrativeArea))
            {
                query = query.Where(p => EF.Functions.Like(p.Address.AdministrativeArea, $"%{filter.AdministrativeArea}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Zoning))
            {
                query = query.Where(p => EF.Functions.Like(p.Zoning, $"%{filter.Zoning}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.ZoningPotential))
            {
                query = query.Where(p => EF.Functions.Like(p.ZoningPotential, $"%{filter.ZoningPotential}%"));
            }

            // TODO: Parse the address information by City, Postal, etc.
            if (!String.IsNullOrWhiteSpace(filter.Address))
            {
                query = query.Where(p => EF.Functions.Like(p.Address.Address1, $"%{filter.Address}%") || EF.Functions.Like(p.Address.AdministrativeArea, $"%{filter.Address}%"));
            }

            if (filter.MinLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea >= filter.MinLandArea);
            }
            if (filter.MaxLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea <= filter.MaxLandArea);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinMarketValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinMarketValue <= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.FiscalKeys.Market)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }
            if (filter.MaxMarketValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxMarketValue >= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.FiscalKeys.Market)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }

            // TODO: Review performance of the evaluation query component.
            if (filter.MinAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinAssessedValue <= p.Evaluations
                                    .FirstOrDefault(e => e.Date == context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }
            if (filter.MaxAssessedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxAssessedValue >= p.Evaluations
                                    .FirstOrDefault(e => e.Date == context.ParcelEvaluations
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.EvaluationKeys.Assessed)
                                                    .Max(pe => pe.Date))
                                    .Value);
            }

            if (filter.Sort?.Any() == true)
            {
                query = query.OrderByProperty(filter.Sort);
            }
            else
            {
                query = query.OrderBy(p => p.Id);
            }

            return(query);
        }
示例#11
0
        /// <summary>
        /// Generate a query for the specified 'filter'.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="user"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static IQueryable <Entity.Views.Property> GenerateQuery(this PimsContext context, ClaimsPrincipal user, Entity.Models.AllPropertyFilter filter)
        {
            filter.ThrowIfNull(nameof(filter));
            filter.ThrowIfNull(nameof(user));

            // Check if user has the ability to view sensitive properties.
            var userAgencies  = user.GetAgenciesAsNullable();
            var viewSensitive = user.HasPermission(Permissions.SensitiveView);
            var isAdmin       = user.HasPermission(Permissions.AdminProperties);

            // Users may only view sensitive properties if they have the `sensitive-view` claim and belong to the owning agency.
            var query = context.Properties
                        .AsNoTracking()
                        .Where(p => p.ClassificationId != 4); // Disposed properties are not visible.

            // Only allowed to see user's own agency properties.
            if (!isAdmin)
            {
                query = query.Where(p => p.IsVisibleToOtherAgencies || userAgencies.Contains(p.AgencyId));
            }
            if (!viewSensitive)
            {
                query = query.Where(p => !p.IsSensitive);
            }

            if (filter.PropertyType.HasValue)
            {
                query = query.Where(p => p.PropertyTypeId == filter.PropertyType.Value);
            }

            if (filter.RentableArea.HasValue)
            {
                query = query.Where(p => p.RentableArea == filter.RentableArea);
            }

            if (filter.BareLandOnly == true)
            {
                query = (from p in query
                         join pb in context.ParcelBuildings
                         on p.Id equals pb.ParcelId into ppbGroup
                         from pb in ppbGroup.DefaultIfEmpty()
                         where pb == null && p.PropertyTypeId == Entity.PropertyTypes.Land
                         select p);
            }

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                var poly = new NetTopologySuite.Geometries.Envelope(filter.NELongitude.Value, filter.SWLongitude.Value, filter.NELatitude.Value, filter.SWLatitude.Value).ToPolygon();
                query = query.Where(p => poly.Contains(p.Location));
            }

            if (filter.Agencies?.Any() == true)
            {
                // Get list of sub-agencies for any agency selected in the filter.
                var filterAgencies = filter.Agencies.Select(a => (int?)a);
                var agencies       = filterAgencies.Concat(context.Agencies.AsNoTracking().Where(a => filterAgencies.Contains(a.Id)).SelectMany(a => a.Children.Select(ac => (int?)ac.Id)).ToArray()).Distinct();
                query = query.Where(p => agencies.Contains(p.AgencyId));
            }
            if (filter.ParcelId.HasValue)
            {
                query = query.Where(p => p.ParcelId == filter.ParcelId);
            }
            if (filter.ClassificationId.HasValue)
            {
                query = query.Where(p => p.ClassificationId == filter.ClassificationId);
            }
            if (!String.IsNullOrWhiteSpace(filter.ProjectNumber))
            {
                query = query.Where(p => EF.Functions.Like(p.ProjectNumber, $"{filter.ProjectNumber}%"));
            }
            if (filter.IgnorePropertiesInProjects == true)
            {
                query = query.Where(p => p.ProjectNumber == null);
            }
            if (filter.InSurplusPropertyProgram == true)
            {
                query = query.Where(p => !String.IsNullOrWhiteSpace(p.ProjectNumber));
            }
            if (!String.IsNullOrWhiteSpace(filter.Description))
            {
                query = query.Where(p => EF.Functions.Like(p.Description, $"%{filter.Description}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Name))
            {
                query = query.Where(p => EF.Functions.Like(p.Name, $"%{filter.Name}%"));
            }

            if (!String.IsNullOrWhiteSpace(filter.PID))
            {
                var pidValue = filter.PID.Replace("-", "").Trim();
                if (Int32.TryParse(pidValue, out int pid))
                {
                    query = query.Where(p => p.PID == pid || p.PIN == pid);
                }
            }
            if (!String.IsNullOrWhiteSpace(filter.AdministrativeArea))
            {
                query = query.Where(p => EF.Functions.Like(p.AdministrativeArea, $"%{filter.AdministrativeArea}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.Zoning))
            {
                query = query.Where(p => EF.Functions.Like(p.Zoning, $"%{filter.Zoning}%"));
            }
            if (!String.IsNullOrWhiteSpace(filter.ZoningPotential))
            {
                query = query.Where(p => EF.Functions.Like(p.ZoningPotential, $"%{filter.ZoningPotential}%"));
            }

            if (filter.ConstructionTypeId.HasValue)
            {
                query = query.Where(p => p.BuildingConstructionTypeId == filter.ConstructionTypeId);
            }
            if (filter.PredominateUseId.HasValue)
            {
                query = query.Where(p => p.BuildingPredominateUseId == filter.PredominateUseId);
            }
            if (filter.FloorCount.HasValue)
            {
                query = query.Where(p => p.BuildingFloorCount == filter.FloorCount);
            }
            if (!String.IsNullOrWhiteSpace(filter.Tenancy))
            {
                query = query.Where(p => EF.Functions.Like(p.BuildingTenancy, $"%{filter.Tenancy}%"));
            }

            if (!String.IsNullOrWhiteSpace(filter.Address))
            {
                query = query.Where(p => EF.Functions.Like(p.Address, $"%{filter.Address}%") || EF.Functions.Like(p.AdministrativeArea, $"%{filter.Address}%"));
            }

            if (filter.MinLandArea.HasValue)
            {
                query = query.Where(p => p.LandArea >= filter.MinLandArea);
            }
            if (filter.MaxLandArea.HasValue)
            {
                query = query.Where(b => b.LandArea <= filter.MaxLandArea);
            }

            if (filter.MinRentableArea.HasValue)
            {
                query = query.Where(p => p.RentableArea >= filter.MinRentableArea);
            }
            if (filter.MaxRentableArea.HasValue)
            {
                query = query.Where(b => b.RentableArea <= filter.MaxRentableArea);
            }

            if (filter.MinMarketValue.HasValue)
            {
                query = query.Where(p => p.Market >= filter.MinMarketValue);
            }
            if (filter.MaxMarketValue.HasValue)
            {
                query = query.Where(p => p.Market <= filter.MaxMarketValue);
            }

            if (filter.MinAssessedValue.HasValue)
            {
                query = query.Where(p => p.Assessed >= filter.MinAssessedValue);
            }
            if (filter.MaxAssessedValue.HasValue)
            {
                query = query.Where(p => p.Assessed <= filter.MaxAssessedValue);
            }

            if (filter.InEnhancedReferralProcess.HasValue && filter.InEnhancedReferralProcess.Value)
            {
                var statuses = context.Workflows.Where(w => w.Code == "ERP")
                               .SelectMany(w => w.Status).Where(x => !x.Status.IsTerminal)
                               .Select(x => x.StatusId).Distinct().ToArray();

                query = query.Where(property =>
                                    context.Projects.Any(project =>
                                                         statuses.Any(st => st == project.StatusId) &&
                                                         project.ProjectNumber == property.ProjectNumber));
            }

            if (filter.Sort?.Any() == true)
            {
                query = query.OrderByProperty(filter.Sort);
            }
            else
            {
                query = query.OrderBy(p => p.AgencyCode).ThenBy(p => p.PID).ThenBy(p => p.PIN).ThenBy(p => p.PropertyTypeId);
            }


            return(query);
        }