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











SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord 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%d°", CHARSET_UTF8);

    if(decimals <= -2)

        return NFormat(cd, sign, deg);

    d = (d - deg) * 60;

    int min = ffloor(d);

    if(decimals <= -1)

        return NFormat(cd + " %02d\'", sign, deg, min);

    d = (d - min) * 60;

    String sec = FormatDoubleFix(d, decimals);

    if(!IsDigit(sec[1]))

        sec.Insert(0, '0');

    return NFormat(cd + " %02d\' %s\"", sign, deg, min, sec);

}

 

String FormatGPSX(double x)

{

    return IsNull(x) ? String() : FormatDegree(x, 2) + (x < 0 ? "W" : "E");

}

 

String FormatGPSY(double y)

{

    return IsNull(y) ? String() : FormatDegree(y, 2) + (y < 0 ? "S" : "N");

}

 

String FormatGPS(Pointf p)

{

    return FormatGPSY(p.y) + ' ' + FormatGPSX(p.x);

}

 

static const double sOffset = 268435456;

static const double sRadius = sOffset / M_PI;

 

static int LToX_(double x)

{

    return int(sOffset + sRadius * x * M_PI / 180);

}

 

static int LToY_(double y)

{

    return int(sOffset - sRadius * log((1 + sin(y * M_PI / 180))/(1 - sin( y * M_PI / 180))) / 2);

}

 

static double XToL_(int x)

{

    return ((x - sOffset) / sRadius) * 180 / M_PI;

}

 

static double YToL_(int y)

{

    return (M_PI / 2 - 2 * atan(exp((y - sOffset) / sRadius))) * 180 / M_PI;

}

 

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

{

    return Pointf(XToL_(LToX_(center.x) + (diff.x << (21 - zoom))),

                  YToL_(LToY_(center.y) + (diff.y << (21 - zoom))));

}

 

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

{

    return GoogleMapsPixelToGps(center, zoom, p - sz / 2);

}

 

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

{

    return Pointf((LToX_(center.x) - LToX_(gps.x)) >> (21 - zoom),

                  (LToY_(center.y) - LToY_(gps.y)) >> (21 - zoom));

}

 

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

{

    return (Sizef)sz / 2.0 - GoogleMapsGpsToPixelDiff(center, zoom, gps);

}

 

 

 

GoogleMaps.lay

 

LAYOUT(MapDlgLayout, 428, 340)

    UNTYPED(map, HSizePosZ(8, 136).VSizePosZ(8, 8))

    ITEM(Button, zoomout, SetLabel(t_("-")).RightPosZ(104, 24).TopPosZ(8, 20))

    ITEM(DropList, zoom, RightPosZ(40, 60).TopPosZ(8, 19))

    ITEM(Button, zoomin, SetLabel(t_("+")).RightPosZ(8, 24).TopPosZ(8, 20))

    ITEM(Button, up, RightPosZ(56, 24).TopPosZ(40, 40))

    ITEM(Button, left, RightPosZ(88, 40).TopPosZ(80, 24))

    ITEM(Button, right, RightPosZ(8, 40).TopPosZ(80, 24))

    ITEM(Button, down, RightPosZ(56, 24).TopPosZ(104, 40))

    ITEM(Button, cancel, SetLabel(t_("Cancel")).RightPosZ(72, 56).BottomPosZ(8, 24))

    ITEM(Button, ok, SetLabel(t_("OK")).RightPosZ(8, 56).BottomPosZ(8, 24))

    ITEM(Label, gpsy, SetFrame(BlackFrame()).RightPosZ(8, 120).TopPosZ(164, 24))

    ITEM(Label, gpsx, SetFrame(BlackFrame()).RightPosZ(8, 120).TopPosZ(192, 24))

END_LAYOUT

 

 

 

 

 

Do you want to contribute?