This sample demonstrates how to use geometry operators to determine the centroid of a polygon by using a U.S. state boundaries FeatureLayer. The sample also lets you visually explore the differences between the boundary polygon’s centroid, label points, and the extent’s center point. A centroid is the geometric center of a polygon, and the label point is often used to place a label in a polygon. The differences between the points are most noticeable in state’s with non-rectangular borders such as Florida, Louisiana and California.
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
The sample uses a feature layer to display the state boundaries, and it listens to click events on map. After a user clicks, hitTest is used to retrieve the relevant boundary polygon from the feature layer.
viewElement.hitTest(event.detail).then((response) => { if (response.results.length) { const stateBoundaryPolygon = response.results.find((result) => { return result.graphic.layer === stateBoundaryFeatureLayer; }).graphic.geometry;
processPolygon(stateBoundaryPolygon); }});The polygon from the hitTest result is passed to the processGeometry() method where the centroidOperator and labelPointOperator each run a geometric operation on the polygon to return a point.
const processGeometry = (geometry) => {
// Run the geometry operations const stateCentroid = centroidOperator.execute(geometry); const stateLabelPoint = labelPointOperator.execute(geometry); . . . }Finally, graphics are created for the state polygon’s extent, extent center, centroid and label point, and then they are added to the map’s graphic layer for visual comparison.
// Create a graphic using the state boundary polygonconst stateGraphic = new Graphic({ geometry: geometry, symbol: stateFillSymbol,});
// Create graphics for the centroid point from the centroidOperatorconst centroidGraphic = new Graphic({ geometry: stateCentroid, symbol: centroidMarkerSymbol,});
// Create a graphic for the label point from the labelPointOperatorconst labelPointGraphic = new Graphic({ geometry: stateLabelPoint, symbol: labelPointSymbol,});
// Create a graphic for the extent center pointconst extentCenterGraphic = new Graphic({ geometry: geometry.extent.center, symbol: extentCenterSymbol,});
// Create a graphic for the extentconst extentGraphic = new Graphic({ geometry: geometry.extent, symbol: extentFillSymbol,});
// Add the graphics to the view's graphics layerviewElement.graphics.addMany([extentGraphic, stateGraphic, centroidGraphic, labelPointGraphic, extentCenterGraphic]);The sample also uses a custom legend that displays the symbology used in the graphics layer. The legend is created using the symbolUtils.renderPreviewHTML() method and assigning it <div> tags as the DOM nodes.
const displayLegend = () => { // Extent center symbol symbolUtils.renderPreviewHTML(extentCenterSymbol, { node: document.getElementById("extentCenterDiv"), size: { width: 20, height: 20 }, symbolConfig: { isSquareFill: true }, });
// Label point symbol symbolUtils.renderPreviewHTML(labelPointSymbol, { node: document.getElementById("labelPointDiv"), size: { width: 20, height: 20 }, symbolConfig: { isSquareFill: true }, });
// Centroid symbol symbolUtils.renderPreviewHTML(centroidMarkerSymbol, { node: document.getElementById("centroidDiv"), size: { width: 20, height: 20 }, symbolConfig: { isSquareFill: true }, });
// Extent symbol symbolUtils.renderPreviewHTML(extentFillSymbol, { node: document.getElementById("extentDiv"), size: { width: 20, height: 20 }, symbolConfig: { isSquareFill: true }, });};