Introduction
A few days ago I've got a task to create my own Google map with several points. It's very easy to create points step by step, but I'm a very lazy man.
I thought that the simplest way would be to create an excel sheet with the POI -s (Point of Interests) and create a program, to get the POI's LAT-LON coordinates.
This task is not so difficult. The Google API provide the possibility to get LAT-LON coordinates from post addresses, and that was what I needed.
What Problem Does this Solution Solve?
This program helps to create Your own Google Map, with .kml file. Not necessary to create own maps point by point, You can create a simple Excel file with POI-s, and postal addresses, and your own map is ready, after some clicks.
Background
First of all very useful to study the Google maps API here: https://developers.google.com/maps/documentation/geocoding/
But I hope the basics and main things can be understand from my code. Then good to have same experience to manipulate Microsoft Excel sheets, and some experience in xml files and Linq.
The simple excel file contains the POI's in this format: Name, zip, city, street, housenumber, country.
In this example I created an excel file, to try, and to see the format the source file of this process. Download the example, complie, and try it. Load my example (ownmap.xls) export the .kml file, and see the result. now You can import this kml file into Google Maps.
Important! You can read 2500 addresses per day from Google Api without license. If You want more, You have to buy the Google's Bussiness license.
What is the Edification?
In this simple code I demonstrate a web request and web response in C#. You can see an example to parse xml file in Linq. The POI's are in an Excel file, so this is a very simple example how to read and write Excel files via Office Interop. Last but not least this program creates a .kml file, which is really an xml, so there is an example how to create simple xml file like a textfile.
Keywords
- Read and write Microsoft Excel sheets via Office Interop
- Simple Web request and response
- Simple Linq for parse xml.
Using the code
First I made a struct mylocatinon
, to be a container for locations. GPS coordinates will be in decimal format, like 47,197484. So LAT and LON coordinates will be double
numbers.
public struct mylocation
{
public double latitude;
public double longitude;
}
After my experience was that Google API can work with our (Hungarian) national characters, like á, é but sometimes not. Beyond that I had to make a standard
URL from postal addresses, i.e change space to %20 etc. So
convuri
method converts any text to URL format without national characters.
public string convuri(string be)
{
if (be == "")
{
return null;
public string convuri(string be)
{
if (be == "")
{
return null;
}
string ret = be;
string[] oldchars = { "á", "í", "ű", "ő", "ü",
"ö", "ú", "ó", "é", " ", "Á", "Í",
"Ű", "Ő", "Ü", "Ö", "Ú", "Ó", "É", "." };
string[] newchars = { "a", "i", "u", "o", "u", "o",
"u", "o", "e", " ", "A", "I", "U",
"O", "U", "O", "U", "O", "E", "." };
for (int i = 0; i < oldchars.Length - 1; i++)
{
ret = ret.Replace(oldchars[i], newchars[i]);
}
ret = ret.Replace(
" ", "%20");
return ret;
}
}
string ret = be;
string[] oldchars = { "á", "í", "ű", "ő", "ü", "ö",
"ú", "ó", "é", " ", "Á", "Í", "Ű",
"Ő", "Ü", "Ö", "Ú", "Ó", "É", "." };
string[] newchars = { "a", "i", "u", "o", "u", "o",
"u", "o", "e", " ", "A", "I", "U",
"O", "U", "O", "U", "O", "E", "." };
for (int i = 0; i < oldchars.Length - 1; i++)
{
ret = ret.Replace(oldchars[i], newchars[i]);
}
ret = ret.Replace(" ", "%20");
return ret;
}
Next thing deserving to emphasize the web request. I wrote a method, name is Getloc
. This method gives back the LAT LON coordinates, from postal address.
If some error is occured, getloc
method gives back -1,-1 coordinates.
In this example myuri
variable contains the converted (see below) URL
with postal address. The address must be in this format: number street zipcode city country. Spaces will be converted into URL format: %20
System.Net.HttpWebRequest webRequest;
System.Net.HttpWebResponse webResponse;
string cim = hsz.Trim() + " " + utca.Trim() + " " + zip.Trim() +
" " + varos.Trim() + " " + orszag.Trim();
cim = convuri(cim);
Uri myuri = new Uri("http://maps.googleapis.com/maps/api/geocode/xml?address=" +
cim + "&sensor=true");
webRequest = (HttpWebRequest)(WebRequest.Create(myuri));
webRequest.Credentials = CredentialCache.DefaultCredentials;
WebProxy p = new WebProxy(textBox2.Text, Convert.ToInt32(textBox3.Text));
p.Credentials = CredentialCache.DefaultCredentials;
if (checkBox1.Checked)
{
webRequest.Proxy = p;
}
webRequest.Proxy = p;
webRequest.Method = "GET";
webRequest.ContentType = "text/xml";
webResponse = (System.Net.HttpWebResponse)(webRequest.GetResponse());
webResponse.GetResponseStream();
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
The web requests answer will be an XML. This example shows how to parse an xml with linq. In this example ret
is a local variable typed
mylocation
(see below)
XmlDocument resxml = new XmlDocument();
resxml.LoadXml(sr.ReadToEnd());
sr.Close();
string sss = resxml.InnerXml.ToString();
resxml = null;
XDocument xdoc = XDocument.Parse(sss);
var aaas = from aaa in xdoc.Descendants("result").Descendants("geometry").Descendants("location")
select new
{
lat = aaa.Element("lat").Value,
lon = aaa.Element("lng").Value
};
foreach (var aaa in aaas)
{
ret.latitude = Convert.ToDouble(aaa.lat);
ret.longitude = Convert.ToDouble(aaa.lon);
}
And last, but not least, how to manipulate MS Excel file with interop module:
Microsoft.Office.Interop.Excel.Application oApp = new Microsoft.Office.Interop.Excel.Application();
Workbook wb = null;
Worksheet ws = null;
oApp.Visible = false;
oApp.UserControl = false;
System.Globalization.CultureInfo oldCI = System.Threading.Thread.CurrentThread.CurrentCulture;
System.Globalization.CultureInfo Cli = new System.Globalization.CultureInfo("en-US");
System.Threading.Thread.CurrentThread.CurrentCulture = Cli;
StringBuilder sb = new StringBuilder();
sb.AppendLine("");
sb.AppendLine("<kml xmlns="http:
sb.AppendLine("<document>");
sb.AppendLine("<name>" + textBox5.Text + "</name>");
try
{
wb = oApp.Workbooks.Open(textBox1.Text);
Sheets sheets = wb.Worksheets;
oApp.DisplayAlerts = false;
ws = (Worksheet)sheets.get_Item(1);
Range ur = ws.UsedRange;
Range cell;
string orszag;
string nev;
string varos;
string utca;
string hsz;
string zip;
string lat;
string lon;
for (int i = 1; i <= ur.Cells.Rows.Count; i++)
{
cell = (Range)ws.Cells[i, 1];
nev = cell.Value.ToString();
label1.Text = nev;
cell = (Range)ws.Cells[i, 2];
zip = cell.Value.ToString();
cell = (Range)ws.Cells[i, 3];
varos = cell.Value.ToString();
cell = (Range)ws.Cells[i, 4];
utca = cell.Value.ToString();
cell = (Range)ws.Cells[i, 5];
hsz = cell.Value.ToString();
cell = (Range)ws.Cells[i, 6];
orszag = cell.Value.ToString();
cell = (Range)ws.Cells[i, 7];
lat = cell.Value.ToString();
cell = (Range)ws.Cells[i, 8];
lon = cell.Value.ToString();
sb.AppendLine("<placemark>");
sb.AppendLine("<name>" + nev + "</name>");
sb.AppendLine("<description>" + varos.Trim() + ", " + zip.Trim() +
" " + utca.Trim() + " " + hsz.Trim() + "</description>");
sb.AppendLine("<point>");
sb.AppendLine("<coordinates>" + lon + "," + lat + ",0</coordinates>");
sb.AppendLine("</point>");
sb.AppendLine("</placemark>");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
wb.Save();
oApp.Quit();
oApp.DisplayAlerts = true;
System.Threading.Thread.CurrentThread.CurrentCulture = oldCI;
Marshal.ReleaseComObject(ws);
Marshal.ReleaseComObject(wb);
Marshal.ReleaseComObject(oApp);
}
sb.AppendLine("</document>");
sb.AppendLine("</kml>");
How to make own Google Map from generated .kml file?
After using this program (Start with excel, then export to .kml the result) You can make an own Google map. A Google account (gmail) is necessary to upload own map. Go to
Google Maps site, choose own places. Create a new map. Give a name, and a short description, then import the new .kml file. Thats all.
History