Пример #1
0
        } // End Function CalculateArea

        public static double CalculateArea2(Wgs84Coordinates[] mycoordinates)
        {
            double[] pointsArray = mycoordinates.ToDoubleArray();
            var      z           = new double[mycoordinates.Length];

            // public static double[] ToDoubleArray(this Wgs84Coordinates[] mycoordinates)


            // source projection is WGS1984
            var projFrom = DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984;
            // most complicated problem - you have to find most suitable projection
            var projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.UtmWgs1984.WGS1984UTMZone37N;

            projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.Europe.EuropeAlbersEqualAreaConic;
            projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.WorldSpheroid.CylindricalEqualAreasphere;
            projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.CylindricalEqualAreaworld;


            DotSpatial.Projections.Reproject.ReprojectPoints(pointsArray, z, projFrom, projTo, 0, pointsArray.Length / 2);

            // assemblying new points array to create polygon
            var points = new System.Collections.Generic.List <GeoAPI.Geometries.Coordinate>(pointsArray.Length / 2);

            for (int i = 0; i < pointsArray.Length / 2; i++)
            {
                points.Add(new GeoAPI.Geometries.Coordinate(pointsArray[i * 2], pointsArray[i * 2 + 1]));
            }

            NetTopologySuite.Geometries.LinearRing lr =
                new NetTopologySuite.Geometries.LinearRing(points.ToArray());

            GeoAPI.Geometries.IPolygon poly = new NetTopologySuite.Geometries.Polygon(lr);
            return(poly.Area);
        }
        public static NetTopologySuite.Geometries.Polygon ToGeometryPolygon(Polygon polygon)
        {
            if (polygon == null)
            {
                throw new ArgumentNullException(nameof(polygon));
            }
            var linearRings  = new NetTopologySuite.Geometries.LinearRing[polygon.NumberOfParts];
            var toPointIndex = polygon.NumberOfPoints;

            for (var partIndex = polygon.NumberOfParts - 1; partIndex >= 0; partIndex--)
            {
                var fromPointIndex = polygon.Parts[partIndex];

                linearRings[partIndex] = new NetTopologySuite.Geometries.LinearRing(
                    GeometryConfiguration.GeometryFactory.CoordinateSequenceFactory.Create(
                        polygon.Points
                        .Skip(fromPointIndex)
                        .Take(toPointIndex - fromPointIndex)
                        .Select(point => new NetTopologySuite.Geometries.Coordinate(point.X, point.Y))
                        .ToArray()),
                    GeometryConfiguration.GeometryFactory);

                toPointIndex = fromPointIndex;
            }

            return(new NetTopologySuite.Geometries.Polygon(
                       linearRings[0],
                       linearRings.Length > 1
                    ? linearRings.Skip(1).ToArray()
                    : Array.Empty <NetTopologySuite.Geometries.LinearRing>()));
        }
Пример #3
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="neLat"></param>
        /// <param name="neLong"></param>
        /// <param name="swLat"></param>
        /// <param name="swLong"></param>
        /// <returns></returns>
        public IEnumerable <Parcel> Get(double neLat, double neLong, double swLat, double swLong)
        {
            this.User.ThrowIfNotAuthorized(Permissions.PropertyView);
            // Check if user has the ability to view sensitive properties.
            var userAgencies  = this.User.GetAgenciesAsNullable();
            var viewSensitive = this.User.HasPermission(Security.Permissions.SensitiveView);
            var isAdmin       = this.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 = this.Context.Parcels.AsNoTracking().Where(p =>
                                                                  (isAdmin ||
                                                                   p.IsVisibleToOtherAgencies ||
                                                                   ((!p.IsSensitive || viewSensitive) &&
                                                                    userAgencies.Contains(p.AgencyId))));

            var pfactory = new NetTopologySuite.Geometries.GeometryFactory();
            var ring     = new NetTopologySuite.Geometries.LinearRing(
                new[] {
                new NetTopologySuite.Geometries.Coordinate(neLong, neLat),
                new NetTopologySuite.Geometries.Coordinate(swLong, neLat),
                new NetTopologySuite.Geometries.Coordinate(swLong, swLat),
                new NetTopologySuite.Geometries.Coordinate(neLong, swLat),
                new NetTopologySuite.Geometries.Coordinate(neLong, neLat)
            });
            var poly = pfactory.CreatePolygon(ring);

            poly.SRID = 4326;
            query     = query.Where(p => poly.Contains(p.Location));

            return(query.ToArray());
        }
Пример #4
0
        public static Task <List <string> > GenerateCoveringGeohashes(this Geohasher hasher, GeoJsonPolygon <GeoJson2DGeographicCoordinates> polygon, int precision = 4)
        {
            var outerRing = new NetTopologySuite.Geometries.LinearRing(
                (from coord in polygon.Coordinates.Exterior.Positions
                 select new NetTopologySuite.Geometries.Coordinate(coord.Latitude, coord.Longitude)).ToArray()
                );
            var p = new NetTopologySuite.Geometries.Polygon(outerRing);

            return(hasher.GetHashesAsync(p, precision, Mode.Intersect));
        }
Пример #5
0
        /// <summary>
        /// Converts the given coordinates list list to the an array of linear rings.
        /// </summary>
        public static NetTopologySuite.Geometries.LinearRing[] ToLinearRings(this List <List <LocalGeo.Coordinate> > coordinates)
        {
            var rings = new NetTopologySuite.Geometries.LinearRing[coordinates.Count];

            for (var i = 0; i < rings.Length; i++)
            {
                rings[i] = coordinates[i].ToLinearRing();
            }
            return(rings);
        }
Пример #6
0
        private static IMultiPolygon ReadMultiPolygon(JsonTextReader jreader)
        {
            if (jreader == null)
            {
                throw new ArgumentNullException("reader", "A valid JSON reader object is required.");
            }

            IMultiPolygon areas = null;

            if (jreader.TokenClass == JsonTokenClass.Array)
            {
                jreader.ReadToken(JsonTokenClass.Array);
                List <IPolygon> polygons = new List <IPolygon>();
                while (jreader.TokenClass == JsonTokenClass.Array)
                {
                    jreader.ReadToken(JsonTokenClass.Array);

                    //Read the outer shell
                    ILinearRing shell = null;
                    if (jreader.TokenClass == JsonTokenClass.Array)
                    {
                        Coordinate[] coordinates = new Coordinate[] { };
                        Read(ref coordinates, jreader);
                        shell = new NetTopologySuite.Geometries.LinearRing(coordinates);
                    }

                    //Read all the holes
                    List <ILinearRing> list = new List <ILinearRing>();
                    while (jreader.TokenClass == JsonTokenClass.Array)
                    {
                        Coordinate[] coordinates = new Coordinate[] { };
                        Read(ref coordinates, jreader);
                        ILinearRing hole = new NetTopologySuite.Geometries.LinearRing(coordinates);
                        list.Add(hole);
                    }

                    jreader.ReadToken(JsonTokenClass.EndArray);

                    //An outer shell was found so a polygon can be created
                    if (shell != null)
                    {
                        IPolygon area = new NetTopologySuite.Geometries.Polygon(shell, list.ToArray());
                        polygons.Add(area);
                    }
                }
                jreader.ReadToken(JsonTokenClass.EndArray);

                areas = new NetTopologySuite.Geometries.MultiPolygon(polygons.ToArray());
            }
            return(areas);
        }
        public static NetTopologySuite.Geometries.MultiPolygon ToGeometryMultiPolygon(Polygon polygon)
        {
            if (polygon == null)
            {
                throw new ArgumentNullException(nameof(polygon));
            }
            var linearRings  = new NetTopologySuite.Geometries.LinearRing[polygon.NumberOfParts];
            var toPointIndex = polygon.NumberOfPoints;

            for (var partIndex = polygon.NumberOfParts - 1; partIndex >= 0; partIndex--)
            {
                var fromPointIndex = polygon.Parts[partIndex];

                linearRings[partIndex] = new NetTopologySuite.Geometries.LinearRing(
                    GeometryConfiguration.GeometryFactory.CoordinateSequenceFactory.Create(
                        polygon.Points
                        .Skip(fromPointIndex)
                        .Take(toPointIndex - fromPointIndex)
                        .Select(point => new NetTopologySuite.Geometries.Coordinate(point.X, point.Y))
                        .ToArray()),
                    GeometryConfiguration.GeometryFactory);

                toPointIndex = fromPointIndex;
            }

            var polygons  = new List <NetTopologySuite.Geometries.Polygon>();
            var ringIndex = 0;

            while (ringIndex < linearRings.Length)
            {
                var shell = linearRings[ringIndex];
                if (shell.IsCCW)
                {
                    throw new InvalidOperationException("The shell of a polygon must have a clockwise orientation.");
                }
                var holes = new List <NetTopologySuite.Geometries.LinearRing>();
                ringIndex++;
                while (ringIndex < linearRings.Length && linearRings[ringIndex].IsCCW)
                {
                    holes.Add(linearRings[ringIndex]);
                    ringIndex++;
                }

                polygons.Add(new NetTopologySuite.Geometries.Polygon(
                                 shell,
                                 holes.ToArray(),
                                 GeometryConfiguration.GeometryFactory));
            }
            return(new NetTopologySuite.Geometries.MultiPolygon(polygons.ToArray(), GeometryConfiguration.GeometryFactory));
        }
Пример #8
0
        public static void CustomizeGeometryMultiPolygon(this IFixture fixture)
        {
            fixture.Customize <NetTopologySuite.Geometries.MultiPolygon>(customization =>
                                                                         customization.FromFactory(generator =>
            {
                var polygonCount = generator.Next(1, 4);
                var polygons     = new NetTopologySuite.Geometries.Polygon[polygonCount];
                for (var polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++)
                {
                    var offsetX = 10.0 * polygonIndex;
                    var offsetY = 10.0 * polygonIndex;

                    var shell = new NetTopologySuite.Geometries.LinearRing(
                        new []
                    {
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY + 5.0).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX + 5.0, offsetY + 5.0).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX + 5.0, offsetY).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY).Coordinate
                    });

                    var holes = new[]     // points are enumerated counter clock wise
                    {
                        new NetTopologySuite.Geometries.LinearRing(
                            new[]
                        {
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 2.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 2.0, offsetY + 3.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 3.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 2.0).Coordinate
                        }),
                        new NetTopologySuite.Geometries.LinearRing(
                            new[]
                        {
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 1.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 4.0, offsetY + 1.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 4.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 1.0).Coordinate
                        })
                    };
                    polygons[polygonIndex] = new NetTopologySuite.Geometries.Polygon(shell, holes, GeometryConfiguration.GeometryFactory);
                }
                return(new NetTopologySuite.Geometries.MultiPolygon(polygons));
            }).OmitAutoProperties()
                                                                         );
        }
Пример #9
0
        private XmlDocument InsertInspektionsroutenNames(XmlDocument xml, XmlNamespaceManager nsmgr, EmsgGisReportParameter reportparams)
        {
            if (reportparams == null)
            {
                return(this.InsertInspektionsroutenNames(xml, nsmgr));
            }
            string[] bboxCoordinates = reportparams.BoundingBox.Split(',');

            Coordinate bottomLeft  = new Coordinate(float.Parse(bboxCoordinates[0], CultureInfo.InvariantCulture.NumberFormat), float.Parse(bboxCoordinates[1], CultureInfo.InvariantCulture.NumberFormat));
            Coordinate topRight    = new Coordinate(float.Parse(bboxCoordinates[2], CultureInfo.InvariantCulture.NumberFormat), float.Parse(bboxCoordinates[3], CultureInfo.InvariantCulture.NumberFormat));
            Coordinate bottomRight = new Coordinate(float.Parse(bboxCoordinates[2], CultureInfo.InvariantCulture.NumberFormat), float.Parse(bboxCoordinates[1], CultureInfo.InvariantCulture.NumberFormat));
            Coordinate topLeft     = new Coordinate(float.Parse(bboxCoordinates[0], CultureInfo.InvariantCulture.NumberFormat), float.Parse(bboxCoordinates[3], CultureInfo.InvariantCulture.NumberFormat));


            ILinearRing linearRing = new NetTopologySuite.Geometries.LinearRing(new Coordinate[] { topLeft, topRight, bottomRight, bottomLeft, topLeft });

            IGeometry filterGeom = new NetTopologySuite.Geometries.Polygon(linearRing);

            filterGeom.SRID = GisConstants.SRID;

            var inspekrouten = inspektionsRouteGISService.GetInspektionsrouteByFilterGeom(filterGeom);

            return(this.InsertInspektionsroutenNames(xml, nsmgr, inspekrouten));
        }
Пример #10
0
        public static void CustomizeMultiPolygon(this IFixture fixture)
        {
            fixture.Customize <Polygon>(customization =>
                                        customization.FromFactory(generator =>
            {
                var polygonCount = generator.Next(1, 4);
                var polygons     = new NetTopologySuite.Geometries.Polygon[polygonCount];
                for (var polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++)
                {
                    var offsetX = 10.0 * polygonIndex;
                    var offsetY = 10.0 * polygonIndex;

                    var shell = new NetTopologySuite.Geometries.LinearRing(
                        new []
                    {
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY + 5.0).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX + 5.0, offsetY + 5.0).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX + 5.0, offsetY).Coordinate,
                        new NetTopologySuite.Geometries.Point(offsetX, offsetY).Coordinate
                    });

                    var holes = new[]     // points are enumerated counter clock wise
                    {
                        new NetTopologySuite.Geometries.LinearRing(
                            new[]
                        {
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 2.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 2.0, offsetY + 3.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 3.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 1.0, offsetY + 2.0).Coordinate
                        }),
                        new NetTopologySuite.Geometries.LinearRing(
                            new[]
                        {
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 1.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 4.0, offsetY + 1.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 4.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 2.0).Coordinate,
                            new NetTopologySuite.Geometries.Point(offsetX + 3.0, offsetY + 1.0).Coordinate
                        })
                    };
                    polygons[polygonIndex] = new NetTopologySuite.Geometries.Polygon(shell, holes);
                }

                var linearRings = polygons
                                  .SelectMany(polygon => new[] { polygon.Shell }.Concat(polygon.Holes))
                                  .ToArray();
                var parts  = new int[linearRings.Length];
                var points = new Point[polygons.Sum(polygon => polygon.Shell.NumPoints + polygon.Holes.Sum(hole => hole.NumPoints))];
                var offset = 0;
                for (var ringIndex = 0; ringIndex < linearRings.Length; ringIndex++)
                {
                    var linearRing   = linearRings[ringIndex];
                    parts[ringIndex] = offset;
                    for (var pointIndex = 0; pointIndex < linearRing.NumPoints; pointIndex++)
                    {
                        var point = linearRing.GetPointN(pointIndex);
                        points[offset + pointIndex] = new Point(point.X, point.Y);
                    }
                    offset += linearRing.NumPoints;
                }

                var boundingBox = new BoundingBox2D(
                    points.Min(p => p.X),
                    points.Min(p => p.Y),
                    points.Max(p => p.X),
                    points.Max(p => p.Y)
                    );
                return(new Polygon(boundingBox, parts, points));
            }).OmitAutoProperties()
                                        );
        }
Пример #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.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 pfactory = new NetTopologySuite.Geometries.GeometryFactory();
                var ring     = new NetTopologySuite.Geometries.LinearRing(
                    new[] {
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value)
                });
                var poly = pfactory.CreatePolygon(ring);
                poly.SRID = 4326;
                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.MinEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinEstimatedValue <= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.FiscalKeys.Estimated)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }
            if (filter.MaxEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxEstimatedValue >= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && pe.Key == Entity.FiscalKeys.Estimated)
                                                    .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);
        }
Пример #12
0
        public static void Test()
        {
            string s1 = "POLYGON((7.5999034 47.5506347,7.5997595 47.5507183,7.5998959 47.5508256,7.5999759 47.5508885,7.6001195 47.550805,7.5999034 47.5506347))";
            string s2 = "POLYGON((7.6003356 47.5509754,7.6001195 47.550805,7.5999759 47.5508885,7.6000322 47.5509328,7.6001926 47.551059,7.6003356 47.5509754))";

            s1 = "POLYGON((7.5999034 47.5506347,7.6001195 47.550805,7.5999759 47.5508885,7.5998959 47.5508256,7.5997595 47.5507183,7.5999034 47.5506347))";
            s2 = "POLYGON((7.6003356 47.5509754,7.6001926 47.551059,7.6000322 47.5509328,7.5999759 47.5508885,7.6001195 47.550805,7.6003356 47.5509754))";


            // NetTopologySuite.Geometries.Implementation.CoordinateArraySequenceFactory
            // GeoAPI.Geometries.IGeometryFactory geoFactory = new NetTopologySuite.Geometries.GeometryFactory();


            NetTopologySuite.IO.WKTReader wr = new NetTopologySuite.IO.WKTReader();

            Wgs84Coordinates[] coords1 = PolygonParsingExtensions.PolygonStringToCoordinates(s1);
            Wgs84Coordinates[] coords2 = PolygonParsingExtensions.PolygonStringToCoordinates(s2);

            var lr = new NetTopologySuite.Geometries.LinearRing(coords1.ToNetTopologyCoordinates());

            System.Console.WriteLine(lr.IsValid);

            var x = new NetTopologySuite.Geometries.Polygon(new NetTopologySuite.Geometries.LinearRing(coords1.ToNetTopologyCoordinates()));

            System.Console.WriteLine(x.IsValid);

            NetTopologySuite.Geometries.GeometryFactory geomFactory = new NetTopologySuite.Geometries.GeometryFactory();

            GeoAPI.Geometries.IPolygon poly1 = geomFactory.CreatePolygon(coords1.ToNetTopologyCoordinates());
            GeoAPI.Geometries.IPolygon poly2 = geomFactory.CreatePolygon(coords2.ToNetTopologyCoordinates());



            /*
             * GeoAPI.Geometries.IPolygon poly1 = (GeoAPI.Geometries.IPolygon)wr.Read(s1);
             * GeoAPI.Geometries.IPolygon poly2 = (GeoAPI.Geometries.IPolygon)wr.Read(s2);
             */

            poly1.SRID = 4326;
            poly2.SRID = 4326;



            CalculateArea2(coords1);
            CalculateArea2(coords2);


            System.Console.WriteLine(poly1.Area);
            System.Console.WriteLine(poly2.Area);


            GeoAPI.Geometries.IPolygon poly3quick = (GeoAPI.Geometries.IPolygon)poly1.Union(poly2);
            System.Console.WriteLine(poly3quick.IsValid);

            // https://gis.stackexchange.com/questions/209797/how-to-get-geometry-points-using-geo-api
            System.Console.Write(poly1.IsValid);
            System.Console.Write(poly2.IsValid);


            System.Collections.Generic.List <GeoAPI.Geometries.IGeometry> lsPolygons =
                new System.Collections.Generic.List <GeoAPI.Geometries.IGeometry>();

            lsPolygons.Add(poly1);
            lsPolygons.Add(poly2);


            GeoAPI.Geometries.IGeometry ig = NetTopologySuite.Operation.Union.CascadedPolygonUnion.Union(lsPolygons);
            System.Console.WriteLine(ig.GetType().FullName);

            GeoAPI.Geometries.IPolygon poly3 = (GeoAPI.Geometries.IPolygon)ig;
            System.Console.WriteLine(poly3);

            // POLYGON ((7.5997595 47.5507183, 7.5999034 47.5506347, 7.6001195 47.550805, 7.6003356 47.5509754
            // , 7.6001926 47.551059, 7.6000322 47.5509328, 7.5999759 47.5508885
            // , 7.5998959 47.5508256, 7.5997595 47.5507183))

            System.Console.WriteLine(poly3.Shell.Coordinates);


            /*
             * // GeoAPI.Geometries.IPolygon poly3 = (GeoAPI.Geometries.IPolygon)ig;
             * NetTopologySuite.Geometries.MultiPolygon poly3a = (NetTopologySuite.Geometries.MultiPolygon)ig;
             * GeoAPI.Geometries.IGeometry ig2 = poly3a.ConvexHull();
             * System.Console.WriteLine(ig2.GetType().FullName);
             */

            // GeoAPI.Geometries.IPolygon poly4 = (GeoAPI.Geometries.IPolygon)ig2;
            // System.Console.WriteLine(poly4);


            System.Console.WriteLine("--- Press any key to continue --- ");
            System.Console.ReadKey();
        } // End Sub Test
Пример #13
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 pfactory = new NetTopologySuite.Geometries.GeometryFactory();
                var ring     = new NetTopologySuite.Geometries.LinearRing(
                    new[] {
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value)
                });
                var poly = pfactory.CreatePolygon(ring);
                poly.SRID = 4326;
                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.MinEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MinEstimatedValue <= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Estimated)
                                                    .Max(pe => pe.FiscalYear))
                                    .Value);
            }
            if (filter.MaxEstimatedValue.HasValue)
            {
                query = query.Where(p =>
                                    filter.MaxEstimatedValue >= p.Fiscals
                                    .FirstOrDefault(e => e.FiscalYear == this.Context.ParcelFiscals
                                                    .Where(pe => pe.ParcelId == p.Id && e.Key == FiscalKeys.Estimated)
                                                    .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()));
        }
Пример #14
0
        } // End Function PolygonArea

        public static double CalculateArea(Wgs84Coordinates[] mycoordinates)
        {
            double[] latLonPoints = new double[mycoordinates.Length * 2];
            double[] z            = new double[mycoordinates.Length];

            // dotspatial takes the x,y in a single array, and z in a separate array.  I'm sure there's a
            // reason for this, but I don't know what it is.
            for (int i = 0; i < mycoordinates.Length; i++)
            {
                latLonPoints[i * 2]     = (double)mycoordinates[i].Longitude;
                latLonPoints[i * 2 + 1] = (double)mycoordinates[i].Latitude;
                z[i] = 0;
            } // Next i


            // source projection is WGS1984
            // https://productforums.google.com/forum/#!msg/gec-data-discussions/FxwUP7bd59g/02tvMDD3vtEJ
            // https://epsg.io/3857
            DotSpatial.Projections.ProjectionInfo projFrom = DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984;

            // most complicated problem - you have to find most suitable projection
            DotSpatial.Projections.ProjectionInfo projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.UtmWgs1984.WGS1984UTMZone37N;
            projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.Europe.EuropeAlbersEqualAreaConic; // 6350.9772005155683
            // projTo= DotSpatial.Projections.KnownCoordinateSystems.Geographic.World.WGS1984; // 5.215560750019806E-07
            // projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.WorldSpheroid.EckertIVsphere; // 6377.26664171461
            // projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.EckertIVworld; // 6391.5626849671826
            projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.CylindricalEqualAreaworld; // 6350.6506013739854

            /*
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.WorldSpheroid.CylindricalEqualAreasphere; // 6377.2695087222382
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.WorldSpheroid.EquidistantCylindricalsphere; // 6448.6818862780929
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.Polyconicworld; // 8483.7701716953889
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.EquidistantCylindricalworld; // 6463.1380225215107
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.EquidistantConicworld; // 8197.4427198320627
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.VanderGrintenIworld; // 6537.3942984174937
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.WebMercator; // 6535.5119516421109
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.World.Mercatorworld; // 6492.7180733950809
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.SpheroidBased.Lambert2; // 9422.0631835013628
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.SpheroidBased.Lambert2Wide; // 9422.0614012926817
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.TransverseMercator.WGS1984lo33; // 6760.01638841012
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.Europe.EuropeAlbersEqualAreaConic; // 6350.9772005155683
             * projTo = DotSpatial.Projections.KnownCoordinateSystems.Projected.UtmOther.EuropeanDatum1950UTMZone37N; // 6480.7883094931021
             */


            // ST_Area(g, false)     6379.25032051953
            // ST_Area(g, true)      6350.65051177517
            // ST_Area(g)            5.21556075001092E-07


            // prepare for ReprojectPoints (it's mutate array)
            DotSpatial.Projections.Reproject.ReprojectPoints(
                latLonPoints, z, projFrom, projTo
                , 0, latLonPoints.Length / 2
                );

            // assemblying new points array to create polygon
            GeoAPI.Geometries.Coordinate[] polyPoints = new GeoAPI.Geometries.Coordinate[latLonPoints.Length / 2];

            for (int i = 0; i < latLonPoints.Length / 2; ++i)
            {
                polyPoints[i] = new GeoAPI.Geometries.Coordinate(latLonPoints[i * 2], latLonPoints[i * 2 + 1]);
            } // Next i

            // Assembling linear ring to create polygon
            NetTopologySuite.Geometries.LinearRing lr =
                new NetTopologySuite.Geometries.LinearRing(polyPoints);

            if (!lr.IsValid)
            {
                throw new System.IO.InvalidDataException("Coordinates are invalid.");
            }

            GeoAPI.Geometries.IPolygon poly = new NetTopologySuite.Geometries.Polygon(lr);
            if (!poly.IsValid)
            {
                throw new System.IO.InvalidDataException("Polygon is invalid.");
            }



            return(poly.Area);
        } // End Function CalculateArea
Пример #15
0
//        public static void CustomizeGeometryPointM(this IFixture fixture)
//        {
//            fixture.Customize<PointM>(customization =>
//                customization.FromFactory(generator =>
//                    new PointM(
//                        fixture.Create<double>(),
//                        fixture.Create<double>(),
//                        fixture.Create<double>(),
//                        fixture.Create<double>()
//                    )
//                ).OmitAutoProperties()
//            );
//        }

        public static void CustomizeGeometryPolygon(this IFixture fixture)
        {
            const int polygonExteriorBufferCoordinate = 50;
            var       coordinateFixture = new Fixture();

            coordinateFixture.Customize <NetTopologySuite.Geometries.Coordinate>(customization =>
                                                                                 customization.FromFactory(generator =>
                                                                                                           new NetTopologySuite.Geometries.Coordinate(
                                                                                                               generator.Next(polygonExteriorBufferCoordinate - 1),
                                                                                                               generator.Next(polygonExteriorBufferCoordinate - 1)
                                                                                                               )
                                                                                                           ).OmitAutoProperties()
                                                                                 );

            var ringFixture = new Fixture();

            ringFixture.Customize <NetTopologySuite.Geometries.LinearRing>(customization =>
                                                                           customization.FromFactory(generator =>
            {
                NetTopologySuite.Geometries.LinearRing ring;
                do
                {
                    var coordinates = coordinateFixture
                                      .CreateMany <NetTopologySuite.Geometries.Coordinate>(3)
                                      .ToList();

                    var coordinate = coordinates[0];
                    coordinates.Add(coordinate.Copy());     //first coordinate must be last

                    ring = new NetTopologySuite.Geometries.LinearRing(
                        GeometryConfiguration.GeometryFactory.CoordinateSequenceFactory.Create(coordinates.ToArray()),
                        GeometryConfiguration.GeometryFactory
                        );
                } while (!ring.IsRing || !ring.IsValid || !ring.IsClosed);

                return(ring);
            }).OmitAutoProperties()
                                                                           );

            fixture.Customize <NetTopologySuite.Geometries.Polygon>(customization =>
                                                                    customization.FromFactory(generator =>
            {
                NetTopologySuite.Geometries.LinearRing exteriorRing;
                do
                {
                    var exteriorCoordinates = coordinateFixture.CreateMany <NetTopologySuite.Geometries.Coordinate>(3)
                                              .Select(point => new NetTopologySuite.Geometries.Coordinate(point.X + polygonExteriorBufferCoordinate,
                                                                                                          point.Y + polygonExteriorBufferCoordinate))
                                              .ToList();

                    var coordinate = exteriorCoordinates[0];
                    exteriorCoordinates.Add(coordinate.Copy());     //first coordinate must be last

                    exteriorRing = new NetTopologySuite.Geometries.LinearRing(
                        new NetTopologySuite.Geometries.Implementation.CoordinateArraySequence(exteriorCoordinates
                                                                                               .ToArray()),
                        GeometryConfiguration.GeometryFactory
                        );
                } while (!exteriorRing.IsRing || !exteriorRing.IsValid || !exteriorRing.IsClosed);

                return(new NetTopologySuite.Geometries.Polygon(exteriorRing,
                                                               ringFixture.CreateMany <NetTopologySuite.Geometries.LinearRing>(generator.Next(0, 1)).ToArray(),
                                                               GeometryConfiguration.GeometryFactory));
            }).OmitAutoProperties()
                                                                    );
        }
Пример #16
0
        private void DealerSearch(System.Windows.Point point)
        {
            Cursor = Cursors.Wait;
            mapControl.SetMapLocation(point, 12, srid);
            reachableObjectLayer.Shapes.Clear();
            isochroneLayer.Shapes.Clear();

            var waypoint = new WaypointDesc()
            {
                linkType      = LinkType.NEXT_SEGMENT,
                wrappedCoords = new XRoute.Point[]
                {
                    new XRoute.Point()
                    {
                        point = new PlainPoint()
                        {
                            x = point.X,
                            y = point.Y,
                        },
                    },
                },
            };

            var expansionDesc = new ExpansionDescription()
            {
                expansionType   = ExpansionType.EXP_TIME,
                wrappedHorizons = new int[] { 900 },
            };

            var options = new ReachableObjectsOptions()
            {
                expansionDesc      = expansionDesc,
                linkType           = LinkType.NEXT_SEGMENT,
                routingDirection   = RoutingDirectionType.FORWARD,
                geodatasourceLayer = XDealerSample.Properties.Settings.Default.GeoDataSource,
            };

            var cc = new CallerContext()
            {
                wrappedProperties = new CallerContextProperty[]
                {
                    new CallerContextProperty()
                    {
                        key = "CoordFormat", value = "PTV_MERCATOR"
                    },
                    new CallerContextProperty()
                    {
                        key = "Profile", value = "carfast"
                    },
                }
            };

            var isoOptions = new IsochroneOptions()
            {
                expansionDesc          = expansionDesc,
                isoDetail              = IsochroneDetail.POLYS_ONLY,
                polygonCalculationMode = PolygonCalculationMode.NODE_BASED,
            };

            ReachableObjects foundObjects = null;
            Isochrone        isochrone    = null;

            using (var xRouteClient = new XRouteWSClient())
            {
                try
                {
                    foundObjects = xRouteClient.searchForReachableObjects(waypoint, null, null, options, null, cc);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(
                        "Exception while searching for objects.\n\nException type: " + exception.GetType().ToString() +
                        "\nMessage: " + exception.Message);
                    Cursor = null;
                    return;
                }
                try
                {
                    isochrone = xRouteClient.calculateIsochrones(waypoint, null, isoOptions, cc);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(
                        "Exception while calculating isochrone.\n\nException type: " + exception.GetType().ToString() +
                        "\nMessage: " + exception.Message);
                    Cursor = null;
                    return;
                }
            }

            foreach (var foundObject in foundObjects.wrappedReachableObject)
            {
                var ball = new Ball()
                {
                    Height  = 10,
                    Width   = 10,
                    Tag     = [email protected],
                    ToolTip = "",
                    Color   = Colors.Blue,
                };
                ball.ToolTipOpening += ball_ToolTipOpening;

                var winPoint = new System.Windows.Point()
                {
                    X = [email protected],
                    Y = [email protected],
                };
                ShapeCanvas.SetLocation(ball, winPoint);
                reachableObjectLayer.Shapes.Add(ball);
            }

            var linearRing = new NetTopologySuite.Geometries.LinearRing(
                isochrone.wrappedIsochrones[0].polys.lineString.wrappedPoints
                .Select(p => new GeoAPI.Geometries.Coordinate(p.x, p.y))
                .ToArray()
                );

            linearRing.Normalize();

            var geom = new NetTopologySuite.Geometries.Polygon(linearRing);

            var bufferedGeom = geom.Buffer(100);
            var polygon      = new MapPolygon()
            {
                Points  = new PointCollection(bufferedGeom.Boundary.Coordinates.Select(c => new System.Windows.Point(c.X, c.Y))),
                Fill    = new SolidColorBrush(Colors.AliceBlue),
                Opacity = 0.75,
                Stroke  = new SolidColorBrush(Colors.DarkSlateGray)
            };

            isochroneLayer.Shapes.Add(polygon);

            Cursor = null;
        }
Пример #17
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);
            }

            if (filter.NELatitude.HasValue && filter.NELongitude.HasValue && filter.SWLatitude.HasValue && filter.SWLongitude.HasValue)
            {
                var pfactory = new NetTopologySuite.Geometries.GeometryFactory();
                var ring     = new NetTopologySuite.Geometries.LinearRing(
                    new[] {
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.NELatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.SWLongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.SWLatitude.Value),
                    new NetTopologySuite.Geometries.Coordinate(filter.NELongitude.Value, filter.NELatitude.Value)
                });
                var poly = pfactory.CreatePolygon(ring);
                poly.SRID = 4326;
                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.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.MinEstimatedValue.HasValue)
            {
                query = query.Where(p => p.Estimated >= filter.MinEstimatedValue);
            }
            if (filter.MaxEstimatedValue.HasValue)
            {
                query = query.Where(p => p.Estimated <= filter.MaxEstimatedValue);
            }

            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);
        }