Skip to content

Instantly share code, notes, and snippets.

@steveoh
Last active April 22, 2020 00:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steveoh/113e095e1ec2760d0edc292fc3720431 to your computer and use it in GitHub Desktop.
Save steveoh/113e095e1ec2760d0edc292fc3720431 to your computer and use it in GitHub Desktop.

Spatial Filters

Introduction

Create a set of spatial filters based on OGC spatial functions.

Proposal

Example Objects

All examples will take place in the following domain:

public class Foo {
     public MultiPolygon shape { get; set; }
     public string bas { get; set; }
}

Proposal

Words

Suggested words in the following examples like shape_contains, shape_crosses, shape_equals, shape_intersects, shape_overlaps, shape_touches, shape_within will be a part of the NamingConvention and can be customized by the user.

For line and polygon geometries, shape_length and shape_area will generate the same filters as the scalar int type.

Spatial filters in HotChocolate will look like the following example:

query foos($point: geometry) {
  foos(where: {shape_contains: $point }}) {
    bas
  }
}

Since points and lines have a hard time intersecting with other points, a method to buffer them into polygons would be very useful for filtering points or lines that are near other points. e.g. an address point in relation to covid testing centers or address points along a road line.

query foos($point: geometry) {
  foos(where: {shape_contains: $point, buffer: 10, unit: "meters" }}) {
    bas
  }
}

The input geometry should allow for the GeoJSON spec and optionally allow for other geometry types like the esri spec to be extended into the system. With custom middleware users could use an address or a route and mile post or a place name to resolve a geometry from an external system. These results will need to be cached or persisted since they can be used multiple times in a single query.

Data is stored in different projections to have the least amount of distortion when making a round world flat. If the input geometry coordinates are stored in a different projection than the underlying data, a hook to reproject the data will be required. This could be resolved via a web service, code, or via a database function if supported.

How others did it

hasura

query geom_table($polygon: geometry){
  geom_table(
    where: {geom_col: {_st_within: $polygon}}
  ){
    id
    geom_col
  }
}

Displaying Spatial Data

Introduction

Create a way to display a geometry when requested as a scalar type.

Proposal

Createa a scalar type that can represent the geometry as GeoJSON or other javascript serializations.

Words

Suggested words in the following examples like area, length, centroid, envelope, wkt, wkb, and all will be a part of the NamingConvention and can be customized by the user.

A centroid will return the center of the geometry. The envelope will return the minimum bounding box around the envelope. wkt will return the well known text representation, wkb will return the well known binary as a byte[], and all will return the full shape as geojson. Every word used here will return the representation as geojson unless otherwise specified or where not applicable e.g. wkt, wkb.

The output serialization can be modified by using arguments.

{
  foos() {
    shape(format: GEOJSON, ESRIJSON, CUSTOM)
    {
       centroid,
       area,
       lenth
    }
  }
}

The output coordinate system can also be supplied as an argument using the well known id.

{
  foos() {
    shape(wkid: 3857, 4326)
    {
       envelope
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment