C# Google Static Maps encoded path calculation - c#

I'm writing a tool that gets GPS coordinates from a XML file and sends them to the Google Static Maps API. I'm trying to get a polyline from Google.
I've found the documentation and so far I've written this to convert a double value to a encoded value for a polyline:
private String convertDouble(Double _input)
{
String result = String.Empty;
//value * 1e5
Int32 multiplication = Convert.ToInt32(Math.Floor(_input * 1e5));
//value to binary string
String binaryString = Convert.ToString(multiplication, 2);
//binary to hex
binaryString = BinaryStringToHexString(binaryString);
//value to hex + 1
Int32 hexConvert = Convert.ToInt32(binaryString, 16) + Convert.ToInt32("01", 16);
//value to binary string
binaryString = Convert.ToString(hexConvert, 2);
//binary string zu int[] for further calculations
Int32[] bitValues = new Int32[binaryString.Length];
for (Int32 i = 0; i < bitValues.Length; i++)
{
if (binaryString[i] == '0')
{
bitValues[i] = 0;
}
else
{
bitValues[i] = 1;
}
}
//shift binary to left
Int32[] bitValues_2 = new Int32[bitValues.Length];
for (Int32 i = 0; i < bitValues.Length - 1; i++)
{
bitValues_2[i] = bitValues[i + 1];
}
bitValues_2[bitValues_2.Length - 1] = 0;
//if input value is negative invert binary
if (_input < 0)
{
for (Int32 i = 0; i < bitValues.Length; i++)
{
if (bitValues_2[i] == 0)
{
bitValues_2[i] = 1;
}
else
{
bitValues_2[i] = 0;
}
}
}
//make blocks of 5
Int32 lengthDifference = bitValues_2.Length % 5;
Int32[] bitValues_3 = new Int32[bitValues_2.Length - lengthDifference];
for (Int32 i = bitValues_2.Length - 1; i > (bitValues_2.Length - bitValues_3.Length); i--)
{
bitValues_3[i - (bitValues_2.Length - bitValues_3.Length)] = bitValues_2[i];
}
//twist blocks
Int32[] bitValues_4 = new Int32[bitValues_3.Length];
Int32 numberOfBlocks = bitValues_3.Length / 5;
Int32 counter = 0;
String[] stringValues = new String[numberOfBlocks];
for (Int32 i = numberOfBlocks - 1; i >= 0; i--)
{
for (Int32 j = i * 5; j < (i * 5) + 5; j++)
{
bitValues_4[counter] = bitValues_3[j];
counter++;
}
}
counter = 0;
//write int[] into strings for final conversion
for (Int32 i = 0; i < bitValues_4.Length; i++)
{
if (i > 0 && i % 5 == 0)
{
counter++;
}
stringValues[counter] += bitValues_4[i].ToString();
}
// blocks ^ 0x20 (32) and convert to char
Int32 value = 0;
Int32[] intValues = new Int32[stringValues.Length];
Char[] charValues = new Char[stringValues.Length];
for (Int32 i = 0; i < stringValues.Length; i++)
{
value = Convert.ToInt32(stringValues[i], 2);
if (i < stringValues.Length - 1)
{
intValues[i] = value ^ 32;
}
else
{
intValues[i] = value;
}
intValues[i] = intValues[i] + 63;
charValues[i] = (Char)intValues[i];
result += charValues[i];
}
return result;
}
If I use the value from the documentation
-179.9832104
I get the result
`~oia#
Which is fine, but if I use one of my values e.g.:
LAT: 8.7587061 LONG: 48.6331662
LAT: 8.8905152 LONG: 48.6226701
I get the wrong values. The final polyline should be in southern Germany. But with my calculation the polyline is somewhere near a cost. Maybe there is a finished class that gives me the encoded coordinates and I haven't found it yet.
And yes, I have to encode the polylines, because there will be many different coordinates in the XML (the GPS tracker runs for several hours and captures the location every 10 seconds).

Well, after another night of searching and testing I have found a solution.
Brian Pedersen has a solution in his blog. And it works just like it should.
I don't want to copy and paste the code here, but the link has it.

Related

inaccurate results with function to add an array of digits together

so i have this function:
static int[] AddArrays(int[] a, int[] b)
{
int length1 = a.Length;
int length2 = b.Length;
int carry = 0;
int max_length = Math.Max(length1, length2) + 1;
int[] minimum_arr = new int[max_length - length1].Concat(a).ToArray();
int[] maximum_arr = new int[max_length - length2].Concat(b).ToArray();
int[] new_arr = new int[max_length];
for (int i = max_length - 1; i >= 0; i--)
{
int first_digit = maximum_arr[i];
int second_digit = i - (max_length - minimum_arr.Length) >= 0 ? minimum_arr[i - (max_length - minimum_arr.Length)] : 0;
if (second_digit + first_digit + carry > 9)
{
new_arr[i] = (second_digit + first_digit + carry) % 10;
carry = 1;
}
else
{
new_arr[i] = second_digit + first_digit + carry;
carry = 0;
}
}
if (carry == 1)
{
int[] result = new int[max_length + 1];
result[0] = 1;
Array.Copy(new_arr, 0, result, 1, max_length);
return result;
}
else
{
return new_arr;
}
}
it basically takes 2 lists of digits and adds them together. the point of this is that each array of digits represent a number that is bigger then the integer limits. now this function is close to working the results get innacurate at certein places and i honestly have no idea why. for example if the function is given these inputs:
"1481298410984109284109481491284901249018490849081048914820948019" and
"3475893498573573849739857349873498739487598" (both of these are being turned into a array of integers before being sent to the function)
the expected output is:
1,481,298,410,984,109,284,112,957,384,783,474,822,868,230,706,430,922,413,560,435,617
and what i get is:
1,481,298,410,984,109,284,457,070,841,142,258,634,158,894,233,092,241,356,043,561,7
i would very much appreciate some help with this ive been trying to figure it out for hours and i cant seem to get it to work perfectly.
I suggest Reverse arrays a and b and use good old school algorithm:
static int[] AddArrays(int[] a, int[] b) {
Array.Reverse(a);
Array.Reverse(b);
int[] result = new int[Math.Max(a.Length, b.Length) + 1];
int carry = 0;
int value = 0;
for (int i = 0; i < Math.Max(a.Length, b.Length); ++i) {
value = (i < a.Length ? a[i] : 0) + (i < b.Length ? b[i] : 0) + carry;
result[i] = value % 10;
carry = value / 10;
}
if (carry > 0)
result[result.Length - 1] = carry;
else
Array.Resize(ref result, result.Length - 1);
// Let's restore a and b
Array.Reverse(a);
Array.Reverse(b);
Array.Reverse(result);
return result;
}
Demo:
string a = "1481298410984109284109481491284901249018490849081048914820948019";
string b = "3475893498573573849739857349873498739487598";
string c = string.Concat(AddArrays(
a.Select(d => d - '0').ToArray(),
b.Select(d => d - '0').ToArray()));
Console.Write(c);
Output:
1481298410984109284112957384783474822868230706430922413560435617

C# - Array transposing bit level

I have an array of 10 x 8 bit(bytes), named Matrix[10], e.g.
byte[] Matrix = new byte[] {
0b01111011,
0b10001100,
0b10101101,
0b10100001,
0b11010110,
0b00011100,
0b00111000,
0b11001111,
0b01111011,
0b10101010,
};
What I want to do is create another array named Matrix_res10 which will have 8 x 10bit (used Int32) elements:
int[] Matrix_res10 = new int[] {
0b0111100101,
0b1000100110,
0b1011001011,
0b1000111010,
0b1110011111,
0b0110110100,
0b1000100111,
0b1011000110
};
Additional explanation in the attached "description" picture.
description
Now, I was able to do it, but I feel the code is too complicated, and can be made simpler, or more logical :)
Any tips ?
my code:
private void button11_Click(object sender, EventArgs e)
{
Int32 i,j;
byte temp;
Random r = new Random();
richTextBox5.Clear();
richTextBox6.Clear();
for (i = 0; i < 10; i++)
{
Matrix[i] = Convert.ToByte(r.Next(0,255));// initialize the matrix with random bytes 0-255
richTextBox5.Text += Convert.ToString(Matrix[i], 2).PadLeft(8, '0')+"\n";//print it
}
for (i = 0; i < 8; i++)
{
Matrix_res10[i] = 0;
for (j = 0; j < 10; j++)
{
temp = (byte)(Matrix[j] << i);
temp = (byte)(temp >> 7);
Matrix_res10[i] += temp*(long)(Math.Pow(2, 9-j)); //convert the bits to a int
}
}
for (i = 0; i < 8; i++)
{
richTextBox6.Text += Convert.ToString(Matrix_res10[i],2).PadLeft(10,'0') + "\n";
}
}
All you have to do is to compute what is jth bit of ith item:
byte[] Matrix = new byte[] {
0b01111011,
0b10001100,
0b10101101,
0b10100001,
0b11010110,
0b00011100,
0b00111000,
0b11001111,
0b01111011,
0b10101010,
};
// 8 - byte has 8 bits; more exact: new int[sizeof(byte) * 8];
// int[] - we have to store 10 bits, that's why byte is not long enough
int[] Matrix_res10 = new int[8];
for (int i = 0; i < Matrix_res10.Length; ++i)
for (int j = 0; j < Matrix.Length; ++j)
Matrix_res10[i] |= ((Matrix[j] >> (Matrix_res10.Length - i - 1)) & 1) <<
(Matrix.Length - j - 1);
Let's have a look at the result:
string report = string.Join(Environment.NewLine, Matrix_res10
.Select(item => Convert.ToString(item, 2).PadLeft(Matrix.Length, '0')));
Console.Write(report);
Outcome:
0111100101
1000100110
1011001011
1000111010
1110011111
0110110100
1000100111
1011000110
A bit of binary arithmetic might help here:
static int[] Transpose(byte[] x) {
var result = new int[8];
for (int i = 7; i >= 0; i--) {
for (int j = 0; j < x.Length; j++) {
// get i-th bit of byte
var mask = 1 << i;
var bit = (x[j] & mask) >> i;
// set that bit at j-th position of target number
result[7 - i] |= bit << (x.Length - 1 - j);
}
}
return result;
}

Reorder digits in integer using C#

I want to ask how I can reorder the digits in an Int32 so they result in the biggest possible number.
Here is an example which visualizes what I am trying to do:
2927466 -> 9766422
12492771 -> 97742211
I want to perform the ordering of the digits without using the System.Linq namespace and without converting the integer into a string value.
This is what I got so far:
public static int ReorderInt32Digits(int v)
{
int n = Math.Abs(v);
int l = ((int)Math.Log10(n > 0 ? n : 1)) + 1;
int[] d = new int[l];
for (int i = 0; i < l; i++)
{
d[(l - i) - 1] = n % 10;
n /= 10;
}
if (v < 0)
d[0] *= -1;
Array.Sort(d);
Array.Reverse(d);
int h = 0;
for (int i = 0; i < d.Length; i++)
{
int index = d.Length - i - 1;
h += ((int)Math.Pow(10, index)) * d[i];
}
return h;
}
This algorithm works flawlessly but I think it is not very efficient.
I would like to know if there is a way to do the same thing more efficiently and how I could improve my algorithm.
You can use this code:
var digit = 2927466;
String.Join("", digit.ToString().ToCharArray().OrderBy(x => x));
Or
var res = String.Join("", digit.ToString().ToCharArray().OrderByDescending(x => x) );
Not that my answer may or may not be more "efficient", but when I read your code you calculated how many digits there are in your number so you can determine how large to make your array, and then you calculated how to turn your array back into a sorted integer.
It would seem to me that you would want to write your own code that did the sorting part without using built in functionality, which is what my sample does. Plus, I've added the ability to sort in ascending or descending order, which is easy to add in your code too.
UPDATED
The original algorithm sorted the digits, now it sorts the digits so that the end result is the largest or smallest depending on the second parameter passed in. However, when dealing with a negative number the second parameter is treated as opposite.
using System;
public class Program
{
public static void Main()
{
int number1 = 2927466;
int number2 = 12492771;
int number3 = -39284925;
Console.WriteLine(OrderDigits(number1, false));
Console.WriteLine(OrderDigits(number2, true));
Console.WriteLine(OrderDigits(number3, false));
}
private static int OrderDigits(int number, bool asc)
{
// Extract each digit into an array
int[] digits = new int[(int)Math.Floor(Math.Log10(Math.Abs(number)) + 1)];
for (int i = 0; i < digits.Length; i++)
{
digits[i] = number % 10;
number /= 10;
}
// Order the digits
for (int i = 0; i < digits.Length; i++)
{
for (int j = i + 1; j < digits.Length; j++)
{
if ((!asc && digits[j] > digits[i]) ||
(asc && digits[j] < digits[i]))
{
int temp = digits[i];
digits[i] = digits[j];
digits[j] = temp;
}
}
}
// Turn the array of digits back into an integer
int result = 0;
for (int i = digits.Length - 1; i >= 0; i--)
{
result += digits[i] * (int)Math.Pow(10, digits.Length - 1 - i);
}
return result;
}
}
Results:
9766422
11224779
-22345899
See working example here... https://dotnetfiddle.net/RWA4XV
public static int ReorderInt32Digits(int v)
{
var nums = Math.Abs(v).ToString().ToCharArray();
Array.Sort(nums);
bool neg = (v < 0);
if(!neg)
{
Array.Reverse(nums);
}
return int.Parse(new string(nums)) * (neg ? -1 : 1);
}
This code fragment below extracts the digits from variable v. You can modify it to store the digits in an array and sort/reverse.
int v = 2345;
while (v > 0) {
int digit = v % 10;
v = v / 10;
Console.WriteLine(digit);
}
You can use similar logic to reconstruct the number from (sorted) digits: Multiply by 10 and add next digit.
I'm posting this second answer because I think I got the most efficient algorithm of all (thanks for the help Atul) :)
void Main()
{
Console.WriteLine (ReorderInt32Digits2(2927466));
Console.WriteLine (ReorderInt32Digits2(12492771));
Console.WriteLine (ReorderInt32Digits2(-1024));
}
public static int ReorderInt32Digits2(int v)
{
bool neg = (v < 0);
int mult = neg ? -1 : 1;
int result = 0;
var counts = GetDigitCounts(v);
for (int i = 0; i < 10; i++)
{
int idx = neg ? 9 - i : i;
for (int j = 0; j < counts[idx]; j++)
{
result += idx * mult;
mult *= 10;
}
}
return result;
}
// From Atul Sikaria's answer
public static int[] GetDigitCounts(int n)
{
int v = Math.Abs(n);
var result = new int[10];
while (v > 0) {
int digit = v % 10;
v = v / 10;
result[digit]++;
}
return result;
}

Listbox not removing values in c# GUI

The user basically enters a number of hex values into a textbox separated by commas eg. AA,1B,FF. These are then displayed in a listbox box. if the number of hex values in the textbox exceeds the size to transfer defined by the user, the listbox only displays the this number of values or if the size to transfer is bigger that adds zero values to the listbox.
this works fine until you enter a value with a zero in front of it such as AA,BB,CC,DD,EE,0F, if sizeToTransfer = 2, the listbox should display 0xAA and 0xBB. but instead it only removes the 0F value?
I'm pretty new to programming so it may be something obvious I'm missing any help would be appreciated.
private void WriteSPI1_Click(object sender, EventArgs e)
{
string hexstring = textbox1.Text;
HexValues.Items.Clear();
string[] hexarray = hexstring.Split((",\r\n".ToCharArray()), StringSplitOptions.RemoveEmptyEntries);
byte[] hexbytes = new byte[hexarray.Length];
uint num = Convert.ToUInt32(hexarray.Length);
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
if (hexarray.Length > sizeToTransfer)
{
diff = num - sizeToTransfer;
for (i = 0; i < diff+1; i++)
{
HexValues.Items.Remove("0x" + x);
}
}
else
{
diff = sizeToTransfer - num;
for (i = 0; i < diff; i++)
{
HexValues.Items.Add("0x00");
}
}
}
CHANGE
for (int j = 0; j < sizeToTransfer; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
WITH
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
and remove the if stantment that follow

TextBox.Text wont show the desired output

I got a project for making an Caesar Cipher. I am stuck in textBox2.text i.e it is not showing the encrypted text.
Kindly check my code and guide , I would be very much thank full!
Please do tell me if there are other mistakes in my code , that would be very nice.
{
key = int.Parse(textBox3.Text) - 48;
// Input.ToLower();
int size = Input.Length;
char[] value = new char[size];
char[] cipher = new char[size];
for (int i = 0; i < size; i++)
{
value[i] = Convert.ToChar(Input.Substring(i, 1));
}
for (int re = 0; re < size; re++)
{
int count = 0;
int a = Convert.ToInt32(value[re]);
for (int y = 1; y <= key; y++)
{
if (count == 0)
{
if (a == 90)
{ a = 64; }
else if (a == 122)
{ a = 96; }
cipher[re] = Convert.ToChar(a + y);
count++;
}
else
{
int b = Convert.ToInt32(cipher[re]);
if (b == 90)
{ b = 64; }
else if (b == 122)
{ b = 96; }
cipher[re] = Convert.ToChar(b + 1);
}
}
}
string ciphertext = "";
for (int p = 0; p < size; p++)
{
ciphertext = ciphertext + cipher[p].ToString();
}
ciphertext.ToUpper();
textBox2.Text = ciphertext;
}
This is very suspicious:
key = int.Parse(textBox3.Text) - 48;
The 48 is a magic number with no explanation. Presumably you're using it because it is the ASCII code for '0'. But int.Parse does not return an ASCII code.
You can either use (only) int.Parse, or else get the ASCII code of the first character in the textbox and do arithmetic on character codes. But combining these is incorrect.
key = int.Parse(textBox3.Text);
or
key = textBox3[0] - '0';
Because your current code is setting key to a negative number, the inner for( y = 1; y <= key; y++ ) loop exits immediately (zero iterations).

Categories