Querying Location Collection and Calculating Midpoint — Multiple Markers on Google Maps with Wix…
Adventures with Wix Velo
Querying Location Collection and Calculating Midpoint — Multiple Markers on Google Maps with Wix Velo
Welcome back to my series on displaying multiple locations on Google Maps with Wix Velo. I’m excited and grateful that you’ve chosen to have a look into what I’ve learned, and I hope that you find this tutorial helpful.
We’re on our second episode of our five part series, and I hope you’re finding it valuable!
Our Goal For the Series
Our goal in this series is to build a website which fully integrates the display of multiple, dynamic map data points into a Google Maps display. We want to be able to update a location and have it almost immediately display on our website. If you’d like to read more about why this is important, here’s my introduction.
Working Example: The example we’ll be using is shown here.
Github / Code Repo: For those who find it useful, the public github repo is here.
Along the way, I’ll share couple of tips on some security considerations, along with helpful observations which will hopefully save you many hours of troubleshooting. The full list of episodes can be found at the bottom of each episode.
As always, I hope this content is helpful. It means the absolute world to me when you take time to clap for an episode, subscribe to my stories or use my referral link to sign up for Medium. It lets me know that my stories are helping you ❤️.
Enjoy, and feel free to drop me a DM on twitter, connect on LinkedIn / Github with thoughts and comments 😃
In This Episode
We’ll be covering the initial query and processing of our location information. Here’s the link to the full code for this episode.
We’ll be covering the following:
- Setup of our backend
.jsw
file to contain our backend functionality - Query of the dataset
- Calculation of a midpoint for our data, given a set of locations
- Combining the results together
Let’s get started!
Backend File Setup
In all modern web development, there is a differentiation between frontend and backend development. Both are pivotal for how websites work, and there is a whole bunch of discussion about what they contribute to the overall user experience.
When it comes to this project, we’ll be doing as much of our processing on the backend as possible, for the following reasons:
- User Experience. Data processing is typically compute intensive. To relieve the burden on our users (and save their battery life!) as much as possible, we want to shift as much data processing to our backend as possible. None of the calculations we’re doing on this example are super intensive, but it is just good practice to do this.
- Information Security. Data which is processed on the backend is typically more secure than front end processing. By focusing on the backend as our processing medium and only presenting a user with ‘their’ information, we limit the opportunities for malicious or unintentional exposure of data.
Here’s how we do this:
- On your Wix Editor, select Dev Mode (typically the top, right hand side of the screen)
- On the left hand side, navigate to the ‘Public & Backend’ setup
- ‘Backend’ section, click the + button
- Select ‘New Web Module’
- Create a file called
queryLastTenLocations.jsw
You should now have your backend file set up. Nice work!
Dataset Query
Some Notes About Wix
Wix has some awesome features which make it wonderful for web development. Here’s two which are relevant to our project:
- Based on
node.js
This means that almost all of our code (except for HTML Elements ironically) can be written in javascript, which really reduces our development time. - Fully featured set of API’s for the full stack of our development
The combination of these two elements is really going to help us out.
Asynchronous Queries
Wix makes extensive use of asynchronous functions (here’s a great post if you want to learn about this). These are denoted by the keywords await
and async
. As a general rule of thumb, all Wix Data queries are asynchronous. This means that if we need to perform sequential (otherwise known as synchronous) operations on the data we’ve asked for, we need to wait for ( i.e. await
) the data return before we move forward.
If you don’t do this, you’ll end with an error along the lines of promise unresolved
or you’ll discover that your code will tell you it was unable to perform operation on empty array
.
If you come across these errors during your development, take a quick look at your promises chains — you may find the error without too much heartache.
Query Collection
With that covered, let’s get going!
- Import the library we will use for querying our dataset
import wixData from 'wix-data';
- Create the function we will need for querying the dataset for the last ten entries. This function will be asynchronous and not exported (i.e. available outside this file). We’ll have no parameters as we want the query to do the exact same thing each time. I’ve called the function
async function getLastTenEntries(){}
Using the details about your collection from Episode 1, fill in the following details:
- Query the collection, filtering on a descending _createdDate, with no more than 10 entries.
- If the number of results is greater than 1 (i.e. the collection is non-empty), convert the field names into names which make sense given our application
- Catch an errors which occur
- Return the results
Here’s the code:
Mid Point Calculation
It turns out there’s a variety of methods to calculate midpoints when it comes to map locations. Without diving too deeply into debate, you can think of the discussion in several ways:
- Do we want the midpoint to be an equal distance from all locations? This might mean a lot of travel time for some people and less for others.
- Balancing the need for precision against computational resources.
- Accounting for the shape of the earth, which is not a perfect sphere.
If it’s a topic which interests you, here’s some interesting links: here, here and a great set of libraries if you need to be super accurate.
For our purposes, I’m using a method which is accurate enough to centre our map across the 10 coordinates. It’s reasonably simple, reasonably accurate and doesn’t require a huge amount of knowledge about coordinates.
The process we go through to calculate it is as follows:
- Convert our Decimal Degrees locations into radians
- Convert our radian locations into cartesian coordinates
- Calculate the average coordinates from our cartesian coordinates
- Revert our average coordinates back into radians
- Convert our radians coordinates back into Decimal Degress
- Return an object with our Decimal Degrees
(As a special note, this method also allows us to weight our locations if we wanted to. It’s not relevant for this project, but may be helpful for you somewhere else).
Here’s the code to do all of this:
Combining Together
Our final step is to combine our 10 locations together with our midpoint into a single JSON object. We’ll also need to specify our target, a concept explained further in episode 4. This is the object we will present to the frontend portion of the site.
We also need to identify the target to which our data is aimed. This will become more relevant in tutorial xxx when we start filling out our HTML Element.
The steps are:
- Use the
getLastTenEntries()
function to query the dataset for the last 10 locations - Pass these locations to the
calculateMidpoint(locations)
function to calculate their midpoint - Create an object to store the 10 locations, midpoint and target
- Return this object
Here’s the code:
Do A Quick Test
Let’s test this function to make sure it works.
- Select the ‘Play’ button on the Wix Editor next to the getLocationData()
- Once the screen pops up, push play again and have a look at the results. You should get an object which shows you the ‘Locations’, ‘Midpoint’ and ‘target’.
Make a note of the format of the data.
Wrapping Up Episode 2
And that’s a wrap for Episode 2! We’ve covered a lot!
In our next episode, we’ll be diving into our HTML Element and getting it ready to receive our locations!
List of Episodes:
The full list of episodes in this series are linked below to help you navigate quickly ❤