Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for geospatial queries #3300

Merged
merged 23 commits into from
Jun 6, 2023
Merged

Add support for geospatial queries #3300

merged 23 commits into from
Jun 6, 2023

Conversation

nirinchev
Copy link
Member

@nirinchev nirinchev commented Apr 24, 2023

Description

Fixes #3299

Summary

Adds initial support for geo queries. In this first version, we're not introducing new datatypes, so users will need to make sure their own types conform to the shape expected for geo queries. We're providing a few helper shapes to write queries against, though those can only be used for querying and cannot be stored in the database.

Example point definition

public partial class CustomGeoPoint : TestEmbeddedObject
{
    [MapTo("coordinates")]
    private IList<double> Coordinates { get; } = null!;

    [MapTo("type")]
    private string Type { get; set; } = "Point";

    public double Latitude => Coordinates.Count > 1 ? Coordinates[1] : throw new Exception($"Invalid coordinate array. Expected at least 2 elements, but got: {Coordinates.Count}");

    public double Longitude => Coordinates.Count > 1 ? Coordinates[0] : throw new Exception($"Invalid coordinate array. Expected at least 2 elements, but got: {Coordinates.Count}");

    public CustomGeoPoint(double latitude, double longitude)
    {
        Coordinates.Add(longitude);
        Coordinates.Add(latitude);
    }
}

Example query

var circle = new GeoCircle((23.459, 49.983), Distance.FromKilometers(10));

// Above example uses implicit conversion from a tuple to GeoPoint, you can also use the explicit one
var circle = new GeoCircle(new GeoPoint(latitude: 23.459, longitude: 49.983), Distance.FromKilometers(10));

// Construct a polygon from a collection of points. First and last one need to be the same
// in order to close the polygon.
var polygon = new GeoPolygon((10, 10), (10, 20), (0, 20), (10, 10));

// Construct a polygon with holes
var outerRing = new GeoPoint[] { (10, 10), (10, 20), (0, 20), (10, 10));
var hole1 = new GeoPoint[] { (1, 1), (1, 2), (0, 2), (1, 1));
var hole2 = new GeoPoint[] { (5, 5), (5, 6), (4, 6), (5, 5));
var polygon = new GeoPolygon(outerRing, hole1, hole2);

// Construct a box from bottom left and top right corners
var box = new GeoBox(bottomLeftCorner: (0, 0), topRightCorner: (10, 10));

// Query using LINQ
var query = realm.all<Company>().Where(c => QueryMethods.GeoWithin(c.Location, circle));

// Query using RQL
var query = realm.All<Company>().Filter("Location geoWithin $0", circle);

TODO

  • Changelog entry
  • Tests (if applicable)

Realm/Realm/Handles/QueryHandle.cs Fixed Show fixed Hide fixed
Realm/Realm/Handles/QueryHandle.cs Fixed Show fixed Hide fixed
Realm/Realm/Linq/RealmResultsVisitor.cs Fixed Show fixed Hide fixed
@coveralls
Copy link

coveralls commented Apr 24, 2023

Pull Request Test Coverage Report for Build 5188514108

  • 215 of 218 (98.62%) changed or added relevant lines in 19 files are covered.
  • 3 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+0.4%) to 82.288%

Changes Missing Coverage Covered Lines Changed/Added Lines %
Realm/Realm/DatabaseTypes/QueryArgument.cs 55 56 98.21%
Realm/Realm/Linq/RealmResultsVisitor.cs 10 11 90.91%
Realm/Realm/Native/Queries/NativeQueryArgument.cs 27 28 96.43%
Files with Coverage Reduction New Missed Lines %
Realm/Realm/Handles/SubscriptionSetHandle.cs 3 95.41%
Totals Coverage Status
Change from base Build 5142624676: 0.4%
Covered Lines: 6120
Relevant Lines: 7295

💛 - Coveralls

Realm/Realm/Native/Queries/NativeGeoPolygon.cs Outdated Show resolved Hide resolved
Realm/Realm/DatabaseTypes/Geospatial/GeoPolygon.cs Outdated Show resolved Hide resolved
wrappers/src/filter.hpp Outdated Show resolved Hide resolved
wrappers/src/marshalling.hpp Outdated Show resolved Hide resolved
wrappers/src/marshalling.hpp Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
{
foreach (var polygon in linearRings)
{
Argument.Ensure(polygon.Count > 3, $"Each linear ring (both the outer one and any holes) must have at least 4 points, but {LinearRingToString(polygon)} only had {polygon.Count}.", nameof(linearRings));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the docs for the class it says that each ring needs to have at least 3 points, not 4

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs say 3 distinct points and the first and the last must match, implying at least 4 points.

foreach (var polygon in linearRings)
{
Argument.Ensure(polygon.Count > 3, $"Each linear ring (both the outer one and any holes) must have at least 4 points, but {LinearRingToString(polygon)} only had {polygon.Count}.", nameof(linearRings));
Argument.Ensure(polygon[0] == polygon[polygon.Count - 1], $"The first and the last points of the polygon {LinearRingToString(polygon)} must be the same.", nameof(linearRings));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I thought in this case the polygon would be considered close anyways

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the case at some point, but Core changed it, so we now need to explicitly close the polygon. Will update the docs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I can see that MongoDB is more relaxed than GeoJSON, so might be worth doing it for the SDKs as well.

Copy link
Contributor

@papafe papafe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from those few notes it looks fine

nirinchev and others added 3 commits June 2, 2023 13:48
Co-authored-by: Ferdinando Papale <4850119+papafe@users.noreply.github.com>
@nirinchev nirinchev merged commit 995f64b into main Jun 6, 2023
9 checks passed
@nirinchev nirinchev deleted the ni/geo-queries branch June 6, 2023 12:29
nirinchev added a commit that referenced this pull request Jun 7, 2023
* main:
  Allow geobox to be constructed from 4 coordinates (#3341)
  Add support for geospatial queries (#3300)
  Update UWP certificate, add instructions on how to do it (#3338)
nirinchev added a commit that referenced this pull request Jun 12, 2023
* main: (29 commits)
  Add platform-specific helpers package (#3323)
  Allow geobox to be constructed from 4 coordinates (#3341)
  Add support for geospatial queries (#3300)
  Update UWP certificate, add instructions on how to do it (#3338)
  Don't throw an exception when setting an embedded property to the same value (#3337)
  Automatically handle object -> embedded object migrations (#3322)
  Add a check for the thread in Realm.IsInTransaction (#3336)
  Update to latest Core (#3334)
  Fix a few typos
  Move the SG and weaver binaries to the Realm package (#3319)
  Update ci-actions to latest commit (#3318)
  Fix a couple of warnings (#3317)
  Prepare for vNext (#3316)
  Prepare for 11.0.0 (#3315)
  Add support for arm on Linux (#3267)
  Update changelog
  Add tests for Set.PropertyChanged notifications (#3309)
  Change testing targets to net7.0 (#3305)
  Adjust codeql config (#3311)
  Allow publishing unity package on prerelease workflow (#3310)
  ...

# Conflicts:
#	Realm/Realm.UnityWeaver/UnityWeaver.cs
#	wrappers/realm-core
nirinchev added a commit that referenced this pull request Jun 21, 2023
* main: (169 commits)
  Prepare for vNext (#3361)
  Prepare for 11.1.2 (#3360)
  Fix maui namespaces (#3357)
  Add a task to verify namespaces (#3358)
  Prepare for vNext (#3356)
  Prepare for 11.1.1 (#3355)
  Fix namespaces to ensure we don't have Realm as a namespace (#3353)
  Better warning for skipped properties with attributes (#3354)
  Revert "Better warning for skipped properties with attributes"
  Better warning for skipped properties with attributes
  Add nuget readme (#3350)
  Prepare for vNext (#3349)
  Prepare for 11.1.0 (#3348)
  Remove SG package reference from XUnit tests
  Use a different MSVC version (#3347)
  Overhaul metrics [feature branch] (#3209)
  Bump NuGet.Protocol from 5.9.3 to 6.0.5 (#3346)
  Add platform-specific helpers package (#3323)
  Allow geobox to be constructed from 4 coordinates (#3341)
  Add support for geospatial queries (#3300)
  ...

# Conflicts:
#	.github/templates/main.yml
#	.github/templates/pr.yml
#	.github/templates/test-net-core.yml
#	.github/templates/test-uwp-managed.yml
#	.github/workflows/pr.yml
#	.github/workflows/test-uwp-managed.yml
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for GeoSpatial queries
3 participants