Search for answers or browse our knowledge base.
Floor Plan
Objective
To gain familiarity with the ClientBuilder and GeoJSON objects to build real-world location-tracking applications
Purpose
- Create a client with a floorplan widget
- Define the dimensions of the area to be tracked
- Use geoJSON datatypes to deliver relevant location information, which will be shown graphically in the Client
Tutorial Overview
This tutorial guides a developer through creating a floor plan client in the Vantiq system. It uses simulated data to display residents moving in a two-story building. The lessons include definition of a resident data type, generation of simulated motion data, and the definition of a floor plan client to display the data.
All sections assume the developer has a working knowledge of the Vantiq IDE. It is recommended that a new developer completes the Introductory Tutorial before starting this tutorial.
Note: if needed, you can import a finished version of this project using the Projects -> Import menu item. Just select Tutorials for Import Type, then select Floor Plan from the second drop-down, then click Import.
1: Creating a Floor Plan Project
The first task in learning about the Vantiq floor plan widget is to create a project in the Vantiq IDE to assemble all the client components.
Use the Projects button, select New Project, which displays the New Project Wizard. Either create a new Namespace (recommended) or add a new project to the current Namespace, select Empty as the Project type, and title the project “FloorPlan”:
The rest of this tutorial will take place inside this Project.
2: Creating a Data Type
The simulation data for this example needs to be stored in the Vantiq database so that it can be used to drive the floor plan client widget. You must create a data type to specify the data associated with each simulated building resident.
Use the Add button to select Type…:
Use the New Type button to create the Resident type. Give it the standard type.
The Resident type contains three properties:
- floor: a String which identifies the floor on which the resident is standing
- location: a GeoJSON object which identifies the X and Y coordinates of the resident on the given floor
- name: a String which is the unique identifier of the resident
While the location property is defined as GeoJSON, the values of the property are not latitude and longitude values for floor plan purposes. Specifically, the coordinates property of the GeoJSON object will contain the X and Y coordinate offsets from the upper-left corner of the floor plan image you’ll define in the next section. The longitude coordinate property is the X offset coordinate and the latitude coordinate is the Y offset coordinate.
Once these three user properties are defined, use the Save button to save the Resident type and add it to the Project.
3: Simulating Resident Data
Now that you’ve created the resident data type, use the IDE to simulate residents changing location in a two-floor building. We will use the Event Generator tool to simulate resident data streams.
Use the Test button to select Event Generators and click New Event Generator. Name the Event Generator ResidentGenerator.
Click the New button in the Event Generator pane to add a new Event Descriptor. Select Types as the resource, Resident as the resourceId, and INSERT as the operation. Set the Repeat For type to Iterations and set the value to 20. Set the Interval to 1 second. This means that the Event Descriptor will generate 20 inserts on the Resident type at a rate of one per second.
Click on the Properties dropdown to configure the instance data.
Set the floor property variation type to Set and click the Random checkbox. Click Edit Set of Strings next to the floor property. Configure the list to contain two values: one and two. This is the set of possible floor values. At runtime a value will be randomly selected from the set.
Set the variation type for the location property to Range and check Random. Click Origin to set the Origin GeoJSON value.
Set the Location Type to Point and set the latitude and longitude to 5.
Click Destination to set the Destination GeoJSON value. Set the Location Type to Point and set the longitude to 25 and longitude to 20.
By setting the origin and destination values, you are having your user show up in a random location well within the confines of the floor plan. The X and Y coordinates of the GeoJSON object are the X and Y offsets from the upper-left corner of the floor plan image.
Set the name property variation type to Set. Click Edit Set of Strings next to the name property. Configure the list to contain three values: alice, bob, and carol. This is the set of names. At runtime, the name of the event will cycle through these three names.
You now have an Event Generator ready to stream 20 Resident motion points to the Vantiq database.
Use the Save button to save the generator and return to the Project.
4: Visualizing a Running System
Now we will use the IDE’s Client Builder feature to create a visual representation of two floors of a building, as well as the movements of residents around those floors.
Use the Add button to select Client…, then use the New Client button to display the New Client dialog:
Enter “Resident” as the Client Name and use the default Design for browser radio button since we’ll be running our client in a browser. Use the OK button to display the Client Builder.
Drag and drop two Plan widgets and two Label widgets from the Data Display list to the canvas area below the widget palette to create a Client Builder layout similar to this:
We’ll get to configuring each widget later so don’t worry about the exact appearance of the widgets yet.
Now that the Client Builder widgets appear in the canvas, we need to create a Data Stream to feed live data for display in the widgets. A Data Stream defines from where a client widget receives its data. The Floor Plan widgets want to display location values, which are found in the Resident records which are generated from the simulated data in Section 3.
Select the Edit tab to see the Data Streams menu item, then right click it to create a new ‘On Data Changed’ Data Stream. The Create New Data Stream dialog is displayed:
Name the Data Stream “Resident”, then select Resident from the type menu and check the Insert checkbox. In addition, the Floor Plan widget makes use of the Group By feature to differentiate residents on each floor of the floor plan. The example uses the resident name (select name (String) from the Group By pull-down) since it is used to uniquely differentiate residents on each floor of the floor plan. Use the Save button to save the new data stream.
There are two display widgets and two label widgets in the diagram above. What follows are the properties for each of those widgets. Any property not mentioned is the default value for that widget. To display the property sheet for any widget, click on the widget. For example, here is the property sheet for the First Floor floor plan:
Floor Plan widgets rely on four properties to be set:
- URL: the location of an floor plan image. The example uses the default the IDE floor plan image but an image URL will work (e.g. http://strandexecutivepark.com/data/uploads/floor-plans/5625floorplan.gif).
- Width and Height: configure how wide and deep the floor plan represents in units (e.g. feet or meters) that match those used in the GeoJSON data. The actual units don’t matter as long as the floor plan dimensions are expressed in the same units as the GeoJSON X and Y offsets in the Resident record. The example uses the default dimensions of 30×25.
- Filter Properties: a JSON object that is used to associate a resident with a particular floor plan. The example uses the floor property of the Resident record to determine whether the resident should be located on floor “one” or “two”. In a more complicated example, a client might want to locate a resident on one of several campus sites, on a specific floor in a specific building. In that case, a Filter Properties JSON object could take the form {“campus”:”Downtown”,”building”:”Psychology”,”floor”:”one”}.
For the First Floor Floor Plan widget (left):
Data Stream: Resident
Filter Properties: {"floor":"one"}
Data Stream Property: location
Label Property: name (String)
For the Second Floor Floor Plan widget (right):
Data Stream: Resident
Filter Properties: {"floor":"two"}
Data Stream Property: location
Label Property: name
For the label widgets (above each Floor Plan widget):
Text: First Floor/Second Floor
Font Size: 20
When you have finished adding and configuring your client widgets, use the Save button to save the client and return to the IDE. The Floor Plan widgets are bound to a data stream and will automatically display data received from the defined data stream. Next, we will use the Event Generator created in section 3 to produce simulated resident data and run your client.
5: Running the Simulation
The last step of this tutorial is to start the event generator and observe the output from the Vantiq system in real-time.
From the Project Content side bar, open the Client list, then click the Click the Resident listing. This will bring up the Resident Client if it’s not visible already.
Use the Run icon button of the Client: Resident pane (small triangle in a square at the top, right of the pane).
To begin the test, open the ResidentGenerator Pane and click the Run Generator button.
As the generator inserts simulated resident motion data in the Vantiq database, colored markers will appear on the two image map images:
In this simple example, a resident be generated in a random location within the floor. In a real-world scenario, the coordinates might be provided by motion sensor or signal strength readings from wireless access points which move the resident markers in a more realistic manner.
The event generator will terminate after 20 seconds.
6: Customizing Markers
The Floor Plan widget (as well as the Map widgets) have two properties in the Specific set that allow the user to customize the markers used for data points: Marker Array and Marker Hash. Use the Marker Array link in the Floor Plan widget’s property sheet to display the Marker Array dialog: