proper data type for storing google maps lattitude and longitude values? - grails

...I have a Grails domain class dealing with geo location data for interacting with google maps:
Float latitude
Float longitude
When the following values get saved to a db :
latitude : 2.5485291419153366, longitude : -76.03939712047577
I end up having : 2.54853;-76.0394 respectively.
What's the best way of preserving the initial values in this case?
Thanks in advannce

Another option would be to just store them as Strings. I know that seems odd, but you're probably just passing the values back to the maps API and not doing any real calculations yourself. If that is the case, Strings are easy. Just because something is a number, doesn't mean it has to be stored in a numeric data type.

You will probably want to use BigDecimal. Floating point numbers arn't garanteed to be 100% accurit while you can control the number of digits with BigDecimal. Grails doesn't offer constraints for this so you'll have to use methods as setScale to determine the number of digits to store. FOr more info see
http://download.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html

... in the end here's what I decided to go with:
BigDecimal latitude
BigDecimal longitude
static constraints = {
latitude( scale : 16 )
longitude( scale : 16 )
}

Related

Swift: converting String to Float and back to String again after doing some mathematical operations

I've been googling and trying to understand how things work with the Float values in swift, but can't seem to make any sense of it, I would really appreciate any help, I feel I'm just wasting my time.
For example, let's say that I have an API that returns some json data, I parse that data, make some calculations and then present some of the data to the user, something like this:
let balance : String = "773480.67" // value that was received through json api
let commission : String = "100000.00" // value that was received through json api
//framework maps the json properties
let floatBalance : Float = Float(balance)! // at this point value is 773480.688
let floatCommission : Float = Float(commission)! //100000.0
//we do some math with the values
let result : Float = floatBalance + floatCommission // this is somehow 873480.687
//and then show some of the values on a label
print("stringBalance: \(balance)") //stringBalance: 773480.67
print("floatBalance: \(floatBalance)") //floatBalance: 773481.0
print("floatCommission: \(floatCommission)") //floatCommission: 100000.0
print("result: \(result)") //result: 873481.0
print("label: \(String(format:"%.2f", result))") //label: 873480.69
print("just kill me now")
I'm using the EVReflection framework to map the json properties to an object, so the conversion from String to Float is done in the background without me doing much about it, but the values shown above are basically what I'm working with.
My question is, what do I need to do at the end to get the correct string (873480.67) from the resulting float (873480.687) or is my approach wrong from the start?
Thank you
Actually floats can not represent numbers accurately, you'll have to use Double.
Here is a very nice answer on that issue:
https://stackoverflow.com/a/3730040/4662531
EDIT:
Sorry, but actually Double should not be use to perform calculations (I'm assuming from the naming of your variables you are working on some banking things). That part of the above linked answer is really giving a great suggestion:
A solution that works in just about any language is to use integers
instead, and count cents. For instance, 1025 would be $10.25. Several
languages also have built-in types to deal with money. Among others,
Java has the BigDecimal class, and C# has the decimal type.
A colleague of mine that used to work in a banking company also confirmed that all calculations were done without using Floats or Double, but with Int as suggested in the link.

Create a JSON string with number of significant figures / decimal places based on key IOS OBJ C

I need to upload JSON data from an app (IOS) to the backend server.
The goal is to optimise the size of the upload packet which is JSON encoded as a NSString. The string is currently about 5MB but contains mostly doubles which have more precision than necessary.
The size of the packet can be reduced by around 40-50% by removing unnecessary decimal places in doubles. This has to be customisable based on the key.
What is the best way to create a JSON string with different numbers of significant figures or decimal places depending on the key.
You may need to do some experiments. Let's say you want to send data with two decimal digits, like 3.14 instead of pi. You know you have to turn all numbers into NSNumber. You would turn x into a number with two decimals by writing
double asDouble = 3.141592653;
NSNumber* asNumber = #(round (asDouble * 100.0) / 100.0);
However, you need to check that this always works; with some bad luck this could send 3.140000000000000000000001 to your server.
Obviously you can replace the 100.0 with 1000.0 etc. Do not replace the division with a multiplication by 0.01 because that will increase rounding errors and the chance that you get tons of decimal digits.
You might check what happens if you write
NSNumber* asNumber = #((float) asDouble);
If NSJSONSerialization is clever enough, it will send fewer decimals.

Rails app unable to store longitude data larger than 15 precisions in Postgres

Im using geocoder gem in my rails app, the lat and long are double precision in my postgres db.
Some of my longitude data are greater than 15 precision (174.83837440000002), and the float type generates double precision can only store 15 precision data, when stored in my database, it just truncated, anyone have this issue?
Thanks
I think you're making mistake using double precision field for this.
First of all double precision is inexact field type. Therefore, as we know from CS 101, data stored there are subjected to rounding error. Not very good, when we thinking about coordinates.
Double precision in postgres has range "15 decimal digits precision". Therefore, behaviour you're describing is perfectly normal.
Field type, you should've been using is decimal - it has user defined precision: "up to 131072 digits before the decimal point; up to 16383 digits after the decimal point". It will be mapped into Ruby bigdecimal, so it will be exact representation of data (without rounding error). More information about postrges data types can be found here and about using decimal within Rails migration here.
However, when you're using Postgres you probably want to use PostGis extension. It has special field type for storing location data "native support for spatial features represented on "geographic" coordinates (sometimes called 'geodetic' coordinates, or 'lat/lon', or 'lon/lat')". More info can be found here (and geocoder supports it, however in limited range).

Converting NSString to Float - Adds in Decimal Places?

I am parsing some vertice information from an XML file which reads as follows (partial extract) :
21081.7 23447.6 2781.62 24207.4 18697.3 -2196.96
I save the string as an NSString and then convert to a float value (which I will later feed into OpenGL ES)
NSString * xPoint = [finishedParsingArray objectAtIndex:baseIndex];
NSLog(#"xPoiint is %#", xPoint);
float x = [xPoint floatValue];
The problem is that float x changes the values as follows :
21081.699219, 23447.599609, 2781.620117, 24207.400391, 18697.300781, -2196.959961
As you can see, it is changing the number of decimal places (not sure how it is doing this - must be hidden formatting in the xml file ?)
My question is how can I store the float to match the original number in the NSString / XML file to the same number of decimal places ?
Thanks in advance !
Your issue seems to be that you don't understand how floats are stored in memory and don't know that floats aren't precise.
Exact values often can't be stored and so the system picks the closest number it can to represent it. If you look carefully, you can see that each of the outputted numbers is very close to your inputted values.
For better accuracy, try using double instead. Double does encounter the same problems, but with better precision. Floats have about 6 significant digits; doubles have more than twice that. Source
Here are some other StackOverflow answers and external articles you should read:
What Every Computer Scientist Should Know About Floating-Point Arithmetic
Floating Points on Wikipedia
This answer on a similar question
All primitives which store floating point numbers have an accuracy issue. Most of the time it's so small it doesn't matter, but sometimes it's vital.
When it's important to keep the exact number, I would suggest using NSDecimalNumber.

Form Google Maps URL that searches for a specific places near specific coordinates

I have the longitude and latitude and the name of the place I want to look for. How do I edit the Google Maps URL so that I obtain all the places (name of the places) near a set of coordinates?
I know I could do this using Google Map API, but just for a link seems a lot of trouble.
You can use the query parameter ll for your lat and long, and you can use the query parameter q for what you want to search.
http://maps.google.com/?ll=39.774769,-74.86084
Or you can
http://maps.google.com/?q=your+query
Yeah, I had the same question for a long time and I found the perfect one. Here are some parameters from it.
https://maps.google.com/?parameter=value
q=
Used to specify the search query in Google maps search.
eg :
https://maps.google.com/?q=newyork or
https://maps.google.com/?q=51.03841,-114.01679
near=
Used to specify the location instead of putting it into q. Also has
the added effect of allowing you to increase the AddressDetails
Accuracy value by being more precise. Mostly only useful if q is a
business or suchlike.
z=
Zoom level. Can be set 19 normally, but in certain cases can go up to 23.
ll=
Latitude and longitude of the map centre point. Must be in that order. Requires decimal format. Interestingly, you can use this without q, in which case it doesn’t show a marker.
sll=
Similar to ll, only this sets the lat/long of the centre point for a business search. Requires the same input criteria as ll.
t=
Sets the kind of map shown. Can be set to:
m – normal map
k – satellite
h – hybrid
p – terrain
saddr=
Sets the starting point for directions searches. You can also add text into this in brackets to bold it in the directions sidebar.
daddr=
Sets the end point for directions searches, and again will bold any text added in brackets.You can also add "+to:" which will set via points. These can be added multiple times.
via=
Allows you to insert via points in directions. Must be in CSV format. For example, via=1,5 addresses 1 and 5 will be via points without entries in the sidebar. The start point (which is set as 0), and 2, 3 and 4 will all show full addresses.
doflg=
Changes the units used to measure distance (will default to the standard unit in country of origin). Change to ptk for metric or ptm for imperial.
msa=
Does stuff with My Maps. Set to 0 show defined My Maps, b to turn the My Maps sidebar on, 1 to show the My Maps tab on its own, or 2 to go to the new My Map creator form.
reference : http://moz.com/ugc/everything-you-never-wanted-to-know-about-google-maps-parameters
additional info:
http://maps.google.com/maps?q=loc:
put in latitude and longitude after, example:
http://maps.google.com/maps?q=loc:51.03841,-114.01679
this will show pointer on map, but will suppress geocoding of the address, best for a location without an address, or for a location where google maps shows the incorrect address.
As of Jan 2018 (update: still works in May 2022) the latest URL is:
https://google.com/maps/search/*your search string* (address, landmark, city, etc. Spaces are ok)
Examples:
https://google.com/maps/search/empire state building
https://google.com/maps/search/1600 Pennsylvania Ave NW, Washington, DC 20500
You can use the new URL for Google Maps: https://www.google.com/maps/#39.774769,-74.86084,18z
equivalent to http://maps.google.com/?ll=39.774769,-74.86084.
39.774769 is the latitude and -74.86084 is longitude and 18z is 18 zoom level.
Google now has a documentation page dedicated to Maps URLs:
https://developers.google.com/maps/documentation/urls/guide
An API key is not required.
Manipulating one of the examples, I came up with this URL scheme that fits your question:
https://www.google.com/maps/search/<search term>/#<coordinates>,<zoom level>z
A valid example of this would be:
https://www.google.com/maps/search/pizza/#41.089988,-81.542901,12z
This should show you all of the pizza places around Akron, Ohio.

Resources