postgraphile-plugin-connection-filter-postgis icon indicating copy to clipboard operation
postgraphile-plugin-connection-filter-postgis copied to clipboard

extend plugin for additional feature: st_dwithin

Open ireznik opened this issue 5 years ago • 2 comments

I would like to extend the plugin to add the function st_dwithin. The postgis function is described here: https://postgis.net/docs/ST_DWithin.html I already made the following changes:

Use this draft to compare: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16

Modified the plugin itself by adding the function, typenames and other properties: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-3a39e3760ed128b03242f96a7d1ceeefR140

Modified fixtures: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-59621d53d50374d9716154d866c9e7e9R10

With the modified geography fixtures I am currently getting some output: [GraphQLError: function st_dwithin(geography, geography) does not exist]

In the geometry.graphql fixtures I added a second input value named $radius; https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-6638aac95b170cc236faa41b2939f63cR1 Which results in the following error: [GraphQLError: Syntax Error: Expected Name, found $]

Additional notes: I've updated the pg library to work with node v14

ireznik avatar Sep 06 '20 11:09 ireznik

here to follow :)

pyramation avatar Sep 24 '20 06:09 pyramation

Does the draft PR actually work? I think you're getting [GraphQLError: function st_dwithin(geography, geography) does not exist] because it should be st_dwithin(geography, geography, double persision) (https://postgis.net/docs/ST_DWithin.html).

I'm in the process of trying to add st_dwithin support and this is what I added so far. Would welcome inputs on improvements.

    // 3 Param Functions
    for (const [fn, baseTypeNames, operatorName, description] of [
      [
        'ST_DWithin',
        [GEOMETRY, GEOGRAPHY],
        'dwithin',
        'Returns true if the geometries are within the specified distance of one another. https://postgis.net/docs/ST_DWithin.html',
      ],
    ] as Operator[]) {
      for (const baseTypeName of baseTypeNames) {
        const sqlGisFunction =
          pgGISExtension.namespaceName === 'public'
            ? sql.identifier(fn.toLowerCase())
            : sql.identifier(pgGISExtension.namespaceName, fn.toLowerCase())
        specs.push({
          typeNames: gqlTypeNamesByGisBaseTypeName[baseTypeName],
          operatorName,
          description,
          resolveType: (fieldType) =>
            new GraphQLInputObjectType({
              name: 'STDWithinInputs',
              fields: {
                gg2: {
                  type: fieldType,
                  description: 'The reference location',
                },
                distance: {
                  type: GraphQLInt,
                  description: 'distance_meters',
                },
              },
            }),
          resolve: (sqlIdentifier, sqlValue, input: any) => {
            const { gg2, distance } = input as {
              gg2: string
              distance: number
            }

            if (!Array.isArray(sqlValue)) {
              throw new Error('Expected sqlValue to be an array')
            }

            // Example sqlValue:
            // [{"type":"RAW","text":"st_geomfromgeojson("},{"type":"VALUE","value":"123"},{"type":"RAW","text":"::text)::"},{"type":"IDENTIFIER","names":["public","geography"]}]
            sqlValue[1] = sql.value(gg2)

            return sql.query`${sqlGisFunction}(${sqlIdentifier}, ${sqlValue}, ${sql.value(
              distance,
            )})`
          },
        })
      }
    }

nick-kang avatar May 21 '22 20:05 nick-kang