Geocoding onto a mobile device

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Geocoding onto a mobile device

Samuel Pickard
Hello everyone,

I'm sorry if this question makes me sound like I'm the most stupid
person here.  I've had a look at the documentation, and I can't see the
answer.

I've written a C++ application for mobile phones (not iPhones, but
ordinary ones like Motorola RAZR and Nokia 6630 etc) that shows
CloudMade maps, and it works very nicely, thank you.

I want to be able to add routing and geocoding data to it, so when I get
a location from the phone, I can mark on the map where I think the user
is.  I can see that there is an API for both of these things, which is
wonderful, but I don't know how to interpet the response data.  Firstly,
the Geocoding API seems to only return JSON data, which isn't very
useful to my little C++ app - is their an XML version or should I write
my own web service to wrap the results?

Secondly, when I get a response from the Geocoding or routing APIs, how
do I translate this to a location on my maps?  How do I know exactly
where to pin the image to say 'here it is'?  I've got a lat/lon, and
I've been returned a tile.  How do I know where on my tile my lat/lon is?

I can see that this has been done in the example applications, but what
is the algorithm?

Thanks

Sam
_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev
Reply | Threaded
Open this post in threaded view
|

Re: Geocoding onto a mobile device

Oleg Shaniuk

Hello Samuel,

First of all - thanks for using our services!

About JSON vs XML - last one will give pretty big output in some cases, so, using it on mobile devices can be a bit memory-consuming thing, while you can get free C++ code for JSON, available for free modification, etc (sample, using boost: http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx ). But, we are thinking now about implementing XML return from our services...

Now, for coordinate resolving: you getting coordinates in lon-lat and have to convert them to pixels starting from top-left corner of world map. When you getting a tile, it has url like: http://server/apikey/style_id/tile_size/zoom/x/y.png. X and Y are offsets from top-left in tiles, to get offset in pixels you have to multiply them by tile_size which is 256 for web and 64 for mobile (but you actually can use both sizes in web and mobile as well). Z is for zoom level. style_id - defines which style of map you want to use. So, tile with coordinates http://...../256/10/10/11.png has pixel offset X = 10 x 256; Y = 11 x 256; The point that belongs to this tile have X,Y in bounds:

10 x 256 <= X11 x 256

11 x 256 <= Y< 12 x 256

for example P(2561, 2820) belongs to this tile.

Ok, now, how to translate lot-lan to pixels?

you should have: lot-lan coordinates and zoom level,

also, if tile size is 256x256, you have 18 zoom steps, if tile size is 64x64 - you have 20 zoom steps,

this is because zoom 0 for 256x256 is equal to zoom 2 for 64x64 tiles... (you're getting the picture of the world - 256x256 pix)

now you can get pixel offset, using this code:

(M_PIl is in math.h)

#define M_PIl 3.1415926535897932384626433832795029L /* pi */

#define DEG_TO_RAD (M_PIl/180)
#define RAD_TO_DEG (180/M_PIl)

class PixelProjection
{
  double *Ac, *Bc, *Cc, *zc;

  public:
  PixelProjection(int levels=18, tileSize ts = 256) {

// you can set here 64 for 64x64 tiles, but then you'll get 20 zoom steps, so, you have to set levels = 20 
  Ac = new double[levels];                                    
  Bc = new double[levels];
  Cc = new double[levels];
  zc = new double[levels];
  int d, c = ts;
  for (d=0; d<levels; d++) {
  int e = c/2;
  Bc[d] = c/360.0;
  Cc[d] = c/(2 * M_PIl);
  zc[d] = e;
  Ac[d] = c;
  c *=2;
  }
  }
  void fromLLtoPixel(double &x, double &y, int zoom) {
  double d = zc[zoom];
  double f = minmax(sin(DEG_TO_RAD * y),-0.9999,0.9999);
  x = round(d + x * Bc[zoom]);
  y = round(d + 0.5*log((1+f)/(1-f))*-Cc[zoom]);
  }
  void fromPixelToLL(double &x, double &y, int zoom) {
  double e = zc[zoom];
  double g = (y - e)/-Cc[zoom];
  x = (x - e)/Bc[zoom];
  y = RAD_TO_DEG * ( 2 * atan(exp(g)) - 0.5 * M_PIl);
  }
};

Hope, this will help you to make your app. Feel free to contact us for any related questions.

--

RO


On Wed, Feb 25, 2009 at 9:42 PM, Samuel Pickard <[hidden email]> wrote:
Hello everyone,

I'm sorry if this question makes me sound like I'm the most stupid
person here.  I've had a look at the documentation, and I can't see the
answer.

I've written a C++ application for mobile phones (not iPhones, but
ordinary ones like Motorola RAZR and Nokia 6630 etc) that shows
CloudMade maps, and it works very nicely, thank you.

I want to be able to add routing and geocoding data to it, so when I get
a location from the phone, I can mark on the map where I think the user
is.  I can see that there is an API for both of these things, which is
wonderful, but I don't know how to interpet the response data.  Firstly,
the Geocoding API seems to only return JSON data, which isn't very
useful to my little C++ app - is their an XML version or should I write
my own web service to wrap the results?

Secondly, when I get a response from the Geocoding or routing APIs, how
do I translate this to a location on my maps?  How do I know exactly
where to pin the image to say 'here it is'?  I've got a lat/lon, and
I've been returned a tile.  How do I know where on my tile my lat/lon is?

I can see that this has been done in the example applications, but what
is the algorithm?

Thanks

Sam
_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev



--
--
RO

_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev
Reply | Threaded
Open this post in threaded view
|

Re: Geocoding onto a mobile device

jaakl

Hello,

 Btw, we are using own server-side parser with mgmaps Java ME SDK, this makes more mobile-friendly XML (minimum data, short tags, some requests are consolidated etc) and compresses data. In Java ME there are gzip implementations available, perhaps there is also on C++.

 

 Another reason to prefer own mobile server-side is to have own full control over API – web servers who are relying on own javascript library tend to be a bit too liberal with new version updates, and forgetting about backward-compatibility. In Web/ajax client has no issue to download new javascript client library with new API. With mobile client this update requirement can be too painful for endusers, even impossible (if you have pre-installed app), so server API must be always 100% backward-compatible and reliable.  So until CloudMade server API is out of beta, we are using own “web to mobile” proxy for geocoding. I’m sure later we can rely on backward-compatibility on actual service, and can skip own GW.

 

/Jaak Laineste

[hidden email]

www.nutiteq.com

Phone: +372 777 8800

Mobile: +372 509 2586

Skype: nutiteq

 

 

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleg Shaniuk
Sent: 26. veebruar 2009. a. 12:49
To: Samuel Pickard
Cc: CloudMade Development mailing list
Subject: Re: [CM Dev] Geocoding onto a mobile device

 

Hello Samuel,

First of all - thanks for using our services!

About JSON vs XML - last one will give pretty big output in some cases, so, using it on mobile devices can be a bit memory-consuming thing, while you can get free C++ code for JSON, available for free modification, etc (sample, using boost: http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx ). But, we are thinking now about implementing XML return from our services...

Now, for coordinate resolving: you getting coordinates in lon-lat and have to convert them to pixels starting from top-left corner of world map. When you getting a tile, it has url like: http://server/apikey/style_id/tile_size/zoom/x/y.png. X and Y are offsets from top-left in tiles, to get offset in pixels you have to multiply them by tile_size which is 256 for web and 64 for mobile (but you actually can use both sizes in web and mobile as well). Z is for zoom level. style_id - defines which style of map you want to use. So, tile with coordinates http://...../256/10/10/11.png has pixel offset X = 10 x 256; Y = 11 x 256; The point that belongs to this tile have X,Y in bounds:

10 x 256 <= X < 11 x 256

11 x 256 <= Y< 12 x 256

for example P(2561, 2820) belongs to this tile.

Ok, now, how to translate lot-lan to pixels?

you should have: lot-lan coordinates and zoom level,

also, if tile size is 256x256, you have 18 zoom steps, if tile size is 64x64 - you have 20 zoom steps,

this is because zoom 0 for 256x256 is equal to zoom 2 for 64x64 tiles... (you're getting the picture of the world - 256x256 pix)

now you can get pixel offset, using this code:

(M_PIl is in math.h)

#define M_PIl 3.1415926535897932384626433832795029L /* pi */

#define DEG_TO_RAD (M_PIl/180)
#define RAD_TO_DEG (180/M_PIl)

class PixelProjection
{
  double *Ac, *Bc, *Cc, *zc;

  public:
  PixelProjection(int levels=18, tileSize ts = 256) {

// you can set here 64 for 64x64 tiles, but then you'll get 20 zoom steps, so, you have to set levels = 20 
  Ac = new double[levels];                                    
  Bc = new double[levels];
  Cc = new double[levels];
  zc = new double[levels];
  int d, c = ts;
  for (d=0; d<levels; d++) {
  int e = c/2;
  Bc[d] = c/360.0;
  Cc[d] = c/(2 * M_PIl);
  zc[d] = e;
  Ac[d] = c;
  c *=2;
  }
  }
  void fromLLtoPixel(double &x, double &y, int zoom) {
  double d = zc[zoom];
  double f = minmax(sin(DEG_TO_RAD * y),-0.9999,0.9999);
  x = round(d + x * Bc[zoom]);
  y = round(d + 0.5*log((1+f)/(1-f))*-Cc[zoom]);
  }
  void fromPixelToLL(double &x, double &y, int zoom) {
  double e = zc[zoom];
  double g = (y - e)/-Cc[zoom];
  x = (x - e)/Bc[zoom];
  y = RAD_TO_DEG * ( 2 * atan(exp(g)) - 0.5 * M_PIl);
  }
};

Hope, this will help you to make your app. Feel free to contact us for any related questions.

--

RO

 

On Wed, Feb 25, 2009 at 9:42 PM, Samuel Pickard <[hidden email]> wrote:

Hello everyone,

I'm sorry if this question makes me sound like I'm the most stupid
person here.  I've had a look at the documentation, and I can't see the
answer.

I've written a C++ application for mobile phones (not iPhones, but
ordinary ones like Motorola RAZR and Nokia 6630 etc) that shows
CloudMade maps, and it works very nicely, thank you.

I want to be able to add routing and geocoding data to it, so when I get
a location from the phone, I can mark on the map where I think the user
is.  I can see that there is an API for both of these things, which is
wonderful, but I don't know how to interpet the response data.  Firstly,
the Geocoding API seems to only return JSON data, which isn't very
useful to my little C++ app - is their an XML version or should I write
my own web service to wrap the results?

Secondly, when I get a response from the Geocoding or routing APIs, how
do I translate this to a location on my maps?  How do I know exactly
where to pin the image to say 'here it is'?  I've got a lat/lon, and
I've been returned a tile.  How do I know where on my tile my lat/lon is?

I can see that this has been done in the example applications, but what
is the algorithm?

Thanks

Sam
_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev




--
--
RO


_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev
Reply | Threaded
Open this post in threaded view
|

Re: Geocoding onto a mobile device

Oleg Shaniuk

Hi Jaak,

Interesting about mobile-friendly XML - is it public or your internal solution? Also, cool to get feedbacks about our services - it helps a lot for development and making choices about technology stack.

--

RO


On Thu, Feb 26, 2009 at 3:59 PM, Jaak Laineste <[hidden email]> wrote:

Hello,

 Btw, we are using own server-side parser with mgmaps Java ME SDK, this makes more mobile-friendly XML (minimum data, short tags, some requests are consolidated etc) and compresses data. In Java ME there are gzip implementations available, perhaps there is also on C++.

 

 Another reason to prefer own mobile server-side is to have own full control over API – web servers who are relying on own javascript library tend to be a bit too liberal with new version updates, and forgetting about backward-compatibility. In Web/ajax client has no issue to download new javascript client library with new API. With mobile client this update requirement can be too painful for endusers, even impossible (if you have pre-installed app), so server API must be always 100% backward-compatible and reliable.  So until CloudMade server API is out of beta, we are using own “web to mobile” proxy for geocoding. I’m sure later we can rely on backward-compatibility on actual service, and can skip own GW.

 

/Jaak Laineste

[hidden email]

www.nutiteq.com

Phone: +372 777 8800

Mobile: +372 509 2586

Skype: nutiteq

 

 

 

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleg Shaniuk
Sent: 26. veebruar 2009. a. 12:49
To: Samuel Pickard
Cc: CloudMade Development mailing list
Subject: Re: [CM Dev] Geocoding onto a mobile device

 

Hello Samuel,

First of all - thanks for using our services!

About JSON vs XML - last one will give pretty big output in some cases, so, using it on mobile devices can be a bit memory-consuming thing, while you can get free C++ code for JSON, available for free modification, etc (sample, using boost: http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx ). But, we are thinking now about implementing XML return from our services...

Now, for coordinate resolving: you getting coordinates in lon-lat and have to convert them to pixels starting from top-left corner of world map. When you getting a tile, it has url like: http://server/apikey/style_id/tile_size/zoom/x/y.png. X and Y are offsets from top-left in tiles, to get offset in pixels you have to multiply them by tile_size which is 256 for web and 64 for mobile (but you actually can use both sizes in web and mobile as well). Z is for zoom level. style_id - defines which style of map you want to use. So, tile with coordinates http://...../256/10/10/11.png has pixel offset X = 10 x 256; Y = 11 x 256; The point that belongs to this tile have X,Y in bounds:

10 x 256 <= X < 11 x 256

11 x 256 <= Y< 12 x 256

for example P(2561, 2820) belongs to this tile.

Ok, now, how to translate lot-lan to pixels?

you should have: lot-lan coordinates and zoom level,

also, if tile size is 256x256, you have 18 zoom steps, if tile size is 64x64 - you have 20 zoom steps,

this is because zoom 0 for 256x256 is equal to zoom 2 for 64x64 tiles... (you're getting the picture of the world - 256x256 pix)

now you can get pixel offset, using this code:

(M_PIl is in math.h)

#define M_PIl 3.1415926535897932384626433832795029L /* pi */

#define DEG_TO_RAD (M_PIl/180)
#define RAD_TO_DEG (180/M_PIl)

class PixelProjection
{
  double *Ac, *Bc, *Cc, *zc;

  public:
  PixelProjection(int levels=18, tileSize ts = 256) {

// you can set here 64 for 64x64 tiles, but then you'll get 20 zoom steps, so, you have to set levels = 20 
  Ac = new double[levels];                                    
  Bc = new double[levels];
  Cc = new double[levels];
  zc = new double[levels];
  int d, c = ts;
  for (d=0; d<levels; d++) {
  int e = c/2;
  Bc[d] = c/360.0;
  Cc[d] = c/(2 * M_PIl);
  zc[d] = e;
  Ac[d] = c;
  c *=2;
  }
  }
  void fromLLtoPixel(double &x, double &y, int zoom) {
  double d = zc[zoom];
  double f = minmax(sin(DEG_TO_RAD * y),-0.9999,0.9999);
  x = round(d + x * Bc[zoom]);
  y = round(d + 0.5*log((1+f)/(1-f))*-Cc[zoom]);
  }
  void fromPixelToLL(double &x, double &y, int zoom) {
  double e = zc[zoom];
  double g = (y - e)/-Cc[zoom];
  x = (x - e)/Bc[zoom];
  y = RAD_TO_DEG * ( 2 * atan(exp(g)) - 0.5 * M_PIl);
  }
};

Hope, this will help you to make your app. Feel free to contact us for any related questions.

--

RO

 

On Wed, Feb 25, 2009 at 9:42 PM, Samuel Pickard <[hidden email]> wrote:

Hello everyone,

I'm sorry if this question makes me sound like I'm the most stupid
person here.  I've had a look at the documentation, and I can't see the
answer.

I've written a C++ application for mobile phones (not iPhones, but
ordinary ones like Motorola RAZR and Nokia 6630 etc) that shows
CloudMade maps, and it works very nicely, thank you.

I want to be able to add routing and geocoding data to it, so when I get
a location from the phone, I can mark on the map where I think the user
is.  I can see that there is an API for both of these things, which is
wonderful, but I don't know how to interpet the response data.  Firstly,
the Geocoding API seems to only return JSON data, which isn't very
useful to my little C++ app - is their an XML version or should I write
my own web service to wrap the results?

Secondly, when I get a response from the Geocoding or routing APIs, how
do I translate this to a location on my maps?  How do I know exactly
where to pin the image to say 'here it is'?  I've got a lat/lon, and
I've been returned a tile.  How do I know where on my tile my lat/lon is?

I can see that this has been done in the example applications, but what
is the algorithm?

Thanks

Sam
_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev




--
--
RO


_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev



--
--
RO

_______________________________________________
Dev site list
[hidden email]
http://lists.cloudmade.com/listinfo/dev