I want to obtain the center point of the SceneGraphicView's current viewport. Is that possible?
Solved! Go to Solution.
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.
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.
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.
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?
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?
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.