How to find the center point of zoomed map in lat lon degrees?

1128
5
Jump to solution
05-20-2021 04:51 AM
FatmaAkdemir
Occasional Contributor II

I want to obtain the center point of the SceneGraphicView's current viewport. Is that possible?

0 Kudos
1 Solution

Accepted Solutions
Nicholas-Furness
Esri Regular Contributor

Yes. You can get the center of the current viewpoint by calling GeoView::currentViewpoint() and passing in a viewpoint type of CenterAndScale (a GeoView could be a MapView (2D) or a SceneView (3D)). The Viewpoint you get back has a targetGeometry, which in this case will be a Point representing the center of the map/scene view.

Since you want lat/lon… The units of x/y coordinates of the center point will depend on the spatial reference of the map/scene view. If you know it's WGS84, you're good. But if you don't know, or you know it's something else (a map using our basemaps will likely be Web Mercator), then you can use GeometryEngine to easily project that point to WGS84 and then get the Lat Lon. Note, lat/lon is y/x, not x/y.

 

 

View solution in original post

5 Replies
Nicholas-Furness
Esri Regular Contributor

Yes. You can get the center of the current viewpoint by calling GeoView::currentViewpoint() and passing in a viewpoint type of CenterAndScale (a GeoView could be a MapView (2D) or a SceneView (3D)). The Viewpoint you get back has a targetGeometry, which in this case will be a Point representing the center of the map/scene view.

Since you want lat/lon… The units of x/y coordinates of the center point will depend on the spatial reference of the map/scene view. If you know it's WGS84, you're good. But if you don't know, or you know it's something else (a map using our basemaps will likely be Web Mercator), then you can use GeometryEngine to easily project that point to WGS84 and then get the Lat Lon. Note, lat/lon is y/x, not x/y.

 

 

FatmaAkdemir
Occasional Contributor II

Hi @Nicholas-Furness ,

Thank you for the detailed reply. What I wanted to achieve was to provide a seamless switch between GlobeCameraController and OrbitLocationCameraController in a 3D SceneView. We have a camera button which user clicks and orbits the camera around the center point of the current viewport.

void MainMapWidget::slotOrbitCameraAroundPoint(bool checked){
	const Point baseSurfacePos = m_sceneView->currentViewpoint(ViewpointType::CenterAndScale).targetGeometry();
	const Viewpoint pt = m_sceneView->currentViewpoint(ViewpointType::CenterAndScale);
	const Camera cm = m_sceneView->currentViewpointCamera();
	 if(checked){
		 OrbitLocationCameraController camCtrl(baseSurfacePos, cm.location());
		 m_sceneView->setCameraController(&camCtrl);
	 }
	 else{
		 m_sceneView->setCameraController(mpDefaultCameraController);
	 }
	 m_sceneView->setViewpoint(pt);
	 m_sceneView->update();
}

 

 

 I was wondering how could I preserve the current scale and viewpoint of the map when I switch to the OrbitCameraController.

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Looks like what you're doing should get you close. But rather than setting the viewpoint (which is already what you want), get the viewpoint, create an OrbitLocationCameraController (as you are doing) using the viewpoint geometry and the current camera's location, and then set the camera controller's DistanceInteractive to false.

Does that work for you?

0 Kudos
FatmaAkdemir
Occasional Contributor II

Hi @Nicholas-Furness ,

I made some small changes and it worked out for me.

 

void MainMapWidget::slotOrbitCameraAroundPoint(bool checked){
	const Point baseSurfacePos = m_sceneView->currentViewpoint(ViewpointType::CenterAndScale).targetGeometry();
	const Viewpoint pt = m_sceneView->currentViewpoint(ViewpointType::CenterAndScale);
	const Camera cm = m_sceneView->currentViewpointCamera();
	 if(checked){
		 OrbitLocationCameraController camCtrl(baseSurfacePos, cm.location().z(), m_sceneView);
		 m_sceneView->setCameraController(&camCtrl);
	 }
	 else{
		 m_sceneView->setCameraController(mpDefaultCameraController);
		 m_sceneView->setViewpoint(pt);
	 }
	 m_sceneView->update();
}

 

 If I had set the DistanceInteractive to false, then the user would not be able to zoom in/out, right?

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Ah. I misread your previous post and thought you had wanted to lock the scale. My mistake 😬 But yes, that's what setting DistanceInteractive to false would have done.

But I'm a little surprised that your solution does what you want. The constructor you're using for OrbitLocationCameraController takes a focus point, and a distance from that focus point. What you have would work if the camera is looking straight down from directly above the point you're looking at, and if the elevation of the point you're looking at is 0.

I would expect that if you take your new code (with setViewpoint code in the else block), but use the OrbitLocationCameraController constructor from your original snippet, then you would get precisely what you want.

0 Kudos