Storing GPS Location in CoreData class + Getting Nearby Stuff

1,802 views
Skip to first unread message

Stefaan Lesage

unread,
Aug 10, 2010, 3:03:06 AM8/10/10
to cocoah...@googlegroups.com
Hi guys,

Just a quick question here.  I'm currently storing the location of some stuff into their corresponding CoreData class.  Since I didn't really know what the best approach was, I used 2 properties called Longitude and Latitude.  Not sure if this is the best approach or if I should have stored the whole CLLocationCoordinate2D or the CLLocation, but I could still change that if necessay (depends on what you guys suggest).

What I would like to do now is get a list of 'Stuff' which is close to my current location, and I'm not quite sure how I should actually do that.  I know the CLLocation has a distanceFromLocation: message, but I can't seem to figure out how to use that in order to get all the Stuff which is close to my current location from the CoreData Context.

So if you guys have any pointers on how I could do something like this, or have a better suggestion on how I should handle all this stuff; I would greatly appreciate it.

--
Best regards,
Stefaan Lesage
__

Devia
Software Development & New Media Technologies
Boekweitbloemstraat 9 - 9940 Ertvelde - Belgi�
http://www.devia.be

Tom Nys

unread,
Aug 10, 2010, 3:14:44 AM8/10/10
to cocoah...@googlegroups.com
Hi Stefaan,

We've been looking into the same issue recently as well, and there are (AFAIK) 2 solutions: 

[1] if you know you only need the items which are located in e.g. a 5 km range, you can do some CoreData filtering prior to fetching them (as described here: http://stackoverflow.com/questions/2176127/core-data-and-core-location)

[2] If you need to sort all elements in your database, based on their distance from the current location, you need to sort them after you fetched them from CoreData (we used sortUsingSelector on the resulting NSArray, whereby the selector uses distanceFromLocation from the 2 elements and compare those results).

Hope this helps,

Tom.

Boekweitbloemstraat 9 - 9940 Ertvelde - Belgiė
http://www.devia.be

--
You received this message because you are subscribed to the Google
Groups "CocoaHeads Belgium" group.
To post to this group, send email to cocoah...@googlegroups.com
To unsubscribe from this group, send email to
cocoaheadsbe...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/cocoaheadsbe?hl=en
The CocoaHeads Belgium website can be reached at http://www.cocoaheads.be

Stefaan Lesage

unread,
Aug 10, 2010, 3:47:17 AM8/10/10
to cocoah...@googlegroups.com
Hi Tom,

Interesting ... So you guys have also stored the Longitude and Latitude as 2 properties of your objects ? I did the same thing, since that looked the simplest way to store the location inside my database, but now that I need to find all Objects close to the current location I started hesitating.

I will do some research on the 2 alternatives you gave me.  But I guess I need more Sample data in order to see if it works correctly.  The 5 objects I currently have are all stored pretty close to my home, so not really good Test Data.

Oh by the way, are there any tools you cuold use to actually fill a CoreData database ? Something I could use to dump some sample data into it ?


--
Best regards,
Stefaan Lesage
__

Devia
Software Development & New Media Technologies
Boekweitbloemstraat 9 - 9940 Ertvelde - België
http://www.devia.be

Tom Nys

unread,
Aug 10, 2010, 5:28:54 AM8/10/10
to cocoah...@googlegroups.com
Hi Stefaan,

We indeed stored both latitude and longitude as 2 attributes in our coredata element.

We prepopulate our database with a custom XML which contains all the elements.  We use tinyxml as XML parsing library on iPhone/iPad, and for each XML element, we create a CoreData element.  When all is created, we commit the changes to the database (all of this in a background thread using GCD).

Hope this helps,

Tom

dpaeme

unread,
Aug 10, 2010, 1:09:55 PM8/10/10
to CocoaHeads Belgium
The way to find stuff that's close is just basic maths and some
optimisation

You can find the distance of any object with coörds x.y to object u.v
with the formula (in math.h speak) :

distance = sqrt(pow((x - u),2) + pow((y - v),2))

It's easy to calculate the maximum values that the coordinates of the
locations you're looking for can have, and you can query CoreData with
those bounding values. The result should be a list of locations that
are with certain min/max x and y values (= within a bounding square).
You can refine this list by using the formula above, and even use it
to sort on the nearest locations.

This way of working is quite quick because you don't have to do
calculations for every element in your database, only the ones that
you got back from within the bounding box. Very handy if you have
large datasets.

Have fun,

D.

(remark: if you're using actual longitude/latitude coördinates,
there's some more magic you need to perform to use real distances, but
I don't have them handy right now. A quick google returns this:
http://www.movable-type.co.uk/scripts/latlong.html )

(remark number 2: i remember some blog post from a long time ago by
the guy that made the Spots app that discusses this kind of stuff and
the optimisations he had to use to make his app perform well - but I
can't find it right now...)





On Aug 10, 11:28 am, Tom Nys <tom....@gmail.com> wrote:
> Hi Stefaan,
>
> We indeed stored both latitude and longitude as 2 attributes in our coredata
> element.
>
> We prepopulate our database with a custom XML which contains all the
> elements.  We use tinyxml as XML parsing library on iPhone/iPad, and for
> each XML element, we create a CoreData element.  When all is created, we
> commit the changes to the database (all of this in a background thread using
> GCD).
>
> Hope this helps,
>
> Tom
>
> > ><stefaan.les...@devia.be>wrote:
> > >> cocoaheadsbe...@googlegroups.com<cocoaheadsbe%2Bunsubscribe@google groups.com>
> > <cocoaheadsbe%2Bunsu...@googlegroups.com<cocoaheadsbe%252Bunsubscribe@g ooglegroups.com>
>
> > >> For more options, visit this group at
> > >>http://groups.google.com/group/cocoaheadsbe?hl=en
> > >> The CocoaHeads Belgium website can be reached at
> > >>http://www.cocoaheads.be
>
> > > --
> > > You received this message because you are subscribed to
> > >the Google
> > > Groups "CocoaHeads Belgium" group.
> > > To post to this group, send email to
> > >cocoah...@googlegroups.com
> > > To unsubscribe from this group, send email to
> > > cocoaheadsbe...@googlegroups.com<cocoaheadsbe%2Bunsubscribe@google groups.com>
> > >For more options, visit this group at
> > >http://groups.google.com/group/cocoaheadsbe?hl=en
> > > The CocoaHeads Belgium website can be reached at
> > >http://www.cocoaheads.be
>
> >  --
> > You received this message because you are subscribed to the Google
> > Groups "CocoaHeads Belgium" group.
> > To post to this group, send email to cocoah...@googlegroups.com
> > To unsubscribe from this group, send email to
> > cocoaheadsbe...@googlegroups.com<cocoaheadsbe%2Bunsubscribe@google groups.com>

Marco Mustapic

unread,
Aug 10, 2010, 2:00:14 PM8/10/10
to cocoah...@googlegroups.com
I use this code to compute distances between two lat/long coordinates:

#define DEG_TO_RAD 0.017453292519943295769236907684886
#define EARTH_RADIUS 6372797.560856

// return distance between two lat/lon points, in meters
double DistanceBetweenCoords(double fromLat, double fromLong, double toLat, double toLong)
{
double latitudeArc  = (fromLat - toLat) * DEG_TO_RAD;
double longitudeArc = (fromLong - toLong) * DEG_TO_RAD;
double latitudeH = sin(latitudeArc * 0.5);
latitudeH *= latitudeH;
double lontitudeH = sin(longitudeArc * 0.5);
lontitudeH *= lontitudeH;
double tmp = cos(fromLat*DEG_TO_RAD) * cos(toLat*DEG_TO_RAD);
return 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH)) * EARTH_RADIUS;
}

I coded a tourist guide app that needed to popup info whenever the user was close enough to a point of interest. I didn't use CoreData, just a plist with all the points of interest loaded in memory. Every time the user's location (or location precision) changed, I launched a background thread to check if any POI was near the user. If I remember correctly, for ~1000 points this worked pretty ok, a small delay is acceptable, since the user position doesn't change constantly. 

Marco Mustapic
www.agilar.org
Reply all
Reply to author
Forward
0 new messages