[Distance Between Coordinates] Speed up or replace server extention finding distance

Forge Component
(7)
Published on 2016-04-26 by Bryan SanAndres
7 votes
Published on 2016-04-26 by Bryan SanAndres

Hello all :)

I have a customer database that consists of approximately 3200 addresses.  I am using a server extension to update the distance between the user (mobile)  and the customer.  In the server action, I select the aggregate then run a loop updating each account.  I then run an action to download the customers that are within a certain distance to a local table.  The issue is this takes over a minute and a half to complete.  Is there a quicker to do this?


Thanks for your time

Stay Safe


I think no. Think about the calculation which is made inside the distance caluculation extension. But it would be of interest, if there is a faster solution.


Hello Andrew,

What you can do is to create your own JavaScript action that calculates the distance between coordinates.

It will run client side and it is going to be very fast.

You can use the Harversine Formula:

https://stackoverflow.com/questions/14560999/using-the-haversine-formula-in-javascript


I did this in my application and it's working perfectly. Using the extension it's certainly not a viable scenario.


Let me know if you need any extra help.


Kind regards,

Rui Barradas

Rui Barradas wrote:

Hello Andrew,

What you can do is to create your own JavaScript action that calculates the distance between coordinates.

It will run client side and it is going to be very fast.

You can use the Harversine Formula:

https://stackoverflow.com/questions/14560999/using-the-haversine-formula-in-javascript


I did this in my application and it's working perfectly. Using the extension it's certainly not a viable scenario.


Let me know if you need any extra help.


Kind regards,

Rui Barradas

Thanks, Rui-

Unfortunately, I don't know the first thing about javascript integration.

Any chance you could point me in a direction to get this done?




Just out of curiosity, Rui,

I would imagine that the speed of calculation shouldn't be that different whether done on local device in Javascript or on server side in .Net.  Or is this the case, is Javascript known to be faster ?


Andrew,

I see more reason for performance problems in the fact that you are updating the database with the calculation results.  Could you try to avoid that, and maybe just build a local list with results, and then sort it on distance and return the top n ?  Just to see if that is any faster.


Dorine

Andrew Finkelstein wrote:

Rui Barradas wrote:

Thanks, Rui-

Unfortunately, I don't know the first thing about javascript integration.

Any chance you could point me in a direction to get this done?

Yes, of course Andrew.

Basically what you need to do is to create a new client action called for example DistanceBetweenCoordinates (every single parameter is a decimal):


Then, you need to place a JavaScript node inside of that action's flow.

And here's my JavaScript code (implementation of the Harversine Formula) that returns the Distance between 2 points:


In the end you just need to assign the output parameter of the JavaScript node to the action's output parameter.

For this particular scenario, the returned distance is in KM and the coordinates from both points are in degrees.

Anyways, I will create a new Forge component with these actions and let you know.


Let me know if you need anything else.


Kind regards,

Rui Barradas

Dorine Boudry wrote:


Just out of curiosity, Rui,

I would imagine that the speed of calculation shouldn't be that different whether done on local device in Javascript or on server side in .Net.  Or is this the case, is Javascript known to be faster ?

Hello Dorine,

Regarding to your question, the speed of any code that is running client side is faster than running it server side. And the main reason is (obviously) because you don't need to go to the server and everything is executed locally in the device. So you avoid any calls and connections between the device and the server (which of course takes time).


Regarding to this particular situation, additionally I verified that these calculations use an extension that is not particularly fast. I don't know the .Net code behind it, but I did a debug and everytime I called the extension, it took a certain time. If you multiply this for 3200 addresses, it will take a long time to execute the flow. That's why I decided to create my own JavaScript code and everything became instantaneous.


Kind regards,

Rui Barradas

Ok,

Thanks for the clarification Rui.  

I wasn't thinking of extra calls to server, but doing calculations after fetching records from database, that server call has to be done anyway.

Anyway, as you say, it all depends on how things are implemented, and you compared speed of that Forge component to you own javascript implementation.  As they say, the proof of the pudding is in the eating.

Cheers,

Dorine

No problem at all Dorine.

Let's hope that Andrew manages to solve his problem as well.


Kind regards,

Rui Barradas

Question-

These calculations can be done client-side and would be faster.  How do I do that?  Would much rather do it on a local table than do a server call

Hi Andrew,

In my project, basically I have a list of around 500 branches that I need to loop in order to get the closer branch to me (according to my GPS coordinates). I have these 500 branches in a server database table, so I just have to fetch this information to the screen, then I have a client action that performs a loop over the branches and run this DistanceBetweenCoordinates action for each one of them. It works like a charm. But I don't need to update the server database after this process.


As far as I can tell, you can perform some similar approach and update the server DB during the process if you need to.


Kind regards,

Rui Barradas

Rui Barradas wrote:

Hi Andrew,

In my project, basically I have a list of around 500 branches that I need to loop in order to get the closer branch to me (according to my GPS coordinates). I have these 500 branches in a server database table, so I just have to fetch this information to the screen, then I have a client action that performs a loop over the branches and run this DistanceBetweenCoordinates action for each one of them. It works like a charm. But I don't need to update the server database after this process.


As far as I can tell, you can perform some similar approach and update the server DB during the process if you need to.


Kind regards,

Rui Barradas

That is the exact solution I am looking for.  Could you walk me through it please


Hello again Andrew,

Sure, but it's just pretty much what I had already told you :)


1) Perform a fetch (server database) in order to get those 3200 addresses to your screen

2) Create a client action DistanceBetweenCoordinates with the logic above to calculate the distances

3) Create a client action GetNearestAddress that receives a list of addresses as input and returns the nearest address to your location


In my case, I have the coordinates of those 500 branches in the database. You should have them too for your 3200 addresses in order to perform the calculations.

In this GetNearestAddress action you need to calculate the distances between your device's location and the addresses' locations. Then you just need to compare if it is closer or not over your list.


Kind regards,

Rui Barradas

Hi Andrew and Rui,


I have done a small demo for testing this on server side, and I don't think the calculation on server side with the forge component's action is the cause of your performance problem.  See attached oml, even with 20000 customer locations in the database, it still comes up with the closest in about 3 seconds.  With only 3000 in the database, it comes back within a second.

Just in case you don't feel like writing this yourself in Javascript, Andrew.

Happy coding,

Dorine

Hi Dorine,

Thanks for your sharing.

I was checking my previous code and I've found this:


This was my previous code (basically the same logic, but server side) that was causing me lots of performance problems. With only 300 records in the DB, it took like 1.5 to 2 minutes to run.

I was using this extension: DistanceFromCoordinate.


Dorine, can you please verify if you're using the same extension or a different one?


Back in the day, I did some debugging and I saw that it took a while everytime I called that CountDistance server action. That's why I decided to implement my own action in JavaScript.


Kind regards,

Rui Barradas

Ah, that's probably it then, that is not the extension I'm using.  I'm using the one that Andrew is using (see title of this post)

I still think the most likely reason his action is taking minutes, must be because he's doing an update of 3000 records in the database.

Dorine Boudry wrote:

Hi Andrew and Rui,


I have done a small demo for testing this on server side, and I don't think the calculation on server side with the forge component's action is the cause of your performance problem.  See attached oml, even with 20000 customer locations in the database, it still comes up with the closest in about 3 seconds.  With only 3000 in the database, it comes back within a second.

Just in case you don't feel like writing this yourself in Javascript, Andrew.

Happy coding,

Dorine

I will give it a try.  Thanks


It could be because of the several updates, that's indeed a possibility.

I though it was the same extension but they are different as we can see. I totally advise everyone to not use the other one ^^


@Andrew, you have basically my solution using JavaScript (that's what I have in production environment right now in my application), but Dorine's point is valid as well (as you can see in the demo).


Let us know your conclusions.


Kind regards,

Rui Barradas

Hello Andrew,

Any news regarding this thread?


Kind regards,

Rui Barradas

Hi Rui!

Thanks for providing such incredible support on this thread. We worked the JavaScript into a client-side action. We’ll upload a new version of the component in the next few days.

Let me know if there’s anything else we could work into the component. 

Problem was taken care of.  For some reason, it just started working much faster.   Thank you all for your help