How can I get the SceneView size?

216
1
Jump to solution
09-05-2017 04:13 AM
LarsFagerbakke
New Contributor III

How can I get the SceneView size in kilometers? I guess it would be based on the current zoom and the actual pixel size of the container, but have anyone done this?

0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Regular Contributor

What do you mean by size of the scene?  If you want the distance between the left edge of the sceneview and the right edge, then I would just find the distance between those two points.  You'll have to decide whether you want a planar or geodesic measurement.

Here's a code sample for this:

// pull in esri/geometry/geometryEngine and esri/geometry/Polyline

// args: sceneView: SceneView, planar: boolean
function getSceneWidth(sceneView, planar){
  let leftBound = {x: 0, y: sceneView.height/2}; // left edge of scene in pixels
  let rightBound = {x: sceneView.width, y: sceneView.height/2} // right edge of scene in pixels

  // iterate along scene until we have a valid point
  // this is necessary if the scene is zoomed out and the
  // left/right edges are in space
  while(!sceneView.toMap(leftBound)){
    leftBound = { x: leftBound.x + 1, y: leftBound.y };
  }

  while (!sceneView.toMap(rightBound)){
    rightBound = { x: rightBound.x - 1, y: rightBound.y };
  }

  let p1 = sceneView.toMap(leftBound);
  let p2 = sceneView.toMap(rightBound);

  // planar measurement
  if (planar) {
    // find in meters, divice by 1000 to get to km
    return p1.distance(p2) / 1000;
  } else {
    // geodesic measurement
    let polyline = new Polyline({
      paths: [ [p1.longitude, p1.latitude], [p2.longitude, p2.latitude] ],
      spatialReference: { wkid: 4326 }
    });
    return geometryEngine.geodesicLength(polyline, 'kilometers');
  }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Another option is to take the ratio between some distance in meters (or whichever linear unit) and that same distance in pixels and use that to convert.  The issue with this method in a sceneview is that that ratio will vary based on where on the globe you're measuring, even at the same zoom.

View solution in original post

1 Reply
ThomasSolow
Regular Contributor

What do you mean by size of the scene?  If you want the distance between the left edge of the sceneview and the right edge, then I would just find the distance between those two points.  You'll have to decide whether you want a planar or geodesic measurement.

Here's a code sample for this:

// pull in esri/geometry/geometryEngine and esri/geometry/Polyline

// args: sceneView: SceneView, planar: boolean
function getSceneWidth(sceneView, planar){
  let leftBound = {x: 0, y: sceneView.height/2}; // left edge of scene in pixels
  let rightBound = {x: sceneView.width, y: sceneView.height/2} // right edge of scene in pixels

  // iterate along scene until we have a valid point
  // this is necessary if the scene is zoomed out and the
  // left/right edges are in space
  while(!sceneView.toMap(leftBound)){
    leftBound = { x: leftBound.x + 1, y: leftBound.y };
  }

  while (!sceneView.toMap(rightBound)){
    rightBound = { x: rightBound.x - 1, y: rightBound.y };
  }

  let p1 = sceneView.toMap(leftBound);
  let p2 = sceneView.toMap(rightBound);

  // planar measurement
  if (planar) {
    // find in meters, divice by 1000 to get to km
    return p1.distance(p2) / 1000;
  } else {
    // geodesic measurement
    let polyline = new Polyline({
      paths: [ [p1.longitude, p1.latitude], [p2.longitude, p2.latitude] ],
      spatialReference: { wkid: 4326 }
    });
    return geometryEngine.geodesicLength(polyline, 'kilometers');
  }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Another option is to take the ratio between some distance in meters (or whichever linear unit) and that same distance in pixels and use that to convert.  The issue with this method in a sceneview is that that ratio will vary based on where on the globe you're measuring, even at the same zoom.

View solution in original post