Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Calculate distance between points + sort them (WORKS!)
Started by FoxB Aug 01 2013 02:02 AM

27 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

Hi all,

 

I have been working on a piece of code I'd like to share with you. Its not a question, the code really works!

 

Features:

- Calculate distance between 2 points

- Sort points (longitude, latitude) by your 'GPS position'

 

I used two sources aswell, because I am not so good at math you know ;p

 

 

Have fun with it!

 

-- source print_r function: https://gist.github.com/nrk/31175
-- source distance between 2 points: http://awesome.naquadah.org/wiki/Kooky_geo

function print_r ( t )
    local print_r_cache={}
    local function sub_print_r(t,indent)
        if (print_r_cache[tostring(t)]) then
            print(indent.."*"..tostring(t))
        else
            print_r_cache[tostring(t)]=true
            if (type(t)=="table") then
                for pos,val in pairs(t) do
                    if (type(val)=="table") then
                        print(indent.."["..pos.."] => "..tostring(t).." {")
                        sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
                        print(indent..string.rep(" ",string.len(pos)+6).."}")
                    else
                        print(indent.."["..pos.."] => "..tostring(val))
                    end
                end
            else
                print(indent..tostring(t))
            end
        end
    end
    sub_print_r(t,"  ")
end

-- Locals
local cos = math.cos
local sin = math.sin
local pi = math.pi
local sqrt = math.sqrt
local min = math.min
local asin = math.asin
local abs = math.abs

-- Calculate distance
 function distance(from, to)
  local distance = 0
  local radius = 6367000
  local radian = pi / 180
  local deltaLatitude = sin(radian * (from.latitude - to.latitude) /2)
  local deltaLongitude = sin(radian * (from.longitude - to.longitude) / 2)

  local circleDistance = 2 * asin(min(1, sqrt(deltaLatitude * deltaLatitude +
     cos(radian * from.latitude) * cos(radian * to.latitude) * deltaLongitude * deltaLongitude)))
  distance = abs(radius * circleDistance)
  return distance
 end

 -- Markers
local markers = {
    { title='Nova Scotia', latitude = -62.937013, longitude = 45.367584}, --  will become position 3
	{ title='Brooklyn', latitude = -73.949204, longitude = 40.644178}, -- will become position 1
	{ title='South Philadelphia West', latitude = -75.181275, longitude = 39.918163} -- will become position 2
}

-- Center; could be your current GPS location
centerPoint = {latitude = -73.995895, longitude = 40.718119} -- new york

-- Set distances in markers
for i, Prop in ipairs(markers) do
	Prop['distance'] = distance(centerPoint, markers[i])
end

-- Sort by distance
function compare(a,b)
  return a['distance'] < b['distance']
end
table.sort(markers, compare)

-- Print sorted markers
print_r(markers)

 

Output:

 

  [1] => table: 002ABBC0 {
           [longitude] => 40.644178
           [latitude] => -73.949204
           [title] => Brooklyn
           [distance] => 5662.823745369
         }
  [2] => table: 002ABBC0 {
           [longitude] => 39.918163
           [latitude] => -75.181275
           [title] => South Philadelphia West
           [distance] => 133824.02894993
         }
  [3] => table: 002ABBC0 {
           [longitude] => 45.367584
           [latitude] => -62.937013
           [title] => Nova Scotia
           [distance] => 1242546.4018208
         }

 



[TOPIC: post.html]
#2

sangam687

[GLOBAL: userInfoPane.html]
sangam687
  • Observer

  • 17 posts
  • Corona SDK

thank you, this code really work very well,

but i want to know, this distance is in which unit(meter, km,feet,)..?

and how can i change in other unit?

 

please reply me if you have any answer



[TOPIC: post.html]
#3

horacebury

[GLOBAL: userInfoPane.html]
horacebury
  • Corona Geek

  • 3,027 posts
  • Corona SDK

You should really post to the Code Exchange: http://code.coronalabs.com/



[TOPIC: post.html]
#4

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

thank you, this code really work very well,

but i want to know, this distance is in which unit(meter, km,feet,)..?

and how can i change in other unit?

 

please reply me if you have any answer

 

Thank you! No problem.

The results are in meters :)



[TOPIC: post.html]
#5

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

You should really post to the Code Exchange: http://code.coronalabs.com/

 

I have been thinking about this, but isn't it a little overhead to create a new repository (Github) just for this piece of code? :)



[TOPIC: post.html]
#6

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

[TOPIC: post.html]
#7

tomaswesterlund

[GLOBAL: userInfoPane.html]
tomaswesterlund
  • Contributor

  • 306 posts
  • Corona SDK

Thanks for the code Sneeuw, I'm using it right now in one of my apps.

 

Best regards,

Tomas



[TOPIC: post.html]
#8

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

Thanks for the code Sneeuw, I'm using it right now in one of my apps.

 

Best regards,

Tomas

 

Great! :)

 

Don't mind to drop the app name/url after you released it. Don't worry; I won't take credits ;)



[TOPIC: post.html]
#9

tomaswesterlund

[GLOBAL: userInfoPane.html]
tomaswesterlund
  • Contributor

  • 306 posts
  • Corona SDK

[TOPIC: post.html]
#10

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,241 posts
  • Enterprise

Just as an FYI on the code exchange....   We recognize that setting up a GitHub account and sharing code through there has some overhead.  This is one reason we support GIST as well.  GIST uses GitHub technology but allows you to quickly share shorter code snippets that are not full projects.  If you have a single function or several that might be in one file, GIST is a much faster way to share that code out.

 

You still have to setup an account, but when it comes to sharing the code, it's a single form.  Check out:  https://gist.github.com/

 

Rob



[TOPIC: post.html]
#11

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

sir can you show me a code similar to this but will only output the nearest marker from your current GPS location(not constant)? I am developing an android app that has a mapview with markers around it, and will be capable of calculating the distance between your current GPS location from the nearest marker.. thank you and more power!



[TOPIC: post.html]
#12

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

sir can you show me a code similar to this but will only output the nearest marker from your current GPS location(not constant)? I am developing an android app that has a mapview with markers around it, and will be capable of calculating the distance between your current GPS location from the nearest marker.. thank you and more power!

 

I think this can simply done by changing this line:

---------------

centerPoint = {latitude = -73.995895, longitude = 40.718119} -- new york

---------------

 

Change the variable to your current GPS location. See more details at http://docs.coronalabs.com/api/event/location/longitude.html

If you want to update your GPS more often, see more details at http://forums.coronalabs.com/topic/36981-gps-location-update-frequency/

 

I hope this will help you :)



[TOPIC: post.html]
#13

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

I'm still confused but thanks a lot for the reply. This might help me solve this problem. And how about displaying only the nearest marker without sorting and displaying all markers?



[TOPIC: post.html]
#14

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

I'm still confused but thanks a lot for the reply. This might help me solve this problem. And how about displaying only the nearest marker without sorting and displaying all markers?

 

Sorry, if I'd be making codes for anyone, I wouldn't even have time left for my own projects.

 

You have to go thru all markers in order to sort them by distance. If you only want the nearest, just only show the first item in the array. 

 

I hope this helps.



[TOPIC: post.html]
#15

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

Thanks a lot sir. I've sorted things out. :)



[TOPIC: post.html]
#16

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

Thanks a lot sir. I've sorted things out. :)

 

:) Great! Thanks for your feedback.



[TOPIC: post.html]
#17

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

**These lines of code will display the output of the distance of your current location from the nearest marker in the corona simulator but the problem is, whenever I run this code in my Android App it doesn't display anything.. Can someone give me an idea about how to display my output in Android?**

function print_r ( t )
local print_r_cache={}
local function sub_print_r(t,indent)
if (print_r_cache[tostring(t)]) then
print(indent.."*"..tostring(t))
else
print_r_cache[tostring(t)]=true
--if (type(t)=="table") then
for pos,val in pairs(t) do
if (type(val)=="table") then
print(indent.."["..pos.."] => "..tostring(t).." {")
sub_print_r(val,indent..string.rep(" ",string.len(pos)+8))
print(indent..string.rep(" ",string.len(pos)+6).."}")
else
print(indent.."["..pos.."] => "..tostring(val))
end
end
--else
--print(indent..tostring(t))
--end
end
end
sub_print_r(t," ")
end

-- Locals
local cos = math.cos
local sin = math.sin
local pi = math.pi
local sqrt = math.sqrt
local min = math.min
local asin = math.asin
local abs = math.abs

-- Calculate distance
function distance(from, to)
local distance = 0
local radius = 6367000
local radian = pi / 180
local deltaLatitude = sin(radian * (from.latitude - to.latitude) /2)
local deltaLongitude = sin(radian * (from.longitude - to.longitude) / 2)

local circleDistance = 2 * asin(min(1, sqrt(deltaLatitude * deltaLatitude +
cos(radian * from.latitude) * cos(radian * to.latitude) * deltaLongitude * deltaLongitude)))
distance = abs(radius * circleDistance)
return distance
end

-- Markers
local markers = {
{ title='sasa1', latitude = 7.07220007, longitude = 125.6208795}, -- will become position 3
{ title='sasa2', latitude = 7.0723912, longitude = 125.61704414}, -- will become position 1
{ title='sasa3', latitude = 7.07362466, longitude = 125.61977253} -- will become position 2
}
--currentLatitude = curentLocation.latitude
--currentLongitude = currentLocation.longitude
-- Center; could be your current GPS location
centerPoint = {latitude = 7.07525189, longitude = 125.61961413} -- new york
--centerPoint = {currentLocation}
--local centerPoint = {myMap:getUserLocation()}

-- Set distances in markers
for i, Prop in ipairs(markers) do
Prop['distance'] = distance(centerPoint, markers[i])
end

-- Sort by distance
function compare(a, B)
return a['distance'] < b['distance']


end
table.sort(markers, compare)


local newText =
"Nearest is: " print_r(markers[1])
native.showAlert( "You Are Here", nearestText, { "OK" } )

end

[TOPIC: post.html]
#18

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

the smiley there is for "b". I'm trying to edit it but I ended up messing around my post. I apologize for my mistake.



[TOPIC: post.html]
#19

demolaysince2009

[GLOBAL: userInfoPane.html]
demolaysince2009
  • Observer

  • 8 posts
  • Corona SDK

[TOPIC: post.html]
#20

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK


local newText =
"Nearest is: " print_r(markers[1])
native.showAlert( "You Are Here", nearestText, { "OK" } )

end

 

print_r can ONLY be used in the Corona SDK Simulator Console. 

Try something like:

local newText = "Nearest is: " .. markers[1].title
native.showAlert( "You Are Here", newText, { "OK" } )
end



[TOPIC: post.html]
#21

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

http://code.coronalabs.com/code/update-gps-every-x-seconds

this code also avoids battery draining for searching your GPS.



[TOPIC: post.html]
#22

alex01

[GLOBAL: userInfoPane.html]
alex01
  • Observer

  • 14 posts
  • Corona SDK

Is there a way to draw a path from point A to point B?



[TOPIC: post.html]
#23

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,241 posts
  • Enterprise

Corona SDK cannot draw lines on top of native.* objects. 



[TOPIC: post.html]
#24

ksan

[GLOBAL: userInfoPane.html]
ksan
  • Corona Geek

  • 2,795 posts
  • Corona SDK

This is a very useful thread. Thank you very much for sharing. 



[TOPIC: post.html]
#25

FoxB

[GLOBAL: userInfoPane.html]
FoxB
  • Enthusiast

  • 37 posts
  • Corona SDK

This is a very useful thread. Thank you very much for sharing. 

 

Thanks, no problem. Glad it helps.




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]