ArcGIS Android MapView缩放过度致坐标NaN,求WGS84可见区域获取方法
解决ArcGIS Runtime SDK for Android缩放超世界范围时可见区域NaN问题
当地图缩放到显示整个世界之外(出现空白区域)时,MapView.getVisibleArea()和screenToLocation()返回NaN,是因为屏幕边缘的点超出了地图空间参考的有效范围,无法转换为合法地理坐标。以下是几种可靠的解决方法:
方法1:限制地图最大缩放级别,避免超出世界范围
直接禁止地图缩放到能显示世界外空白区的级别,从根源上避免NaN问题。通过地图的全范围计算出对应的最大缩放比例(scale值越大,视图越近),设置为地图的最大允许缩放比例:
// 获取地图全范围 val fullExtent = mapView.map.fullExtent // 计算显示全范围所需的最大缩放比例 val maxScale = mapView.getScaleForGeometry(fullExtent) // 设置地图最大缩放比例,禁止缩得比世界范围更远 mapView.setMaxScale(maxScale)
方法2:通过Viewpoint获取可靠的可见区域
使用Viewpoint.Type.BOUNDING_GEOMETRY获取视口对应的边界几何,该方法会基于地图的有效范围计算,不会返回NaN。之后可将其投影为WGS84坐标:
// 获取当前视口的边界几何视图 val viewpoint = mapView.getCurrentViewpoint(Viewpoint.Type.BOUNDING_GEOMETRY) val targetGeometry = viewpoint.targetGeometry ?: return // 转换为WGS84坐标(SRID:4326) val wgs84SpatialRef = SpatialReference.create(4326) val visibleAreaWgs84 = GeometryEngine.project(targetGeometry, wgs84SpatialRef) as Envelope
方法3:手动处理screenToLocation()的NaN值
如果需要基于屏幕坐标计算,可对转换结果进行过滤,用地图全范围的边界值补充NaN点:
// 定义屏幕四个角的坐标 val screenCorners = listOf( Point(0f, 0f), Point(mapView.width.toFloat(), 0f), Point(mapView.width.toFloat(), mapView.height.toFloat()), Point(0f, mapView.height.toFloat()) ) // 转换屏幕坐标为地图坐标 val mapPoints = screenCorners.map { mapView.screenToLocation(it) } // 过滤掉包含NaN的无效点 val validPoints = mapPoints.filter { !it.hasNaN() } // 获取地图全范围作为 fallback val fullExtent = mapView.map.fullExtent // 计算可见区域的边界,无效点用全范围边界替代 val minX = validPoints.minOfOrNull { it.x } ?: fullExtent.xMin val maxX = validPoints.maxOfOrNull { it.x } ?: fullExtent.xMax val minY = validPoints.minOfOrNull { it.y } ?: fullExtent.yMin val maxY = validPoints.maxOfOrNull { it.y } ?: fullExtent.yMax // 创建地图坐标系下的可见区域,再转换为WGS84 val visibleEnvelope = Envelope(minX, minY, maxX, maxY, mapView.map.spatialReference) val visibleEnvelopeWgs84 = GeometryEngine.project(visibleEnvelope, SpatialReference.create(4326)) as Envelope
内容的提问来源于stack exchange,提问作者Michael Krutoyarskiy
相关产品推荐
相关产品推荐

