Skip to main content
Version: Release 2 - 1.2.3.X

Geometry & Projection Helpers

Why you’d use these helpers

  • Run spatial math (buffers, intersections, boolean checks) without bundling your own Turf build.
  • Convert between projections, clip extents, or reproject individual coordinates with the same projection helpers Maptaskr Power Maps uses internally.
  • Access convenience utilities (distance, centroid, bbox, simplification) via a single cached GeoHelper bundle.

All helpers are available through our extension services. An example would be inside custom action callbacks or Power Automate-triggered extension hooks.

const control = globalThis.MaptaskrControlManager.getControl(controlId);

const turfHelper = control.getTurfHelper();

const projHelper = control.getProjHelper();

const geoHelper = control.getGeoHelper();

API reference

Turf

FunctionDescriptionAcceptsReturns
buffer(feature, radius, { units, steps })Expands geometries by radius in Turf-supported units (meters default).GeoJSON Feature or FeatureCollection, numeric radius.Buffered Feature/FeatureCollection.
union(features, { properties })Merges overlapping polygons into a single feature while optionally overriding properties.Polygon/MultiPolygon FeatureCollection.Combined Feature or null.
featureCollection(features, { bbox, id })Convenience creator for valid FeatureCollections (useful after manipulating geometries).Array of GeoJSON Feature.FeatureCollection.
difference(features) Subtracts the second polygon from the first in the collection.Polygon/MultiPolygon FeatureCollection.Resulting Feature or null.
intersect(features, { properties }) Computes the intersection of polygons.Polygon/MultiPolygon FeatureCollection.Intersection Feature or null.
booleanDisjoint(featureA, featureB, { ignoreSelfIntersections })Tests whether two geometries share any space.GeoJSON Feature or raw Geometry.boolean.
booleanIntersects(featureA, featureB, { ignoreSelfIntersections })Checks if geometries overlap/touch.GeoJSON Feature or raw Geometry.boolean.

Usage:

const control = globalThis.MaptaskrControlManager.getControl(controlId);

// Minimal example demonstrating TurfHelper functions
const turfHelper = control.getTurfHelper();

// --- Example Inputs ---
const geometry1 = { // Polygon
type: "Polygon",
coordinates: [[
[150.0, -34.0],
[151.0, -34.0],
[151.0, -33.0],
[150.0, -33.0],
[150.0, -34.0],
]]
};

const geometry2 = { // Polygon
type: "Polygon",
coordinates: [[
[150.5, -34.5],
[151.5, -34.5],
[151.5, -33.5],
[150.5, -33.5],
[150.5, -34.5],
]]
};

// Wrap as Turf Features
const feature1 = { type: "Feature", geometry: geometry1, properties: {} };
const feature2 = { type: "Feature", geometry: geometry2, properties: {} };

// --- Using TurfHelper Functions ---

// Create a feature collection
const collection = turfHelper.featureCollection([feature1, feature2]);
console.log("Feature collection:", collection);

// Buffer (expand geometry by distance in km)
const buffered = turfHelper.buffer(feature1, 10, { units: "kilometers" });
console.log("Buffered feature (10km):", buffered);

// Union (merge geometries)
const unionResult = turfHelper.union(collection);
console.log("Union result:", unionResult);

// Difference (geometry1 minus geometry2)
const differenceResult = turfHelper.difference(collection);
console.log("Difference (geometry1 - geometry2):", differenceResult);

// Intersect (overlapping area)
const intersection = turfHelper.intersect(collection);
console.log("Intersection:", intersection);

// Boolean: disjoint (no overlap?)
const isDisjoint = turfHelper.booleanDisjoint(feature1, feature2);
console.log("Are disjoint:", isDisjoint);

// Boolean: intersects (any overlap?)
const doesIntersect = turfHelper.booleanIntersects(feature1, feature2);
console.log("Do intersect:", doesIntersect);

Proj4

FunctionDescription
getNameForWkid(wkid) / getWkidForName(name)Lookup helpers to get a projection name from the Power Maps projection registry.
convertExtentTo4326(extent) / convertExtentToTargetProjection(extent, target)Reprojects bounding boxes between spatial references while preserving north/south ordering.
reprojectPoint(coord, sourceWkid, targetWkid)Single-point reprojection (returns a new MaptaskrCoordinate).
getValid4326BoundsForWkid(wkid) Returns a safe lat/long extent for the projection or null if none.
ensureProjection(code)Loads projection metadata on-demand (no-ops if already cached).
getDefault4326Extent() Handy constant for “show me the world” views.
ensureValid4326Extent(extent) Clamps and normalizes extents to stay inside WGS84 limits.
isSupported(code) Quick guard before letting users pick a projection.

Usage:

const control = globalThis.MaptaskrControlManager.getControl(controlId);

// Minimal example demonstrating ProjectionHelper functions
const projHelper = control.getProjHelper();

// --- Example Inputs ---
const extent4326 = { //Extent
xmin: 150.123456,
ymin: -35.654321,
xmax: 151.987654,
ymax: -34.123456,
zmin: 0,
zmax: 0,
spatialReference: { wkid: 4326, latestWkid: 4326 },
};

const point = [150.5, -34.5]; //MaptaskrCoordinate
const exampleProjectionCode = 3857;

// --- Using ProjectionHelper Functions ---

// Get projection name from WKID
const projName = projHelper.getNameForWkid(4326);
console.log("Projection name for WKID 4326:", projName);

// Get WKID from name
const wkidFromName = projHelper.getWkidForName(projName);
console.log(`WKID for projection name "${projName}":`, wkidFromName);

// Convert extent to 4326
const extentTo4326 = projHelper.convertExtentTo4326(extent4326);
console.log("Extent converted to 4326:", extentTo4326);

// Convert extent to another target projection
const extentToTarget = projHelper.convertExtentToTargetProjection(extent4326, exampleProjectionCode);
console.log(`Extent converted to EPSG:${exampleProjectionCode}:`, extentToTarget);

// Reproject a single point
const reprojectedPoint = projHelper.reprojectPoint(point, 4326, exampleProjectionCode);
console.log("Point reprojected to EPSG:3857:", reprojectedPoint);

// Get valid 4326 bounds for a projection
const validBounds = projHelper.getValid4326BoundsForWkid(exampleProjectionCode);
console.log("Valid 4326 bounds for EPSG:3857:", validBounds);

// Ensure projection is loaded
try {
projHelper.ensureProjection(exampleProjectionCode);
console.log("Projection EPSG:3857 loaded successfully.");
} catch (ex) {
console.error("Error loading projection:", ex);
}

// Get default 4326 extent
const defaultExtent = projHelper.getDefault4326Extent();
console.log("Default 4326 extent:", defaultExtent);

// Ensure a valid 4326 extent (clamped if needed)
const safeExtent = projHelper.ensureValid4326Extent({
xmin: -200, // intentionally invalid
ymin: -100,
xmax: 200,
ymax: 100,
zmin: 0,
zmax: 0,
spatialReference: { wkid: 4326, latestWkid: 4326 },
});
console.log("Clamped/safe 4326 extent:", safeExtent);

// Check if a projection is supported
const supported = projHelper.isSupported(exampleProjectionCode);
console.log("Is EPSG:3857 supported?", supported);

GeoHelper

FunctionWhat it does
degToRad(angle) Converts angles to radians (useful before trig math).
getDistance(coordA, coordB, radius)Distance on a sphere with configurable radius.
extentsIntersect(extentA, extentB) Boolean overlap check for Extent objects.
calculateExtent(geometry) Builds a Maptaskr Power Maps Extent around any GeoJSON geometry.
calculateCentroidFromExtent(extent)Returns { latitude, longitude } for the extent center.
intersectExtents(extentA, extentB) Returns the overlapping extent or undefined.
isFeatureInExtent(feature, extent, extentAsGeometry?) Determines if a Maptaskr Power Maps Feature falls inside an extent.
simplifyGeometry(geometry, tolerance)Lightweight Douglas–Peucker simplification for faster drawing.
reprojectGeometry(geometry, source, target, clone)Mass-reprojects all coordinates (optionally cloning first).
getBoundingBox(geometry)Returns { xmin, ymin, xmax, ymax }.
getFlattenedCoordinates(geometry)Flattens nested rings into a simple coordinate array.
calculateCentroid(geometry)Computes the centroid as a MaptaskrCoordinate.

Usage:

const control = globalThis.MaptaskrControlManager.getControl(controlId);

// Minimal example demonstrating GeoHelper functions with high-precision coordinates
const geoHelper = control.getGeoHelper();

// --- Example Inputs ---
const extentA = { //Extent
xmin: 151.000123,
ymin: -34.000456,
xmax: 152.000789,
ymax: -33.000321,
zmin: 0,
zmax: 0,
spatialReference: { wkid: 4326, latestWkid: 4326 },
};

const extentB = { //Extent
xmin: 151.500111,
ymin: -33.500222,
xmax: 152.500333,
ymax: -32.500444,
zmin: 0,
zmax: 0,
spatialReference: { wkid: 4326, latestWkid: 4326 },
};

const geometry = { //Geometry
type: "Polygon",
coordinates: [
[
[151.000123, -34.000456],
[151.500567, -34.000789],
[152.000789, -33.500321],
[151.500987, -33.000654],
[151.000123, -34.000456], // closing the polygon
],
],
};

const selectedFeature = { //CustomFeature
featureId: "feature1",
properties: new Map(),
geometry,
};

// --- Using GeoHelper Functions ---

// Angle conversion
const radians = geoHelper.degToRad(90);
console.log("Radians:", radians);

// Distance in meters
const distance = geoHelper.getDistance([151.000123, -33.000321], [152.000789, -34.000654], 6371000);
console.log("Distance (m):", distance);

// Extent overlap
const overlaps = geoHelper.extentsIntersect(extentA, extentB);
console.log("Extents overlap:", overlaps);

// Calculate extent from geometry
const derivedExtent = geoHelper.calculateExtent(geometry);
console.log("Derived extent:", derivedExtent);

// Centroid from extent
const centroidFromExtent = geoHelper.calculateCentroidFromExtent(extentA);
console.log("Centroid from extent:", centroidFromExtent);

// Intersection of extents
const extentIntersection = geoHelper.intersectExtents(extentA, extentB);
console.log("Intersection extent:", extentIntersection);

// Feature inside extent?
const inside = geoHelper.isFeatureInExtent(selectedFeature, extentA);
console.log("Feature inside extent:", inside);

// Simplify geometry
const simplified = geoHelper.simplifyGeometry(geometry, 0.001);
console.log("Original geometry:", geometry);
console.log("Simplified geometry:", simplified);

// Reproject geometry
const reprojected = geoHelper.reprojectGeometry(geometry, 4326, 3857, true);
console.log("Reprojected geometry:", reprojected);

// Bounding box
const bbox = geoHelper.getBoundingBox(geometry);
console.log("Bounding box:", bbox);

// Flattened coordinates
const coords = geoHelper.getFlattenedCoordinates(geometry);
console.log("Flattened coordinates:", coords);

// Centroid of geometry
const centroid = geoHelper.calculateCentroid(geometry);
console.log("Centroid of geometry:", centroid);

Best practices

  • Stay type-safe. Our TypeScript declarations differentiate between Maptaskr Power Maps Feature (rich metadata) and raw GeoJSON. When a helper expects GeoJSON, pass feature.geometry.
  • Mind your units. Turf defaults to kilometers; pass { units: 'meters' | 'miles' | ... } explicitly if you surface UI inputs in other units.
  • Wrap async usage. Many helper workflows feed back into action execution (e.g., highlight, filtering). Always handle Promise rejections from your own async code before returning control to Maptaskr Power Maps.