I have the following so far, but can't figure out a tidy way to get the direction letters in without a bunch of messy if statements. Any ideas? Ideally I'd like to extend the CLLocation class with a category to do this.
-(NSString *)nicePosition{
double latitude = [self.latitude doubleValue];
double longitude = [self.longitude doubleValue];
int latSeconds = (int)round(latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;
int longSeconds = (int)round(longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = abs(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;
//TODO: Use N,E,S,W notation in lat/long
return [NSString stringWithFormat:#"%i° %i' %i\", %i° %i' %i\"", latDegrees, latMinutes, latSeconds, longDegrees, longMinutes, longSeconds];
}
For the record I did the following.
-(NSString *)nicePosition{
double latitude = [self.latitude doubleValue];
double longitude = [self.longitude doubleValue];
int latSeconds = (int)round(abs(latitude * 3600));
int latDegrees = latSeconds / 3600;
latSeconds = latSeconds % 3600;
int latMinutes = latSeconds / 60;
latSeconds %= 60;
int longSeconds = (int)round(abs(longitude * 3600));
int longDegrees = longSeconds / 3600;
longSeconds = longSeconds % 3600;
int longMinutes = longSeconds / 60;
longSeconds %= 60;
char latDirection = (latitude >= 0) ? 'N' : 'S';
char longDirection = (longitude >= 0) ? 'E' : 'W';
return [NSString stringWithFormat:#"%i° %i' %i\" %c, %i° %i' %i\" %c", latDegrees, latMinutes, latSeconds, latDirection, longDegrees, longMinutes, longSeconds, longDirection];
}
Standard way:
char lonLetter = (lon > 0) ? 'E' : 'W';
char latLetter = (lat > 0) ? 'N' : 'S';
Here's some Objective-C based on Daniel's solution above:
- (NSString*)coordinateString {
int latSeconds = (int)(self.latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = ABS(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;
int longSeconds = (int)(self.longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = ABS(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;
NSString* result = [NSString stringWithFormat:#"%d°%d'%d\"%# %d°%d'%d\"%#",
ABS(latDegrees),
latMinutes,
latSeconds,
latDegrees >= 0 ? #"N" : #"S",
ABS(longDegrees),
longMinutes,
longSeconds,
longDegrees >= 0 ? #"E" : #"W"];
return result;
}
Here's a solution in C#:
void Run(double latitude, double longitude)
{
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;
Console.WriteLine("{0}° {1}' {2}\" {3}, {4}° {5}' {6}\" {7}",
Math.Abs(latDegrees),
latMinutes,
latSeconds,
latDegrees >= 0 ? "N" : "S",
Math.Abs(longDegrees),
longMinutes,
longSeconds,
latDegrees >= 0 ? "E" : "W");
}
This is an example run:
new Program().Run(-15.14131211, 56.345678);
new Program().Run(15.14131211, -56.345678);
new Program().Run(15.14131211, 56.345678);
Which prints:
15° 8' 29" S, 56° 20' 44" W
15° 8' 29" N, 56° 20' 44" E
15° 8' 29" N, 56° 20' 44" E
Hope this helps, and that it does the right thing. Good luck!
If you want to do it in swift you can make something like that:
import MapKit
extension CLLocationCoordinate2D {
var latitudeDegreeDescription: String {
return fromDecToDeg(self.latitude) + " \(self.latitude >= 0 ? "N" : "S")"
}
var longitudeDegreeDescription: String {
return fromDecToDeg(self.longitude) + " \(self.longitude >= 0 ? "E" : "W")"
}
private func fromDecToDeg(input: Double) -> String {
var inputSeconds = Int(input * 3600)
let inputDegrees = inputSeconds / 3600
inputSeconds = abs(inputSeconds % 3600)
let inputMinutes = inputSeconds / 60
inputSeconds %= 60
return "\(abs(inputDegrees))°\(inputMinutes)'\(inputSeconds)''"
}
}
Regarding to Alex's answer, here is a solution in Swift 3 with an output tuple. It returns the coordinates in a tuple.
Furthermore, it really extends the class CLLocationDegrees and doesn't require an extra parameter.
import MapKit
extension CLLocationDegrees {
func degreeRepresentation() -> (northOrEast: Bool, degrees: Int, minutes: Int, seconds: Int) {
var inputSeconds = Int(self * 3600)
let inputDegrees = inputSeconds / 3600
inputSeconds = abs(inputSeconds % 3600)
let inputMinutes = inputSeconds / 60
inputSeconds %= 60
return (inputDegrees > 0, abs(inputDegrees), inputMinutes, inputSeconds)
}
}
int latSeconds = (int)round(abs(latitude * 3600));
This is mistake! Proper is
int latSeconds = abs(round(latitude * 3600));
Related
I am working on ESC POS printer. Using below code I am able to print the image, but the issue is an image not printing properly. You can see in the below image. Please review my code and let me know where exactly the issue.
- (void) btnPrintPicture{
UIImage * img = [UIImage imageNamed:#"download.png"];
int width = img.size.width;
int height = img.size.height;
unsigned char * binaryImageData = malloc(width * height);
unsigned char * data = malloc(height * (8 + width / 8));
unsigned char * grayData = [self convertImageToGray:img];
format_K_threshold(grayData, width, height, binaryImageData);
eachLinePixToCmd(binaryImageData, width, height, 0, data);
NSMutableArray *dataArray = [NSMutableArray new];
int splitBytes = 100;
NSData *comData = [[NSData alloc] initWithBytes:(const void *)data length:(height * (8+width/8))];
for(int i = 0; i < comData.length ; i=i+splitBytes){
NSData *subData = nil;
if((i+splitBytes)>comData.length){
subData = [comData subdataWithRange:NSMakeRange(i, (comData.length-i))];
}else{
subData = [comData subdataWithRange:NSMakeRange(i, splitBytes)];
}
[dataArray addObject:subData];
}
[dataArray enumerateObjectsUsingBlock:^(NSData *obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self.discoveredPeripheral writeValue:obj forCharacteristic:self.discoveredCharacteristic type:CBCharacteristicWriteWithResponse];
}];
free(grayData);
free(binaryImageData);
free(data);
}
This method is used for converting image to grayscale.
-(unsigned char *)convertImageToGray:(UIImage *)i
{
int kRed = 1;
int kGreen = 2;
int kBlue = 4;
int colors = kGreen | kBlue | kRed;
int m_width = i.size.width;
int m_height = i.size.height;
uint32_t *rgbImage = (uint32_t *) malloc(m_width * m_height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbImage, m_width, m_height, 8, m_width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetShouldAntialias(context, NO);
CGContextDrawImage(context, CGRectMake(0, 0, m_width, m_height), [i CGImage]);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
// now convert to grayscale
uint8_t *m_imageData = (uint8_t *) malloc(m_width * m_height);
for(int y = 0; y < m_height; y++) {
for(int x = 0; x < m_width; x++) {
uint32_t rgbPixel=rgbImage[y*m_width+x];
uint32_t sum=0,count=0;
if (colors & kRed) {sum += (rgbPixel>>24)&255; count++;}
if (colors & kGreen) {sum += (rgbPixel>>16)&255; count++;}
if (colors & kBlue) {sum += (rgbPixel>>8)&255; count++;}
m_imageData[y*m_width+x]=sum/count;
}
}
free(rgbImage);
return m_imageData;}
void format_K_threshold(unsigned char * orgpixels, int xsize, int ysize, unsigned char * despixels) {
int graytotal = 0;
int k = 0;
int i;
int j;
int gray;
for(i = 0; i < ysize; ++i) {
for(j = 0; j < xsize; ++j) {
gray = orgpixels[k] & 255;
graytotal += gray;
++k;
}
}
int grayave = graytotal / ysize / xsize;
k = 0;
for(i = 0; i < ysize; ++i) {
for(j = 0; j < xsize; ++j) {
gray = orgpixels[k] & 255;
if(gray > grayave) {
despixels[k] = 0;
} else {
despixels[k] = 1;
}
++k;
}
}
}
This method is using ESC commands to print the image.
void eachLinePixToCmd(unsigned char * src, int nWidth, int nHeight, int nMode, unsigned char * data) {
int p0[] = { 0, 0x80 };
int p1[] = { 0, 0x40 };
int p2[] = { 0, 0x20 };
int p3[] = { 0, 0x10 };
int p4[] = { 0, 0x08 };
int p5[] = { 0, 0x04 };
int p6[] = { 0, 0x02 };
int nBytesPerLine = nWidth / 8;
int offset = 0;
int k = 0;
for (int i = 0; i < nHeight; i++) {
offset = i * (8 + nBytesPerLine);
data[offset + 0] = 0x1d;
data[offset + 1] = 0x76;
data[offset + 2] = 0x30;
data[offset + 3] = (unsigned char) (nMode & 0x01);
data[offset + 4] = (unsigned char) (nBytesPerLine % 0xff);
data[offset + 5] = (unsigned char) (nBytesPerLine / 0xff);
data[offset + 6] = 0x01;
data[offset + 7] = 0x00;
for (int j = 0; j < nBytesPerLine; j++) {
data[offset + 8 + j] = (unsigned char) (p0[src[k]] + p1[src[k + 1]] + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]] + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
k = k + 8;
}
}
}
Thanks in advance.
Based on having fixed a very similar bug in a different project with this change, I am guessing that your image width is not divisible by 8.
This line will drop nWidth % 8 pixels on each row, causing a rightward slant if the image width is not divisible by 8.
int nBytesPerLine = nWidth / 8;
Instead, you should be padding with zeroes:
int nBytesPerLine = (nWidth + 7) / 8;
Your data variable needs to grow to match as well, it has the same issue.
Lastly, you are issuing the GS v 0 command for each row, which is not very efficient. You can issue this once for the entire image, and specify the height. From the same project, a C example is here.
The arrayTwelveLEngth variable isn't working as expected. When I placed a breakpoint on the amount = 1; line above, I hovered over arrayTwelve, and found that it was empty with 0 elements. Immediately after, I then hovered about arrayTwelveLength, expecting to see 0, but instead it seems that the arrayTwelveLength had a value of 1876662112. I don't know how it got that value, and I need to solve that problem. What am I doing wrong?
NSMutableArray *redValues = [NSMutableArray array];
NSMutableArray *arrayTwelve = [NSMutableArray array];
__block int counter = 0;
__block NSInteger u;
NSUInteger redValuesLength = [redValues count];
__block int arrayTwelveLength = 0;
__block float diffForAverage, fps, averageTime, bloodSpeed;
float average;
__block int amount = 1;
__block float totalTwelve, totalThirteen;
__block NSUInteger totalNumberOfFramesInSmallArrays = 0;
__block NSUInteger totalNumberOfFramesNotInSmallArrays;
for (u = (counter + 24); u < (redValuesLength - 24); u++)
{
diffForAverage = average - [redValues[u + 1] floatValue];
float test = [redValues[u] floatValue];
arrayTwelveLength = [arrayTwelve count];
if (diffForAverage > -1 && diffForAverage < 1)
{
totalTwelve += [redValues[u + 1] floatValue];
amount++;
[arrayTwelve addObject:#(test)];
counter++;
}
else
{
if (arrayTwelveLength >= 8)
{
counter++;
break;
}
else
{
[arrayTwelve removeAllObjects];
totalTwelve = [redValues[u + 1] floatValue];
counter++;
amount = 1;
}
}
}
amount = 1; // I added a breakpoint here
totalThirteen = [redValues[u + 1] floatValue];
average = totalThirteen / amount;
if (counter == redValuesLength)
{
totalNumberOfFramesNotInSmallArrays = redValuesLength - totalNumberOfFramesInSmallArrays - 25 - (redValuesLength - counter);
fps = redValuesLength / 30;
averageTime = totalNumberOfFramesNotInSmallArrays / fps;
bloodSpeed = 3 / averageTime;
[_BloodSpeedValue setText:[NSString stringWithFormat:#"%f", bloodSpeed]];
}
if (arrayTwelveLength == NULL)
{
arrayTwelveLength = 0;
}
totalNumberOfFramesInSmallArrays += arrayTwelveLength;
You have problems with unsigned/signed types and with your data set the first for loop should not even enter, because your for loop index variable u (== 24) < (redValuesLength (== 0) - 24) but, because redValuesLength being Unsigned type it wraps around and you get:
(unsigned long)0 - (unsigned long)24 = -24 modulo ULONG_MAX + 1= 18446744073709551592
Also, you are not initialising average before usage.
Hello I tried to find a solution in Objective C to get the lenght of audio file included milliseconds.
at the moment I have only this code:
-(NSString *) DoubleToNSStringTime:(double)valore
{
NSNumber *theDouble = [NSNumber numberWithDouble:valore];
int inputSeconds = [theDouble intValue];
int hours = inputSeconds / 3600;
int minutes = (inputSeconds - hours * 3600 ) / 60;
int seconds = inputSeconds - hours * 3600 - minutes * 60;
NSString *theTime = [NSString stringWithFormat:#"%.2d:%.2d", minutes, seconds];
NSLog(#"TDoubleToNSStringTime= %#", theTime);
return theTime;
}
the Issue is this:
I would like to get more precise timePosition, Minutes : Seconds : Milleseconds
some of you has a solution?
Thanks
You don’t need to convert to NSNumber and back:
- (NSString *)DoubleToNSStringTime:(double)valore
{
NSInteger interval = (NSInteger)valore;
double milliseconds = (valore - interval) * 1000;
NSInteger seconds = interval % 60;
NSInteger minutes = (interval / 60) % 60;
minutes += (interval / 60);
return [NSString stringWithFormat:#"%02ld:%02ld:%3.0f", minutes, seconds, milliseconds];
}
That should print something like 60:45:789 for an input of 3645.789.
I have a script that divides file into 10MB chunks. Haven't had a problem with this script until I tried to do it on a 6GB file. Getting negative values on ranges even if they are uint64_t. Any suggestions on where is the error?
NSData *conData = [NSURLConnection sendSynchronousRequest:fileSizeRequest returningResponse:&response error:&error];
if (conData)
{
NSDictionary *headers = [response allHeaderFields];
NSString *fileSizeString = [headers objectForKey:#"Content-Length"];
uint64_t fileSize = strtoull([fileSizeString UTF8String], NULL, 0);
self.size += fileSize;
uint64_t amountOfRanges = fileSize / 10485760;
for (int i = 0; i <= amountOfRanges; i++)
{
uint64_t rangeMin = 0;
uint64_t rangeMax = 0;
if (i != amountOfRanges)
{
rangeMin = i * 10485760;
rangeMax = (i + 1) * 10485760 - 1;
}
else
{
if (i == 0)
{
rangeMin = 0;
rangeMax = fileSize - 1;
}
else
{
rangeMin = i * 10485760;
rangeMax = i * 10485760 - 1 + (fileSize - rangeMin);
}
}
}
}
You have a problem with expressions such as this:
rangeMin = i * 10485760;
Note that i is an int and 10485760 is an int literal, so the resulting int expression can easily overflow. You should ideally make i a uint64_t and/or use unsigned long long literals, e.g.
rangeMin = i * 10485760ULL;
how to get digits after decimal point from float number in objective c
OK, this is C-style, but I imagine the process would be the same.
int decimals = (number -((int)number) );
while( decimals > 0.0 )
{
reportNextNumber( (int)(decimals*10) );
decimals = (number -((int)number) );
}
this code works
CGFloat x = 2.43;
// CGFloat x = 3.145;
// CGFloat x = 2.0003;
// CGFloat x = 1.0;
// CGFloat x = 3.1415926535;
NSLog(#"%f -> %#", x, #([self numberOfFractionDigits:x]));
- (NSString *)numberOfFractionDigits:(CGFloat)number {
CGFloat fractionalPart = number - (NSInteger)number;
NSMutableString *r = [NSMutableString stringWithString:#""];
while (fractionalPart) {
[r appendFormat:#"%#", #((NSUInteger)(fractionalPart * 10 + .5))];
number *= 10;
fractionalPart = number - (NSInteger)number;
}
return r;
}
output:
2.430000 -> 43
3.145000 -> 145
2.000300 -> 0003
1.000000 ->
3.141593 -> 1415926535 // for x = 3.1415926535;