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
GeoHelperbundle.
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
| Function | Description | Accepts | Returns |
|---|---|---|---|
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
| Function | Description |
|---|---|
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
| Function | What 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.