Skip to content

feat (buffer): add buffer parameter to intersect, nearest-neighbour and within - #247

Open
NtnHgr wants to merge 28 commits into
mainfrom
buffer
Open

NtnHgr wants to merge 28 commits into
mainfrom
buffer

Conversation

@NtnHgr

@NtnHgr NtnHgr commented Sep 7, 2026 •

Copy link
Copy Markdown

Description

Adds buffer functionality to the GeospatialAnalyzer.
The new functionality allows creating a buffer around an input geometry based on a configurable buffer distance in meter.

Changes

Added buffer analysis functionality.
All query tools use central method getAnalysisGeometry where optional buffer is implemented.
All query tool classes inherit from class ParameterDto or BufferParameterDto (which inherits from ParameterDto).
So the specification of buffer-parameters is only possible for selected query tools: within, nearest-neighbour, intersects).
The specifiable parameters are:
"buffer": (default 100), --> distance [m]
"returnBufferGeometry": (default false), --> geometry output

Using PostGIS, the buffer is not round. It's a Polygon with n segments per quarter-circle (quadSegs).
Using the implemented method getBufferQuadSegs, the count of quadSegs depends on the buffer-distance,
that the max. error (in comparison to a circle) is 10cm.

Testing

The implementation was tested locally with the PostGIS database.

Impact

The existing analysis functionality remains unchanged. The buffer operation is available as an additional spatial analysis function.

@sebeweiss
sebeweiss self-requested a review September 11, 2026 06:44
Comment thread src/general/geospatial.service.ts
Comment thread src/general/geospatial.service.ts Outdated
Comment thread src/general/geospatial.service.ts Outdated
Comment thread src/general/geospatial.service.ts Outdated
Comment thread bom.json Outdated
@sebeweiss
sebeweiss self-requested a review September 18, 2026 12:49

@sebeweiss sebeweiss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the updates. The UNION order, quad helper, bom.json removal, and separate buffer.util.ts module all look good.

I left a few comments.

One thing still open: no test coverage for the buffer query path, and buffer has no upper bound. We talked about the last point. Perhaps we should choose a reasonable value.

Comment thread src/general/geospatial.service.ts Outdated
Comment thread src/general/dto/parameter.dto.ts
Comment thread src/general/db-adapter.service.ts Outdated
Comment thread src/general/buffer.util.spec.ts Outdated
Comment thread documentation/within.md Outdated
Comment thread documentation/intersect.md Outdated
Comment thread documentation/neighbour.md Outdated
@sebeweiss sebeweiss added the enhancement New feature or request label Sep 18, 2026
@NtnHgr NtnHgr closed this Sep 21, 2026
@NtnHgr NtnHgr reopened this Sep 21, 2026
@sebeweiss
sebeweiss self-requested a review September 22, 2026 12:40

@sebeweiss sebeweiss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Buffer features can't be matched to their input geometry

Returned buffer features have no reference to the input geometry they were created from. They have neither __geoProperties nor an identifier in their properties. With multiple input geometries, clients can therefore only match buffers to inputs by their position in the response, which is fragile.

I suggest giving buffer features the same __geoProperties as the topic features of their input geometry. Clients already use __geoProperties.__geometryIdentifier__ to match topic results to their input, so the same mechanism can be used for buffers without special handling. Caller-supplied identifiers are preserved. Buffers remain identifiable via __buffer: true and the absence of __topic.

Expected result

"properties": {
  "__buffer": true,
  "__bufferDistance": 500,
  "__requestParams": { ... },
  "__geoProperties": {
    "name": "test_name",
    "__geometryIdentifier__": "__ID_0"
  }
}

Suggested changes

  1. src/general/geospatial.service.ts
    For the buffer query's id column, use getAndSetGeoID(feature, featureIndex) instead of __BUFFER_${featureIndex}. Bind the ID as a query parameter, like #getQueryBuilderStart does for _feature_id_. The identifier may come from the caller, so it must not be interpolated into the SQL.

  2. src/general/general.service.ts
    In prepareResponseFeatures, move __geoProperties = map.get(result.id) outside the if (!isBufferFeature) block. Only __topic and the source metadata should remain excluded for buffer features.

  3. Test
    Add an e2e test with two input geometries, one using a custom __geometryIdentifier__, and verify that each buffer carries the identifier of its corresponding input. The existing single-geometry test cannot catch mismatches.

Comment thread tsconfig.build.tsbuildinfo Outdated
Comment thread test/intersect.e2e-spec.ts Outdated
Comment thread test/intersect.e2e-spec.ts Outdated
Comment thread CHANGELOG.md Outdated

- `GEOSPATIAL_ANALYZER_CORS_ORIGINS` environment variable to configure allowed CORS origins as a comma-separated list. CORS remains disabled when the variable is unset.
- `sn_flurstueck_f`/`flurstueck_f` now provide `gemarkungsschluessel` and `gemarkungsname`.
- `intersect`, `within`, and `nearestNeighbour` now provide optional `buffer` (distance in meters; value range: 0 - 20 000). Using a polygonal approximation, its accuracy is at least 10cm. The optional specification of `getBufferGeometry`(boolean) returns its coordinates.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The CHANGELOG says “its accuracy is at least 10 cm,” which sounds like the buffer can be off by 10 cm or more. The intended meaning is the opposite: the deviation from the exact arc is at most 10 cm. Please reword it and getBufferGeometry must be changed to returnBufferGeometry.

@sebeweiss

Copy link
Copy Markdown
Collaborator

Buffer semantics for nearestNeighbour

The buffer in nearestNeighbour needs to match how the endpoint will behave in the future. We're planning to add an option to exclude geometries that lie inside the input geometry, and the buffer should follow the same rule.
Currently, __dist and maxDistanceToNeighbour are measured from the buffer edge, so every feature touching the buffer gets __dist = 0. If more features touch the buffer than the count allows, the result is non-deterministic.

We haven't settled on the target behaviour yet and should sit down together to discuss it.
One option would be to remove the buffer from nearestNeighbour for now and merge it only for intersect and within. We could then add the nearestNeighbour buffer together with the new option.
That way, we avoid releasing behaviour that we might have to change later in a breaking way.
What do you think @NtnHgr and @BHandrick?

@sebeweiss

Copy link
Copy Markdown
Collaborator

Apart from the points above, it looks very good. Thanks for the work! :)

@NtnHgr

NtnHgr commented Oct 5, 2026

Copy link
Copy Markdown
Author

Buffer semantics for nearestNeighbour

We haven't settled on the target behaviour yet and should sit down together to discuss it. One option would be to remove the buffer from nearestNeighbour for now and merge it only for intersect and within. We could then add the nearestNeighbour buffer together with the new option. That way, we avoid releasing behaviour that we might have to change later in a breaking way. What do you think @NtnHgr and @BHandrick?

We could remove the buffer from nearestNeighbour. Instead an optional minDistanceToNeighbour parameter could be added here next to maxDistanceToNeighbour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants