Geometry operator - using a worker for analysis

This sample demonstrates how to use geometry operators in a web worker. Web workers allow for CPU intensive code to be run on a background thread to minimize the possibility of degrading the user interface performance.

The Introduction to geometry operators guide topic offers an overview of the capabilities for performing client-side geometric operations on points, multipoints, lines, polygons and extents.

How it works

This sample uses a web worker, geometry-operator-worker.mjs, to retrieve a FeatureSet of river and creek polyline segments and then it creates a buffer around them.

The web worker is initialized in the index.html file using an open-source, Apache 2.0 licensed library called Comlink to help simplify the implementation.

Use dark colors for code blocksCopy
1
2
3
4
5
// Create a new worker thread that will be used to perform the geometry operations
const geometryOperatorsWorker = new ComlinkWorker(new URL("./geometry-operators-worker.mjs", import.meta.url), {
  name: "geometryOperatorWorker",
  type: "module",
});

Comlink provides a simple interface for communicating with the worker. Here a buffer polygon is created around a click point on the map. The buffer is converted to JSON and then passed to the getRiverBuffers() method in the worker.

Use dark colors for code blocksCopy
1
const result = await geometryOperatorWorker.getRiverBuffers(queryBuffer.toJSON());

The worker uses a feature service. A query performs a contains operation on the service to return all features that are fully within the buffer polygon. To learn more about the SDK's query parameters see the Query reference page.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
const queryParams = {
  geometry: queryBufferPolygon,
  geometryType: "esriGeometryPolygon",
  spatialRel: "esriSpatialRelContains",
  returnGeometry: true
};

const featureSet = await query.executeQueryJSON(rivers, queryParams);

The query returns a feature set of river and creek polyline segments that represent the centerline data for each feature. Then the sample loops through the features and uses the bufferOperator to create a buffer for each segment.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
    const riverPolyline = new Polyline({
      paths: feature.geometry.paths,
      spatialReference: featureSet.spatialReference
    });

    const riverBufferPolygon = bufferOperator.execute(riverPolyline, 200, {
      unit: "meters"
    });

Both the polylines and their buffers are then generalized. This optional step simplifies the geometry shapes and reduces the number of vertices. It can help with performance when serializing the data that is sent back to the main thread by reducing the number of vertices on the polyline and polygon buffer geometries while still preserving the overall shape.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
    // Generalize the polylines and buffer polygons to simplify the shape and reduce the number of vertices.
    const generalizedPolyline = generalizeOperator.execute(riverPolyline, 10, {
      unit: "meters"
    });

    const generalizedRiverBufferPolygon = generalizeOperator.execute(riverBufferPolygon, 10, {
      unit: "meters"
    });

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.