主题位置: 通讯与导航 
» 论坛 » 通讯与导航 » 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现(附程序,免费 ...
locked 本帖已锁定
旧帖 2008-06-18 22:04:47
Post #1
说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现(附程序,免费 ...
最近爬山的时候想弄个卫星地图给我的手机导航,就在网上东找西找,也发现几个取GOOGLE卫星图片的工具软件,不过用起来总是不顺,主要是如下这几个问题:取的图片精度太低,不能取100米或50米的卫星图片;或者拼接出来的最终地图尺寸太小,难以做超过10000*10000的大图;或者就是取一会儿就会被GOOGLE识别出而封堵了IP;再就是无法取GOOGLE TERRAIN的等高线图;还有就是有些不能自动生成MAP文件,这个要手工用OZI校准也是个繁重的工作;还有就是要收费的

所以就萌生了自己研究一下并写个小程序的念头。

借用磨房的宝地,将相关的技术问题和程序实现与大家交流和讨论一下。
这里仅做GPS地图方面的程序学习和技术研究的交流,请大家使用我提供的代码或程序之前,认真阅读MAPS.GOOGLE.COM的《使用条款》。对于我提供的代码、程序,或者是GOOGLE的卫星地图的不正当使用,可能导致的一切问题,本人概不负责^-^

下面要提供的一些技术文档或代码,都是在写这个小程序中用到的,很多来自网上的文章或者网友提供的代码,这里就不一一指出了,先行谢过。

还有就是我时间有限,只能晚上有空的时候慢慢整理逐贴贴出来,请XDJM谅解了
之翼 于 2008-06-20 14:17:23 编辑
旧帖 2008-06-18 22:12:48
Post #2
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
我第一次在磨房混在磨房发贴,不知道转贴一些其他地方来的文字行不行。
不过,都是与这个主题有关的技术文字了。

首先要自动生成OZI/SMARTCOMGPS可以用的已经校准的.MAP文件,就得知道该文件的格式定义,下面的这个说明是不可以不看的。

OZI MAP文件格式详解


Map File Format

In the text below the lines in the map file are marked with a dot.

Only those parameters which can be modified/created by the user are described, parameters which are used for special cases are not described.

The lines in green are optional

The Map File

The lines are in the order they are in the map file.


--------------------------------------------------------------------------------

Header and Version of File

OziExplorer Map Data File Version 2.1

--------------------------------------------------------------------------------

Title of Map - any text string

Brisbane Region

--------------------------------------------------------------------------------

Link to map image file

D:OziMapsregionalsouth.ozf2
Can be 1 of 2 things

1 TIFF scale factor - redundant, no longer used and has been replaced by line below
1 ,Map Code, - only used for special types of maps - Note - cannot be modified by the user but must be there.

--------------------------------------------------------------------------------

Datum settings

WGS 84,, 0.0000, 0.0000,WGS 84 - Note - for normal maps only the datum in the first field is used the rest of the parameters are for datum shifts and there is normally no need for these to be modified by the user.

--------------------------------------------------------------------------------

Reserved fields, the lines must be there

Reserved 1
Reserved 2

--------------------------------------------------------------------------------

Magnetic Variation entry - degrees,minutes

Magnetic Variation,,,E

--------------------------------------------------------------------------------

Map Projection

Map Projection,Lambert Conformal Conic,PolyCal,No,AutoCalOnly,No,BSBUseWPX,Yes
Parameters

Map Projection - must match the projection name used in OziExplorer
PolyCal - the next parameter is Yes if Polynomial calibration is used and No if not
AutoCalOnly - Yes if calibration cannot be adjusted by the user No if it can
BSBUseWPX - For BSB images only, Yes if the calibration equations contained in the BSB file are used.

--------------------------------------------------------------------------------

Calibration points, there are always 30
Only 9 points can be modified from within OziExplorer but OziExplorer will use the full 30 if they exist in the .map file.

Point01,xy, 494, 235,in, deg, 24, 0,S, 148, 0,E, grid, , , ,S
Point02,xy, 4076, 238,in, deg, 24, 0,S, 154, 0,E, grid, , , ,S
Point03,xy, 4011, 2854,in, deg, 28, 0,S, 154, 0,E, grid, , , ,S
Point04,xy, 550, 2851,in, deg, 28, 0,S, 148, 0,E, grid, , , ,S
Point05,xy, , ,in, deg, , ,S, , ,E, grid, , , ,S
Point06,xy, , ,in, deg, , ,S, , ,E, grid, , , ,S
...
Point30,xy, , ,in, deg, , ,N, , ,W, grid, , , ,N

--------------------------------------------------------------------------------

Projection setup parmeters, all on one line.

Projection Setup, 0.000000000, 152.000000000, 1.000000000, 2500000.00, 100000.00, -24.666667000, -27.333333000,,,
Parameters

Latitude Origin
Longitude Origin
K Factor
False Easting
False Northing
Latitude 1
Latitude 2
Height - used in the Vertical Near-Sided Perspective Projection
Sat - not used
Path - not used

--------------------------------------------------------------------------------

A marker line, it contains no information but is used as a file marker, must be there

Map Feature = MF ; Map Comment = MC These follow if they exist
Map Features, there are 3 lines per feature

Line 1 Parameters

Number
Name
Latitude
Longitude
Show Format - not used
Fore Color
Back Color
Symbol Name
Create Waypoint
Waypoint Name
Format Type - internal use
Line 2 - the link to the picture, if there is no picture a blank line must be there
Line 3 - the description of the feature, if no description the blank line must be there

MF, 1,MF 1 , -26.557302, 152.679007, 0, 16777215, 16711680, ,1,MF1
c:picturesphoto5.jpg
This is a good camping spot
MF, 2,MF 7 , -26.713354, 153.249176, 0, 16777215, 16711680,Asterisk.bmp ,1,MF7
Map Comments, there are 2 lines per comment

Line 1 Parameters

Number
Latitude
Longitude
Show Format - not used
Fore Color
Back Color
Width
Height
Font Size
Font Style
Line 2 - The text for the comment

MC, 1, -26.572626, 152.512726, 0, 0, 65280, 68,20,6,0
Map Comment 1
MC, 2, -26.661532, 152.633450, 0, 0, 13158342, 182,82,13,1
Map Comment 2 This is a large map comment
MC, 3, -26.659946, 152.634492, 0, 0, 13158342, 182,82,13,1
Map Comment 3
Attached file marker, .plt, .wpt, .evt, .pnt files can be included

Track File = TF These follow if they exist
The attached files - not limited to just track files

TF,e:GpsMapData0_2.plt
TF,e:GpsMapDataaa_demo1.plt
TF,e:GpsMapData0_test.plt
TF,e:GpsMapData1_test.plt
TF,e:GpsMapDataaaa.pnt
TF,e:GpsMapDatanames.pnt

--------------------------------------------------------------------------------

The Moving Map section marker

Moving Map Parameters = MM? These follow if they exist
Use in Moving Map, if this parameter is set to No then the map will be excluded when looking for a new map to change to when using moving map mode. It does not affect other map find functions.

MM0,Yes
Number of Map border points (corner markers)
Only 4 points can be set graphically in OziExplorer but up to 100 points can be used when derived from other sources, such as importing BSB charts.

MMPNUM,4
The x, y pixel location of each border point, there must be an entry for each border point.
These are used by OziExplorer as the map loads to determine the map border points.

MMPXY,1,494,234
MMPXY,2,4076,238
MMPXY,3,4012,2855
MMPXY,4,549,2852
The lat, lon position of each border point, there must be an entry for each border point.
These values are used in the map find and moving map functions when looking for maps.
If these values are not there then the map will never be found.
If these values do not agree with the MMPXY points (after map calibration is applied) then map finding in moving map will not function correctly.
These values will be overwritten by the calculated value from the above x, y points every time the map is saved.

MMPLL,1, 147.999332, -23.998496
MMPLL,2, 154.000701, -23.999946
MMPLL,3, 154.001025, -28.001546
MMPLL,4, 147.998983, -28.001469
The scale of the image meters/pixel, its calculated in the left / right image direction.
It is calculated each time OziExplorer is run, the value in the file is used when searching for maps of "more detailed" scale.

MM1B,170.352987

--------------------------------------------------------------------------------

The lat/lon grid setup

LL Grid Setup
LLGRID,No,10 Min,Yes,8421504,255,16711935,10 Min,16777215,8421504,9,1,Yes,x
Parameters

LLGRID - identifier
Grid On - Yes = display grid
Grid spacing - number and unit
Autoscale - Yes = autoscale on
Degree line color
Minute line color
second line color
label spacing - number and unit
label fore color
label back color
label size
label - show on all screens
x - ignore
The Other grid setup

Other Grid Setup
GRGRID,No,10 Km,Yes,255,16711680,10 Km,16711680,16777215,9,1,Yes,Yes,No,x
GRGRID - identifier
Grid On - Yes = display grid
Grid spacing - number and unit
Autoscale - Yes = autoscale on
Km line color
Meter line color
label spacing - number and unit
label fore color
label back color
label size
label - show on all screens
Clip to neat line
No meters shown in label ??
Show last 3 digits in label ??
x - ignore
The position the map will display when it is opened

MOP,Map Open Position,3008,2324
The map image width and height - not used, just for information

IWH,Map Image Width/Height,4440,3590
旧帖 2008-06-18 22:22:35
Post #3
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
首先看看行:

The scale of the image meters/pixel, its calculated in the left / right image direction.
It is calculated each time OziExplorer is run, the value in the file is used when searching for maps of "more detailed" scale.

MM1B,170.352987

地图中每个像素多少米?

计算的方法就是:计算截取到的地图的左上角和右上角两点经纬度之间的距离,除以地图横向的像素总数,就可以得到。下面是计算两点经纬度之间距离的代码:

double rad(double d)
{
    return d * 3.1415926535897 / 180.0;
}

double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
    double radLat1 = rad(lat1);
    double radLat2 = rad(lat2);
    double a = radLat1 - radLat2;
    double b = rad(lng1) - rad(lng2);
    double s = 2 * asin(sqrt(pow(sin(a/2), 2) + cos(radLat1)*cos(radLat2)*pow(sin(b/2),2)));
    s = s * 6378.137 * 1000; //m not km
    return s;
}
旧帖 2008-06-18 22:39:04
Post #4
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
GOOGLE的卫星图片,都是256*256像素的小块组成,每一个小块由一串由“qrst”的字母序列来表示。这个方面在网上搜索一下,有很多文字介绍。进入MAPS.GOOGLE.COM网站看卫星图片时,还有一个放大倍数的也很重要,决定了图片的精度。每放大倍数提升一级,原来256*256大小的图片,就会裂变为4个256*256的图片了。最大的倍数是20,缩小一级就减一。例如广州,就只提供最大级别为19的精度。

所以我们如果要截取某个地方某个放大倍数的图片的时候,就要由这些信息首先计算出“qrst”字母序列来。下面是计算的代码。返回的序列前面加上了GOOGLE MAPS服务器的URL和相关的参数。

BOOL GetQuadtreeAddress(double dlong, double dlat, int nLevel, CString& cstrAddress)
{
    double PI = 3.1415926535897;

    nLevel--;

    // now convert to normalized square coordinates
    // use standard equations to map into mercator projection
    double x = (180.0 + dlong) / 360.0;
    double y = -dlat * PI / 180; // convert to radians
    y = 0.5 * log((1 + sin(y)) / (1 - sin(y)));
    y *= 1.0/(2 * PI); // scale factor from radians to normalized
    y += 0.5; // and make y range from 0 - 1
    cstrAddress = "http://kh0.google.com/kh?v=27&t=t"; // google addresses start with t
    CString lookup = "qrts"; // tl tr bl br
    while (nLevel--)
    {
        // make sure we only look at fractional part
        x -= floor(x);
        y -= floor(y);
        cstrAddress = cstrAddress + lookup.GetAt((x >= 0.5 ? 1 : 0) + (y >= 0.5 ? 2 : 0));
        // now descend into that square
        x *= 2;
        y *= 2;
    }
    return TRUE;
}
旧帖 2008-06-18 22:40:51
Post #5
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
忘记说了,这里提供的代码都只考虑在北纬和东经范围内的情况。没有考虑纬度和经度为负值时的情况
旧帖 2008-06-18 22:43:27
Post #6
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
这里的代码,都已经考虑地球是一个球体,进行了投影计算的
旧帖 2008-06-18 22:52:53
Post #7
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
上面的代码,讲到了由经纬度计算qrst序列的方法,有了这个qrst序列,就可以让我们取到某处的256*256的卫星图片了。然而取到的这个图片,所代表的却是某个经纬度范围内的。那么,如果我们能计算出这个图片所代表的经纬度范围,就可以利用它做最终的.MAP文件的自动校准了。

计算方法如下:

struct _LONGLAT_OF_QRST
{
    char    qrst[24];
    double  flongmin;
    double  flongmax;
    double  flatmin;
    double  flatmax;
    double  flong;
    double  flat;
};
typedef struct _LONGLAT_OF_QRST LONGLAT_OF_QRST;
typedef struct _LONGLAT_OF_QRST *PLLONGLAT_OF_QRST;


double NormalToMercator(double y)
{
    double PI = 3.1415926535897;

    y -= 0.5;
    y *= 2 * PI;
    y = exp(y * 2);
    y = (y-1)/(y+1);
    y = asin(y);
    y = y * (-180.0/PI);
    return y;
}


BOOL GetCoordinatesFromAddress(CString cstrqrst, LONGLAT_OF_QRST *plloq)
{
    // get normalized coordinate first
    double x = 0.0;
    double y = 0.0;
    double scale = 1.0;

    cstrqrst.MakeLower();
    lstrcpy(plloq->qrst, (LPCTSTR) cstrqrst);

    cstrqrst = cstrqrst.Mid(1); // skip the first character

    while (cstrqrst.GetLength() > 0)
    {
        TCHAR c;
        scale *= 0.5;
        c = cstrqrst.GetAt(0); // remove first character

        if (c == 'r' || c == 's'wink
        {
            x += scale;
        }
        if (c == 't' || c == 's'wink
        {
            y += scale;
        }
        cstrqrst = cstrqrst.Mid(1);
    }

    plloq->flongmin = (x - 0.5) * 360;
    plloq->flongmax = (x + scale - 0.5) * 360;
    plloq->flong    = (x + scale * 0.5 - 0.5) * 360;
    plloq->flatmax  = NormalToMercator(y);
    plloq->flatmin  = NormalToMercator(y + scale);
    plloq->flat     = NormalToMercator(y + scale * 0.5);

    return TRUE;
}

经纬度范围存入LONGLAT_OF_QRST结构中,记录了该256*256图片的四个边或四个点的经纬度值
旧帖 2008-06-18 22:55:06
Post #8
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
晕,上面的括号竟然变成了表情符号
旧帖 2008-06-18 23:11:37
Post #9
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图 ...
现在来考虑要做的GOOGLE地图的位置和范围

简单的方法就是直接给出地图的左上角和右下角的两点经纬度,取下这两点之间(经纬度做矩形处理,实际就是4点)所有的卫星图片,这样就可以做一个矩形的地图了。所以按下面的图示设计地图的范围。

其中经纬度的获得,大家可以安装一个GOOGLE EARTH,直接查看你要取的某个山脉或某个城镇的经纬度即可。GOOGLE EARTH的OPTIONS里可以更改经纬度的显示格式。



旧帖 2008-06-18 23:19:57
Post #10
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
洗澡睡觉去,明天有空再继续了。
旧帖 2008-06-19 06:45:47
Post #11
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
  学习中 +5个好评……
旧帖 2008-06-19 09:58:11
Post #12
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
大部分GIS软件都是WGS84坐标,WGS84中地球是个椭球
如果哪天在iphone上做3D的可以学习楼主的经验
楼主写代码的时候也可多考虑一下可移植性,iphone 3G这样的平台未来会比较适合这类应用,可以寄希望于google发布iphone版的google earth,如果他不发布,楼主可以自己做

----------------------------------------
会心处不必在远

旧帖 2008-06-19 14:14:23
Post #13
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图 ...
在MAPS.GOOGLE.COM上看卫星图片的时候,每一个256*256图片都是用一个qrst序列来表示其服务器上的URL地址,但是对于GOOGLE的地形地表(terrain)的图片来说,却是采取的另外一个表示方法,这个大家可以读一下这段文字描述:

For Google map, the url of a tile looks like : http://mt1.google.com/mt?n=404&v=w2.12&x=130&y=93&zoom=9 using x and Y for the tile coordinates, and a zoom factor. The zoom factor goes from 17 (fully zoomed out) to 0 (maximum definition). At a factor 17, the whole earth is in one tile where x=0 and y=0. At a factor 16, the earth is divided in 2x2 parts, where 0<=x<=1 and 0<=y<=1. and at each zoom step, each tile is divided into 4 parts. So at a zoom factor Z, the number of horizontal and vertical tiles is 2^(17-z)

根据这个算法,网上也能搜索到一些根据经纬度来计算这个URL地址的代码,但是几乎见到的都是没有考虑球体投影的代码,计算出来的结果,在纬度方面偏差很大,显然不能用于GPS定位和导航。

考虑球体投影后,我修正的代码如下:


BOOL GetQuadtreeAddress(double dlong, double dlat, int zoom, CString& cstrAddress)
{
    double PI = 3.1415926535897;

    // now convert to normalized square coordinates
    // use standard equations to map into mercator projection
    double x = (180.0 + dlong) / 360.0;
    double y = -dlat * PI / 180; // convert to radians
    y = 0.5 * log((1 + sin(y)) / (1 - sin(y)));
    y *= 1.0/(2 * PI); // scale factor from radians to normalized
    y += 0.5; // and make y range from 0 - 1

    int nx, ny;
    nx = (int) floor(x * pow(2, (17-zoom)));
    ny = (int) floor(y * pow(2, (17-zoom)));

    cstrAddress.Format("http://mt0.google.com/mt?n=404&v=w2p.71&x=%d&y=%d&zoom=%d", nx, ny, zoom);
    return TRUE;
}


这里的函数名称,就直接用了计算qrst序列时的名字,以便对应着看,大家就不要直接从英文字母的意思上去理解了。
旧帖 2008-06-19 14:28:19
Post #14
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图的程序实现
对应GOOGLE TERRAIN的X, Y, zoom表示方法,同样也有一个根据x, y, zoom值来计算每一个256*256像素图片的四个边(或者说四个顶点)的经纬度值的算法,代码如下:

struct _LONGLAT_OF_XYZOOM
{
    int     nx;
    int     ny;
    int     nzoom;
    double  flongmin;
    double  flongmax;
    double  flatmin;
    double  flatmax;
    double  flong;
    double  flat;
};
typedef struct _LONGLAT_OF_XYZOOM LONGLAT_OF_XYZOOM;
typedef struct _LONGLAT_OF_XYZOOM *PLLONGLAT_OF_XYZOOM;


double NormalToMercator(double y)
{
    double PI = 3.1415926535897;

    y -= 0.5;
    y *= 2 * PI;
    y = exp(y * 2);
    y = (y-1)/(y+1);
    y = asin(y);
    y = y * (-180.0/PI);
    return y;
}


BOOL GetCoordinatesFromAddress(int nx, int ny, int nzoom, LONGLAT_OF_XYZOOM *plloq)
{
    plloq->nx = nx;
    plloq->ny = ny;
    plloq->nzoom = nzoom;

    // get normalized coordinate first
    double x = 0.0;
    double y = 0.0;
    double scale = 1.0;

    scale = 1.0 / (double)pow(2, (17 - nzoom));
    x = (double) nx / (double)pow(2, (17 - nzoom));
    y = (double) ny / (double)pow(2, (17 - nzoom));

    plloq->flongmin = (x - 0.5) * 360;
    plloq->flongmax = (x + scale - 0.5) * 360;
    plloq->flong    = (x + scale * 0.5 - 0.5) * 360;
    plloq->flatmax  = NormalToMercator(y);
    plloq->flatmin  = NormalToMercator(y + scale);
    plloq->flat     = NormalToMercator(y + scale * 0.5);

    return TRUE;
}

经纬度范围存入LONGLAT_OF_XYZOOM结构中,记录了该256*256图片的四个边或四个点的经纬度值
旧帖 2008-06-19 15:01:46
Post #15
Re: 说说从GOOGLE MAPS网站上截图制作GPS导航地图 ...
上面基本上将GOOGLE的卫星图片在服务器上的URL计算方法都讲到了。我的文字功底差,比较凌乱,大家感兴趣的就勉强坚持下,呵呵。现在说说怎么取到这个URL上的图片:

有了URL后,我们就可以在程序窗口上开一个WEBBROWSER的控件,连接到这个URL上取回并显示该图片。
图片取到后,WEBBROWSER得到OnDocumentComplete事件。这时,我们就可以把该控件上显示的图片截取下来,并保存到自己的电脑上。我在程序里做了另外一个窗口,用于显示从WEBBROWSER控件上截取到的256*256图片,一方面可以用于调整真实卫星图片显示在WEBBROWSER控件上的偏移位置,再者也可以看着程序在快速地存取GOOGLE卫星图片,也是一个蛮有快感的体验。

程序窗口如下:



locked 本帖已锁定
快速回复
内容