I want using GPS data (I got it from $GPRMC) in an desktop application(that uses from mappoint 2009). I get the latitude & longitude, but when I check these points on map, I see the result is incorrect (for example My Data is: 43.412 N, 79.369 W ; but the correct point is: 43.686 N, 79.616 W ).
I guess, I must use a correction method before use; I try "Projection method" like "Miller" or "Mercator", but those aren't effective.
Can anyone guide me?
Are you using the same coordinate systems? E.g. WGS-84 or something else?
Related
The simple equation for user location using inbuilt inertial measurement unit (IMU) which is also called pedestrian dead reckoning (PDR) is given as:
x= x(previous)+step length * sin(heading direction)
y= y(previous)+step length *cos(heading direction )
We can use the motionManager property of CMMotionManager class to access raw values from accelerometer, gyroscope, and magnetometer. Also, we can get attitudes values as roll, pitch, and yaw. The step length can be calculated as the double square root of acceleration. However, I'm confused with the heading direction. Some of the published literature has used a combination of magnetometer and gyroscope data to estimate the heading direction. I can see that CLHeading also gives heading information. There are some online tutorials especially for an android platform like this to estimate user location. However, it does not give any proper mathematical explanation.
I've followed many online resources like this, this,this, and this to make a PDR app. My app can detect the steps and gives the step length properly however its output is full of errors. I think the error is due to the lack of proper heading direction. I've used the following relation to get heading direction from the magnetometer.
magnetometerHeading = atan2(-self.motionManager.magnetometerData.magneticField.y, self.motionManager.magnetometerData.magneticField.x);
Similarly, from gyroscope:
grysocopeHeading +=-self.motionManager.gyroData.rotationRate.z*180/M_PI;
Finally, I give proportional weight to the previous heading driection, gryoscopeheading, and magnetometerHeading as follows:
headingDriection = (2*headingDirection/5)+(magnetometerHeading/5)+(2*gryospoceHeading/5);
I followed this method from a published journal paper. However, I'm getting lots of error in my work. Is my approach wrong? What exactly should I do to get a proper heading direction such that the localization estimation error would be minimum?
Any help would be appreciated.
Thank you.
EDIT
I noticed that while calculating heading direction using gyroscope data, I didn't multiply the rotation rate (which is in radian/sec) with the delta time. For this, I added following code:
CMDeviceMotion *motion = self.motionManager.deviceMotion;
[_motionManager startDeviceMotionUpdates];
if(!previousTime)
previousTime = motion.timestamp;
double deltaTime = motion.timestamp - previousTime;
previousTime = motion.timestamp;
Then I updated the gyroscope heading with :
gyroscopeHeading+= -self.motionManager.gryoData.rotationRate.z*deltaTime*180/M_PI;
The localization result is still not close to the real location. Is my approach correct?
Given a GEO-JSON polygon, such as the below:
[
[15.520376, 38.231155],
[15.160243, 37.444046],
[15.309898, 37.134219],
[15.099988, 36.619987],
[14.335229, 36.996631],
[13.826733, 37.104531],
[12.431004, 37.61295],
[12.570944, 38.126381],
[13.741156, 38.034966],
[14.761249, 38.143874],
[15.520376, 38.231155]
]
How can I check if a GPS location is within the polygon region?
For example, if the user is at Lat 37.387617, Long 14.458008, how would I go about searching the array?
I don't need someone to necessarily write the code for me, I just don't understand the logic of how I can check. If you have any example (any language) please point me.
This task is called point in polygon test.
Gerve has explained the algorithm that is widley used for this task. But this will not help you in implementing it. There are foot traps, like parallel lines.
One of that algorithms is called Crossings Multiply test, which is an optimized variant.
Source code: CrossingsMultiplyTest (last function in the file)
An Overview is given in "Point in Polygon Strategies"
Use longitude for the x coordinate, and latitude for the y coordinate.
I've found an article about the Ray-casting algorithm. It's explained pretty well here, the jist of it is (in pseudo code):
count ← 0
foreach side in polygon:
if ray_intersects_segment(P,side) then
count ← count + 1
if is_odd(count) then
return inside
else
return outside
Here's my problem: a smartphone will send to my server some gps coordinates (latitude,longitude,altitude) and I'll have to compare these to an address stored in db in order to see how much distance there is between smartphone and address.
I'll need to obtain this address coordinates as well in order to do the actual comparison.
Is there a good and easy to use gps library for java?Any suggestions?
In your answers please note that I need a way to get coordinates from an address too!! So, given an address "second street 2,New York, zip code 01245", I need to find latitude,longitude,altitude,ecc.
Android's Location class has a static method distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, results). You can look at the source code and use it in your program.
You could take a look at
A distance calculator using GeoCodes
Distance between 2 geocodes
I'd like to know the local time where my user is sending his request from.
Basically, is there such a thing as a function like this
var localTime = getLocalTime( lat, long );
I'm not sure if a simple division on the lat could work, since most of the countries don't have perfect geometric shapes.
Any help would be great. Any language is accepted. I'd like to avoid calling distant APIs.
The Google Time Zone API seems to be what you're after. It, however does not have any free tier.
The Time Zone API provides time offset data for locations on the surface of the earth. Requesting the time zone information for a specific Latitude/Longitude pair will return the name of that time zone, the time offset from UTC, and the Daylight Savings offset.
The shapefile used to compute the timezone is not maintained anymore.
I just faced the same issue today, and I am not sure how relevant my answer is after all this time, but I basically just wrote a Python function that does what you want. You can find it here.
https://github.com/cstich/gpstotz
Edit:
As mentioned in the comments I should also post code. The code is based on Eric Muller's shapefile of timezones, which you can get here - http://efele.net/maps/tz/world/.
Edit 2:
As it turns out shapefiles have a somewhat archaic definition of exterior and interior rings (basically exterior rings are using the right hand rule, while interior rings are using the left hand rule). In any case fiona seems to take care of that and I updated the code accordingly.
from rtree import index # requires libspatialindex-c3.deb
from shapely.geometry import Polygon
from shapely.geometry import Point
import os
import fiona
''' Read the world timezone shapefile '''
tzshpFN = os.path.join(os.path.dirname(__file__),
'resources/world/tz_world.shp')
''' Build the geo-index '''
idx = index.Index()
with fiona.open(tzshpFN) as shapes:
for i, shape in enumerate(shapes):
assert shape['geometry']['type'] == 'Polygon'
exterior = shape['geometry']['coordinates'][0]
interior = shape['geometry']['coordinates'][1:]
record = shape['properties']['TZID']
poly = Polygon(exterior, interior)
idx.insert(i, poly.bounds, obj=(i, record, poly))
def gpsToTimezone(lat, lon):
'''
For a pair of lat, lon coordiantes returns the appropriate timezone info.
If a point is on a timezone boundary, then this point is not within the
timezone as it is on the boundary. Does not deal with maritime points.
For a discussion of those see here:
http://efele.net/maps/tz/world/
#lat: latitude
#lon: longitude
#return: Timezone info string
'''
query = [n.object for n in idx.intersection((lon, lat, lon, lat),
objects=True)]
queryPoint = Point(lon, lat)
result = [q[1] for q in query
if q[2].contains(queryPoint)]
if len(result) > 0:
return result[0]
else:
return None
if __name__ == "__main__":
''' Tests '''
assert gpsToTimezone(0, 0) is None # In the ocean somewhere
assert gpsToTimezone(51.50, 0.12) == 'Europe/London'
I was searching for the same thing couple of days ago and unfortunately I could not find an API or a simple function that does it. The reason being as you said that countries do not have perfect geometric shapes. You have to create a representation of the area of each time zone and see where your point lies. I think this will be a pain and I have no idea if it can be done at all.
The only one I found is described here: Determine timezone from latitude/longitude without using web services like Geonames.org . Basically you need a database with information about timezones and you are trying to see which one is closest to your point of interest.
However, I was looking for static solutions(without using internet), so if you can use internet connection you can use: http://www.earthtools.org/webservices.htm which provides a webservice to give you the timezone given lat/lon coordinates.
As of 2019, Google API does not have any free tier and the data source of #cstich answer is not maintained anymore.
If you want an API, timezonedb.com offers a free tier rate limited to 1 request/second.
The original maintainer of the data used by #cstich link to this project which retrieve data from OpenStreetMap. The readme contains link to look up libraries in a wide variety of languages.
Couldn't you simply use the user IP to determine which they live in ? And then you use an array of (Countries | Difference with GMT) to get the local time.
I am trying to make an app which uses both the GPS and the magnetometer for finding the way and direction for mecca (Mosque). It has some special features like date picker for upcoming prayers, prayer timings left calculated from current location time zone and weather on the current location and some more on. If anyone has sample code regarding to this, please reply.
Thanks in advance
The magnetometer can be told just to return the current device heading, via CLLocationManager. It can return in unfiltered 3d, but there's no reason to use it — from CLHeading just use the trueHeading property. That'll give you the same information shown in the Compass app.
To work out the heading to Mecca from where you are, you can use the formulas given here. Google Maps gives me a geolocation of about 21.436, 39.832 for Masjid al-Haram (I'm not sure it's terribly accurate, so I've rounded inappropriately low), so you could get the bearing from whatever location CLLocationManager tells you you're at something like:
#define toRadians(x) ((x)*M_PI / 180.0)
#define toDegrees(x) ((x)*180.0 / M_PI)
...
double y = sin(toRadians(39.832 - currentLocation.longitude)) * cos(toRadians(21.436));
double x = cos(toRadians(currentLocation.latitude)) * dsin(toRadians(21.436)) -
sin(toRadians(currentLocation.latitude)) * dcos(toRadians(21.436)) * dcos(toRadians(39.832 - currentLocation.longitude));
double bearing = toDegrees(atan2(y, x));
You can then rotate a pointer on screen by the difference between the device's heading and the one you've just calculated. Probably easiest to use a CGAffineTransform on a UIView's transform property.
That's all typed as I answer by the way, not tested. I'd check it against a reliable source before you depend on it.