Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site













SourceForge.net Logo

GoogleMaps

 

Example using GoogleMaps static API to display the map of given location

Description

The examples show how to obtain map content from GoogleMaps and display it within U++ application.

Result

 

 

 

GoogleMaps.h

 

#ifndef _GoogleMaps_GoogleMaps_h

#define _GoogleMaps_GoogleMaps_h

 

#include <CtrlLib/CtrlLib.h>

 

using namespace Upp;

 

#define LAYOUTFILE <GoogleMaps/GoogleMaps.lay>

#include <CtrlCore/lay.h>

 

#define IMAGECLASS GoogleMapsImg

#define IMAGEFILE <GoogleMaps/GoogleMaps.iml>

#include <Draw/iml_header.h>

 

void   SetGoogleMapsKey(const char *key);

String GetGoogleMap(double center_x, double center_y, int zoom, int cx, int cy,

                   const char *format = "png", String *error = NULL);

Image  GetGoogleMapImage(double center_x, double center_y, int zoom, int cx, int cy,

                        const char *format = "png", String *error = NULL);

double CvDeg(double deg, double minutes, double seconds);

 

Pointf GoogleMapsPixelToGps(Pointf center, int zoom, Point diff);

Pointf GoogleMapsPixelToGps(Pointf center, int zoom, Size sz, Point p);

Pointf GoogleMapsGpsToPixelDiff(Pointf center, int zoom, Pointf gps);

Pointf GoogleMapsGpsToPixel(Pointf center, int zoom, Size sz, Pointf gps);

 

Pointf ScanGPS(const char *s);

 

String FormatGPSX(double x);

String FormatGPSY(double y);

String FormatGPS(Pointf p);

 

bool MapDlg(Pointf& p);

 

#endif

 

 

 

Main.cpp

 

#include "GoogleMaps.h"

 

GUI_APP_MAIN {

    Pointf p(0, 51.477222);

    if(MapDlg(p))

        Exclamation("Marker position " + FormatGPS(p));

}

 

 

 

MapDlg.cpp

 

#include "GoogleMaps.h"

 

#define IMAGECLASS GoogleMapsImg

#define IMAGEFILE <GoogleMaps/GoogleMaps.iml>

#include <Draw/iml_source.h>

 

struct MapImage : public Ctrl {

    Image  map;

    String error;

    Point  home;

    

    Callback1<Point> WhenLeftClick;

    

    virtual void LeftDown(Point p, dword)

    {

        WhenLeftClick(p);

    }

    

    virtual void Paint(Draw& w) {

        Size sz = GetSize();

        w.DrawRect(sz, SColorPaper());

        if(IsNull(map))

            w.DrawText(0, 0, error);

        else {

            w.DrawImage(0, 0, map);

            Point p = GoogleMapsImg::Pin().GetHotSpot();

            w.DrawImage(home.x - p.x, home.y - p.y, GoogleMapsImg::Pin());

        }

    }

    

    MapImage() { SetFrame(ViewFrame()); BackPaint(); }

};

 

struct MapDlgDlg : public WithMapDlgLayout<TopWindow> {

    typedef MapDlgDlg CLASSNAME;

 

    Pointf   home;

    Pointf   center;

    MapImage map;

    

    void LoadMap();

    void SetHome();

    void MapClick(Point p);

    

    void ZoomIn();

    void ZoomOut();

    void Move(int x, int y);

    

    void   Set(Pointf p);

    Pointf Get() { return home; }

    

    MapDlgDlg();

};

 

void MapDlgDlg::SetHome()

{

    map.home = GoogleMapsGpsToPixel(center, ~zoom, Size(640, 640), home);

    gpsy.SetLabel("  " + FormatGPSY(home.y));

    gpsx.SetLabel("  " + FormatGPSX(home.x));

    map.Refresh();

}

 

void MapDlgDlg::LoadMap()

{

    map.map = GetGoogleMapImage(center.x, center.y, ~zoom, 640, 640, "png", &map.error);

    SetHome();

}

 

void MapDlgDlg::Move(int x, int y)

{

    center = GoogleMapsPixelToGps(center, ~zoom, Point(250 * x, 250 * y));

    LoadMap();

}

 

void MapDlgDlg::MapClick(Point p)

{

    home = GoogleMapsPixelToGps(center, ~zoom, Size(640, 640), p);

    SetHome();

}

 

void MapDlgDlg::Set(Pointf p)

{

    home = center = p;

    LoadMap();

}

 

void MapDlgDlg::ZoomIn()

{

    zoom <<= min((int)~zoom + 1, 21);

    LoadMap();

}

 

void MapDlgDlg::ZoomOut()

{

    zoom <<= max((int)~zoom - 1, 0);

    LoadMap();    

}

 

MapDlgDlg::MapDlgDlg()

{

    CtrlLayoutOKCancel(*this, "");

    

    Size sz = GetSize();

    Size msz = map.GetSize();

    sz += Size(640 - msz.cx, 640 - msz.cy);

    SetRect(sz);

 

    for(int i = 0; i < 22; i++)

        zoom.Add(i);    

    zoom <<= 17;

    zoom <<= THISBACK(LoadMap);

    zoomin <<= THISBACK(ZoomIn);

    zoomout <<= THISBACK(ZoomOut);

    

    left <<= THISBACK2(Move, -1, 0);

    left.SetImage(CtrlImg::SmallLeft());

    right <<= THISBACK2(Move, 1, 0);

    right.SetImage(CtrlImg::SmallRight());

    up <<= THISBACK2(Move, 0, -1);

    up.SetImage(CtrlImg::SmallUp());

    down <<= THISBACK2(Move, 0, 1);

    down.SetImage(CtrlImg::SmallDown());

    

    map.WhenLeftClick = THISBACK(MapClick);

}

 

bool MapDlg(Pointf& p)

{

    MapDlgDlg dlg;

    dlg.Set(p);

    if(dlg.Run() == IDOK) {

        p = dlg.Get();

        return true;

    }

    return false;

}

 

 

 

GoogleMaps.cpp

 

#include "GoogleMaps.h"

 

using namespace Upp;

 

#define LLOG(x) // LOG(x)

 

String apikey = "";

 

void SetGoogleMapsKey(const char *key)

{

    apikey = key;

}

 

String GetGoogleMap(double center_x, double center_y, int zoom, int cx, int cy,

                   const char *format, String *error)

{

    String request;

    request << "http://maps.google.com/maps/api/staticmap?center=" <<

               AsString(center_y) << ',' << AsString(center_x) <<

               "&zoom=" << zoom <<

               "&size=" << cx << 'x' << cy <<

               "&format=" << format <<

               "&sensor=false&key=" << apikey;

    HttpRequest r(request);

    String h = r.Execute();

    if(r.IsFailure())

        *error = r.GetErrorDesc();

    return h;

}

 

Image GetGoogleMapImage(double center_x, double center_y, int zoom, int cx, int cy,

                       const char *format, String *error)

{

    return StreamRaster::LoadStringAny(GetGoogleMap(center_x, center_y, zoom, cx, cy, format, error));

}

 

double CvDeg(double deg, double minutes, double seconds)

{

    return deg + (double)minutes / 60 + seconds / 3600;

}

 

static void sFetch(double& a, double *x, int& ii)

{

    a = CvDeg(x[0], x[1], x[2]);

    ii = 0;

}

 

int CharFilterH(int c)

{

    return c == 'e' || c == 'E' ? 'r' : c == '\'' || c == '\"' ? '@' : c;

}

 

Pointf ScanGPS(const char *s)

{

    String h = Filter(s, CharFilterH);

    Pointf r = Null;

    double x[3];

    CParser p(h);

    x[0] = x[1] = x[2] = 0;

    int ii = 0;

    while(!p.IsEof()) {

        if(p.IsDouble()) {

            if(ii < 3)

                x[ii++] = p.ReadDouble();

            else {

                if(IsNull(r.y))

                    sFetch(r.y, x, ii);

                else {

                    sFetch(r.x, x, ii);

                    break;

                }

                x[ii++] = p.ReadDouble();

            }

        }

        else

        if(p.Char('W') || p.Char('w')) {

            if(x[0] > 0)

                x[0] = -x[0];

            sFetch(r.x, x, ii);

        }

        else

        if(p.Char('r'))

            sFetch(r.x, x, ii);

        else

        if(p.Char('S') || p.Char('s')) {

            if(x[0] > 0)

                x[0] = -x[0];

            sFetch(r.y, x, ii);

        }

        else

        if(p.Char('N') || p.Char('n'))

            sFetch(r.y, x, ii);

        else

            p.SkipTerm();

    }

    if(!IsNull(r.y) && IsNull(r.x))

        sFetch(r.x, x, ii);

    return r;

}

 

String FormatDegree(double d, int decimals)

{

    if(IsNull(d))

        return Null;

    d = modulo(d + 180, 360) - 180;

    char sign = (d < 0 ? '-' : '+');

    if(d < 0) d = -d;

    int deg = ffloor(d);

    String cd = ToCharset(CHARSET_DEFAULT, "%c%ERROR: Invalid UTF-8 sequence: `"`,` CHARSET`_UTF8

Do you want to contribute?