Esri / Esri/geometry-api-java

GeometryEngine.Difference throws GeometryException: internal error for closed polyline touching endpoint

Abierto
#328 3 comentarios 0 reacciones 1 asignado Reclamado por @DavidHollman Ver en GitHub
bug fixed_to_verify
Lenguaje dominante
Java
Estrellas
710
Forks
269
Merge medio
7 d 23 h
PR fusionados (30 d)
1

Descripción

I've been using the project https://github.com/EchoParkLabs/geometry-api-cs which seems to be derived from here. Hopefully this report is still useful even though its not the same codebase.

## Summary

`com.epl.geometry.GeometryEngine.Difference()` throws

* **`com.epl.geometry.GeometryException: internal error`**

when subtracting a two-point polyline from a multi-path polyline whose first path is closed and shares its start/end vertex with the subtractor.

The two geometries only touch at one endpoint. `GeometryEngine.Intersect` reports an empty result for this case. Removing the duplicate closing vertex from the first path makes `Difference` succeed.

## Minimal failing geometry

### `p1`

`p1` contains two paths. The first path is closed because its final point repeats its initial point:

```text
MULTILINESTRING (
(
117422 -64366,
119336 -64652,
119218 -65440,
114999 -64810,
115034 -64578,
115117 -64022,
117422 -64366
),
(
111611 -62617,
111365 -64268,
110476 -64135,
110722 -62484,
110975 -62522,
111611 -62617
)
)
```

### `p2`

```text
MULTILINESTRING (
(
117422 -64366,
117911 -61089
)
)
```

The first point of `p2` equals both the first and final point of the first path in `p1`.

## Minimal C# reproduction

This code targets .NET Framework 4.8 and references geometry-api-cs. The code below uses only the failing first path; adding the second path from `p1` above also fails.

```csharp
using System;
using com.epl.geometry;

internal static class Program
{
private static void Main()
{
var p1 = CreatePolyline(new[]
{
(117422, -64366),
(119336, -64652),
(119218, -65440),
(114999, -64810),
(115034, -64578),
(115117, -64022),
(117422, -64366)
});

var p2 = CreatePolyline(new[]
{
(117422, -64366),
(117911, -61089)
});

try
{
var result = GeometryEngine.Difference(p1, p2, null);
Console.WriteLine("Difference succeeded: " + !result.IsEmpty());
}
catch (Exception exception)
{
Console.WriteLine(exception.GetType().FullName);
Console.WriteLine(exception.Message);
}
}

private static Polyline CreatePolyline((int X, int Y)[] points)
{
var polyline = new Polyline();
polyline.StartPath(new Point(points[0].X, points[0].Y));

for (var i = 1; i < points.Length; i++)
{
polyline.LineTo(new Point(points[i].X, points[i].Y));
}

return polyline;
}
}
```

Expected output:

```text
com.epl.geometry.GeometryException
internal error
```

## Control cases

### Open first path succeeds

Changing `p1` so its first path does not repeat its initial point causes `Difference` to succeed:

```csharp
var p1 = CreatePolyline(new[]
{
(117422, -64366),
(119336, -64652),
(119218, -65440),
(114999, -64810),
(115034, -64578),
(115117, -64022)
});
```

### Intersection reports no overlap

The geometries only meet at the shared endpoint:

```csharp
var intersection = GeometryEngine.Intersect(p1, p2, null);
Console.WriteLine(intersection.IsEmpty());
```

This reports `true` for the failing closed-path case.

### Reversing `p2` still fails

```csharp
var p2Reversed = CreatePolyline(new[]
{
(117911, -61089),
(117422, -64366)
});
```

`Difference(p1, p2Reversed, null)` also throws `GeometryException: internal error`.

## Observed stack location

```text
com.epl.geometry.TopologicalOperations.RestorePolylineParts_
com.epl.geometry.TopologicalOperations.TopoOperationPolylinePolylineOrPolygon_
com.epl.geometry.TopologicalOperations.Difference
com.epl.geometry.TopologicalOperations.Difference
com.epl.geometry.OperatorDifferenceLocal.Difference
com.epl.geometry.OperatorDifferenceCursor.Next
com.epl.geometry.OperatorDifferenceLocal.Execute
com.epl.geometry.GeometryEngine.Difference
```

## Environment / Misc details

- Operating system: Windows
- Runtime: .NET Framework 4.8
- Spatial reference: `null`

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.