ArcGIS Developer Foundation study materials
ArcGIS Developer Foundation study resources

500-Meter Hydrant Proximity Search at 61 Degrees North

ArcGIS Developer Foundation · Put your knowledge to work in context.

All case studies

500-Meter Hydrant Proximity Search at 61 Degrees North

A city at 61.2 degrees north maintains 12,400 hydrants in a hosted feature layer published in WGS 1984 (EPSG:4326). A dispatch web app lets a call-taker click a leak location and list hydrants within 500 meters. The developer queries the layer with geometry equal to the clicked point, spatialRel=esriSpatialRelIntersects, distance=500, and does not set units. Results are badly wrong: one test returned 214 hydrants up to 22 kilometers away, while another returned only hydrants on the same city block. A second version buffered the point in Web Mercator on the client with a planar 500-unit buffer and then queried; results were closer, but hydrants near the northern edge were consistently about twice as far as intended. The hydrant layer is read-only and must remain in 4326 for a national dataset. The app also needs to report driving distance to each hydrant using a routing service.

1. Explain both failure modes in terms of units and spatial reference.

Read the worked answer

These are two different errors, both about what a number means.

Failure one: distance=500 with no units. The distance parameter is interpreted in the units of the layer's spatial reference unless units is supplied. The layer is in EPSG:4326, whose units are degrees, so 500 was read as 500 degrees, a radius that covers most of the planet, which is why 214 hydrants up to 22 kilometers away came back. The same-block result points to a second issue: a geometry sent in Web Mercator without inSR is assumed to be in the layer's spatial reference, so the click point lands somewhere else entirely.

Failure two: a planar buffer in Web Mercator. Mercator is conformal, but its scale inflates with latitude by roughly 1/cos(latitude). At 61.2 degrees, cosine is about 0.482, so the scale factor is about 2.07. A 500-unit planar buffer represents roughly 1,035 meters on the ground, about twice the intended distance, which matches the northern-edge observation. Area distortion is the square of that, about 4.3 times.

Neither failure is fixed by tuning the radius; both require explicit units and a consistent spatial reference at both ends.

2. Specify a correct proximity query and buffer approach that keeps the published layer in 4326.

Read the worked answer

There are two defensible designs; pick one and make the spatial reference explicit at both ends.

Design A, server-side distance query: send the geometry with inSR=4326, spatialRel=esriSpatialRelIntersects, distance=500, units=esriSRUnit_Meter, plus outSR set to whatever the client displays and a limited outFields list. Validate that the service evaluates the distance correctly against the layer's geographic coordinate system by testing a hydrant pair measured independently on the ground.

Design B, explicit geodesic buffer, which is easier to reason about: compute geometryEngineAsync.geodesicBuffer(point, 500, 'meters') so the buffer is built on the ellipsoid, then query with that polygon and an intersects relationship. Alternatively project both the point and the hydrants to UTM Zone 6N (EPSG:26906), buffer 500 meters in that plane, and project results back for display. The published layer stays in 4326 either way; never reproject the national dataset to make client math simpler.

Add a regression test with hydrants at known ground distances such as 480 and 520 meters so a unit regression is caught before dispatch sees it.

3. The app must also show driving distance. What unit and service decisions matter?

Read the worked answer

Routing introduces a second unit system and a second service, so the same explicitness applies. Set directionsLengthUnits=esriNAUMeters, or kilometers if the UI displays kilometers, because the default is miles and will silently change every number on screen. Choose a travel mode that matches the agency's vehicles; the default driving mode may not reflect truck restrictions or one-way assumptions.

For a call with around 200 candidate hydrants, do not solve 200 routes. Reduce candidates with the 500-meter proximity query first, usually to a handful, then solve routes to those, or use an origin-destination cost matrix to obtain travel time and distance for many origins in one request, respecting the service's stop limits and chunking accordingly. Cache results for the lifetime of the call; they change over the day but not within one dispatch.

Present straight-line distance and driving distance as distinct labels, because conflating them erodes dispatcher trust. Handle no-route results explicitly, such as a hydrant across a river with no nearby bridge, instead of dropping it silently from the list. Finally, account for routing consumption separately from feature queries when estimating credits.