Building Interaction Sample

1297
9
04-20-2017 05:36 PM
RichieCarmichael
Esri Contributor
1 9 1,297

Animation of building interaction sample

This developer sample demonstrates how to interact with a multi-level building in three dimensions using Esri's ArcGIS API for JavaScript version 4.3. With a simple click/tap and drag operation a building can be intuitively and smoothly repositioned on the Earth's surface. Note that each floor is a separate graphic but are treated as a single entity when manipulated.

Click here for the live application.

Click here for the source code.

It is important to note that the sample uses a few undocumented API calls to achieve this behavior. As such we caution against using these calls in a production environment as they are unsupported and will very likely change in the near future.

The code may seem overly or unnecessarily complicated, below is a summary of what the code does:

  • Building Construction
    For portability reasons, building floors are constructed from a set of hardcoded values. It is important to note that each floor is an individual graphic attributed with a building identifier. This identifier is used to group all adjacent floors for highlighting and spatial translation.
  • Dragging
    The code is using the SceneView's drag event to respond to the three phases of a pointer's drag operation, namely start, update and end. During the "start" phase, a hittest is performed to identify the building floor (if any) under the pointer. If a floor is found, adjacent floors are identified and highlighted. In the "update" phase, two undocumented methods SceneView._stage.pick and SceneView._computeMapPointFromIntersectionResult are used to tracking pointer displacement in real world coordinates. These methods return the map location directly beneath the pointer, ignoring features and graphics.
  • Disabling/Enabling Pointer Interaction
    When a building is dragged to a new location, it is necessary to disable map interaction so that map does not pan. To achieve this we used another undocumented method, SceneView.inputManager, to add and then restore handlers.
  • Moving
    At present, it is not possible to update the geometry of an existing graphic. In order to show a graphic moving it must be deleted and then re-added. This may seem somewhat cumbersome but the performance hit is negligible.
  • Throttling
    It is likely that the rate of the drag event is fired will exceed the display frame rate. If the display is performing at 60 frames per second (or better) then excessive drag events are ignored.

Once again I would like to stress that this is a developer sample specifically for version 4.3 of the Esri JavaScript API. It is very likely that some of the code used is this application will be either obsolete or redundant (or both) in future releases.

Special thanks to Johannes Schmid‌ for his technical expertise!

9 Comments
VirNaidoo
New Contributor

Hi Richie Carmichael ,

   I' d like to know could i use my buildings in sceneLayer to achieve this function???

RichieCarmichael
Esri Contributor

Hi Naidoo‌, no it is not possible to edit or move single features in a SceneLayer.  But having said that I have seen one of my colleagues demonstrate a simulated editing workflow.  When a user clicks on a building (from the SceneLayer) create a new graphic using the building's cloned geometry.  Hide the clicked building using a definition query on the SceneLayer.  Use the logic described in this post to translate the cloned building. Hope this helps!

VirNaidoo
New Contributor

Hi Richie Carmichael ,

   What you said is important to me , but how can i  hide the building with definition query?

Do you have any demo that i can learn to?? 

thank you advance.

RichieCarmichael
Esri Contributor

Vir Naidoo‌, click here to learn how to define a scene layer definition expression.

VirNaidoo
New Contributor

Hi Richie Carmichael ,

   I want to know if three is any way to achieve using click event in sceneView  to find which building i have clicked? If so, how to achieve it,please show me the detail,thanks advance.

RichieCarmichael
Esri Contributor

Vir Naidoo‌, to display the name of a clicked building you could do something like this:

_view.on("click", function (e) {

    // Stop propagation.

    e.stopPropagation();

 

    // Perform hittest to get clicked building (if any).

    _view.hitTest(e.screenPoint).then(function (p) {

        if (!p || !p.results || p.results.length === 0) { return; }

        var graphic = p.results[0].graphic;

        if (!graphic) { return; }

 

        // Popup name of clicked building.

        alert(graphic.attributes.name);

    });

});

VirNaidoo
New Contributor

Hi Richie Carmichael ,

   First, I am very grateful for your help , and this time i want to know is the graphic.attributes.name, where did it from ?

is it from the attributes table i have add it in my attributes  table??

thanks advance.

VirNaidoo
New Contributor

and Richie Carmichael ,

Here is an another question, I have used your code,but the result is not right. the graphic.attributes.only have an OBJECTID attribute, did not include name or other.

So , how do you think to solve this??

thanks advance.

RichieCarmichael
Esri Contributor

Vir Naidoo‌, I admire your curiosity and enthusiasm but I think that taking advantage of Esri's online training material might be a more effective way of gaining the necessary knowledge. On Esri's training page there are more than 30 JavaScript related courses most of which are either free or complimentary with a current maintenance subscription.  For more information please contact your local Esri distributor.