How to find degree from the latitude value in android? - java

I have a latitude and longitude values as a double value(37.33168900, -122.03073100).
I want to convert it to the degree value like (37 19' 54 ,48 11' 52 ).
Any Idea? Thanx in advance.

This will give you Strings in degrees, minutes and seconds of arc:
String strLongitude = location.convert(location.getLongitude(), location.FORMAT_SECONDS);
String strLatitude = location.convert(location.getLatitude(), location.FORMAT_SECONDS);
.

use this
public static String getFormattedLocationInDegree(double latitude, double longitude) {
try {
int latSeconds = (int) Math.round(latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = Math.abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;
int longSeconds = (int) Math.round(longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = Math.abs(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;
String latDegree = latDegrees >= 0 ? "N" : "S";
String lonDegrees = longDegrees >= 0 ? "E" : "W";
return Math.abs(latDegrees) + "°" + latMinutes + "'" + latSeconds
+ "\"" + latDegree +" "+ Math.abs(longDegrees) + "°" + longMinutes
+ "'" + longSeconds + "\"" + lonDegrees;
} catch (Exception e) {
return ""+ String.format("%8.5f", latitude) + " "
+ String.format("%8.5f", longitude) ;
}
}

Should be some math:
(int)37.33168 => 37
37.33168 % 1 = 0.33168
0.33168 * 60 = 19,905 => 19
19.905 % 1 = 0.905
0.905 * 60 => 54
same with -122 (add 360 if nagative value)
EDIT:
May be there is some API, which I don't know.

Also take a look at the Location class documentation especially at the convert() method as it should do just what you want.

Abi's answer works very well in my location, but produces errors in some others, e.g. "E" instead of "W" on the Western Hemisphere. IMO it should be:
String lonDegrees = longDegrees >= 0 ? "E" : "W";
instead of:
String lonDegrees = latDegrees >= 0 ? "E" : "W";

Another way you can achieve this is using the following function
private String convertCoordinate(double coordinate, boolean isLatitude){
String[] pString = isLatitude ? new String[]{"N", "S"} : new String[]{"E", "W"};
int degree = (int) coordinate;
int minute = (int) (Math.abs(coordinate) * 60) % 60;
int second = (int) (Math.abs(coordinate) * 3600) % 60;
int index = degree < 0 ? 1 : 0;
degree = Math.abs(degree);
return degree + pString[index] + " " + minute + "' " + second + "\"";
}

Based on SO answers i made a code which convert DEG to DMS with FORMAT
example : 40°42′51″ N 74°00′21″ W
example call : getLocationAsDMS(location,8)
8 is the right number for this format
public String getLocationAsDMS (Location location, int decimalPlace){
String strLatitude = Location.convert(location.getLatitude(), Location.FORMAT_SECONDS);
strLatitude = replaceDelimiters(strLatitude, decimalPlace);
char latCardinal = location.getLongitude() >= 0 ? 'N' : 'S';
strLatitude = strLatitude + " " + latCardinal;
String strLongitude = Location.convert(location.getLongitude(), Location.FORMAT_SECONDS);
strLongitude = replaceDelimiters(strLongitude, decimalPlace);
char lonCardinal = location.getLongitude() >= 0 ? 'E' : 'W';
strLongitude = strLongitude + " " + lonCardinal;
return strLatitude + " " + strLongitude;
}
#NonNull
private String replaceDelimiters(String str, int decimalPlace) {
str = str.replaceFirst(":", "°");
str = str.replaceFirst(":", "'");
int pointIndex = str.indexOf(".");
int endIndex = pointIndex + 1 + decimalPlace;
if(endIndex < str.length()) {
str = str.substring(0, endIndex);
}
str = str + "\"";
return str;
}

Related

How to calcucate a product of n adjecent numbers using ArrayList and subList?

Im trying to solve EulerProblem8 https://projecteuler.net/problem=8 and i just don't get it , what am i doing wrong ? I tried before with a file and ArrayList but couldn't pull it off ... Whats wrong , the subtsrings , the loops , the *= ... i dont know what to do anymore?
package largestproductinaseries_ep8;
//The four adjacent digits in the 1000-digit number
//that have the greatest product are 9 × 9 × 8 × 9 = 5832.
//Find the thirteen adjacent digits in the 1000-digit number
//that have the greatest product. What is the value of this product?
public class LargestProductInASeries_EP8 {
public static void main(String[] args){
String bigNum = "73167176531330624919225119674426574742355349194934" +
"96983520312774506326239578318016984801869478851843" +
"85861560789112949495459501737958331952853208805511" +
"12540698747158523863050715693290963295227443043557" +
"66896648950445244523161731856403098711121722383113" +
"62229893423380308135336276614282806444486645238749" +
"30358907296290491560440772390713810515859307960866" +
"70172427121883998797908792274921901699720888093776" +
"65727333001053367881220235421809751254540594752243" +
"52584907711670556013604839586446706324415722155397" +
"53697817977846174064955149290862569321978468622482" +
"83972241375657056057490261407972968652414535100474" +
"82166370484403199890008895243450658541227588666881" +
"16427171479924442928230863465674813919123162824586" +
"17866458359124566529476545682848912883142607690042" +
"24219022671055626321111109370544217506941658960408" +
"07198403850962455444362981230987879927244284909188" +
"84580156166097919133875499200524063689912560717606" +
"05886116467109405077541002256983155200055935729725" +
"71636269561882670428252483600823257530420752963450";
int a = 0;
String peace = "";
String onePeace = "";
int onePeaceNum = 0;
int multi = 1;
int maxMulti = 0;
while(a<bigNum.length()-12){
peace = bigNum.substring(a, a+13);
if(!peace.contains("0")){
for(int i = 12; i>=0; i--){
onePeace = peace.substring(i, i+1);
onePeaceNum = Integer.parseInt(onePeace);
multi *= onePeaceNum;
if(multi>maxMulti){
maxMulti = multi;
}
}
multi = 1;
}
a++;
}
System.out.println(maxMulti);
}
}
//23514624000 this is Euler answer
// 2091059712 this is my output
You have a problem in your implementation, you never reset the mult value so you keep multiplying and you don't stop after 13 numbers.
Your code should be:
if (mult > maxMult) {
maxMult = mult;
mult = 1;
} else {
mult = 1;
}

Calculation of times off milliseconds to time

This code below is used to format milliseconds. The calculations are off by a long shot. I need some help with it. Output of my code is below as well as the milliseconds into a Date class.
public static void main(String[] args) {
System.out.println("Wrong Time: " + getTime(999999999 * 599));
}
//Being called into this method is milliseconds = 598999999401
public static String getTime(long miliseconds) {
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 52);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Date date = new Date(598999999401L);//This gets the real time
System.out.println("Right Time: " + date.getYear() + " years " + (int)(date.getMonth() % 12) + " months " + (int)(date.getDay() % 52) + " weeks "
+ (int)(date.getDay() % 7) + " days " + (int)(date.getHours() % 24) + " hours " + (int)(date.getMinutes() % 60) + " minutes " +
+ (int)(date.getSeconds() % 60) + " seconds");
return (years <= 0 ? "" : years + " year" + (years != 1 ? "s" : "")) +
(months <= 0 ? "" : " " + months + " month" + (months != 1 ? "s" : "")) +
(weeks <= 0 ? "" : " " + weeks + " week" + (weeks != 1 ? "s" : "")) +
(days <= 0 ? "" : " " + days + " day" + (days != 1 ? "s" : "")) +
(hours <= 0 ? "" : " " + hours + " hour" + (hours != 1 ? "s" : "")) +
(minutes <= 0 ? "" : " " + minutes + " minute" + (minutes != 1 ? "s" : "")) +
(seconds <= 0 ? "" : " " + seconds + " second" + (seconds != 1 ? "s" : ""));
}
Correct Output(Date class)
Right Time: 88 years 11 months 6 weeks 6 days 14 hours 53 minutes 19 seconds
Wrong Output(My method)
Wrong Time: 1 month 3 weeks 2 days 3 hours 25 minutes 45 seconds
UPDATE 1 (NEW CALCULATIONS)(Still has logic errors):
int years = (int) ((miliseconds / (1000*60*60*24*7*4*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*4) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 4);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Two issues.
Your code seems to reflect a belief that there are 52 weeks in a month. These are the two lines at fault.
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
Also, you're using int where you should be using long. The maximum int number of milliseconds is just under 25 days, so you can never do date/time arithmetic with int.
One problem is int overflow since your main method is using int literals, not longs. Try:
System.out.println("Wrong Time: " + getTime(999999999L * 599L));
Also, don't use magic numbers. Use constants that make sense and that make your code self-commenting:
private static final int MILI_PER_SEC = 1000;
private static final int SEC_PER_MIN = 60;
private static final int MIN_PER_HR = 60;
private static final int HR_PER_DAY = 24;
private static final int DAYS_PER_YR = 365;
and then,
int years = (int) (miliseconds / (MILI_PER_SEC * SEC_PER_MIN * MIN_PER_HR *
HR_PER_DAY * DAYS_PER_YR));
Also, your calculations are all off. You shouldn't be using weeks in the year calculation at all. Use constants, have them make sense. And how do you know that the "correct" result is in fact correct? You are using deprecated code, and Date doesn't use miliseconds the way that you think that it does. It calculates the date relative to January 1, 1970, 00:00:00 GMT as per the Date API.

Adding multiple Variables on println

public static void main(String[] args) {
//Numbers
int operand1 = 25;
int operand2 = 6;
//Arithmetic values
int sum = 0;
int difference = 0;
int product = 0;
int quotient = 0;
int remainder = 0;
//Operations
sum = operand1 + operand2;
difference = operand1 - operand2;
product = operand1*operand2;
quotient = operand1/operand2;
remainder = operand1%operand2;
//Output
System.out.println("Arithmetic");
System.out.println("============================");
System.out.println("25 + 6 = " + sum);
System.out.println("25 - 6 = " + difference);
System.out.println("25 * 6 = " + product);
System.out.println("25 / 6 = " + quotient);
System.out.println("25 % 6 = " + remainder);
I'm trying to find a way to replace "25 + 6", "25 - 6", etc... with variables like
(operand1 "+" operand2 "=" sum) so the values will change dynamically depending on what value I put on oeprand1 and operand2. Is there any way to do that? Thanks
You do it the same exact way you are inserting your result variables into the strings...
System.out.println(operand1 + " + " + operand2 + " = " + sum);
You could also use printf if you wanted to although you have to insert the line break explicitly:
System.out.printf("%d + %d = %d%n", operand1, operand2, sum);
Maybe it is just me but I find this to look much cleaner.
System.out.print(MessageFormat.format(
"Arithmetic\n" +
"============================\n"+
"{0} + {1} = {2}\n"+
"{0} - {1} = {3}\n"+
"{0} * {1} = {4}\n"+
"{0} / {1} = {5}\n"+
"{0} % {1} = {6}\n", operand1,operand2,sum,difference,product,quotient,remainder));
The MessageFormat.format provides a neat alternative way to accomplish what you are looking for.
Remember sometimes less is more! Why repeat the print command over and over again?

Converting KB to MB, GB, TB dynamically

public String size(int size){
String hrSize = "";
int k = size;
double m = size/1024;
double g = size/1048576;
double t = size/1073741824;
DecimalFormat dec = new DecimalFormat("0.00");
if (k>0)
{
hrSize = dec.format(k).concat("KB");
}
if (m>0)
{
hrSize = dec.format(m).concat("MB");
}
if (g>0)
{
hrSize = dec.format(g).concat("GB");
}
if (t>0)
{
hrSize = dec.format(t).concat("TB");
}
return hrSize;
}
This is a method that should return size in GB,MB, KB or TB. Input value is in KB.
for example result for 1245 should be like 1.21MB but what I get is 1.00MB.
A modified version. Only calls format once. Includes "Bytes".
public static String formatFileSize(long size) {
String hrSize = null;
double b = size;
double k = size/1024.0;
double m = ((size/1024.0)/1024.0);
double g = (((size/1024.0)/1024.0)/1024.0);
double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0);
DecimalFormat dec = new DecimalFormat("0.00");
if ( t>1 ) {
hrSize = dec.format(t).concat(" TB");
} else if ( g>1 ) {
hrSize = dec.format(g).concat(" GB");
} else if ( m>1 ) {
hrSize = dec.format(m).concat(" MB");
} else if ( k>1 ) {
hrSize = dec.format(k).concat(" KB");
} else {
hrSize = dec.format(b).concat(" Bytes");
}
return hrSize;
}
You are performing integer division. So the result of division is also integer. And fractional part is truncated.
so, 1245 / 1024 = 1
Change your division to floating point division: -
double m = size/1024.0;
double g = size/1048576.0;
double t = size/1073741824.0;
Also, your comparison is faulty. You should do the comparison with 1.
if (m > 1), if (t > 1), if (g > 1)
Ideally I would change your comparison to: -
if (t > 1) {
hrSize = dec.format(t).concat("TB");
} else if (g > 1) {
hrSize = dec.format(g).concat("GB");
} else if (m > 1) {
hrSize = dec.format(m).concat("MB");
} else {
hrSize = dec.format(size).concat("KB");
}
You need to compare with the higher unit first, and then move to the lower one.
I love this:
public static String getDynamicSpace(long diskSpaceUsed)
{
if (diskSpaceUsed <= 0) {
return "0";
}
final String[] units = new String[] { "B", "KiB", "MiB", "GiB", "TiB" };
int digitGroups = (int) (Math.log10(diskSpaceUsed) / Math.log10(1024));
return new DecimalFormat("#,##0.#").format(diskSpaceUsed / Math.pow(1024, digitGroups))
+ " " + units[digitGroups];
}
The problem is that you're using integer division. Change your code to:
double m = size/1024.0;
double g = size/1048576.0;
double t = size/1073741824.0;
In your original code, double m = size/1024 would divide the integer size by 1024, truncate the result to an integer, and only then convert it to double. This is why the fractional part was getting lost.
You are performing integer division,
i.e., 31/15 will result in 2, not 2.whatever
just append the number with D or d which denotes it as a double and you will be fine
double m = size/1024D;
double g = size/1048576D;
double t = size/1073741824D;
Its not easy to get that right. Rohit Jain mentioned the integer operation. Also rounding can be an issue, as always rounding down may not be desirable. I would advise to go for an available solution like in the triava library.
It can format numbers with arbitrary precision, in 3 different systems (SI, IEC, JEDEC) and various output options. Here are some code examples from the triava unit tests:
UnitFormatter.formatAsUnit(1126, UnitSystem.SI, "B");
// = "1.13kB"
UnitFormatter.formatAsUnit(2094, UnitSystem.IEC, "B");
// = "2.04KiB"
Printing exact kilo, mega values (here with W = Watt):
UnitFormatter.formatAsUnits(12_000_678, UnitSystem.SI, "W", ", ");
// = "12MW, 678W"
You can pass a DecimalFormat to customize the output:
UnitFormatter.formatAsUnit(2085, UnitSystem.IEC, "B", new DecimalFormat("0.0000"));
// = "2.0361KiB"
For arbitrary operations on kilo or mega values, you can split them into components:
UnitComponent uc = new UnitComponent(123_345_567_789L, UnitSystem.SI);
int kilos = uc.kilo(); // 567
int gigas = uc.giga(); // 123
class ConverterUtils{
public static void main(String[] args) {
System.out.println(getSize(1234567));
}
public static String getSize(long size) {
String s = "";
double kb = size / 1024;
double mb = kb / 1024;
double gb = mb / 1024;
double tb = gb / 1024;
if(size < 1024L) {
s = size + " Bytes";
} else if(size >= 1024 && size < (1024L * 1024)) {
s = String.format("%.2f", kb) + " KB";
} else if(size >= (1024L * 1024) && size < (1024L * 1024 * 1024)) {
s = String.format("%.2f", mb) + " MB";
} else if(size >= (1024L * 1024 * 1024) && size < (1024L * 1024 * 1024 * 1024)) {
s = String.format("%.2f", gb) + " GB";
} else if(size >= (1024L * 1024 * 1024 * 1024)) {
s = String.format("%.2f", tb) + " TB";
}
return s;
}
}
To better understand - https://www.techspot.com/news/68482-quickly-convert-between-storage-size-units-kb-mb.html
public class FileSizeCalculator {
String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
public static void main(String[] args) {
FileSizeCalculator fs = new FileSizeCalculator();
String properFileSize = fs.calculateProperFileSize(2362232012l);
System.out.println("Proper file size: " + properFileSize);
}
public String calculateProperFileSize(long noOfBytes){
String sizeToReturn = "";// = FileUtils.byteCountToDisplaySize(bytes), unit = "";
double bytes = noOfBytes;
int index = 0;
for(index = 0; index < fileSizeUnits.length; index++){
if(bytes < 1024){
break;
}
bytes = bytes / 1024;
}
sizeToReturn = String.valueOf(bytes) + " " + fileSizeUnits[index];
return sizeToReturn;
}
}
Just add more file unit (if any missing), and you will see unit size up to that unit (if your file has that much length)
My basic version (you CAN define some constants instead of computing POW all the time):
public static String GetFolderSizeHuman(long aBytes)
{
if (aBytes < 1024 * 1024)
return aBytes + " KB";
else if (aBytes < Math.pow(2, 20) * 1024)
return (int) aBytes / Math.pow(2, 20) + " MB";
else if (aBytes < Math.pow(2, 30) * 1024 )
return kGbTbFormatter.format(aBytes / Math.pow(2, 30)) + " GB";
else if (aBytes < Math.pow(2, 40) * 1024)
return kGbTbFormatter.format(aBytes / Math.pow(2, 40)) + " TB";
else return "N/A (1TB?)";
}
bickster's answer works quite alright but the problem with it is that it returns results like 45.00 Bytes and 12.00 KB. In my opinion, the last decimal digits should be removed if they are zeros. So instead of 45.00 Bytes and 12.00 KB, you get 45 B and 12 KB (notice that Bytes has been changed to B. This is just for uniformity since we have KB, MB etc and not Kilobytes, Megabytes etc).
private boolean isDouble(double value) {
if (value % 1 == 0) {
Log.d(TAG, "value is " + value + " and is not double");
return false;
} else {
Log.d(TAG, "value is " + value + " and is double");
return true;
}
}
The above method simply checks if the value has zeros as decimal digits.
private String formatFileSize(long size) {
String hrSize = null;
double b = size;
double k = size/1024.0;
double m = ((size/1024.0)/1024.0);
double g = (((size/1024.0)/1024.0)/1024.0);
double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0);
DecimalFormat dec1 = new DecimalFormat("0.00");
DecimalFormat dec2 = new DecimalFormat("0");
if (t>1) {
hrSize = isDouble(t) ? dec1.format(t).concat(" TB") : dec2.format(t).concat(" TB");
} else if (g>1) {
hrSize = isDouble(g) ? dec1.format(g).concat(" GB") : dec2.format(g).concat(" GB");
} else if (m>1) {
hrSize = isDouble(m) ? dec1.format(m).concat(" MB") : dec2.format(m).concat(" MB");
} else if (k>1) {
hrSize = isDouble(k) ? dec1.format(k).concat(" KB") : dec2.format(k).concat(" KB");
} else {
hrSize = isDouble(b) ? dec1.format(b).concat(" B") : dec2.format(b).concat(" B");
}
return hrSize;
}

Java Homework MaxSumTest

I am currently attempting to revise a Java Homework program for my Data Structures class that displays the output of the MaxSumTest program in a table.
I've created four arrays, and placed them inside one of the loops that calculates the timing info. I am trying to populate each array with only the timing info for one algorithm. So each array would have 4 elements. However, every time I run my revision of the program, I get an out of bounds error.
Here is the Original
The only method I revised is getTimingInfo. Here is my revision:
public static void getTimingInfo( int n, int alg )
{
int [] test = new int[ n ];
long startTime = System.currentTimeMillis( );;
long totalTime = 0;
//create an array for each Algorithm
long[] alg4;
long[] alg3;
long[] alg2;
long[] alg1;
//allocate memory for 5 long ints
alg4 = new long[5];
alg3 = new long[5];
alg2 = new long[5];
alg1 = new long[5];
int i;
int j;
int index = 0;
for( i = 0; totalTime < 4000; i++ )
{
for( j = 0; j < test.length; j++ )
test[ j ] = rand.nextInt( 100 ) - 50;
index = j;
switch( alg )
{
case 1:
maxSubSum1( test );
break;
case 2:
maxSubSum2( test );
break;
case 3:
maxSubSum3( test );
break;
case 4:
maxSubSum4( test );
break;
}
totalTime = System.currentTimeMillis( ) - startTime;
}
alg1[index] = totalTime * 1000 / i;
alg2[index] = totalTime * 1000 / i;
alg3[index] = totalTime * 1000 / i;
alg4[index] = totalTime * 1000 / i;
//Build first column of table
System.out.println("Size of N Algorithms\t" + "250\t" + "2500\t" + "25000\t" + "250000");
System.out.println("Alg #4\t" + alg4[0] + "\t" + alg4[1] + "\t" + alg4[2] + "\t" + alg4[3] + "\t" + alg4[4]);
System.out.println("Alg #3\t" + alg3[0] + "\t" + alg3[1] + "\t" + alg3[2] + "\t" + alg3[3] + "\t" + alg3[4]);
System.out.println("Alg #2\t" + alg2[0] + "\t" + alg2[1] + "\t" + alg2[2] + "\t" + alg2[3] + "\t" + alg2[4]);
System.out.println("Alg #1\t" + alg1[0] + "\t" + alg1[1] + "\t" + alg1[2] + "\t" + alg1[3] + "\t" + alg1[4]);
/*
System.out.println( "Algorithm #" + alg + "\t"
+ "N = " + test.length
+ "\ttime = " + ( totalTime * 1000 / i ) + " microsec" );
*/
}
Any advice or pointers in the right direction would be appreciated.
Shouldn't the lines that update the array elements be inside the inner loop?
alg1[index] = totalTime * 1000 / i;
alg2[index] = totalTime * 1000 / i;
alg3[index] = totalTime * 1000 / i;
alg4[index] = totalTime * 1000 / i;
You are assigning them outside the loop, where the value of index is 5, so it's out of bounds.
I'm not sure exactly what you are trying to do, but I think that what you really want to do is call getTimingInfo() a number of times and then assign the results to a table, not change the internal workings of getTimingInfo().
This requires that you define the arrays in which you will store the timing data OUTSIDE of getTimingInfo(), and then the only change inside of getTimingInfo() would be storing to that (already defined) array, rather than printing.
long[] alg1;
alg4 = new long[5];
Can be better expressed as
long[] alg1 = new long[5];
maxSubSum3( test );
Is written nicer as
maxSubSum3(test);
int j;
int index = 0;
Actually do the same thing.
Just to pick a few points.
You are setting the alg4, alg3, alg2, and alg1 to size 5, not size 4 as you said you needed.

Categories