Easy OpenStreetMaps With Mendix
This article intends to show an easy procedure to incorporate Map Visualization in your Mendix Application, considering that you have only the Street Address
If you need to use maps with a Mendix-made web application, the procedure is very straightforward: just drop a Map widget and add a Marker with the Latitude and Longitude. You don’t need even a Dataview and an Entity with the marker coordinates as attributes. The coordinates can be configured hardcoded in the widget. But what happens if the coordinates are unknown?
Fortunately, if it is your case, you can use a service provided by the site Nominatim, which provides geocoding based on OpenStreetMap data.
Procedure
- [1] In Studio Pro (here is used 9.24.23), create a New App using the Blank Web Application.
- [2] We need to use the Nominatin Rest API. In order to test this service, use the curl command below in a Windows Terminal:
curl 'https://nominatim.openstreetmap.org/search?q=22+Boston+Wharf+Rd+Boston,+MA+02210,+United+States&format=json&limit=1'
- [3] There’s an endpoint called Search that we can use to get the data from the desired Street Address. The result is a JSON containing the results:
[
{
"place_id": 18204742,
"licence": "Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright",
"osm_type": "relation",
"osm_id": 6775971,
"lat": "42.35043815",
"lon": "-71.04698594908186",
"class": "building",
"type": "yes",
"place_rank": 30,
"importance": 8.102616922250732e-05,
"addresstype": "building",
"name": "22 Boston Wharf Road",
"display_name": "22 Boston Wharf Road, 22, Boston Wharf Road, Seaport, South Boston, Boston, Suffolk County, Massachusetts, 02210, United States",
"boundingbox": ["42.3501037", "42.3507926", "-71.0473963", "-71.0465607"]
}
]
- [4] Back to Studio Pro, create a JSON_structure. Copy/Paste the JSON above in the JSON snippet field. Click on the Refresh button in Studio Pro to parse the JSON
- [5] Create an ImportMapping object and configure it to use the JSON_Structure defined in the previous step. Observe the Schema elements. You can select all or just the minimal elements needed, as shown in the figure:
- [6] Click on the button Map automatically … to instruct Studio Pro to create a Non-Persistent Entity responsible for holding the results from the API call.
- [7] Go to Domain Model and rename the JsonObject entity to Nominatim. Then, create another Non-Persistent Entity called Local as shown below. This entity should have only one attribute called QueryAddress and an association 1–1 to Nominatim.
- Optionally, you can define a default address in the QueryAddress attribute:
- [8] Create a Microflow DS_Local_Create to instantiate the Local entity. The result of the Microflow will be used as datasource in the next step.
- [9] Drop a DataView on the Home_Web page. Configure the DataView to use the Microflow DS_Local_Create. In the DataView, add a TextBox and configure it to use the QueryAddress attribute from the Local Entity.
- [10] Drop another DataView, this time nested to the previous. Configure this DataView to use the Nominatin context, via Local association. Then, drop a Map inside this DataView. After double-clicking on the Map to access the Properties dialog box, go to the Advanced tab and choose Open street as the Map provider.
- [11] Go to the General tab and add a New Marker to the list of static locations (the topmost list). Select Based on latitude and longitude in the Location groupbox. For the Latitude field, configure it as the Nominatim/Lat attribute using a parametric caption. Repeat the procedure for the Longitude (Nominatim/Lon) and Title (Nominatim/Display_text) fields.
- Almost Done! Now we need to find a way to fire the Rest API call. In my case, I decided to use the On Enter key press event of the QueryAddress text box linked to a Microflow that does the job.
- [12] Double-click on the QueryAddress text box and create a Microflow called ACT_Local_ExecuteQueryAddress for the On Enter key press:
- [13] This Microflow is automatically created with a Local object as a parameter. We will use the Local/QueryAddress value to call the Nominatim service. To do so, first, we need to prepare this query, as such a query cannot have any blank spaces (or special characters) on it. Create a string variable called QueryAddressNoSpaces and call the function urlEncode passing the Local/QueryAddress as a parameter to convert the address to a valid URL:
- [14] Drag a Call Rest Service to the Microflow. Double-click on it and, in the General tab, define the Location as shown below. Observe that we are using the string created in the previous step as a parameter to the Endpoint definition:
https://nominatim.openstreetmap.org/search?q={1}&format=json
- [15] In the Response tab, choose Apply import mapping as Response handling. Select the Import_mapping defined in the Step 5. Select the First in Range and Yes in Store in variable. Use NominatimResult as a Variable name:
- [16] Add a Decision in the Microflow to confirm that the NominatimResult is not empty. We can use the Studio Pro logic bot to help us in this task:
- [17] Add a Change object activity to define the association between the Local object and the NominatimResult. To do so, click on New and select the association in Member and the $NominatimResult as Value:
- [18] Eventually, Rest API calls may fail. Therefore, we must protect the application against errors. Right-mouse click on the Call Rest (GET) activity, then click on Set error handling…, and select Custom with rollback on Type:
[19] Drag a flow from the yellow circle to create a new branch in the Microflow. This flow will handle a possible error in the Rest API call. For the sake of simplicity, we just log an error message with the Log message activity in the console. We can use the same approach in the False branch of the Decision. At the end, the Microflow will be like:
[20] We’re done! After running the application, this is the result after pressing Enter in the Query address textbox:
Comments
- Obviously, this code is very simple and certainly can be improved a lot. The main goal here was to demonstrate how easy is to use the Nominatim service in a Mendix-made web application.
- Worth noticing that Nominatim, despite the fact is a free service, runs on servers with limited capacity. Please read the Nominatim Usage Policy for more details.
Source Code
You are welcome to clone this project from my personal GitHub and file any issues or solutions!
Acknowledgments
I would like to thank Bianca Gugelmin for this helpful tip.