I tried to set view point for ArcGIS map and encountered an error exception:
ArcGIS Runtime Error Occurred. Set a breakpoint on C++ exceptions to see the original callstack and context for this error: Error Domain=com.esri.arcgis.runtime.error Code=2 "Invalid argument." UserInfo={NSLocalizedFailureReason=target_extent has zero for width or height., NSLocalizedDescription=Invalid argument., Additional Message=target_extent has zero for width or height.}
The code to set the view point is attached bellow, and I recognized that the error just happens with some AGSPoint.
Solved! Go to Solution.
Well, a possible workaround might look like this
let extent: AGSEnvelope
if min(polygon.extent.width, polygon.extent.height) == .zero {
let length = max(polygon.extent.width, polygon.extent.height)
extent = AGSEnvelope(center: polygon.extent.center, width: length, height: length)
} else {
extent = polygon.extent
}
mapView.setViewpointGeometry(extent)
When the extent of the polygon/polyline has zero width or height, add a condition to adjust its extent to a square, so that it can be correctly converted to a valid viewpoint target extent.
If you don't mind losing the original tightly-bound behavior, simply create a square extent for all geometries, regardless of whether it has a zero dimension or not.
let length = max(polygon.extent.width, polygon.extent.height)
let extent = AGSEnvelope(center: polygon.extent.center, width: length, height: length)
mapView.setViewpointGeometry(extent)
Although this is just a temporary fix and doesn't work perfectly. Hopefully the bug will be addressed in the upcoming versions of Runtime. 🙂
I see. It happens when the points are sharing the same latitude or longitude. I can see why it might happen - if all the points are on a same line parallel to x or y axis, then the bounding box (extent) of the geometry would be ill-formed, not being a rectangle but a line.
I'll query our team on their thoughts, but I personally think the behavior is expected, as indicated in the error message: target_extent has zero for width or height. A point or a x/y-parallel polyline doesn't have a valid rectangle extent.
Edit: team think it is a bug for not working on horizontal and vertical lines, will be fixed in the future.
In the meantime, here are a few alternatives you may consider.
You can always set a viewpoint to the center of your geometry and apply a scale, such as
mapView.setViewpointCenter(polygon.extent.center, scale: 1e4)
this is preferred because you can control the exact location and scale where you want to look at. Consider a point could represent a street address, or the centroid of a country - how much you zoom depends on what the point represents
If you buffer the center point of a geometry to a circle, it would always have a valid extent. Please notice, the planar buffer works the best with an equal-area projection map, and makes more sense to use with Web Mercator than WGS 84. We do have a geodetic buffer but that might be an overkill here.
// Note the distance is in the unit of the geometry's spatial reference, so with lat-lon it means 1 degree.
mapView.setViewpointGeometry(AGSGeometryEngine.bufferGeometry(polygon.extent.center, byDistance: 1)!)
Grate! This solution works for me. But with the first solution, could you share with me how to calculate the scale factor. Because the scale is depended on the points which I want to show on the map. I want to show all of the points to the map, so the scale should be suitable to show all points.
mapView.setViewpointCenter(polygon.extent.center, scale: 1e4)
Well, a possible workaround might look like this
let extent: AGSEnvelope
if min(polygon.extent.width, polygon.extent.height) == .zero {
let length = max(polygon.extent.width, polygon.extent.height)
extent = AGSEnvelope(center: polygon.extent.center, width: length, height: length)
} else {
extent = polygon.extent
}
mapView.setViewpointGeometry(extent)
When the extent of the polygon/polyline has zero width or height, add a condition to adjust its extent to a square, so that it can be correctly converted to a valid viewpoint target extent.
If you don't mind losing the original tightly-bound behavior, simply create a square extent for all geometries, regardless of whether it has a zero dimension or not.
let length = max(polygon.extent.width, polygon.extent.height)
let extent = AGSEnvelope(center: polygon.extent.center, width: length, height: length)
mapView.setViewpointGeometry(extent)
Although this is just a temporary fix and doesn't work perfectly. Hopefully the bug will be addressed in the upcoming versions of Runtime. 🙂
Thank you for your solution. It work perfectly 😎