Search This Blog

Wednesday, October 15, 2008

Cell Positions

Enter into LICENCE either:


The main license types for cell phone base stations are SZ, SY, and SX (relates to transmit power, SZ is most common).

From here you can drill down to find LAT/LNG for each transmitter.

Thursday, September 18, 2008

Google Maps - Quadtree tiling system

So Google and other online mapsite using a tiling system to transfer large images.

These images are cut into smaller ones, based on a nested hierachy.... known as Quadtree. Good explaination here

Google use q,r,t,s (0-3) to denote one of 4 corners of a tile.

So to find your location run this Python code....

Run it like this:

python 17 -43.525 172.616

Spherical Mercator (ESPG:900913) coordinates for lat/lon:
(19215525.222771712, -5392226.689463486)
17/128383/47899 ( TileMapService: z / x / y )
Google: 128383 83172
Quadkey: 31311030123311311 ( 14851095925 )

Substitute the QUADKEY values as follows

Then type that list of letters into this page...

Here's an example for Christchurch, NZ

Other useful info on tiling

cut your own tiles - x,y info

view tiles on one page

how it works

overlay on web your own image and create the tiles for it

use python to create a local cache of WMS tiles

Wednesday, September 17, 2008

Some Mapping links - most with source code included!

Display OpenStreetMap on a DEM!

- - - -
Adding MS VE to a .NET application!

- - - -
3D and graphics tools


3d mini terrain viewer

- - - -

connecting Wii to MS VE

Monday, June 23, 2008

Google Map Hacking

Great set of examples and explanations for anyone working on Google Map hacking!

Tuesday, June 17, 2008

Open mapping sources

Two open map sources

Earth Bridge (GPS to Google Earth)

Earth Bridge... link GPS to Google Earth...
Takes standard NMEA output....

Sunday, June 15, 2008

Coastal GIS tools

Just stumbled across these... some coastal tools for GIS people.

Particularly interested in the 3D viewer and comparing volume changes between LiDAR dataset from different times.

Sunday, May 25, 2008


A briefcase + GPS + many batteries + DHL + the World = self portrait

Tuesday, May 20, 2008

Population movement tracking in malls

Using people's phones as a way to track movements.

Here the IMEI numbers unique to each phone are determined from shoppers so that the number of shoppers, country the phone is registered, and length of time spent in the mall can be stored. The trends can be used to extend shopping hours, or change the language of signs if it's found one nation is well represented in a shopping mall.

Monday, April 28, 2008

TCPIP sockets in c#

Many great working examples on TCPIP sockets... in C#

- - -
/*C# Network Programming by Richard BlumPublisher: Sybex ISBN: 0782141765*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class FixedTcpSrvr
private static int SendData(Socket s, byte[] data)
int total = 0;
int size = data.Length;
int dataleft = size;
int sent;
while (total < size)
sent = s.Send(data, total, dataleft, SocketFlags.None);
total += sent;
dataleft -= sent;
return total;
private static byte[] ReceiveData(Socket s, int size)
int total = 0;
int dataleft = size;
byte[] data = new byte[size];
int recv;
while (total < size)
recv = s.Receive(data, total, dataleft, 0);
if (recv == 0)
data = Encoding.ASCII.GetBytes("exit ");
total += recv;
dataleft -= recv;
return data;
public static void Main()
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 12008);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
Console.WriteLine("Waiting for a client...");
Socket client = newsock.Accept();
IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;
Console.WriteLine("Connected with {0} at port {1}",
newclient.Address, newclient.Port);
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
int sent = SendData(client, data);
for (int i = 0; i < 5; i++)
data = ReceiveData(client, 9);
Console.WriteLine("Disconnected from {0}", newclient.Address);

Tuesday, April 1, 2008

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

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)

Excellent article on his webstie:

- - - - - -

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

- - -

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" (
* 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
* 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[] {
0x00, 0x0e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Offset 0x11
0x00, 0x00, 0x00, 0x00, // Offset 0x15
0x00, 0x00, 0x00, 0x00, // Offset 0x19
0x00, 0x00,
0x00, 0x00, 0x00, 0x00, // Offset 0x1f
0x00, 0x00, 0x00, 0x00, // Offset 0x23
0x00, 0x00, 0x00, 0x00, // Offset 0x27
0x00, 0x00, 0x00, 0x00, // Offset 0x2b
0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00
bool isUMTSCell = ((Int64)CID > 65535);
if (isUMTSCell)
Console.WriteLine("UMTS CID. {0}", shortCID ? "Using short CID to resolve." : "");
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;
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\"]");
string shortCID = ""; /* Default, no change at all */
if (args.Length == 5)
shortCID = args[4].ToLower();
try {
String url = "";
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);
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(
lat.ToString().Replace(',','.'), lon.ToString().Replace(',','.'));
Console.WriteLine("Error {0}", ret_code);
Console.WriteLine("HTTP Status {0} {1}", res.StatusCode, res.StatusDescription);
catch (Exception) {

Monday, March 10, 2008

Sunday, March 9, 2008

Monday, February 25, 2008

NZMG - WGS84 Projections

NZMG was the official New Zealand mapping projection until 2001.

From the LINZ website (NZ mapping body):

"NZMG is not based on a geometric projection (transverse Mercator is based on a cylinder). Instead it uses a complex-number polynomial expansion. This has the advantage of exhibiting minimal scale distortion over New Zealand; however it is a projection unique to New Zealand and so can be difficult to use or program into computer software or positioning devices. "

In packages such as ESRI ArcGIS you can reproject data easily...... however if you're writting your own software you need to find some libraries to do this.

PROJ4 is one such library. It can be downloaded with GDAL / OGR as part of FW TOOLS.

Here there are 2 tools to assist in transformations... PROJ and CS2CS.
CS2CS caters with changes in DATUM.

To convert from NZMG to WGS84 requires a change in datum.

There are 3 methods to do this...

a) 3 parameter shift
b) 7 parameter shift
c) grid (NTv2)

a) is only good to the nearest 100m or so...
b) is only good to 5m or so..
c) uses a look up grid and should be good to nearest few cm

The look up grid can be downloaded from here:

Syntax to convert a user entered co-ordinate from WGS84 lat/long to NZMG x,y (m):

C:\Program Files\FWTools2.1.0\bin>cs2cs +proj=latlong +datum=WGS84 +to +proj=nzmg +datum=nzgd49 +nadgrids=o:/nzgd2kgrid0005.gsb

170 -43 [enter]
2265438.60 5796423.71 0.00

This should give you metre accuracte conversions.


To carry out from C# using FW TOOLS... you will need to check the C# example from Tamas Szekeres. This can be found in the FWTOOLS / csharp /apps folder.. and is entitled OSRTransform.cs.

A few modifications are required to work with NZMG and WGS84... as follows:

OSGeo.OSR.SpatialReference src = new OSGeo.OSR.SpatialReference("");

src.ImportFromProj4("+proj=latlong +datum=WGS84");

OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference("");

dst.ImportFromProj4("+proj=nzmg +x_0=25100000.0000000000 +y_0=6023150.0000000000 +datum=nzgd49 +nadgrids='o:\nzgd2kgrid0005.gsb'");

CoordinateTransformation ct = new OSGeo.OSR.CoordinateTransformation(src, dst);

double[] p = new double[3];

p[0] = 172.585303;

p[1] = -43.510183;

p[2]=0; //needed even if 0 value

ct.TransformPoint(p); Console.WriteLine("x:" + p[0] + " y:" + p[1]) ;

This should give you results accurate to a few metres.

Tuesday, February 19, 2008

List of great web sites relating to GIS and GPS

Awesome listing of GIS tools, blogs, web pages, development examples...
A great starting point in any search for GIS or GPS tools...

Open Source GIS tools - starting page

Intro to GRASS, GDAL, PROJ, and other useful open source GIS tools.

Tuesday, February 12, 2008

Spoken word

Books read by volunteers....

Can download to Nokia's Audio books tool for S60 phones!

Garmin get talking

So.. Nokia are getting mapping...

Why shouldn't the mapping people get talking...

Check this out! New from Garmin in the near future!

The Nuviphone!

Nokia gets mapping big time!

OK.. so Nokia (phones) are getting into mapping...

They brought out the 6610 with GPS (as used by Ewan McGreggor on long way down) :-

Then the multimedia computer that was the N95.. with all it troubles and slow lock on to GPS signals.

The N82 which improved on the N95 GPS performance...
An Updated N95 8GB which sorted out the original N95 GPS troubles....
An update to the N95 to get it back on track....

They've purchased NavTec for a few billion,137887-c,mapping/article.html
These guys make the maps! Next time you're using Google Maps.. check the bottom line to see if NavTec are mentioned! If they're not chances are that TeleAtlas are.. oh yer. they've just been bought by TomTom a GPS giant!

So what's next for Nokia? Well it seems the next mobile mapping software will be aimed at pedestrians...

Monday, February 4, 2008

Mobile Phones as Environmental Sensors

Mobile phones are a form of ubiqutous computing.
The connected crowd (Rheingold).

Sensors on phones include:
location (GPS, cell-id, wifi)
movement (accelerometers)
ad hoc bluetooth devices

Now projects using mobiles to collect environmental data are becoming common place:
Cellphones to monitor highway traffic

Cellphones to detect dirty bombs?

Cellphones to track air pollution

Capturing ambient intelligence