Posted by: bearc0025 | June 26, 2009

Cell phone: My Location – Google Mobile Maps

Content from: Location Cube: My Location – Google Mobile Maps

So you don’t have GPS but your phone can run JAVA apps… or Python apps..

Google Maps for mobiles can use the GSM tower (cell) id to look up roughly where you are… it plots you on Google Map (for mobile) to within a few km (at worst).

So if Google have access to some database of Cell Tower ID – Lat/Long can we access that data too?

Well.. you can buy it.. or try to use Google’s dataset.

In the background the Google maps application uses this website to post your Cell ID

http://www.google.com/glm/mmap

Neil Young written a demo C# app to make use of this to get a lat/long for a given Cell id.
(copy of source at end of this article)

http://maps.alphadex.de/datafiles/fct0e1b11782832f02.cs

Excellent article on his webstie: http://maps.alphadex.de/index.php?section=mylocation

- – - – - -

Yahoo have something similar but no where near as populated or dense cell data.

http://developer.yahoo.com/yrb/zonetag/locatecell.html

- – -

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Diagnostics;
/*
* Sample code to obtain geo codes from a cell info
* “GSM/UMTS” setting revealed by smuraro, thanks!
*/
/* (c) “Neil Young” (neil.young@freenet.de)
*
* This script/program is provided “as is”.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* GNU General Public License, see .
*/
namespace GMM {
class Program {
static byte[] PostData(int MCC, int MNC, int LAC, int CID, bool shortCID) {
/* The shortCID parameter follows heuristic experiences:
* Sometimes UMTS CIDs are build up from the original GSM CID (lower 4 hex digits)
* and the RNC-ID left shifted into the upper 4 digits.
*/
byte[] pd = new byte[] {
0×00, 0x0e,
0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
0×00, 0×00,
0×00, 0×00,
0×00, 0×00,
0x1b,
0×00, 0×00, 0×00, 0×00, // Offset 0×11
0×00, 0×00, 0×00, 0×00, // Offset 0×15
0×00, 0×00, 0×00, 0×00, // Offset 0×19
0×00, 0×00,
0×00, 0×00, 0×00, 0×00, // Offset 0x1f
0×00, 0×00, 0×00, 0×00, // Offset 0×23
0×00, 0×00, 0×00, 0×00, // Offset 0×27
0×00, 0×00, 0×00, 0×00, // Offset 0x2b
0xff, 0xff, 0xff, 0xff,
0×00, 0×00, 0×00, 0×00
};
bool isUMTSCell = ((Int64)CID > 65535);
if (isUMTSCell)
Console.WriteLine(“UMTS CID. {0}”, shortCID ? “Using short CID to resolve.” : “”);
else
Console.WriteLine(“GSM CID given.”);
if (shortCID)
CID &= 0xFFFF; /* Attempt to resolve the cell using the GSM CID part */
if ((Int64)CID > 65536) /* GSM: 4 hex digits, UTMS: 6 hex digits */
pd[0x1c] = 5;
else
pd[0x1c] = 3;
pd[0x11] = (byte)((MNC >> 24) & 0xFF);
pd[0x12] = (byte)((MNC >> 16) & 0xFF);
pd[0x13] = (byte)((MNC >> 8) & 0xFF);
pd[0x14] = (byte)((MNC >> 0) & 0xFF);
pd[0x15] = (byte)((MCC >> 24) & 0xFF);
pd[0x16] = (byte)((MCC >> 16) & 0xFF);
pd[0x17] = (byte)((MCC >> 8) & 0xFF);
pd[0x18] = (byte)((MCC >> 0) & 0xFF);
pd[0x27] = (byte)((MNC >> 24) & 0xFF);
pd[0x28] = (byte)((MNC >> 16) & 0xFF);
pd[0x29] = (byte)((MNC >> 8) & 0xFF);
pd[0x2a] = (byte)((MNC >> 0) & 0xFF);
pd[0x2b] = (byte)((MCC >> 24) & 0xFF);
pd[0x2c] = (byte)((MCC >> 16) & 0xFF);
pd[0x2d] = (byte)((MCC >> 8) & 0xFF);
pd[0x2e] = (byte)((MCC >> 0) & 0xFF);
pd[0x1f] = (byte)((CID >> 24) & 0xFF);
pd[0x20] = (byte)((CID >> 16) & 0xFF);
pd[0x21] = (byte)((CID >> 8) & 0xFF);
pd[0x22] = (byte)((CID >> 0) & 0xFF);
pd[0x23] = (byte)((LAC >> 24) & 0xFF);
pd[0x24] = (byte)((LAC >> 16) & 0xFF);
pd[0x25] = (byte)((LAC >> 8) & 0xFF);
pd[0x26] = (byte)((LAC >> 0) & 0xFF);
return pd;
}
static void Main(string[] args) {
if (args.Length < 4) {
Console.WriteLine(“Usage: gmm MCC MNC LAC CID [\"shortcid\"]“);
return;
}
string shortCID = “”; /* Default, no change at all */
if (args.Length == 5)
shortCID = args[4].ToLower();
try {
String url = “http://www.google.com/glm/mmap&#8221;;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url));
req.Method = “POST”;

int MCC = Convert.ToInt32(args[0]);
int MNC = Convert.ToInt32(args[1]);
int LAC = Convert.ToInt32(args[2]);
int CID = Convert.ToInt32(args[3]);
byte[] pd = PostData(MCC, MNC, LAC, CID, shortCID == “shortcid”);
req.ContentLength = pd.Length;
req.ContentType = “application/binary”;
Stream outputStream = req.GetRequestStream();
outputStream.Write(pd, 0, pd.Length);
outputStream.Close();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
byte[] ps = new byte[res.ContentLength];
int totalBytesRead = 0;
while (totalBytesRead < ps.Length) {
totalBytesRead += res.GetResponseStream().Read(ps, totalBytesRead, ps.Length – totalBytesRead);
}
if (res.StatusCode == HttpStatusCode.OK) {
short opcode1 = (short)(ps[0] << 8 ps[1]);
byte opcode2 = ps[2];
System.Diagnostics.Debug.Assert(opcode1 == 0x0e);
System.Diagnostics.Debug.Assert(opcode2 == 0x1b);
int ret_code = (int)((ps[3] << 24) (ps[4] << 16) (ps[5] << 8) (ps[6]));

if (ret_code == 0) {
double lat = ((double)((ps[7] << 24) (ps[8] << 16) (ps[9] << 8) (ps[10]))) / 1000000;
double lon = ((double)((ps[11] << 24) (ps[12] << 16) (ps[13] << 8) (ps[14]))) / 1000000;
Console.WriteLine(“Latitude: {0}, Longitude: {1}”, lat, lon);

Process p = new Process();
p.StartInfo.FileName = “iexplore”;
Console.WriteLine(“\nClose map window to exit\n”);
p.StartInfo.Arguments = String.Format(
http://maps.google.de/maps?f=q&hl=de&q={0},{1}&ie=UTF8&z=15″,
lat.ToString().Replace(‘,’,’.’), lon.ToString().Replace(‘,’,’.’));
p.Start();
p.WaitForExit();
}
else
Console.WriteLine(“Error {0}”, ret_code);
}
else
Console.WriteLine(“HTTP Status {0} {1}”, res.StatusCode, res.StatusDescription);
}
catch (Exception) {
throw;
}
}
}
}

About these ads

Responses

  1. Very interesting. But how do you get the visible cell towers list on the iPhone? As far as I know, you could do that in pre-2.0 SDK with the private CoreTelephony.h, but this no longer works…

  2. I actually haven’t tried this – I mostly re-posted it here for future reference as I have posted just links in the past and the post eventually goes away.

    Thanks for the comment – sorry I can’t add more.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

Follow

Get every new post delivered to your Inbox.

Join 386 other followers

%d bloggers like this: