0%

Visualizing JSTS Topology Preserving Simplification

JSTS (JavaScript Topology Suite) is a powerful JavaScript library for geometric operations. In this tutorial, we’ll explore how to use JSTS’s simplification algorithms with interactive code examples.

🚀 Interactive Demo

Click the button below to open a live, executable notebook where each code cell can be run independently:

Or view it embedded below:


What is JSTS?

JSTS is a JavaScript port of the Java Topology Suite (JTS), providing:

  • Geometric operations (union, intersection, buffer, etc.)
  • Topology-preserving simplification algorithms
  • Spatial predicates and analysis
  • GeoJSON support

Simplification Algorithms

JSTS provides several simplification algorithms:

1. TopologyPreservingSimplifier

Based on Douglas-Peucker but prevents self-intersections and maintains valid geometry. Similar to PostGIS’s ST_SimplifyPreserveTopology.

2. DouglasPeuckerSimplifier

Standard Douglas-Peucker algorithm - fast but can create invalid geometries.

3. VWSimplifier (Visvalingam-Whyatt)

Area-based simplification that often produces visually pleasing results.

Code Walkthrough

Below are snippets from the interactive notebook demonstrating the simplification process.

1. Import Libraries

Using Deno, we import JSTS directly from a CDN.

1
2
3
4
5
6
7
8
9
10
// Load JSTS library
import * as jsts from 'https://esm.sh/jsts@2.12.1/dist/jsts.min.js';

// Access paths (interop handling)
const lib = jsts.default || jsts;
const GeoJSONReader = lib.io?.GeoJSONReader || lib.IO?.GeoJSONReader;
const GeoJSONWriter = lib.io?.GeoJSONWriter || lib.IO?.GeoJSONWriter;

const reader = new GeoJSONReader();
const writer = new GeoJSONWriter();

2. Simplification Logic

We define a helper function to switch between different simplification strategies.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function simplifyGeometry(geojson, tolerance, method = 'topology') {
const geometry = reader.read(geojson);
const lib = jsts.default || jsts;
let simplified;

switch(method) {
case 'topology':
simplified = lib.simplify.TopologyPreservingSimplifier.simplify(geometry, tolerance);
break;
case 'douglas':
simplified = lib.simplify.DouglasPeuckerSimplifier.simplify(geometry, tolerance);
break;
case 'vw':
simplified = lib.simplify.VWSimplifier.simplify(geometry, tolerance);
break;
default:
throw new Error('Unknown method');
}

return writer.write(simplified);
}

3. Visualization with SVG (Auto-Scaling)

The visualization function has been updated to automatically calculate bounding boxes, ensuring that any polygon—regardless of size or position—fits perfectly within the SVG view panel.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Helper to get bounding box
function getBounds(geojson) {
const coords = geojson.coordinates[0];
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
coords.forEach(c => {
minX = Math.min(minX, c[0]);
minY = Math.min(minY, c[1]);
maxX = Math.max(maxX, c[0]);
maxY = Math.max(maxY, c[1]);
});
return { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY };
}

// Transform coordinates to fit SVG panel
// ... logic to scale and offset points ...

Comparison Results

The notebook compares the algorithm on a procedurally generated “Noisy Circle” (200+ vertices) to truly test the simplification capabilities.

Algorithm Speed Validity Aggressiveness Best For
TopologyPreserving Medium ✅ Always Valid Conservative GIS, CAD
DouglasPeucker Fast ⚠️ May Break Aggressive Visualization
Visvalingam-Whyatt Medium ✅ Usually Valid Balanced Cartography

Conclusion

JSTS provides powerful geometry simplification algorithms for JavaScript. TopologyPreservingSimplifier is the safest choice for most applications, ensuring your simplified geometries remain valid. Use DouglasPeucker only when performance is critical and geometry validity can be compromised.

Open the interactive notebook above to try it yourself!