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 process
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 polygon const stateGraphic = new Graphic({ geometry: geometry, symbol: stateFillSymbol, }); // Create graphics for the centroid point from the centroidOperator const centroidGraphic = new Graphic({ geometry: stateCentroid, symbol: centroidMarkerSymbol, }); // Create a graphic for the label point from the labelPointOperator const labelPointGraphic = new Graphic({ geometry: stateLabelPoint, symbol: labelPointSymbol, }); // Create a graphic for the extent center point const extentCenterGraphic = new Graphic({ geometry: geometry.extent.center, symbol: extentCenterSymbol, }); // Create a graphic for the extent const extentGraphic = new Graphic({ geometry: geometry.extent, symbol: extentFillSymbol, }); // Add the graphics to the view's graphics layer viewElement.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 }, }); };