Create Bing maps v8 polygon from lookup files - c#

I have two files (fileA.txt and fileB.txt) that I need to use to create polygons on a map. FileA contains the list of reference numbers that refer to fileB. I am able to get that list from A and find the corresponding file in B using streamreader. What I can not seem to grab is the data that I need from that file.
FileA looks like:
|ADV|170613/0448|170613/0600|KRIW||0|1
WYZ023 500230 Star_Valley
WYZ013 500130 Jackson_Hole
I take the number in bold, 500230, and look for it in fileB which looks like this:
|FIPS|500230|
8 59.094 59.091 -138.413 -138.425 59.091 -138.413 59.092 -138.425 59.094 -138.415 59.091 -138.413
8 59.101 59.099 -138.397 -138.413 59.099 -138.405
59.101 -138.413 59.100 -138.397 59.099 -138.405
|FIPS|500231|
Each line that starts with 8 after the |FIPS| line is one polygon. The number 8 represents the number of lat long pairs AFTER the numbers in bold. This 8 can be anywhere from 4 to 20. I can also have anywhere from 1 to 20 of these "groups" of lat long pairs within each |FIPS|.
In the end, I'm trying to get a list of lat long pairs for each |FIPS| that equals the |FIPS| that is looked up.
or an array of arrays. Any thoughts?
UPDATE: this is what I came up with but Im getting stuck on mainListLoop. The streamReader only reads to the end of the line but I need it to read to the next FIPS. Any suggestions?
[HttpGet]
public ActionResult GetWinterData()
{
var winterFilePaths = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["WatchWarnFilePath"] + "/wstm.txt");
var stringData = new List<string>();
var mainList = new List<WinterModel>();
using (var reader = new StreamReader(winterFilePaths))
{
while (!reader.EndOfStream)
{
var data = reader.ReadLine().Trim();
if (!string.IsNullOrEmpty(data))
stringData.Add(data);
}
reader.Close();
}
WinterModel temp = null;
stringData.ForEach(line =>
{
if (line.StartsWith("|"))
{
if (temp != null)
{
mainList.Add(temp);
}
string[] rawData = line.Split('|');
temp = new WinterModel
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
PolyBorderThickness = GetPolyBorderThickness(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
innerData = new List<tempInnerWinterModel>(),
InfoboxTitle = GetInfoboxTitle(rawData[0], types.WINTER)
};
}
else
{
string[] tempLine = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
temp.innerData.Add(new tempInnerWinterModel
{
param1 = tempLine[0],
FIPS = tempLine[1],
Location = tempLine[2],
latLongs = new List<lat_longPairs>()
});
}
});
mainList.Add(temp);
getWinterLatLongPairs2(mainList);
var tempJson = (from item in stringData
select item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
into rawData
select new WatchPolygons
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
//Lat_Long_Pairs = getWinterLatLongPairs2(rawData[5])
//Metadata = "Watch Type: " + rawData[0] + "< /br>" + "Watch Start: " + rawData[1] + ' ' + rawData[2]
// + "< /br>" + "Watch End: " + rawData[3] + ' ' + rawData[4]
});
return Json((from item in stringData
select item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
into rawData
select new WatchPolygons
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
//Lat_Long_Pairs = getWinterLatLongPairs2(rawData[5])
//Metadata = "Watch Type: " + rawData[0] + "< /br>" + "Watch Start: " + rawData[1] + ' ' + rawData[2]
// + "< /br>" + "Watch End: " + rawData[3] + ' ' + rawData[4]
}).ToList(), JsonRequestBehavior.AllowGet);
}
private static void getWinterLatLongPairs2(List<WinterModel> inputFips)
{
var searchFips = inputFips;
var fipFilePath = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["WatchWarnFilePath"] + "/pfzbnds.tbl");
var stringInnerData = new List<string>();
using (var reader = new StreamReader(fipFilePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Trim();
if (!string.IsNullOrEmpty(line) && line.Contains("<FIPS>"))
{
MainListLoop(inputFips, line, reader);
if (inputFips.Last().innerData.Last().latLongs.Count > 0)
{
return;
}
}
}
reader.Close();
}
return;
}
private static void MainListLoop(List<WinterModel> inputFips, string line, StreamReader reader)
{
inputFips.ForEach(main =>
{
main.innerData.ForEach(fips =>
{
if (line.Contains(fips.FIPS))
{
var line2 = reader.ReadLine().Trim();
fips.param1 = "CHANGE";
string[] tempLine = line2.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string numLatLongPairs = tempLine[0];
var latLonPairsWint = new List<lat_longPairs>();
int endIndex = ((Int16.Parse(numLatLongPairs) * 2) + 3 - 1);
//grab each pair of lat/longs starting at the 5th and add them to the array
for (int i = 5; i < endIndex; i += 2)
{
fips.latLongs.Add(new lat_longPairs { latitude = decimal.Parse(tempLine[i]), longitude = decimal.Parse(tempLine[i + 1]) });
}
return;
}
});
});
}

Not 100% clear on the file format of A, but if fileB isn't massive, I would recommend parsing fileB first into a dictionary where the key is the fips code and the value is a array of array of lat,long pairs, or whatever coordinate object you have in your application (numbers work fine too). From there when parsing fileA, when ever you come across a fips value, check the dictionary. This would be the easiest implementation.
If however fileB is massive, then memory on your computer or server (where you are parsing this), may be an issue. Or if fileA only references a small subset of data in fileB, then parsing all the data in fileB likely isn't the greatest. In these case, parse fileA and get a list of fips code. Next, scan through fileB until you find a fips code and see if it is in your list from fileA. If it is, parse that data from fileB and remove that value from your fileA list. Continue this until all fips in the filaA list are removed or you reach the end of fileB. For scanning fileB, you can write a custom stream reader, or if the file isn't massive, read the whole thing as a string, then use the index and substring to skip through fileB looking for fips.

Related

Can't properly rebuild a string with Replacement values from Dictionary

I am trying to build a file using a template. I am processing the file in a while loop line by line. The first section of the file, first 35 lines are header information. The infromation is surrounded by # signs. Take this string for example:
Field InspectionStationID 3 {"PVA TePla #WSM#", "sw#data.tool_context.TOOL_SOFTWARE_VERSION#", "#data.context.TOOL_ENTITY#"}
The expected output should be:
Field InspectionStationID 3 {"PVA TePla", "sw0.2.002", "WSM102"}
This header section uses a different mapping than the rest of the file so I wanted to parse the file line by line from top to bottom and use a different logic for each section so that I don't waste time parsing the entire file at once multiple times for different sections.
The logic uses two dictionaries populated from an xml file. Because the file has mutliple tables, I combined them in the two dictionaries like so:
var headerCdataIndexKeyVals = Dictionary<string, int>(){
{"data.tool_context.TOOL_SOFTWARE_VERSION", 1},
{"data.context.TOOL_ENTITY",0}
};
var headerCdataArrayKeyVals = new Dictionary<string, List<string>>();
var tool_contextCdataList = new list <string>{"HM654", "sw0.2.002"};
var contextCdataList = new List<string>{"WSM102"}
headerCdataArrayKeyVals.add("tool_context", tool_contextCdataList);
headerCdataArrayKeyVals.add("context", contextCdataList);
To help me map the values to their respective positions in the string in one go and without having to loop through multiple dictionaries.
I am using the following logic:
public static string FindSubsInDelimetersAndReturn(string str, char openDelimiter, char closeDelimiter, HeaderMapperData mapperData )
{
string newString = string.Empty;
// Stores the indices of
Stack <int> dels = new Stack <int>();
for (int i = 0; i < str.Length; i++)
{
var let = str[i];
// If opening delimeter
// is encountered
if (str[i] == openDelimiter && dels.Count == 0)
{
dels.Push(i);
}
// If closing delimeter
// is encountered
else if (str[i] == closeDelimiter && dels.Count > 0)
{
// Extract the position
// of opening delimeter
int pos = dels.Peek();
dels.Pop();
// Length of substring
int len = i - 1 - pos;
// Extract the substring
string headerSubstring = str.Substring(pos + 1, len);
bool hasKey = mapperData.HeaderCdataIndexKeyVals.TryGetValue(headerSubstring.ToUpper(), out int headerCdataIndex);
string[] headerSubstringSplit = headerSubstring.Split('.');
string headerCDataVal = string.Empty;
if (hasKey)
{
if (headerSubstring.Contains("CONTAINER.CONTEXT", StringComparison.OrdinalIgnoreCase))
{
headerCDataVal = mapperData.HeaderCdataArrayKeyVals[headerSubstringSplit[1].ToUpper() + '.' + headerSubstringSplit[2].ToUpper()][headerCdataIndex];
//mapperData.HeaderCdataArrayKeyVals[]
}
else
{
headerCDataVal = mapperData.HeaderCdataArrayKeyVals[headerSubstringSplit[1].ToUpper()][headerCdataIndex];
}
string strToReplace = openDelimiter + headerSubstring + closeDelimiter;
string sub = str.Remove(i + 1);
sub = sub.Replace(strToReplace, headerCDataVal);
newString += sub;
}
else if (headerSubstring == "WSM" && closeDelimiter == '#')
{
string sub = str.Remove(len + 1);
newString += sub.Replace(openDelimiter + headerSubstring + closeDelimiter, "");
}
else
{
newString += let;
}
}
}
return newString;
}
}
But my output turns out to be:
"\tFie\tField InspectionStationID 3 {\"PVA TePla#WSM#\", \"sw0.2.002\tField InspectionStationID 3 {\"PVA TePla#WSM#\", \"sw#data.tool_context.TOOL_SOFTWARE_VERSION#\", \"WSM102"
Can someone help understand why this is happening and how I can go about correcting it so I get the output:
Field InspectionStationID 3 {"PVA TePla", "sw0.2.002", "WSM102"}
Am i even trying to solve this the right way or is there a better cleaner way to do it? Btw if the key is not in the dictionary I replace it with empty string

Differentiating between different values with a Line.Contains()

Something I was curious about, I'm coding a utility for a old game that I play and this allows for custom NPC's. Long story short, I'm coding a reader for these custom NPC files. I've gotten most of the reading down with a line.contains() method (all code will be shown later) but there's a problem. The file can contain either just "height" or "gfxheight" which both do different things. Using line.contains("width") will make it output both width and gfxwidth twice. I don't really know any good way to explain it so here's the file:
width=32
height=32
gfxwidth=64
gfxheight=32
nofireball=1
noiceball=1
noyoshi=1
grabside=0
The Console output when I read it in and do what I need to split the lines and such:
And here's the code I use for height and gfxheight (of course there are others but these are the only problems I have when reading):
if (line.Contains("height"))
{
var split = line.Split(new char[] { '=' }, 2);
decimal dc;
//var val = int.Parse(split.ToString());
Console.WriteLine(split[0].ToString() + " is equal to " + split[1].ToString());
npcHeight.Value = Decimal.Parse(split[1].ToString());
npcHeight.Enabled = true;
npcHCb.Checked = true;
}
if (line.Contains("gfxheight"))
{
var split = line.Split(new char[] { '=' }, 2);
//var val = int.Parse(split.ToString());
Console.WriteLine(split[0].ToString() + " is equal to " + split[1].ToString());
}
Of course there's also the code for width and gfxwidth and the other various codes but I'm not going to bother posting those because I can apply what I get for the height to those.
So what would I have to do to differentiate between them? Suggestions?
Thanks in advanced,
Mike
Read the file into a string array, then parse it into a dictionary.
var file = File.ReadAllLines(yourFile);
var config = (from line in file
let s = line.Split('=')
select new { Key = s[0], Value = s[1] })
.ToDictionary(x => x.Key, x => x.Value);
Now you can access anything you want by referencing the key:
var gfxHeight = config["gfxheight"]; // gfxHeight is a string containing "32"
If you know the value after the = is always a number, you could parse it:
var config = (from line in file
let s = line.Split('=')
select new { Key = s[0], Value = int.Parse(s[1]) })
.ToDictionary(x => x.Key, x => x.Value);
var gfxHeight = config["gfxheight"]; // gfxHeight is an int containing 32
Instead of trying to figure out what each line is before splitting it, try splitting it first. This parsing approach leverages the format of the file and has a much-reduced dependency on its data:
foreach (var line in lines) {
var data = line.Split('=', 2);
if (data.Length != 2) {
continue;
}
var attrib = data[0];
var value = data[1];
Console.WriteLine(attrib + " is equal to " + value);
switch (attrib) {
case "height":
// ...
break;
case "gfxheight":
// ...
break;
}
}
I figured out a solution actually! Be warned: I haven't refreshed the page yet to see any proposed answers.
if (line.Contains("width"))
{
if (line.Contains("gfx"))
{
var split = line.Split(new char[] { '=' }, 2);
//var val = int.Parse(split.ToString());
Console.WriteLine(split[0].ToString() + " is equal to " + split[1].ToString());
npcWidth.Value = Decimal.Parse(split[1].ToString());
npcWidth.Enabled = true;
npcWCb.Checked = true;
}
else
{
var split = line.Split(new char[] { '=' }, 2);
Console.WriteLine(split[0].ToString() + " is equal to " + split[1].ToString());
pNpcWidth.Value = Decimal.Parse(split[1].ToString());
pNpcWidth.Enabled = true;
pNpcWidthCb.Checked = true;
}
}
Basically that ^
What it does is checks if the line is width with that line.Contains method. And if it does, it then checks to see if it contains gfx in it (as in gfxheight, gfxwidth, etc) and if it does, then that's the gfxheight or gfxwidth value. If not, it's the regular height/width.

Get first value in column from CSV file in C#

I am using this code in my Web Api to get data from a csv file, and plug that data into a Item List.
private List<Item> ietms = new List<Item>();
public ItemRepository()
{
string filename = HttpRuntime.AppDomainAppPath + "App_Data\\items.csv";
var lines = File.ReadAllLines(filename).Skip(1).ToList();
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var columns = line.Split('$');
//get rid of newline characters in the middle of data lines
while (columns.Length < 9)
{
i += 1;
line = line.Replace("\n", " ") + lines[i];
columns = line.Split('$');
}
//Remove Starting and Trailing open quotes from fields
columns = columns.Select(c => { if (string.IsNullOrEmpty(c) == false) { return c.Substring(1, c.Length - 2); } return string.Empty; }).ToArray();
items.Add(new Item()
{
Id = int.Parse(columns[0]),
Name = columns[1],
Description = columns[2],
Price = string.IsNullOrEmpty(columns[3].Trim()) ? null : (double?)double.Parse(columns[3]),
Weight = columns[8],
PhotoUrl = columns[7],
Category=columns[9]
});
}
}
In the csv file one of the columns/value is structured like this:
Groups>Subgroup>item
or in some cases
MajorGroup|Groups>Subgroup>item
How do I pull out only the first value before the > or |, so that I would get the value as Groups in the first case and MajorGroup in the second, and store it in the Category property in the Item List, which is now just set to the entire value in column 9 which would return the whole string "Groups>Subgroup>item".
Add the following line before calling "Add item"
var temp = columns[9].Split('|', '>');
Then assign the category as follows.
Category = temp[0];
Based on: MSDN String Method Documentation
Did you mean something like this?
string data = "MajorGroup|Groups>Subgroup>item";
string groupOrCategory;
if (data.Contains('|'))
{
groupOrCategory = data.Substring(0, data.IndexOf('|'));
}
else
{
groupOrCategory = data.Substring(0, data.IndexOf('>'));
}
Console.WriteLine(groupOrCategory);

In file, if line contains substring, get all of the line from the right

I have a file. Each line looks like the following:
[00000] 0xD176234F81150469: foo
What I am attempting to do is, if a line contains a certain substring, I want to extract everything on the right of the substring found. For instance, if I were searching for 0xD176234F81150469: in the above line, it would return foo. Each string is of variable length. I am using C#.
As a note, every line in the file looks like the above, having a base-16 number enclosed in square brackets on the left, followed by a hexadecimal hash and a semicolon, and an english string afterwards.
How could I go about this?
Edit
Here is my code:
private void button1_Click(object sender, EventArgs e)
{
Form1 box = new Form1();
if(MessageBox.Show("This process may take a little while as we loop through all the books.", "Confirm?", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
XDocument doc = XDocument.Load(#"C:\Users\****\Desktop\books.xml");
var Titles = doc.Descendants("Title");
List<string> list = new List<string>();
foreach(var Title in Titles)
{
string searchstr = Title.Parent.Name.ToString();
string val = Title.Value;
string has = #"Gameplay/Excel/Books/" + searchstr + #":" + val;
ulong hash = FNV64.GetHash(has);
var hash2 = string.Format("0x{0:X}", hash);
list.Add(val + " (" + hash2 + ")");
// Sample output: "foo (0xD176234F81150469)"
}
string[] books = list.ToArray();
File.WriteAllLines(#"C:\Users\****\Desktop\books.txt", books);
}
else
{
MessageBox.Show("Aborted.", "Aborted");
}
}
I also iterated through every line of the file, adding it to a list<>. I must've accidentally deleted this when trying the suggestions. Also, I am very new to C#. The main thing I am getting stumped on is the matching.
You could use File.ReadLines and this Linq query:
string search = "0xD176234F81150469:";
IEnumerable<String> lines = File.ReadLines(path)
.Select(l => new { Line = l, Index = l.IndexOf(search) })
.Where(x => x.Index > -1)
.Select(x => x.Line.Substring(x.Index + search.Length));
foreach (var line in lines)
Console.WriteLine("Line: " + line);
This works if you don't want to use Linq query.
//"I also iterated through every line of the file, adding it to a list<>." Do this again.
List<string> li = new List<string>()
//However you create this string make sure you include the ":" at the end.
string searchStr = "0xD176234F81150469:";
private void button1_Click(object sender, EventArgs e)
{
foreach (string line in li)
{
string[] words;
words = line.Split(' '); //{"[00000]", "0xD176234F81150469:", "foo"}
if (temp[1] == searchStr)
{
list.Add(temp[2] + " (" + temp[1] + ")");
// Sample output: "foo (0xD176234F81150469)"
}
}
}
string file = ...
string search= ...
var result = File.ReadLines(file)
.Where(line => line.Contains(search))
.Select(line => line.Substring(
line.IndexOf(search) + search.Length + 1);
Unfortunately, none of the other solutions worked for me. I was iterating through the hashes using foreach, so I would be iterating through all the items millions of times needlessly. In the end, I did this:
using (StreamReader r = new StreamReader(#"C:\Users\****\Desktop\strings.txt"))
{
string line;
while ((line = r.ReadLine()) != null)
{
lines++;
if (lines >= 6)
{
string[] bits = line.Split(':');
if(string.IsNullOrWhiteSpace(line))
{
continue;
}
try
{
strlist.Add(bits[0].Substring(10), bits[1]);
}
catch (Exception)
{
continue;
}
}
}
}
foreach(var Title in Titles)
{
string searchstr = Title.Parent.Name.ToString();
string val = Title.Value;
string has = #"Gameplay/Excel/Books/" + searchstr + ":" + val;
ulong hash = FNV64.GetHash(has);
var hash2 = " " + string.Format("0x{0:X}", hash);
try
{
if (strlist.ContainsKey(hash2))
{
list.Add(strlist[hash2]);
}
}
catch (ArgumentOutOfRangeException)
{
continue;
}
}
This gave me the output I expected in a short period of time.

Does anyone have c# code to use betfair api?

I am creating a c# windows app to display current sports market rates using betfair exchange webservice, I used the
getmarketpricescompressed()
method which returns a price string that looks like this:
106093239~GBP~ACTIVE~0~1~~true~5.0~1343114432333~~N:7337~1~6992.56~2.16~~~false~~~~|2.16~1036.19~L~1~2.14~97.18~L~2~2.12~5.0~L~3~|2.18~467.36~B~1~2.2~34.12~B~2~2.22~162.03~B~3~:414464~2~102181.96~1.86~~~false~~~~|1.85~2900.33~L~1~1.84~1831.59~L~2~1.83~1593.73~L~3~|1.86~58.83~B~1~1.87~1171.77~B~2~1.88~169.15~B~3~
i don't know how to properly unpack this string, for now i am using this code:
GetMarketPricesCompressedReq price_req1 = new GetMarketPricesCompressedReq();
price_req1.header = header2;
price_req1.marketId = marketid_temp;
price_req1.currencyCode = "GBP";
GetMarketPricesCompressedResp price_resp = new GetMarketPricesCompressedResp();
price_resp = bfg2.getMarketPricesCompressed(price_req1);
//MessageBox.Show(price_resp.errorCode.ToString());
//richTextBox1.Text = "";
//richTextBox1.Text = price_resp.marketPrices;
string prices = price_resp.marketPrices;
richTextBox1.Text = price_resp.marketPrices;
string[] ab1 = prices.Split('|');
string[] temp = ab1[1].Split('~');
textBox3.Text = temp[0];
textBox4.Text = temp[4];
textBox5.Text = temp[8];
temp = ab1[2].Split('~');
textBox6.Text = temp[0];
textBox7.Text = temp[4];
textBox8.Text = temp[8];
temp = ab1[3].Split('~');
textBox9.Text = temp[0];
textBox10.Text = temp[4];
textBox11.Text = temp[8];
temp = ab1[4].Split('~');
textBox12.Text = temp[0];
textBox13.Text = temp[4];
textBox14.Text = temp[8];
if (ab1.Length >5)
{
temp = ab1[5].Split('~');
textBox15.Text = temp[0];
textBox16.Text = temp[4];
textBox17.Text = temp[8];
temp = ab1[6].Split('~');
textBox18.Text = temp[0];
textBox19.Text = temp[4];
textBox20.Text = temp[8];
}
It works fine for a few matches, but i observed the string changes for a few other matches and it thus generates exceptions,
Can any1 help me with a proper code to unpack this string, i've googled it and found a vb code, which was not very usefull,
and btw, i want to arrange the data in something like this:
Consider the following:
a|b|c|d
In this, you have four chunks. But it doesn't necessarily have to be only four. It can be two, it can be six.
Try going at it by iterating the string-array you get as a result of the
string[] ab1 = prices.Split('|');
Something like
foreach(var stringChunk in ab1)
{
string[] temp = stringChunk.Split('~');
// use the strings here as you please
}
Consider using a more dynamic approach in presenting your data as well, using a row-based, repeating control instead of static textboxes. =)
The full documentation for the compressed data is available here: https://docs.developer.betfair.com/betfair/#!page=00008360-MC.00008307-MC
Just guessing, I think the data is organised like this
first delimited by : then | we get
106093239~GBP~ACTIVE~0~1~~true~5.0~1343114432333~~N
7337~1~6992.56~2.16~~~false~~~~
2.16~1036.19~L~1~2.14~97.18~L~2~2.12~5.0~L~3~
2.18~467.36~B~1~2.2~34.12~B~2~2.22~162.03~B~3~
414464~2~102181.96~1.86~~~false~~~~
1.85~2900.33~L~1~1.84~1831.59~L~2~1.83~1593.73~L~3~
1.86~58.83~B~1~1.87~1171.77~B~2~1.88~169.15~B~3~
I think that first row is clearly a header, that first number being the market ID perhaps.
Likewise, the first part of each subsequent section is a row identifier. Delimited by ~ something like
(SelectionId)7337 (Order)1 (TotalMatched?)6992.56 (EvenPoint)2.16 (???)false
I think the price rows are delimited by ~ in tuples of 4, like this
(Price)2.16 (MatchAvailable)1036.19 (Type)L (Order)1
(Price)2.14 (MatchAvailable)0097.18 (Type)L (Order)2
(Price)2.12 (MatchAvailable)0005.00 (Type)L (Order)3
for example.
To test my guesses I'd have to compare with the BetFair rendering on thier web site.
I converted the vb code to c# myself, if anyone might find it useful, I am posting it here:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
namespace stock
{
class UnpackMarketPricesCompressed : stock.BFExchangeService.MarketPrices
{
//The substitute code for "\:"
private const string ColonCode = "&%^#";
//Unpack the string
public UnpackMarketPricesCompressed(string MarketPrices)
{
string[] Mprices = null;
string[] Part = null;
string[] Field = null;
int n = 0;
Mprices = MarketPrices.Replace("\\:", ColonCode).Split(':');
//Split header and runner data
Field = Mprices[0].Replace("\\~", "-").Split('~');
//Split market data fields
marketId = Convert.ToInt32(Field[0]);
//Assign the market data
currencyCode = Field[1];
marketStatus = (stock.BFExchangeService.MarketStatusEnum)Enum.Parse(typeof(stock.BFExchangeService.MarketStatusEnum), Field[2], true);
delay = Convert.ToInt32(Field[3]);
numberOfWinners = Convert.ToInt32(Field[4]);
marketInfo = Field[5].Replace(ColonCode, ":");
discountAllowed = (Field[6].ToLower() == "true");
marketBaseRate = float.Parse(Field[7]);
lastRefresh = long.Parse(Field[8]);
removedRunners = Field[9].Replace(ColonCode, ":");
bspMarket = (Field[10] == "Y");
n = Mprices.Length - 1;
// ERROR: Not supported in C#: ReDimStatement
//For each runner
for (int i = 0; i <= n; i++)
{
Part = Mprices[i + 1].Split('|');
//Split runner string into 3 parts
Field = Part[0].Split('~');
//Split runner data fields
runnerPrices[i] = new stock.BFExchangeService.RunnerPrices();
var _with1 = runnerPrices[i];
//Assign the runner data
_with1.selectionId = Convert.ToInt32(Field[0]);
_with1.sortOrder = Convert.ToInt32(Field[1]);
_with1.totalAmountMatched = Convert.ToDouble(Field[2]);
_with1.lastPriceMatched = Convert.ToDouble(Field[3]);
_with1.handicap = Convert.ToDouble(Field[4]);
_with1.reductionFactor = Convert.ToDouble(Field[5]);
_with1.vacant = (Field[6].ToLower() == "true");
_with1.farBSP = Convert.ToDouble(Field[7]);
_with1.nearBSP = Convert.ToDouble(Field[8]);
_with1.actualBSP = Convert.ToDouble(Field[9]);
_with1.bestPricesToBack = Prices(Part[1]);
_with1.bestPricesToLay = Prices(Part[2]);
}
}
private stock.BFExchangeService.Price[] Prices(string PriceString)
{
string[] Field = null;
stock.BFExchangeService.Price[] Price = null;
int k = 0;
int m = 0;
Field = PriceString.Split('~');
//Split price fields
m = (Field.Length / 4) - 1;
//m = number of prices - 1
// ERROR: Not supported in C#: ReDimStatement
for (int i = 0; i <= m; i++)
{
Price[i] = new stock.BFExchangeService.Price();
var _with2 = Price[i];
_with2.price = Convert.ToInt32(Field[k + 0]);
//Assign price data
_with2.amountAvailable = Convert.ToInt32(Field[k + 1]);
_with2.betType = (stock.BFExchangeService.BetTypeEnum)Enum.Parse(typeof(stock.BFExchangeService.BetTypeEnum), Field[k + 2], true);
_with2.depth = Convert.ToInt32(Field[k + 3]);
k += 4;
}
return Price;
//Return the array of prices
}
}
}

Categories